Skip to content

capability: exchange cockpit execution events with the OpenRig coordinator #421

Closed

Description

@smota

Kind: capability

Epic: #371

Part

When the project's metadata names OpenRig, the cockpit sends two things to that coordinator: a request to start or resume work, and the person's gate answer.
The coordinator returns the status the person needs to see.
No message goes to a builder, a tester, or a reviewer. The cockpit does not call a seat itself.
A coordinator message does not advance a gate.

Depends on

The execution-control capability, the person loop, and the project binding.

Acceptance boundary

Change class: high-assurance.

A configured project exchanges only those interactions with its coordinator. An unconfigured project has no such path.

Excludes

An event bus. Squad maps. Direct seat calls.

Part of #371

Replaces #379

Activity

  1. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 0
    role: product-manager
    status: skipped
    seat: pm.manager
    reason: Parent goal #371 already framed this part.
    body:
    Phase 0 skipped. Parent goal #371 already framed this part. Recorded by orch.arch so phase 2 can start on this admitted capability.

  2. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 1
    role: analyst
    status: skipped
    seat: pm.analyst
    reason: Acceptance is the capability body on #421.
    body:
    Phase 1 skipped. The acceptance is the capability body on #421. Recorded by orch.arch so phase 2 can start.

  3. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 2
    role: architect
    status: pass
    seat: orch.arch
    reason:
    body:
    Phase 2 — architect · #421 coordinator events

    Contract

    Only a project whose metadata names OpenRig talks to a coordinator. The address is the DEV coordinator on that project's record. The cockpit sends two kinds of message: start or resume, naming the project and the goal, and the person's gate answer, naming the gate and the subject. The coordinator returns a status. The cockpit shows that status as coordinator status. It is not the phase and it is not the gate status.

    A coordinator message cannot move a gate. If the coordinator cannot be reached, the cockpit shows coordinator unreachable, and a gate answer is still recorded. A project with no execution layer sends nothing.

    Boundary

    No other seat is addressed. No event bus. No new gate class. Tests may use a fake coordinator. They must show the request shape and that an unreachable coordinator does not drop the gate answer.

    Profile

    High-assurance. Builder dev.build-sr. Human acceptance is required on the open pull request before merge.

  4. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 3
    role: implementation-planner
    status: pass
    seat: orch.arch
    reason:
    body:
    Phase 3 — implementation plan · #421 only

    Branch

    feat/371-coordinator-events from origin/development, in .worktrees/feat/371-coordinator-events. Do not commit on the primary checkout.

    Files

    • Add a small coordinator client used only when the project record names OpenRig and has a DEV coordinator.
    • On start or resume, send one request with the project and the goal. On a filed gate answer, send one request with the answer, the gate, and the subject. Record the returned status separately from phase and gate state.
    • If the send fails, show coordinator unreachable and keep the gate answer.
    • If the project has no execution layer, send nothing.
    • Tests with a fake coordinator for the request shape, the status label, the refusal to move a gate, the unreachable case, and the no-layer case.

    Proof

    pnpm exec vitest run on the new coordinator-event tests.

    Out of scope

    #379 stays the note. Do not open a second capability. Do not address any seat except the configured coordinator. Do not file a live gate.

  5. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 4
    role: developer
    status: pass
    seat: dev.build-sr
    reason:
    body:
    Phase 4, #421 coordinator events. Branch feat/371-coordinator-events at 1cd3e87 from origin/development 87469a8, local and not pushed. New lib/cockpit-coordinator.mjs: devCoordinatorFor(binding) returns the record's DEV coordinator only when the binding is supported and names OpenRig, else null. It builds two events: start-or-resume {type, project, goal} and gate-answer {type, project, goal, answer, gate, subject}. Each is sent as one line, agentflow-cockpit , through rig send (execFile, no shell, 15 s timeout). answerThenTell files the line first and sends after. startThenTell sends only after the start-next-phase write succeeds. scripts/cockpit-server.mjs wires both and returns the reply under coordinator: {label: 'coordinator status', to, status}, separate from the decision and from the phase. A thrown, empty, or blank reply gives 'coordinator unreachable', and the filed answer stands. An address starting with '-' is never handed to the transport. A project with no layer or no DEV coordinator sends nothing. The gates file output is unchanged; the gate digest comes from an internal fileLine helper, because flow-limit pins that output's keys. docs/cockpit.md has a new Coordinator events section, and the #415 'sent nowhere else' line is corrected. Tests: lib/tests/cockpit-coordinator-events.test.mjs, 16 tests with a fake coordinator. They cover: binding rules, including a hand-edited record with no layer; exact request shapes for both events, including changes and block; no send for a refused line; unreachable on refused, empty, or blank replies, with the answer kept; no layer sends nothing; replies of 'agreed', 'phase 5 pass', and a confirmation line leave the gate waiting and the gate log and phase record byte-identical; only DEV is addressed, never PM; an option-like address is refused; events need all fields. Mutations, each caught: ignore the layer (1 fail), use the PM coordinator (8), send before filing (5), swallow unreachable as delivered (2), drop the address check (1), report the answer as the status (3). Run: vitest run lib/tests/cockpit-coordinator-events.test.mjs, 16/16 pass. pnpm is blocked in worktrees, so I used the repo's vitest binary. Full suite: 156 files, 1565 passed, 1 skipped. All 5 validators exit 0, and prettier is clean. Not done: the real rig send transport is not exercised by tests, per the rule against smoke-testing rig-calling code; its status is 'delivered' on exit 0, which is delivery to the coordinator's terminal, not a coordinator decision. No other seat, no event bus, no gate class, no second capability, no live gate.

  6. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 5
    role: tester
    status: skipped
    seat: dev.qa
    reason: Contract gap: terminal delivery is presented as coordinator status; phase 2 requires a coordinator reply
    body:
    Phase5 SKIPPED — #421 coordinator events. Contract gap, not a passing verdict. Independently executed dev.qa; launcher/executor codex, local CLI transport, no delegation.
    Exact commit1cd3e87ff10f4ec8153ac9358491245a9601909e in .worktrees/feat/371-coordinator-events; clean before/after. Linux x64, Nodev22.23.3, Vitest2.1.9.
    Phase2/3/4 read verified; phase4 #421 (comment) at revision629610d5b90775f6b31a8f2bc48d2ce285dbe6aebc9c4d5eb673f0ea2eaba2fc.

    Contract defect: phase4 explicitly discloses real rig transport returns delivered on rig send exit0, meaning terminal delivery rather than a coordinator reply. Phase2 requires coordinator-returned status. Architect orch.arch explicitly ruled at2026-10-11T21:02Z that this is not an accepted limit and directed phase5 skipped, hand review for phase6 return4. No real rig transport call is required or authorized to establish this disclosed gap. Fake replies do not certify real coordinator status.

    Executed commands from candidate:
    ../../../node_modules/.bin/vitest run --root . lib/tests/cockpit-coordinator-events.test.mjs —16passed.
    ../../../node_modules/.bin/vitest run --root . —156files passed,1565tests passed,1skipped,0failed.
    node scripts/validate-docs.mjs —119files,noerrors.
    node scripts/verify-agent-workflow.mjs —pass.
    node scripts/verify-hooks.mjs —pass.
    node scripts/validate-role-catalog.mjs —READY.
    node scripts/audit-reachability.mjs —READY.
    ../../../node_modules/.bin/prettier --check docs/cockpit.md lib/tests/cockpit-coordinator-events.test.mjs lib/cockpit-coordinator.mjs scripts/cockpit-server.mjs scripts/person-gates.mjs —pass.
    git status --short and git rev-parse HEAD —clean,SHAabove.

    Independent node --input-type=module fake-transport API probes pass for start event fields, write-before-send order, DEV-only address, separate coordinator status, no layer/no send, failed write/no send, thrown send/unreachable.21 gate-answer shape/status cases (three decisions x seven reply statuses) preserve filed result, send only after file, and blank/null replies become unreachable. Refused file sends nothing; thrown transport retains filed result.
    Initial mock omitted gateDigest and returned unreachable as designed, then corrected documented shape. Option-like address extra probe incorrectly expected devCoordinatorFor to return null; helper returns raw configured address, so no safety verdict inferred from that failed assertion. Targeted suite covers refusal before transport.
    No candidate source inspection/modification, live gate, actual rig transport or coordinator event send. Builder mutations are attributed, not independently repeated.
    Hand phase6 to rev.review to record skipped return to phase4 for terminal delivery being presented as coordinator reply/status. Candidate stays unchanged until recorded return. Human security/acceptance remains required.

  7. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 6
    role: reviewer
    status: skipped
    seat: rev.review
    reason: rig send exit 0 is terminal delivery, not a coordinator status (return to phase 4)
    body:
    Phase 6 — independent review · CHANGES_REQUESTED · 1cd3e87ff10f4ec8153ac9358491245a9601909e

    Verdict

    CHANGES_REQUESTED. Returned to phase 4. The candidate was not edited.

    Phase 2 requires the coordinator to return a status, shown as coordinator status, distinct from the phase and the gate. The real transport does not do that.

    rigTransport.send in lib/cockpit-coordinator.mjs calls rig send. On exit 0 it resolves { status: 'delivered' } and ignores any reply text. sendCoordinatorEvent then shows that string under the label coordinator status. Exit 0 means the message reached the coordinator's terminal. It is not a status the coordinator returned.

    The fake-transport tests can still pass, because a fake may return any status. They do not prove the real path. No live rig send was run for this review.

    Fix

    Do not present terminal delivery as coordinator status. The shown status has to be a reply from the coordinator, separate from delivery. If this transport cannot carry that reply, show coordinator unreachable, or a delivery fact that is not labeled coordinator status. Keep the rest: file or write first, send only to the DEV coordinator, send nothing with no layer, and never let the coordinator message move the gate.

    High-assurance human acceptance on the open pull request remains. This return does not waive it.

    Executed by: pi · Launcher: pi · Executor: pi · Transport: intercom-session · Delegation boundary: separate-local-session · Model: grok-4.7 · Seat: rev.review

  8. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 4
    role: developer
    status: pass
    seat: dev.build-sr
    reason:
    body:
    Phase 4 — return fix · 85b72a8 on feat/371-coordinator-events

    rig send exiting 0 is delivery only. Coordinator status is the coordinator's reply, or null when none came back. An unreachable send still keeps the gate answer.

    The builder had this edit uncommitted and then went idle. orch.arch committed it after cockpit-coordinator-events.test.mjs passed, 19 tests. The builder seat is still the author of the change.

  9. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 5
    role: tester
    status: pass
    seat: dev.qa
    reason:
    body:
    Phase5 PASS — #421 return fix at85b72a8aa2afa425b773382f5209473f046bdd19 in .worktrees/feat/371-coordinator-events, clean. Independent dev.qa execution, launcher/executor codex, local CLI transport, no delegation. Linux x64, Nodev22.23.3, Vitest2.1.9.
    Phase4 verified #421 (comment) at revision6caf489b5f913faba172361b32b119e02747cc137b765b4981eecda9a88ce49d.
    Architect at21:10Z supplied accepted transport contract: only coordinatorStatus string is a reply; missing/blank/legacy status field yields coordinatorStatus null with delivery delivered; throw yields delivery coordinator unreachable and null coordinatorStatus. QA probed this exact contract.

    Commands:
    ../../../node_modules/.bin/vitest run --root . lib/tests/cockpit-coordinator-events.test.mjs —19passed.
    ../../../node_modules/.bin/vitest run --root . —156files passed,1568tests passed,1skipped,0failed.
    node scripts/validate-docs.mjs —119files,noerrors.
    node scripts/verify-agent-workflow.mjs —pass.
    node scripts/verify-hooks.mjs —pass.
    node scripts/validate-role-catalog.mjs —READY.
    node scripts/audit-reachability.mjs —READY.
    ../../../node_modules/.bin/prettier --check lib/tests/cockpit-coordinator-events.test.mjs lib/cockpit-coordinator.mjs —pass.
    git status --short and git rev-parse HEAD —clean,SHAabove.

    Independent node --input-type=module black-box assertions:18 answer cases across agree/changes-requested/blocked and six transport replies (explicit accepted,blank,missing,legacy delivered,phase-like text,null). For each, file occurs before send, only DEV addressed, exact answer event checked, filed object bytes unchanged, result has distinct delivery and coordinatorStatus. Legacy {status:delivered} never becomes coordinatorStatus. Explicit reply only populates coordinatorStatus; text resembling phase pass stays separate and does not alter filed result. Throw reports coordinator unreachable, status null, and same filed object retained. Two start cases distinguish legacy delivery and explicit accepted reply.
    Preliminary schema-discovery probes explored other fields without asserting their contract; final checks match architect's specified coordinatorStatus shape.
    No real rig transport exercised, no actual coordinator event, source inspection/modification, or live gate filed. Fake-transport evidence certifies field separation and retention, not end-to-end coordinator reply infrastructure. Existing real transport remains delivery-only and exposes no reply as null; human security/acceptance remains required on open PR. Hand phase6 to rev.review.

  10. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 6
    role: reviewer
    status: pass
    seat: rev.review
    reason:
    body:
    Phase 6 — independent review · APPROVED · 85b72a8aa2afa425b773382f5209473f046bdd19

    Verdict

    APPROVED for the status split at 85b72a8aa2afa425b773382f5209473f046bdd19 on feat/371-coordinator-events. The phase 6 return is fixed. This is not human security or acceptance review. The candidate was not edited.

    Reviewed 1cd3e87..85b72a8 (2 files). Worktree was clean. Re-ran lib/__tests__/cockpit-coordinator-events.test.mjs: 19 passed. Re-probed the transport result.

    What holds

    • rig send exit 0 resolves an empty reply. Delivery is delivered. coordinatorStatus is null.
    • A legacy { status: 'delivered' } does not become coordinatorStatus. Only a non-blank coordinatorStatus string is shown as the coordinator's reply.
    • A thrown send is delivery coordinator unreachable and coordinatorStatus null. The filed answer is unchanged.
    • The reply is separate from the phase and the gate. A phase-like reply text does not move the gate.

    Residuals (not a return)

    • The real rig send transport still cannot carry a coordinator reply, so a live send has coordinatorStatus null. That is the accepted split, not a delivered status. No live rig send was run.
    • docs/cockpit.md still describes one coordinator-status field. Phase 7 should say delivery and coordinator status are separate, and that exit 0 alone leaves the reply null.
    • High-assurance human acceptance on the open pull request remains. Do not merge on this verdict.

    Executed by: pi · Launcher: pi · Executor: pi · Transport: intercom-session · Delegation boundary: separate-local-session · Model: grok-4.7 · Seat: rev.review

  11. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 7
    role: technical-writer
    status: pass
    seat: orch.arch
    reason:
    body:
    Phase 7 — technical writer · delivery and coordinator status are separate

    Commit bb400d5 on feat/371-coordinator-events. docs/cockpit-concepts-and-rules.md now says a send that exits 0 is delivery, not a reply. Coordinator status is only what the coordinator itself replied, and it is empty when none came back. It is not the phase and it is not the gate. A coordinator message cannot move a gate. If the coordinator cannot be reached, the gate answer still stands.

    No screenshot. No live coordinator was called.

  12. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    phase: 8
    role: pr-readiness
    status: pass
    seat: orch.arch
    reason:
    body:
    Phase 8 — PR readiness · not merged

    PR: #422
    Base: development
    Head: feat/371-coordinator-events, code 85b72a8 and docs bb400d5
    High-assurance. Merge owner is the person. Human acceptance is still required. Tests used a fake coordinator. Do not merge on this phase.

  13. smota commented on Oct 11, 2026

    @smota
    OwnerAuthor

    Closed as completed via PR #422 (commit 4dc19a1).

  14. github-actions commented on Oct 11, 2026

    @github-actions

    Integrated into development by PR #422: #422

    Merge commit: 4dc19a1dc6b6cbf77575d0868d13e360e6bcdecc
    Release/promotion to main is tracked separately.

  15. added
    integrated:developmentManaged by agentflow-sdlc integration lifecycle automation
    awaiting-releaseManaged by agentflow-sdlc integration lifecycle automation
    state:deliveredManaged by agentflow-sdlc integration lifecycle automation
    and removed on Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting-releaseManaged by agentflow-sdlc integration lifecycle automationintegrated:developmentManaged by agentflow-sdlc integration lifecycle automationkind:capabilityWork altitude: capabilitystate:deliveredManaged by agentflow-sdlc integration lifecycle automation

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions