Skip to content

mcp ask: require the final round's answer; refuse sealed state when the host clock fails (findings 10, 11) - #616

Merged
MattJackson merged 4 commits into
predevfrom
lane-mcpfix-ask
Oct 8, 2026
Merged

MattJackson merged 4 commits into
predevfrom
lane-mcpfix-ask

Conversation

@MattJackson

@MattJackson MattJackson commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Closes MEDIUM findings 10 and 11 in plane-mcp.md.

Finding 10: the state minted for the final ask round, re-sent with no inputResponses, proceeded to the tool because the final redeem ran before the answered check. The answered check now runs first; the refusal spends nothing (spec 379-390).

Finding 11: a failed clock.now was read as 0, so every sealed state (busbar's own and relayed) passed its TTL and fresh states were stamped at the epoch. DoorSeal::now now returns Option and nothing substitutes 0. busbar's own ask refuses with the new ClockUnavailable (ask_clock_unavailable, text names the clock, not the signing key); a relayed ask and a task relay refuse with Unavailable (ask_unavailable) carrying CLOCK_UNAVAILABLE. Relayed-state sealing is one function, seal_relayed, shared by both sites. Fail closed (spec 1576, 3295-3370).

RED plants (fail by assertion on the unfixed tree):

  • 6643353: crates/busbar-plane-mcp/src/tests/ask.rs final-round test; tests/door_clock.rs own and relayed state under a failed clock.
  • b7fc13f: tests/door_clock.rs relayed ask and task relay refuse as ask_unavailable naming the clock.

Proof (Latchkey): job cli-7fd0ebd0-cd55-4ee6-9342-92c6d4608dbb, RED on b7fc13f exit 1 (the two relay plants fail), GREEN on head adb1d4d exit 0 (fmt, clippy -D warnings, crate tests, root busbar build). Earlier job cli-bc1e7ee9-fe67-456d-b802-926abc4d9a23 proved the 6643353 plants (RED 1, GREEN 0).

Test seam: DoorSeal, Site, decide_ask, seal_relayed are pub and doc(hidden) so an integration test (which may use unsafe host fakes; the lib forbids it) can drive them. No test retired.

… clock refuses sealed state, own and relayed (finding 11)

Plants for the two MEDIUM findings; both fail by assertion on the unfixed tree:
- ask: the state minted for the final round, re-sent with no inputResponses, proceeds
  to the tool (spec 379-390, the ask gate).
- door: a host whose clock.now fails (served and failing, or unserved) accepts a lapsed
  own state and a lapsed relayed state because now=0, and mints a state stamped at the
  epoch (spec 1576, 3295-3370 fail closed).
…aled state (findings 10, 11)

10: decide() redeemed the final round's state before the answered check, so the state
minted for the last round, re-sent with no inputResponses, proceeded to the tool. The
answered check now runs before the final redeem; the refusal spends nothing (spec 379-390,
the ask gate; ask.rs module promise).

11: DoorSeal::now returns None when clock.now fails, and the reads that fed a sealed
state's window (decide_ask, relay_ask, the task relay's mint and open) no longer
substitute 0: decide_ask treats a failed clock as no sealer, relay_ask refuses as no
sealer, the task relay mints and opens nothing. Fail closed (spec 1576, 3295-3370).
…used as ask_unavailable naming the clock (finding 11)

The relayed state's seal is one function, seal_relayed, shared by relay_ask and the task relay
(behaviour unchanged: a clock failure still answers as NoSealer). The plants call it with each
site's window and assert the refusal reason ask_unavailable and the CLOCK_UNAVAILABLE words;
both fail by assertion (spec 3295-3370, fail closed).
…y text (findings 10, 11)

A clock.now failure answered as NoSealer, whose text says the deployment has no
auth.signing_key. busbar's own ask and a relayed state presented to decide_ask now refuse
with ClockUnavailable (reason word ask_clock_unavailable); a relayed ask and a task relay's
park refuse with Unavailable (ask_unavailable) carrying CLOCK_UNAVAILABLE. Still fail
closed, never the epoch (spec 3295-3370).
@MattJackson
MattJackson enabled auto-merge October 7, 2026 23:07
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

promote into predev: BOARD @adb1d4d5e: 2 failing test row(s), 10 DENY row(s)

Failing tests (2)

crate test step first panic
transport_dropped_in_serves a_dropped_in_transport_registers_through_the_one_fold_and_serves test:dropped-in-tcp-transport crates/busbar/tests/transport_dropped_in_serves.rs:168:13: busbar exited (ExitStatus(unix_wait_status(512))) before serving; log:
-p busbar --test transport_dropped_in_serves test target failed test:dropped-in-tcp-transport

DENY rows (10)

gate row detail
construction one-pick-site 3 production call site(s) of 'pick_among(' (ceiling 2): crates/busbar-kernel-egress/src/walk.rs:298; crates/busbar-llm/src/engine/exhaustion/fallback.rs:120; crates/busbar-llm/src/engine/pipeline.rs:8
kind-isolation kind-isolation:deps 3 finding(s), 93 shipped edge instance(s) over 32 class(es), 93 declaration(s); 57 '[[dep]]' row(s), 0 question(s): unlisted-dep-edge legacy -> plane busbar-llm -> busbar-plane-llm is a shipped edge w
kind-isolation kind-isolation:test-deps 4 finding(s), 44 test edge instance(s) over 26 class(es), 44 declaration(s); 27 '[[dep]]' row(s), 0 question(s): unlisted-dep-edge cleanliness -> legacy busbar-core-admin -> busbar-a2a is a test edge
kind-isolation-ship kind-isolation:deps 13 finding(s) over 93 shipped edge(s): ship-edge kernel -> hooks busbar-kernel -> busbar-hook-ranking is 'not-allowed': the architecture grants no kernel -> hooks edge, and the ship criterion is the a
kind-isolation-ship kind-isolation:test-deps 18 finding(s) over 44 test edge(s): ship-edge cleanliness -> export busbar-core-admin -> busbar-export-prometheus is 'not-allowed': the architecture grants no cleanliness -> export edge, and the ship
kind-isolation-ship kind-isolation:faces 3 finding(s) over 39 crate(s): foreign-entry crates/busbar busbar is kind 'root' and implements 'Transport' 1 time(s) in shipped source — the entry face of kind 'transport'. A trait implementation is
kind-isolation-ship kind-isolation:shape 2 deviation(s) over 10 crate(s): entry-count crates/busbar-transport-http busbar-transport-http implements 'Transport' 3 time(s) in shipped source (its 'impl' blocks plus its door tails); every crate
kind-isolation-ship kind-isolation:legacy-drain 3 finding(s): transitional-live qa/kind-isolation.toml 'busbar-a2a -> busbar-core-admin' (legacy drain: the retiring A2A engine's tests drive the admin surface that drained into the cleanliness tier)
ship-ready ship-ready:ship-twin 'kind-isolation-ship' is not green: kind-isolation:deps (a dependency the architecture does not grant is still in the graph); kind-isolation:test-deps (a dependency the architecture does not grant is
structure-lint structure-lint:plane-dup:unledgered 22 finding(s): PLANE-DUPLICATE (module): 'config.rs' — a2a:crates/busbar-a2a/src/a2a/config.rs decisions:crates/busbar-plane-decisions/src/config.rs voice:crates/busbar-voice/src/config.rs (the ledger

Judged against base 2bf9d9b37: 0 new red, 0 worse, 6 standing (excused).

tests passed: 15558, failed: 1. Run: https://github.com/GetBusbar/busbar/actions/runs/37700387361 . Artifact verdict-adb1d4d5e034f301bf654d35dd17882bd61228c9 (failures.json, junit.xml, raw.log; 90 days).

@MattJackson
MattJackson added this pull request to the merge queue Oct 7, 2026
MattJackson added a commit that referenced this pull request Oct 8, 2026
…d ahead) into lane-mcpfix-deadplane: purity keeps both source scans (no satisfier of an upstream's ask; no cross-plane route or unserved plane impl)
MattJackson added a commit that referenced this pull request Oct 8, 2026
…pfix-tasks: the relayed task leg opens the retry's state from this branch's state argument and keeps ask's rule that a clock that cannot be read opens nothing
Merged via the queue into predev with commit f64499e Oct 8, 2026
8 checks passed
@MattJackson
MattJackson deleted the lane-mcpfix-ask branch October 8, 2026 05:43
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.

1 participant