Skip to content

docs(kanban): worker lane contract + review-required convention (closes #19931)#23483

Merged
teknium1 merged 1 commit into
mainfrom
docs/kanban-worker-lanes-contract
May 11, 2026
Merged

docs(kanban): worker lane contract + review-required convention (closes #19931)#23483
teknium1 merged 1 commit into
mainfrom
docs/kanban-worker-lanes-contract

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Closes the architectural-pin part of #19931 with docs + a small review-required convention, no kernel changes.

What's missing on main vs the issue's 6 architectural rules

# Rule State
1 Hermes Kanban owns lifecycle state ✓ already true (kanban kernel + KANBAN_GUIDANCE enforce "decompose, don't execute")
2 Code-changing workers transition success → blocked(review-required) ✗ missing — fixed here as a documented convention
3 Worker logs under <root>/kanban/logs/<task_id>.log ✓ already done via worker_logs_dir(board=...)
4 Workers non-interactive + sandboxed, env pinned to workspace ✓ already done — dispatcher injects HERMES_KANBAN_WORKSPACE / HERMES_KANBAN_TASK / etc.; --yolo mode for autonomous workers
5 Explicit assignee routing, unknown assignees don't silently invoke shell ✓ already done — skipped_nonspawnable lane + recent #23273 toolset-name validation
6 Worker outputs are reviewable artifacts ◐ partial — kanban_complete(metadata={...}) carries this; this PR documents the convention explicitly

What this PR ships

  • agent/prompt_builder.py::KANBAN_GUIDANCE: ~60 chars added to step 5 explaining the review-required exception. Auto-injected into every kanban worker's system prompt, so workers see the cue without loading any extra skill. Prompt size 3275/4096 chars; well under the test-enforced budget.
  • skills/devops/kanban-worker/SKILL.md: worked example for the kanban_comment (structured metadata) + kanban_block(reason="review-required: ...") pattern, slotted between the existing Coding-task and Research-task examples.
  • website/docs/user-guide/features/kanban-worker-lanes.md (new): the integrator-facing contract page. Covers the lane hierarchy, the three things every lane must provide (assignee, spawn mechanism, lifecycle terminator), the env vars the dispatcher injects, the review-required convention, the failure modes the kernel handles for free, and an explicit "external CLI worker lane" section flagged as deferred-pending-concrete-asker (with links back to Architecture: specialist worker lanes under Hermes Kanban orchestration #19931 and the closed-not-merged Codex PR feat: add Codex Kanban worker lane #19924).
  • website/sidebars.ts: link the new page under user-guide/features.

Why no kernel changes

  • "Code-changing task" is fuzzy. Forcing block-instead-of-complete on every code worker would break flows where no review is wanted (typo fixes, docs commits). Convention + visible cue is enough.
  • kanban_complete / kanban_block / kanban_comment already do everything needed. block_task accepts a free-form reason; comments are the durable structured-metadata channel; the dashboard already renders both.

Why no kanban_block(metadata=...) extension

The skill example uses kanban_comment(body=json.dumps(...)) followed by kanban_block(reason=...) — comments are the durable annotation channel. Extending kanban_block to take metadata would be a real new tool surface; not warranted by one convention.

What's NOT in this PR

External CLI worker lane runner (Codex CLI, Claude Code CLI, OpenCode CLI as kanban workers via dispatcher → <cli> --task=<id>). The dispatcher's spawn_fn parameter already supports plugin-shaped extension, but the per-CLI integration work (auth, sandbox policy, exit-code mapping, workspace injection) needs a concrete asker. The new docs page tells would-be integrators the contract any such lane must satisfy.

#19924 was the Codex-specific concrete proposal; it closed without merging. Until someone shows up with a concrete plugin proposal and a real workflow they're trying to enable, the docs-only path is the right shape.

Validation

Before After
KANBAN_GUIDANCE size ~3000 chars ~3275 chars (test_kanban_guidance_size still passes; budget is 1500–4096)
tests/tools/test_kanban_tools.py (kanban_guidance subset) 3/3 3/3
tests/tools/test_kanban_tools.py + tests/hermes_cli/test_kanban_db.py + test_kanban_core_functionality.py 294/294 294/294

Closes #19931.

Closes the architectural-pin part of #19931. Most of what that issue
asked for is already implemented (logs under kanban root, env-pinned
workspace, dispatcher routing of unknown assignees, lifecycle
ownership, structured handoff conventions). What was missing:

1. A written contract integrators can point at when adding a new
   worker lane shape, and
2. The "code-changing workers should not auto-promote success to
   done" convention.

This commit ships both as docs+convention layered on existing primitives.
No kernel changes — the kanban_complete / kanban_block / kanban_comment
surfaces already support the review-required pattern; we just hadn't
written it down or made it visible to workers.

Changes:

- `agent/prompt_builder.py::KANBAN_GUIDANCE`: append the review-required
  exception to step 5 of the lifecycle. Workers get the cue
  auto-injected into their system prompt — drop structured metadata
  into a kanban_comment first, then end with
  kanban_block(reason="review-required: <summary>") instead of
  kanban_complete when the work needs review. Total prompt size went
  from ~3000 to ~3275 chars; well under the 4096 budget enforced by
  test_kanban_guidance_size.

- `skills/devops/kanban-worker/SKILL.md`: add a worked example to the
  existing "Good summary + metadata shapes" section between the
  Coding-task and Research-task examples. Same shape as the others
  (kanban_comment with structured handoff JSON, then kanban_block with
  the human-readable reason). Plus a one-line guide on when to use
  kanban_complete vs the review-required pattern.

- `website/docs/user-guide/features/kanban-worker-lanes.md` (new): the
  integrator-facing contract. Covers the hierarchy, the three things
  every lane must provide (assignee, spawn mechanism, lifecycle
  terminator), the env vars the dispatcher injects, the
  review-required convention, the failure modes the kernel handles
  for free, and an explicit "external CLI worker lane" deferred-
  pending-concrete-asker section that links to #19931 and #19924.

- `website/sidebars.ts`: link the new page under user-guide/features.

The "specialist worker lanes for external CLI tools (Codex / Claude
Code / OpenCode)" runner is NOT shipped here. The dispatcher's
spawn_fn parameter already supports plugin-shaped extension; the
per-CLI integration work (auth, sandbox policy, exit-code mapping)
needs a concrete asker. The new docs page tells would-be integrators
the contract any such lane must satisfy.

Refs #19931
@teknium1 teknium1 merged commit ae83a54 into main May 11, 2026
13 of 16 checks passed
@teknium1 teknium1 deleted the docs/kanban-worker-lanes-contract branch May 11, 2026 01:15
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: docs/kanban-worker-lanes-contract vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8121 on HEAD, 8121 on base (➖ 0)

🆕 New issues (3):

Rule Count
invalid-argument-type 3
First entries
run_agent.py:7160: [invalid-argument-type] invalid-argument-type: Argument to function `build_anthropic_client` is incorrect: Expected `str`, found `str | dict[Unknown, Unknown] | Any | ... omitted 3 union elements`
run_agent.py:13287: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `(str & ~AlwaysFalsy) | (dict[Unknown, Unknown] & ~AlwaysFalsy) | (Any & ~AlwaysFalsy) | ... omitted 3 union elements`
run_agent.py:13284: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown, Unknown] | Any | ... omitted 3 union elements`

✅ Fixed issues (3):

Rule Count
invalid-argument-type 3
First entries
run_agent.py:13287: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `(str & ~AlwaysFalsy) | (dict[Unknown | str, Unknown | str | dict[str, str]] & ~AlwaysFalsy) | (Any & ~AlwaysFalsy) | ... omitted 3 union elements`
run_agent.py:13284: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`
run_agent.py:7160: [invalid-argument-type] invalid-argument-type: Argument to function `build_anthropic_client` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`

Unchanged: 4263 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Architecture: specialist worker lanes under Hermes Kanban orchestration

1 participant