Skip to content

feat(work-ledger): kirocrew-work tools and kirocrew-worker agent (phase 2) - #9152

Merged
bolichen97 merged 1 commit into
mainfrom
feat/work-ledger-tools
Sep 7, 2026
Merged

feat(work-ledger): kirocrew-work tools and kirocrew-worker agent (phase 2)#9152
bolichen97 merged 1 commit into
mainfrom
feat/work-ledger-tools

Conversation

@iamwhatever

@iamwhatever iamwhatever commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Phase 2 of 4 of docs/request-for-change/rfc-conductor-work-ledger.md (revision v2, already on main). Builds on #8855, which landed the store with no tools.

Problem / Motivation

A conductor session dispatches work to child sessions and learns what happened by reading their transcripts. Four costs follow from that shape, and they are the RFC's motivation section: latency equals the patrol interval; every patrol cycle spends a model turn whether anything moved or not; a stalled worker, a dead worker and a worker mid-build all look identical (session_read_message returns "no new assistant message" for all three); and the worker's conclusion arrives as prose the conductor must interpret, so done is an inference the conductor makes over text a worker authored.

The obvious fix is withheld deliberately. session_send hands its body to enqueue_or_run_prompt — the same call the human composer uses — so a worker's text would be the conductor's next prompt, executed under the conductor's grants. Granting it downward turns every worker into an operator of its parent.

Why it matters

Without a structured record there is nothing for a probe to fingerprint, so a conductor patrol cannot be gated the way monitor_start's pull-request subject already is: every tick costs a turn. And done staying an inference over prose is the failure mode that matters most — a worker that says the right words gets believed.

This PR does not fix the turn cost by itself; it lands the record the Phase 3 gate reads.

What changed (motivation → approach → change)

The requirement is not "a channel from worker to conductor" but a channel that cannot carry an instruction. So: a store, reached through the dashboard HTTP API with a server-resolved session key.

Four tools on one new opt-in server, kirocrew-work (src/kiro_crew/mcp_work.py):

tool caller surface
work_brief worker no arguments; its own item's title, acceptance, round, the conductor's latest decision, its own last status
work_report worker status / summary / artifacts / pr — and nothing else
work_ledger_read conductor no arguments; the record, every item, derived orphaned/stale, event tails, accept_batch
work_ledger_record conductor one action per call

The worker tool's guarantee is an absence, not a filter. work_report has no item_id, no session, no acceptance, no verdict and no state parameter, so a worker cannot write a conductor-owned field — a stronger property than an allowlist that must be kept correct as fields are added. test_a_report_writes_no_conductor_owned_field asserts it as a set difference over the whole item record, so a field added later joins the check automatically.

Identity is resolved, never asserted. Every tool routes through mcp_core.require_strict_session_key and sends the key that passed the gate; the route derives the conductor key and item id from bindings/<caller digest>.json. The lenient /proc ancestor walk is never reachable, which is what stops a subagent from resolving to its parent and reporting against the parent's item.

Dispatch is by what the caller resolves to, not by which spec mounted the tool — because a session can be a worker to its parent and a conductor to its own children. All four tools are advertised to everyone; the refusal happens at call time:

resolved caller brief / report read / record
binding, no ledger dir available no_ledger 404
ledger dir, no binding not_bound 403 available
both (second-level conductor) available available
neither not_bound 403 no_ledger 404

No autoApprove key on the server, and none may be added. An autoApproved MCP tool is approved inside kiro-cli and emits no permission request, so hooks.on_tool_call — the deny floor, the sensitive-path check, the governance ceiling — is never reached for it. test_the_managed_entry_has_no_auto_approve_key pins that so it cannot be added later without a failing test. Both halves get per-tool allowedTools grants instead, each spec granting only the tools that answer it: the conductors get the two conductor tools (a worker tool would only ever answer them with a refusal), the worker gets the two worker tools (a worker that must ask permission to say it is blocked will not say it).

kirocrew-worker is the default agent's SUPERSET, which is v2's reversal of v1. A worker writes files, runs builds and drives git, so anything a narrowed spec withheld would be something some work item needs — the same defect an omitted agent on session_create produces by handing the child kirocrew-conductor, which has no fs_write. So _install_worker_agent appends to what build_agent_config() resolved rather than rewriting tools/allowedTools the way the conductor installers do: a tool added to the default agent tomorrow reaches the worker for free, and one the ceiling withholds there stays withheld here.

session_create's agent description is corrected. It said "Omit to use the default agent", which is wrong about the mechanism a conductor most depends on: create_session falls back to the caller's own agent, so a conductor that omits it gets a second conductor. A test asserts both the new wording and that the code it describes still behaves that way.

Channel agents are hard-blocked from all four tools, joining the seven already in CHANNEL_AGENT_BLOCKED_TOOLS: a channel agent has no dispatch relationship, and reading a brief would pull a private dispatch's acceptance bar into a channel other humans can see.

Registered in every registry that ratchets on a managed server: _MANAGED_MCP_SERVERS (opt-in), the CLI subcommand, _MANAGED_SERVER_SUBCOMMANDS, _MANAGED_SERVER_TOOL_MODULES, _MANAGED_SERVERS_CALLER_AWARE, OPT_IN_BIN_MCP_SERVERS, REFLEXIVE_TOOL_MODULES, cli_doctor._STRICT_IDENTITY_SERVERS, the security-posture schema registry list, and OWNED_KIRO_AGENT_FILES.

Deviations from the RFC

Four, each with its reason:

  1. accept is a route action, not a store action. The RFC's §Tools table omits accept entirely (this PR adds it, since a conductor needs an explicit write to promote a worker's claimed pr into the bar). It is not a seventh work_ledger.CONDUCTOR_ACTIONS member, because Phase 1 pins that frozenset to exactly six (test_conductor_actions_are_exactly_six) and Phase 2 must not change Phase 1's semantics. The store gains one small function, apply_acceptance_update, and the action enum lives in the validation schema and the route. Its event is kind decision for the same reason — EVENT_KINDS is pinned to six, and promoting a bar is a conductor decision.

  2. Keys are folded through session_ledger.ledger_key() on both sides. The RFC says only "the key". One dashboard session is legitimately spelled both dashboard_chat-X and chat-X, so without the fold a conductor could bind the spelling session_create returned while the worker resolves the other one and reads not_bound against a binding that exists. The fold is applied to the caller's own key and to the worker_session_key supplied at bind.

  3. goal and create bootstrap the ledger; every other action requires one. The RFC does not say what opens a ledger. apply_conductor_action raises no_ledger when none exists, so something must call ensure_conductor — and making it these two means a conductor cannot bind or decide against a ledger that was never opened, while neither ergonomic order (goal-first or item-first) hits a dead end. Depth and parent_item derive from the caller's own binding, so a session that is itself a worker opens its ledger at depth+1.

  4. The depth cap permits a ledger at MAX_DEPTH that can create nothing. The RFC's prose says "that child's workers may not conduct"; Phase 1's actual code lets child_depth reach 2 and refuses create at record.depth >= MAX_DEPTH. The test follows the code: a third-level session opens a ledger at depth 2 and is refused depth_exceeded on its first create. Same practical cap (two levels of dispatch), reported one call later than the prose implies.

Also worth flagging, though not a deviation: the routes refuse an unknown field rather than dropping it, unlike session_ledger's pre-filter. A silently dropped item_id would answer 200, telling a worker its write landed where it aimed it.

Tests

test/test_work_ledger_tools.py (31), test/test_mcp_work.py (32), test/test_worker_agent.py (18) — one per Phase 2 exit criterion, plus:

  • a two-conductor two-worker fixture: worker A's report reaches A's item, and B's item file is byte-identical afterwards
  • every error code asserted with its HTTP status, and the code→status map asserted exhaustive over the store's CODE_* constants so a new code cannot degrade to 400 unnoticed
  • a subagent (strict resolution answering nothing) refused on all four tools, with the HTTP helpers replaced by a raiser so a call without strict identity fails the test rather than passing silently
  • accept_batch piped into the real goal-conductor/scripts/accept_eval.py as a subprocess, asserting it returns a verdict per item from the store's own five-value vocabulary
  • a worker sets pr: 999111; the claim is visible on the item row and absent from every accept_batch entry
  • all four dispatch-table cells against both tool halves
  • the default agent spec carries neither the entry nor an @kirocrew-work ref, asserted on both spec-writing loops — and a refresh keeps an existing grant current while never introducing one
  • the schema caps assert-equal against the store's MAX_* constants, since validation cannot import the store on the gateway's request path

