Repository navigation
fix(pm): an accepted relay dispatch with no run is UNCONFIRMED under auto too, never a direct write - #22101
Merged
objectstack-fleet[bot] merged 9 commits intoOct 7, 2026
Conversation
… no run under auto, never a direct write An accepted relay dispatch whose run had not appeared in the start window fell back to the direct additive verbs under auto, booking the stroke against the seat's personal account. That arm is gone: no-run is exit 6 under auto exactly as under an explicit dispatch, and the self-test pin that held the fall-back now holds the ruled answer. Claude-Session: https://claude.ai/code/session_011SekRJwTRqXSmsP6xTSci4 Co-authored-by: Claude <noreply@anthropic.com>
…h no run under auto, never the direct POST Under auto, a no-run outcome printed the fall-back line and created the card directly as the seat's personal account; the relay run could then create a second card. No-run is now exit 6 under auto as under an explicit dispatch, the pin that held the fall-back holds the ruled answer, and the tool carries the no-run conformance probe. Claude-Session: https://claude.ai/code/session_011SekRJwTRqXSmsP6xTSci4 Co-authored-by: Claude <noreply@anthropic.com>
…ith no run under auto, never the direct mutation Under auto, a no-run outcome printed the fall-back line and sent the transfer mutation as the seat's personal account. No-run is now exit 6 under auto as under an explicit dispatch, the pin that held the fall-back holds the ruled answer, and the tool carries the no-run conformance probe. Claude-Session: https://claude.ai/code/session_011SekRJwTRqXSmsP6xTSci4 Co-authored-by: Claude <noreply@anthropic.com>
…h no run under auto, never the direct write The transport step moves out of main into writeThroughRoute: the relay's one dispatch or the direct verb, never both. Under auto a no-run outcome used to null the relay result and fall through to writeArtefact as the seat's personal account; it is now exit 6 as under an explicit dispatch. The live layer takes an optional deps door so the no-run conformance probe drives the real write step offline; the live path passes none. Claude-Session: https://claude.ai/code/session_011SekRJwTRqXSmsP6xTSci4 Co-authored-by: Claude <noreply@anthropic.com>
close-cards already answers an accepted dispatch with no run as UNCONFIRMED under every transport request and issues no direct write. It gains the relayMissProbe export the shared no-run conformance drives, and its offline driver accepts the conformance's sender; no behaviour of the tool changes. Claude-Session: https://claude.ai/code/session_011SekRJwTRqXSmsP6xTSci4 Co-authored-by: Claude <noreply@anthropic.com>
…D with zero direct writes fallbackText lost its last caller and is deleted with its pin; the header now says no outcome of an accepted dispatch is ever fallen back from, under any transport request. A new self-test battery discovers every sender from the source (any scripts/ file naming sendFleetWrite), drives each one's relayMissProbe through the real sendFleetWrite with an accepted dispatch whose run never appears (auto and explicit dispatch) or never completes (auto), and requires exit 6, one dispatch, zero direct writes and the shared UNCONFIRMED sentence; a direct-route control proves each recorder sees a write. A sender without the probe fails until it has one. Claude-Session: https://claude.ai/code/session_011SekRJwTRqXSmsP6xTSci4 Co-authored-by: Claude <noreply@anthropic.com>
…a crash Under a re-planted fall-back the result carries no relay outcome, and the shared-sentence case threw before it could record a failure. Each pin now reads false when there is no relay outcome, so an ablation reports the failed case and the self-test still reaches its verdict. Claude-Session: https://claude.ai/code/session_011SekRJwTRqXSmsP6xTSci4 Co-authored-by: Claude <noreply@anthropic.com>
Continues the released claim's branch at 4c5f2c1 (no rebase: the branch is shared). Claude-Session: https://claude.ai/code/session_01CXydFDyiQwNbGFkmwrcRQq Co-authored-by: Claude <noreply@anthropic.com>
…d's write step to one direct write off the relay - label-write / issue-create / issue-transfer: the relay battery pins rise to the cases they now register (14 / 9 / 9), so the added "the answer an EXPLICIT dispatch gives" case is floored rather than riding slack. - post-stamped: its own gate gains the synchronous half of the no-run rule — main writes only through writeThroughRoute, whose ONE direct write sits on the non-dispatch branch ahead of the relay, and whose no-run / timeout branch returns UNCONFIRMED (the behaviour stays driven by dispatch.mjs's no-run conformance). - dispatch.mjs: RELAY_MISS_PROBE moves below the three timing constants it had split, and the success line names the no-run conformance it now carries. Claude-Session: https://claude.ai/code/session_01CXydFDyiQwNbGFkmwrcRQq Co-authored-by: Claude <noreply@anthropic.com>
objectstack-fleet
Bot
deleted the
claude/issue-21892-no-run-is-unconfirmed
branch
October 7, 2026 17:49
This was referenced Oct 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #21892
Clause-②: no
What changes
After a relay dispatch the platform ACCEPTED (HTTP 204), "no run appeared within the start window" — or a run that never completed — is now answered UNCONFIRMED by every relay sender: exit 6, the shared
unconfirmedTextsentence (go READ the card, never re-run blind), underautoexactly as under an explicitdispatch. No sender takes a direct write after an accepted dispatch any more, so a relay that is merely queued can no longer turn into a write under the seat's personal login (and a second write when the queued run executes).OS_FLEET_TRANSPORT=directstays the only way to write as the personal account; the route-selection read (condition ③ infleet-write/dispatch.mjs: the workflow file's 404,disabled_manually) is unchanged.main(3d9188502e) underauto+no-runscripts/pm/label-write.mjsfallbackText(...)then the direct additive POST/DELETEscripts/pm/issue-create.mjsfallbackText(...)then the direct POSTscripts/pm/issue-transfer.mjsfallbackText(...)then the direct GraphQL mutationscripts/pm/post-stamped.mjsfallbackText(...)then the direct comment POST / body PATCHscripts/pm/close-cards.mjsfallbackTextis deleted fromfleet-write/dispatch.mjs: after the change it has no caller anywhere in the tree (git grep -n fallbackTextat776ab7f2ff: 0 hits;with-fleet.shnever called it — itsautoasksdispatch.mjs --routebefore anything is sent, and an actions file goes to this file's CLI, which has no direct path).The enumeration pin (the triage grade's "a tool added later fails the pin")
node scripts/pm/fleet-write/dispatch.mjs --self-testgains one battery, the no-run conformance (27 cases, floor 18 batteries):scripts/exceptdispatch.mjsthat namessendFleetWrite— with a by-name floor of today's five, so a scan gone blind reds;relayMissProbe({ route, send, pace }): ONE write through its real write path against its own offline fake platform. A sender without it fails the pin;sendFleetWriteover a fake platform with an accepted (204) dispatch and (a) no run underauto, (b) no run under explicitdispatch, (c) a run that never completes underauto. Each must answer exit 6, after exactly ONE dispatch, with ZERO direct writes (any request but GET/HEAD), printing the shared UNCONFIRMED sentence;direct: its write is issued directly and seen by the recorder, and nothing is dispatched — so the empty lists above are a measurement;dispatch.mjs's own CLI answers the same (exit 6, one dispatch, no other write).The per-tool pins that said "auto falls back only on no-run" are flipped in
label-write,issue-createandissue-transferto exit 6 and the exact request list after the dispatch (pre-read only, or none);close-cardsalready pinned it.post-stamped's self-test is synchronous, so its behavioural pin is the conformance; its own gate now also carries the structural half (main writes only throughwriteThroughRoute, whose one direct write sits on the non-dispatch branch ahead of the relay, and whose no-run/timeout branch returns UNCONFIRMED). CI runs the dispatcher self-test on every PR (theFleet-write dispatcher self-teststep inlint.ymlcarries noif:).Inherited commits — read as UNVERIFIED, verdict per hunk
The branch continues the released claim's work at
4c5f2c15fc(7 commits over607463d736).origin/mainwas merged in (69f2346dca, merge of3d9188502e, no rebase — the branch is shared);mainhad not touched the six files since607463d736(git diff --stat 607463d736 origin/mainover the six paths: empty), and the merge left the branch's delta at exactly these six files (+402 / -94).a6bc9b3e08label-writefallbackText; theauto && no-runarm removed, the remaining arm answersno-run/timeoutUNCONFIRMED for every requested transportrelayMissProbeoverdriveOffline(the realrunLabelWrite)776ab7f2ff51139a6248issue-createrelayMissProbe, flipped case (exit 6, number null, zero requests)b1cebeea98issue-transferrelayMissProbe, flipped case (exit 6, pre-read only)f99f21158apost-stampeddepsdoor onrest/readCardTail/writeArtefact/writeViaRelay(the live path passes none; every default is the old value)writeThroughRouteextracted frommain: the old branches, minus theauto+no-runfall-back;mainnow one call, and its catch still classifies a direct write's failurerelayMissProbe; structural pin retargeted towriteThroughRoute(776ab7f2ff(battery pin 12 → 13)27f2f3ed9fclose-cardsstubs.sendpassthrough;relayMissProbespelling the two child tools' writes as the requests they stand for846527f4c0dispatch.mjsfallbackTextdeleted; its self-test case replaced by "accepted (204), no run known"RELAY_MISS_PROBEdeclared betweenDEFAULT_START_MSandDEFAULT_CEILING_MS4c5f2c15fcdrivewrapper), per-tool second cases guarded with?.Dropped: none.
Self-tests at
776ab7f2ff(rule ⑤: each edited script's own; no*.test.*underscripts/ortests/names any of the six —git grepexit 1)The inherited tree alone (
69f2346dca, before776ab7f2ff) was green on the same six, post-stamped at 629 cases.What each probe's recorder sees (a scratch driver handing each
relayMissProbean accepted no-run result, thendirect):Ablation — both directions, at
776ab7f2ff, throughscripts/ablation-replace.mjs(anchor must hit, blob must change, restore proven)auto+no-run→writeArtefact[[],2,true,true,true]post-stamped.mjs: auto + an ACCEPTED dispatch + no-rungot[0,1,204,"no-run",["POST /repos/objectstack-ai/objectstack/issues/7/comments"],false]relayMissProbeexports relayMissProbegot"undefined"; battery floor 23 below 27auto+no-run→ direct[GET issues/7, POST issues/7/labels, GET issues/7]label-write.mjs: auto + … + no-rungot[0,1,204,"no-run",["POST …/issues/7/labels"],false]Every leg restored: blob equals
HEAD(post-stamped.mjsf51c37c8f5,label-write.mjsb364caeacc),git diff HEAD0 bytes,git status --porcelainempty. The green direction is the same commands on the restored tree (the self-test block above). The first attempt of legs A and C was refused byablation-replace(the replacement still contained the anchor, "the anchor count moved 1 to 1") — no command ran, not a measurement; both were re-anchored and re-run.Gate families (derived by
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths: 6 paths vs merge base3d9188502e, 38 commands)All at
776ab7f2ff, exit codes captured before any pipe:check-ci-filter-parity,check-closing-keyword-parity(+--self-test),check-comment-mask-corpus,check-declaration-mirrors(+--self-test),check-scripts-symbol-anchors(+--self-test),check-self-test-wired(+--self-test),check-self-test-workflow-commands(+--self-test),check-whole-set-label-write(+--self-test),pm/bare-root-worklist --self-test,check:agent-test-spelling,check:bash32-floor,check:cli-command-ids,check:cross-package-test-inputs,check:driver-memory-census,check:entry-guard,check:gitlink-declared,check:nul-bytes,check:parse-guard,check:pm-close-cards,check:pm-fleet-write-dispatch,check:pm-fleet-write-execute,check:pm-fleet-write-validate,check:pm-issue-create,check:pm-issue-transfer,check:pm-label-write,check:pm-post-stamped,check:pm-write-pace,check:pnpm-filter-targets,check:ratchet-remedy-authority,check:refd-timer-probe,check:watch-hint-literal.check:pm-dispatch-gates(the battery, an unlocked run): exit 0 —✓ check:pm-dispatch-gates --self-test: the exit contract holds in all three directions.then✓ dispatch-gates self-test: 1976 cases pass.(1279.8 s on this box).--ranreconciliation, exit 0:Run reconciliation — 38 derived, 38 run, 0 NOT-MEASURED, 0 UNRUN.(all 38 carry a recorded exit code).origin/mainhas since moved tob04a5295f7without touching the six files or their imports.check-published-list-mirrors(+--self-test),check:engine-double-contract,check:i18n-stale-fill,check:pm-label-desc-cap,check-dts-references --self-test. NOT MEASURED —check:dts-closureandcheck:published-readme-exports(exit 3 PREREQUISITE NOT MET: no packagedist/; this diff touches no package),check:console-injection(exit 0 but skipped: no console dist).pnpm exec eslint --no-inline-config --format jsonover the six files — 6 files, 0 errors, 0 warnings (none reported as ignored). Population:eslint.config.mjs's**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}block coversscripts/pm/*.mjs. Invariance: the config never enables type-aware linting (noparserOptions.project, said in its own header) and its plugin rules are per-file, so this diff cannot move any untouched file's verdict. The repo-widepnpm lintis CI's.Acceptance notes
post-stamped.mjsnamescheck:pm-post-stampedbut notcheck:pm-fleet-write-dispatch, where the conformance lives; CI runs the dispatcher self-test unconditionally, and post-stamped's own gate now carries the structural half. Noted, not filed (the derivation script is frozen).post-stamped.mjs's size route (a body over the relay's 60,000-byte cap underautogoes direct for that write, with one line naming bytes, cap and identity) is a pre-dispatch, declared and pinned route decision, untouched here. It sits beside the grade's sentence thatOS_FLEET_TRANSPORT=directstays the only way to write as the personal account; whether that sentence covers it is a ruling, not this card. Noted, not filed.disabled_manuallymust refuse, never fall back to the personal identity; the read runs behind the proxy re-exec; a proxy 403 is not a rate limit #19774 is the route-selection half of this class and is not touched; pm-dispatch: relay-opened dev PRs are never attached to the seat's session, and the relay landing route has no allow rule, so auto mode decides seat landings call by call #19990, finding(pm tooling): a cloud seat cannot read the numbers a fleet-write run reports — job logs 403 through the proxy, check-runoutput.summarynull; emitissue_create/ transfer results as check-run annotations (closure card, 2 sightings) #21294, fleet-write: no relay op for PUT /pulls/{n}/update-branch — the sanctioned base sync (rest-channel.md:49) runs as bare REST and authors the merge commit under the seat's personal account (PR #22002 head fab444b4) #22052 and protocol(pm): a silent claim has no reclaim clock or write path — seat-lifecycle.md:37's one-day recycle names no actor, so p1 #21892 idles 34 h with no PR and its serial dependent #21915 waits #22053 remain open and are not addressed here.Writes
git push(twice: the merge, then776ab7f2ff); REST through the relay asobjectstack-fleet[bot]: thispr_create(draft), onelabel-write(skip-changeset+ PR assignee), oneos-dev-reportcomment on the card. MCP GitHub calls: 0. No changeset:scripts/pm/**publishes nothing.Generated by Claude Code