test/test_work_ledger.py — Phase 1's "nothing imports this module" grep becomes an allowlist with one entry, keeping its anti-proliferation intent. One entry is the strong form: even mcp_work.py does not import the store, reaching it over the HTTP API like every other consumer. The scan also had a real bug — it excluded by basename, so the new dashboard/handlers/work_ledger.py was silently skipped; it now excludes by path and asserts the routes module is in the candidate set.

The three suites whose pinned spec surface this widens (test_conductor_agent, test_pipeline_conductor_agent, test_mcp_managed_caller_identity) are extended in the same commit — that is what those ratchets are for.

Manual verification

N/A — unit coverage is sufficient here: every surface is a pure function of an on-disk store and a request, both driven directly in-test, and the one external dependency (accept_eval.py) is executed for real rather than mocked. The gateway was not restarted and no live session was bound.

Related Issues

no linked issue: Phase 2 of 4 of the RFC; the tracking issue closes with Phase 4. Builds on #8855 (Phase 1) and #8842 (RFC doc).

@iamwhatever
iamwhatever requested a review from a team as a code owner September 6, 2026 23:21
@iamwhatever
iamwhatever requested a review from pepmach September 6, 2026 23:21
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Sep 6, 2026
@iamwhatever
iamwhatever force-pushed the feat/work-ledger-tools branch from c3e02aa to 9e1f12d Compare September 6, 2026 23:23
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review — ✅ human override accepted

Human judgment by @iamwhatever overrides the GPT 5.6 finding for 8063500c02448933b02871018709a39f3e1235a9; the recorded reason is authoritative for this commit.

This comment is updated in place on each push.

The model was not re-run because an authorized human decision supersedes it.

False positive or not applicable? A repository writer can comment:
/ai-review override gpt 8063500c02448933b02871018709a39f3e1235a9: <one-sentence reason>

@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention labels Sep 6, 2026
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5.1) — ✅ PASS

Design-level review of 8063500c02448933b02871018709a39f3e1235a9 — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

Design-Verdict: PASS

A narrow, unforgeable worker→conductor data channel whose safety rests on absent parameters and resolved identity, not filters — sound, proportionate, and reversible (opt-in, pre-launch).

The problem is real (conductor inferring worker state from transcripts), the shape is right (a store reached by server-resolved session key rather than a message that could become the conductor's prompt), and the load-bearing guarantees are structural: the worker tool has no conductor-owned parameter, identity is resolved strictly rather than asserted, and every ratchet registry is updated. The four documented RFC deviations (accept as a route action, key folding, goal/create bootstrap, off-by-one depth reporting) each carry a defensible reason and none opens a one-way door. Incremental delivery (turn-cost gate deferred to Phase 3) is stated honestly and leaves nothing shipped that can't be walked back.

[DESIGN-REVIEWED] 8063500

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

First Principles Review (Fable 5.1) — ✅ PASS

Premise-level review of 8063500c02448933b02871018709a39f3e1235a9 — why this exists and whether the shipped surface is the smallest honest version. Updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

First-Principles-Verdict: PASS

Every item traces to the on-main RFC or to a named security boundary (agent-untrusted-over-its-ceiling, channel/external-content containment); the worker→conductor channel deliberately cannot carry an instruction, which is the whole point.

What this change ships

Intent: let a conductor learn what its dispatched workers did from a forgery-resistant structured record instead of by reading transcripts. ADDITION (RFC Phase 2, revision v2 already on main).

  1. New opt-in kirocrew-work MCP server, four tools — justified (cause-level: replaces transcript inference with data)
  2. New kirocrew-worker agent = default superset + work server + reporting prompt — justified
  3. work_report has no conductor-owned parameter (absence-as-guarantee) — justified
  4. accept route action beyond the RFC's six store actions — justified (declared deviation; promotes a claimed pr into the bar)
  5. Conductors auto-approve the two read/record tools; worker auto-approves brief/report — justified
  6. All four tools blocked for channel agents + refused server-side for channel/mirrored sessions — justified (containment boundary)
  7. work-ledger dir OS-masked and fenced as sensitive path — justified (keystone: agent untrusted over its records)
  8. session_create's agent description corrected — justified (names the second-conductor-with-no-fs_write defect)
  9. Second-level-conductor / depth-capped bootstrap routing — derived from Phase-1 depth machinery
  10. Registration across ~10 ratcheted registries — mechanical

Subtractions

  • ROUTE_CODES (work_ledger.py:94): zero production consumers — the eleven codes are used individually at _refuse_* sites; the frozenset only feeds test_the_route_owned_codes_are_disjoint. A hand-maintained second enumeration with nothing enforcing sync to the call sites. Minor; drop it and assert the disjointness invariant directly if kept.

[FIRST-PRINCIPLES-REVIEWED] 8063500

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Opus 4.8 Review — ✅ no blocking findings

Reviewed 8063500c02448933b02871018709a39f3e1235a9 — this comment is updated in place on each push.

Review details

The candidate dies under falsification:

  • Premise 2 is false in practice. session_control.create_session (session_control.py:898–902) forces the child into the caller's own workspace (workspace = getattr(caller_slot, "workspace", ...)), with explicit agent_workspace_mismatch and caller_workspace_changed refusals guarding consistency. A worker whose _created_by folds to conductor_key (already required by the worker_not_owned check) was therefore born in the conductor's workspace. A cross-workspace bind requires a post-creation workspace move of the worker — not established, only "could".
  • Premise 1 is unverified. That the conductor's own slot is unresolvable via both conductor_key and dashboard_{conductor_key} while it is a live, _recognize_session-accepted caller is "could", not a concrete condition.
  • The check is defense-in-depth. The real memory boundary is authorize_target's workspace_mismatch refusal (session_control.py:1520–1523) plus the OS sandbox mask on the work-ledger leaf (added in this diff to _CREW_HIDDEN_LEAVES/_CREW_SECRET_LEAVES), not this best-effort slot lookup.

Neither (a) nor the harm chain re-derives without "could/might", and the candidate self-rates low. Nothing else in the diff grounds a new finding at the bar.

No findings.

[OPUS-REVIEWED] 8063500

Verdict parsed from the review's SHA-scoped output markers for commit 8063500c02448933b02871018709a39f3e1235a9.

False positive or not applicable? A repository writer can comment:
/ai-review override fable 8063500c02448933b02871018709a39f3e1235a9: <one-sentence reason>

@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Sep 6, 2026
@iamwhatever
iamwhatever force-pushed the feat/work-ledger-tools branch from 9e1f12d to f6a70a2 Compare September 6, 2026 23:41
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Sep 6, 2026
@iamwhatever
iamwhatever force-pushed the feat/work-ledger-tools branch from f6a70a2 to 9128982 Compare September 7, 2026 00:29
@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Sep 7, 2026
@iamwhatever
iamwhatever force-pushed the feat/work-ledger-tools branch from 9128982 to 3a94d67 Compare September 7, 2026 01:15
@iamwhatever

Copy link
Copy Markdown
Collaborator Author

/ai-review override gpt 3a94d67: The boot-path finding on handlers/init.py does not hold — handlers/work_ledger.py introduces no module to the gateway boot: its only non-sibling import, messaging.link, is already imported at module scope by handlers/_shared.py:33, handlers/cron.py:49 and dashboard/state.py:62, all of which this module already depends on, and session_control (the one module that would be new) is deliberately imported inside _reaches_a_channel for exactly that reason; registration is identical to the 40 sibling handler imports in that file, session_ledger included, so a lazy wrapper here would be machinery no sibling has. The other two blocking findings on this head are fixed at cause: the outbound-mirror bypass now fails closed through session_control._has_channel_mirror, and the accept action refuses a missing or empty acceptance instead of clearing the bar.

@github-actions github-actions Bot removed the readiness: action required A blocking check or review needs attention label Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

AI-review override not recorded: keep the reason to 500 characters or fewer.

@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: checking Automated validation is still running labels Sep 7, 2026
@github-actions github-actions Bot added the readiness: checking Automated validation is still running label Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Human judgment recorded, but the following reviewer lane(s) could not be re-run automatically: GPT 5.6. Re-run the lane's latest workflow run for a955a0b0213b9affb2f81bac8e1160c5b20a0806 manually from the Actions tab.

@github-actions github-actions Bot added the merge conflict Branch has merge conflicts with its base — author must resolve before merge label Sep 7, 2026
@iamwhatever
iamwhatever force-pushed the feat/work-ledger-tools branch from a955a0b to f8292d1 Compare September 7, 2026 06:06
@iamwhatever

Copy link
Copy Markdown
Collaborator Author

/ai-review override gpt f8292d1: Maintainer-approved acceptance of the no-new-work-on-gateway-boot-path finding on _install_worker_agent() — the seventh sibling of six identical spec writes already on rebuild_agent_config, harm rated bounded/MEDIUM by the adjudicator, and lazy install was measured to be non-functional because session_create validates the agent name against the boot-time materialized-agent snapshot before the spawn path runs.

Head f8292d18a is a955a0b02 rebased onto current main (a7ea47b19, the PR had gone CONFLICTING). The only conflicting file was security.py, where #9089 moved large spans; resolved by taking main's file wholesale and re-applying this PR's single "work-ledger" fence entry beside "ledger". Payload otherwise byte-identical. 2580 tests pass locally across the touched suites, test_security.py included — the _dir_holds_sensitive_leaf breakage on earlier heads is fixed upstream.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Human judgment recorded

@iamwhatever marked the gpt AI finding as false positive, not applicable, or explicitly accepted for f8292d18a2f266faf7cc2e6e7f5336a6fce8bc8a.

Maintainer-approved acceptance of the no-new-work-on-gateway-boot-path finding on _install_worker_agent() — the seventh sibling of six identical spec writes already on rebuild_agent_config, harm rated bounded/MEDIUM by the adjudicator, and lazy install was measured to be non-functional because session_create validates the agent name against the boot-time materialized-agent snapshot before the spawn path runs.

This decision applies only to this commit. A new push requires a new judgment.

@github-actions github-actions Bot added readiness: passed Eligible automated validation passed for the current revision merge conflict Branch has merge conflicts with its base — author must resolve before merge and removed merge conflict Branch has merge conflicts with its base — author must resolve before merge readiness: checking Automated validation is still running labels Sep 7, 2026
…se 2)

Phase 2 of the conductor work ledger: the four MCP tools, their dashboard
routes, the opt-in kirocrew-work server, and the kirocrew-worker agent.

A conductor learns what its workers did by reading transcripts. This lands the
narrow write path in the other direction: a worker writes a schema-bounded
status against the ONE item it was bound to, and the conductor reads that record
as data. work_report has no item_id, no session, no acceptance, no verdict and
no state parameter, so an out-of-bounds write is unrepresentable rather than
validated away, and nothing in the path reaches enqueue_or_run_prompt - which is
why this is a store and not the session_send grant the design refuses.

Identity is resolved, never asserted: every tool routes through
require_strict_session_key, and the route derives the conductor key and item id
from the caller's own binding file. Which half of the server answers depends on
what the caller resolves to - a binding makes it a worker, a ledger directory
makes it a conductor, both make it a second-level conductor, neither gets
not_bound / no_ledger.

The server is opt-in and carries no autoApprove key, for the reason the two
existing managed servers document: an autoApproved MCP tool never reaches
hooks.on_tool_call, so the deny floor and governance ceiling would be bypassed.
Both conductors and the worker get per-tool grants instead, each half only for
the tools that answer it.

The worker agent is the default agent's SUPERSET plus that one server, not a
narrowing: a worker writes files, runs builds and drives git, so anything a
narrowed spec withheld would be something some work item needs.
@iamwhatever
iamwhatever force-pushed the feat/work-ledger-tools branch from f8292d1 to 8063500 Compare September 7, 2026 08:05
@iamwhatever

Copy link
Copy Markdown
Collaborator Author

/ai-review override gpt 8063500: Maintainer-approved acceptance of the no-new-work-on-gateway-boot-path finding on _install_worker_agent() — the seventh sibling of six identical spec writes already on rebuild_agent_config, harm rated bounded/MEDIUM by the adjudicator, and lazy install was measured non-functional because session_create validates the agent name against the boot-time materialized-agent snapshot before the spawn path runs.

Head 8063500c0 = previous head rebased onto 09c54c743 (#9183 split security.py into a package; the single "work-ledger" fence line moved to src/kiro_crew/security/paths.py beside "ledger"), plus one fix from the local pre-push review lanes: stale now reads the worker slot's .running (a turn in flight) rather than slot existence, so an idle worker whose tab is open but which stopped without reporting is flagged — which is the case the flag exists for. orphaned keeps the existence test. Local Opus lane: no findings; local GPT lane: that one finding, fixed.

@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: passed Eligible automated validation passed for the current revision labels Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Human judgment recorded

@iamwhatever marked the gpt AI finding as false positive, not applicable, or explicitly accepted for 8063500c02448933b02871018709a39f3e1235a9.

Maintainer-approved acceptance of the no-new-work-on-gateway-boot-path finding on _install_worker_agent() — the seventh sibling of six identical spec writes already on rebuild_agent_config, harm rated bounded/MEDIUM by the adjudicator, and lazy install was measured non-functional because session_create validates the agent name against the boot-time materialized-agent snapshot before the spawn path runs.

This decision applies only to this commit. A new push requires a new judgment.

@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running readiness: passed Eligible automated validation passed for the current revision and removed merge conflict Branch has merge conflicts with its base — author must resolve before merge readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention readiness: passed Eligible automated validation passed for the current revision labels Sep 7, 2026

@bolichen97 bolichen97 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tech Lead review — approved.

no-new-builtin-apps: not engaged. The rule is file-scoped to src/kiro_crew/apps/builtins/** and closes the app set (a new app.json that rides the wheel and cannot be uninstalled). kirocrew-worker is an agent spec installed by rebuild_agent_config, the seventh sibling of six already there (_install_lite_agent_fallback, _install_knowledge_agent, _install_research_agent, _install_heartbeat_agent, _install_conductor_agent, _install_pipeline_conductor_agent). No app directory, no App Store surface, nothing under apps/builtins/. The agent set is not closed by any rule in AUTOSDE.yaml.

MCP-first: satisfied in the compliant direction. The capability ships as four MCP tools first; the new kirocrew mcp-work verb is the server-launch subcommand (same shape as mcp-dashboard), not an LLM-facing CLI command lacking a twin.

Statelessness: holds. mcp_work.py carries no per-caller or per-session process state — every module-level binding is an immutable str/tuple constant, no cache, no accumulator. All four tools resolve identity per call through require_strict_session_key (never the lenient /proc walk) and forward to gateway routes that own the state. work_report taking no item_id/session parameter is the stronger form of the guarantee than a filter.

Scope: coherent. 28 files / +3631, of which ~1762 is test code; production weight is the route module, the server, the agent installer and the schemas. RFC Phase 2 with revision v2 already on main, four deviations declared with reasons, every ratchet registry updated in the same commit. No drive-by.

Findings: none blocking. GPT's no-new-work-on-gateway-boot-path finding carries a maintainer override on this exact head, and the reasoning is measured rather than asserted — lazy install was tested and is non-functional because session_create validates the agent name against the boot-time materialized-agent snapshot. Design PASS, First Principles PASS, Opus no blocking findings, UX PASS.

One follow-up, not a blocker: docs/architecture/mcp.md § Server and tool inventory still lists four managed servers. kirocrew-work is registered in _MANAGED_MCP_SERVERS, so by that table's own stated criterion it belongs there alongside the opt-in kirocrew-dashboard, with its four tools. AGENTS.md routes "MCP servers or tools (adding, changing, statelessness)" to that doc with a same-commit obligation. Not holding the merge for it: another push would re-run the full 60-check matrix and invalidate the SHA-bound GPT override for one table row, and the surface is already documented on main in the RFC, config.md and dev-fleet.md. Please add the row in a follow-up.

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.

2 participants