Skip to content

0.14.64 — dispatch args embedding + submodule floor/note completion + routing corrections - #1166

Merged
SQPferrer merged 15 commits into
masterfrom
dev/2026-07-26-dispatch-args-and-floor-coverage
Jul 27, 2026
Merged

0.14.64 — dispatch args embedding + submodule floor/note completion + routing corrections#1166
SQPferrer merged 15 commits into
masterfrom
dev/2026-07-26-dispatch-args-and-floor-coverage

Conversation

@Ljferrer

Copy link
Copy Markdown
Owner

Campaign 2026-07-26-doc-truth-and-engine-hardening, plan 1 of 4 (stack-and-plow, ADR 0011). All three phases landed via /war --afk --ace.

Plan: docs/plans/2026-07-26-dispatch-args-and-floor-coverage.md · Red-team: docs/red-team/2026-07-26-dispatch-args-and-floor-coverage.md (CLEARED, 3 rounds) · Epics #1157, #1158, #1159.

What lands

  1. stage-workflow.mjs --args <file> (war-followup: per-phase Workflow args cannot ride the tool call at real size — stage-workflow.mjs should embed them (--args <file>) #1134) — embeds over-size phase args into the staged script. At real campaign size assembled args cannot ride the Workflow tool call inline; this mechanizes the operator-approved hand edit. Fail-loud, pre-write validation; without the flag the staged output is byte-identical to a stage predating it. The prelude is inserted after the export const meta statement (a leading const makes the Workflow tool refuse the script — reproduced live during this very campaign), and a test pins the position, not mere presence.
  2. Submodule floor/note completed across three dispatch families (war-followup: submodule scoping/floors incomplete across three dispatch families (re-land, polish merge, floor-retry) #1114, landed as WAR task 1.1 — Submodule floor/note completion + classificationClause arbiter #1160) — both re-land prompts now carry submodLandNote; the polish merge carries the floor invocation bare; the floor-retry re-merge carries what its own comments already claimed.
  3. Two operator-visible routing corrections, both reusing existing enum members — a floor-retry submodule-blocked now HARD-holds the phase instead of soft-landing it minus the task; a re-land submodule-pr now yields held:submodule-pr with the PR ref preserved. land-decision.mjs is byte-untouched (ADR 0005).
  4. classificationClause's site list arbitered by a drift guard (workflow-template: classificationClause header comment hand-enumerates consumer sites with no drift-guard arbiter #1151) instead of narrated in a header comment — the gateCaptureClause header comment names 2 of 3 consumer sites after environment-proceed became the third #1034 rot shape.

Unexecuted backstops

  • Integrated-tip sweep re-check — DISCHARGED WITH ONE FAILURE (run at the integrated tip). submodLandNote 4 ✓ · assert-no-submodule-mutation 5 dispatched-prompt sites ✓ · classificationClause( 3 ✓ · every submodule-pr/submodule-blocked arm hard-or-held ✓ · EMBEDDED_ARGS/ARGS_FALLBACK_ANCHOR hits 5 skills/ surfaces, not the 4 the plan expected ✗ — the 5th is a banner comment at skill-doc-contracts.test.mjs:509 that spells the token pair contiguously. Recorded as an End-state-9 deviation, not waived (ADR 0017); routed to dispatch-args phase 2 residuals: fifth EMBEDDED_ARGS sweep surface + two untested fail-loud arms #1163.
  • First real-size --args live-transport observation — STILL OPEN. Every phase of this run dispatched via a Lead hand-embed at ~32–44 KB, not through the newly landed --args CLI path — so neither the ~104.5 KB size class nor the CLI path was exercised. The runner is the first campaign phase that actually uses --args.

Follow-ups filed

Merge order

Campaign is paused by operator directive after this plan. This is the only open PR in the stack; plans 2–4 remain queued and unstarted, so there is no stacked ordering constraint yet — this merges directly into master.

🤖 Generated with Claude Code

WAR Test and others added 15 commits July 27, 2026 12:18
…ed in place, plan-4 contention truth-fix

Three rounds (wf_48d56909-8b6, wf_719ad503-b53, wf_2f6a8f84-ed4). 4 Majors resolved:
End-state-1 negative re-scoped to substitution evidence; --args=<file> attached-form
guard enforced; doc-truth cascade gated per-medium in skill-doc-contracts.test.mjs;
polish skip-sentence constrained descriptive. Plan 4's two 'sole shared non-release
file' sentences corrected (skill-doc-contracts.test.mjs is now a second shared file).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ish and floor-retry; arbiter classificationClause (#1160)

Closes the three sibling gaps 2026-07-24-recovery-re-merge-dispatch-coherence
phase 1 left open (#1114), and repairs the #1151 header enumeration while it is
still accurate.

- (a) Both re-land dispatches (land:phase-<id>:environment-proceed and
  :baseline-proceed) now carry the submodule-phase land note, mirroring the
  initial land's trailing placement. A submodule phase whose first land
  gate-fails recoverable is no longer re-dispatched land-blind.
- (a') Both re-land results route status 'submodule-pr' to held:submodule-pr
  with pr_number/pr_remote captured, byte-mirroring the initial land's
  direct-return guard — a 2B PR-and-hold (newly reachable) would otherwise
  mislabel held:land-failed and lose the PR ref the Lead's gh-resume reads.
- (b) The class-exempt polish merge now runs assert-no-submodule-mutation.sh
  BARE (a coherence sweep is never a declared gitlink bump). The skip sentence
  was reworded so it no longer implies all floors are skipped; it names the
  submodule floor descriptively, never by filename (the sweep-count fork).
  No routing edit: both non-'merged' statuses already hit the fail-open DISCARD.
- (c) The floor-retry re-merge now re-runs the submodule floor with the
  gitlink-bump --declared conditional — making its own two adjacent comments
  ("ALL floor invocations (test + packaging + submodule)") true, no edit.
- (c') The floor-retry post-loop routing gains an explicit 'submodule-blocked'
  arm escalating with the existing reason 'escalate'. Without it the result
  reached the soft `reason: floorMr.status` fallback ('submodule-blocked' is not
  in HARD_ESCALATION_REASONS) and the phase would land minus the task.
- (#1151) The classificationClause header comment is rewritten count-free and
  names its new drift guard as the arbiter of the site list; the guard counts
  bare `classificationClause(` call-paren matches and pins 3.

Enum discipline held (ADR 0005): no land-decision.mjs edit, no MERGE_RESULT
status addition, no HARD_ESCALATION_REASONS / KNOWN_LAND_DECISIONS member
change, no agents/*.md or hooks/ surface. submodLandNote/submodMergeNote stay
'' off the submodule path, so every non-submodule prompt test passes unmodified.

Tests: seven label-keyed dispatch-capture / routing tests (the #1032 harness,
zero net-new machinery) plus the one deliberate source-count drift guard. Every
new assertion was proven RED by a mutate-and-run probe. Survey-derived
correction: the sibling 'ALL floor invocations' test enumerated two of three
floors — the submodule assertion and its title now match its own claim.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ationClause arbiter claim

Phase-close coherence sweep for phase 1 — two queued findings, no seam hunting.

[Nit] New polish-merge test's packaging collateral pin is presence-only, so a
'skip' -> 'run' reword would not RED: the pin now matches its own message —
/skip the packaging floor assert-packaging-in-diff\.sh/ instead of the bare
filename. Probe: rewording the dispatched prompt's clause skip->run REDs the
test (restored; the loose pin stayed green on that same mutation).

[Minor] classificationClause header comment (and its mirrored test comment)
overstate what the new drift guard mechanically enforces: both surfaces now
claim only what the guard actually forbids — the call-paren byte-run — and
name count-free as convention, not mechanism. A re-added prose count or bare
site list stays green, so the comment no longer asserts a false code fact
inside the construct whose purpose is killing comment drift (#1034 lesson).
The narrowed wording deliberately avoids spelling the call-paren byte-run
(the guard would count it as a 4th site): still exactly 3.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three code-verified project lessons from dispatch-args-and-floor-coverage phase 1:
- header-comment-delegates-site-count-to-drift-guard-test-instead-of-enumerating (update)
- submodule-scoping-gap-survives-in-land-and-polish-dispatch-families (update — the three
  sibling gaps this phase closed)
- reland-submodule-pr-arm-leaves-stale-landresult-unlike-initial-land (new)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…im was false

Reproduced live during phase 1: the Workflow tool refuses any script whose first STATEMENT is
not `export const meta` ("Invalid workflow script"), so Task 2.1's "prepend to the top of the
staged text" instruction and the spec §8 claim that placement above the opening COUPLING comment
is legal would ship a stager that produces undispatchable scripts. A leading comment is fine; a
leading const is not.

Corrects Task 2.1 substitution step (3), End state 2(i), and the phase-2 test list (the pin is
now positional — a presence-only check passes the broken prepend). Red-team round 0 could not
catch this: its executed probe asserted on staged text and never dispatched a staged script
through the real Workflow tool.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… args (#1162)

Closes the #1134 shape: at real campaign size the assembled phase args
(~104.5 KB — args.memory + verbatim plan slices + intent) cannot ride the
Workflow tool call, and an args-less resumeFromRunId then dies at the
template's entry validation despite a healthy journal. The phase-1 hand edit
of a staged copy is now mechanized.

stage-workflow.mjs
- New exported ARGS_FALLBACK_ANCHOR (the template's string-arm fallback tail),
  imported by the anchor guard like the two meta anchors — never a second
  hardcoded copy. The stager now exports three anchors.
- `--args <file>` is TWO-TOKEN only, peeled with its value out of the raw argv
  BEFORE the --force filter and the positional split. The value is the
  immediately-following token verbatim, so `--args --force` dies at the named
  read error. Missing value / duplicate / attached `--args=<file>` each exit
  non-zero with the usage error before any write — without the attached-form
  guard that token is not a flag to the parser at all: it survives the --force
  filter, binds to campaignOrdinal, and stages an args-LESS script at exit 0.
- Validate before any write (ADR 0034 predicate mirrored): read, JSON.parse,
  require a non-null non-array object; each failure is one named
  `stage-workflow:` stderr error, no staged file written.
- Substitution order: two meta anchors, then the fallback rewrite, then LAST
  the prelude — payload bytes injected only after every exactly-once count has
  run, so an anchor-quoting payload cannot fork the stage.
- The prelude is inserted immediately AFTER the `export const meta { … }`
  statement, never prepended: the Workflow tool refuses a script whose first
  STATEMENT is not `export const meta` (reproduced live 2026-07-27). A leading
  comment is fine; a leading const is not.
- Write-if-absent short-circuits before any --args processing exactly as
  before; the sole addition is one stderr warning that --args was ignored.
  Exit code and stdout are byte-unchanged.
- Without --args, steps (2)-(3) never run — byte-identical output.

workflow-template.js: referential coupling comment beside the fallback, same
commit. It names the stager, the constant and the anchor-guard arbiter but
restates neither the anchor bytes (exactly-once fork) nor the rewritten form /
prelude declaration (those bytes would ride into every staged copy and falsify
the no-flag negative).

Tests (stage-workflow.test.mjs): anchor guard extended to all three anchors;
every invalid-`--args` arm incl. duplicate, `--args --force` peel ordering and
the attached form; valid-`--args` staged text with a POSITIONAL prelude pin
plus a no-statement-precedes-meta dispatch-shape assertion (a presence-only
check passes the broken prepend); the anchor-quoting + JS-meta payload case;
the no-flag negative in SUBSTITUTION-EVIDENCE form; the ignored-`--args`
warning; and the semantic half of backstop 2 pulled pre-merge — a net-new
~3-line AsyncFunction harness drives the shipped template staged with --args
under a FALSY `args` and proves the embedded fallback clears entry validation,
with a no-flag control. Only the live-transport half stays deferred. The file
header's design invariant is reworded with the carve-out for that harness.

Mutate-and-run probes (all RED with the edit removed, restored after): prepend
the prelude -> (i); drop the attached-form guard -> (h); skip the fallback
rewrite -> (i)/(j)/(m); duplicate the fallback bytes in the template -> (f).

Doc truth, same commit and mechanically gated rather than prose-waived:
SKILL.md's ADR 0037 staging paragraph documents the whole --args flow (args
JSON sibling of the staged script, dispatch with no Workflow args because a
dispatched {} is truthy, dispatched-args-always-win, the resume note and its
residuals, the campaign-default decision rule, the --force re-embed rule and
the stage-failure runbook line) and its inline command gains [--args <file>];
ADR 0037 decision 2 gains an inline dated amendment covering BOTH of its
two-scoped sentences (three substitutions, three exports); CONTEXT.md's
staged-phase-script entry gains the optional-third clause in place. Both are
gated by new block-scoped rows D23/D24 in skill-doc-contracts.test.mjs —
per-medium (ADR append-only: NEW-present only; CONTEXT.md in-place:
NEW-present + sentence-literal OLD-absent), extracted by construct, comment
leaders stripped before whitespace-normalizing. Both proven RED against the
unamended docs.

Sweep (spec 4.4): EMBEDDED_ARGS|ARGS_FALLBACK_ANCHOR hits exactly the four
named surfaces — stager 3, test 17, template 2 (referential comment only, no
anchor bytes), SKILL.md 1; `: (args || {})` still exactly-once in the template.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…workflow.test.mjs (#1162)

Absorbs two auditor Minor findings (same defect, one fix):

1. [Minor] (guard) symlink-regression comment orphaned from its test by the
   inserted --args section — the new --args banner and cases (h)-(m) were
   spliced between the (guard) symlink-invocation explanatory comment block
   and the test('(guard) symlinked invocation still runs main() ...') it
   documents, so the comment read as the preamble to the --args block and a
   reader would attribute the RED-against-pre-normalization-guard rationale
   to the wrong construct (comment/construct-adjacency rot class, #1034;
   ADR 0025 item 3 comment-lag duty).

2. [Minor] (guard) symlink-test's explanatory comment is orphaned 236 lines
   from its test by the inserted --args section — as shipped the comment
   introduced the --args section it preceded and the (guard) test carried no
   comment at all; the same plan slice mandated a same-commit coupling-comment
   reword of this file's header for exactly this rot class, so leaving a
   second comment falsified by the file's own new layout is inconsistent with
   the slice's stated discipline.

Fix: move the six-line (guard) comment block down to sit immediately above
its test; the --args <file> embedding (#1134) banner is now the section's
sole introduction. Comment-only move — no assertion touched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…-level-args sentence (#1162)

Phase-2 coherence sweep — two queued findings, docs only, no code change.

1. [Minor] ADR 0037 Consequences row still attributes the whole anchor mirror
   pair to the `export const meta` literals. Decision 2's dated amendment
   correctly supersedes both `two`-scoped sentences (three substitutions, three
   exports) and D23 gates it, but the Consequences bullet still describes the
   canonical-source <-> mirror-site pair as "the stager's exported anchor
   constants and `workflow-template.js`'s `export const meta` literals" — the
   third anchor's mirror site is the `const A =` ternary's args-fallback tail,
   not a meta literal, so the row under-describes what the arbiter covers.
   Fixed append-only: a parallel dated note nested under the Consequences
   bullet (same arbiter, wider pair); the ratified sentence stays byte-intact,
   per the append-only ADR discipline. Phrased out of the spec §4.4
   four-surface sweep (ADR still greps 0 for EMBEDDED_ARGS|ARGS_FALLBACK_ANCHOR;
   SKILL.md still exactly 1).

2. [Nit] SKILL.md: "must also supply ... as required top-level `args`" now
   follows "dispatch with no Workflow `args` at all". Read literally in the new
   `--args` context, the sentence invites a partial inline args object — which
   is truthy, beats EMBEDDED_ARGS, and discards the whole assembled payload:
   the footgun the same paragraph warns about. Scoped to "required top-level
   keys of the assembled `args` — inline, or in the `--args` file when the
   payload rides the staged script"; the derivation-trio clause and the
   schemas.md pointer are preserved (war-config.test.mjs's derivation-trio
   doc contract still names all three keys).

Gate: node --test 'skills/**/*.test.mjs' 973/973 pass (exit 0); shell suite
exit 0. No version/release-slot literal touched.
Three project lessons from dispatch-args-and-floor-coverage phase 2:
- absorb-fix-for-attribution-finding-can-itself-invert-mirror-direction (code-verified)
- spliced-test-section-orphans-adjacent-explanatory-comment (agent-unverified)
- coupling-comment-restating-grep-pattern-bytes-self-matches-the-sweep (code-verified)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bump the four release slots together to the next free patch above the
live integration base, resolved AT LAND TIME from the slots themselves
(never a plan literal): plugin.json `version`, marketplace.json
`metadata.version` and `plugins[0].version`, and the README `## Status`
line (replace-in-place, no badge). All four read 0.14.63 at the phase-3
integration tip, at origin/master, and at the monotonic-floor window max
(measured), so the next free patch is 0.14.64.

This plan changes plugin-shipped surfaces (stage-workflow.mjs,
workflow-template.js, their test assets, skills/war/SKILL.md); users
receive them only via a release.

Release blurb is additive and enumerates exactly what its headline count
claims — four changes: (1) `--args <file>` stage-time args embedding
(absent-args fallback only; dispatched args still win), (2) completed
submodule floor/note coverage across the re-land, polish-merge and
floor-retry dispatch prompts, (3) the two operator-visible routing
corrections that coverage makes reachable — a floor-retry
`submodule-blocked` now HARD-holds the phase instead of soft-landing
minus the task, and a re-land `submodule-pr` now returns
`held:submodule-pr` carrying the PR refs instead of `held:land-failed` —
and (4) the `classificationClause` site-list drift guard. It claims no
enum, floor-script or land-decision.mjs byte changed, because none did.

Gate green: node --test 'skills/**/*.test.mjs' 973/973; all *.test.sh
exit 0. version-slots.test.mjs (lock-step + monotonic floor) green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Recurrence 8 of release-blurb-overstates-guard-semantics: a closing
gating-premise clause covered only 2 of the 4 gains enumerated above it.
Verified code-verified against the landed tip da7a5f3.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ends are unconditional (#1165)

The closing clause of item (2) claimed 'every existing non-submodule prompt
is byte-unchanged'. The submodLandNote/submodMergeNote premise only covers
the two re-land note gains; the polish-merge (workflow-template.js:1861) and
floor-retry (:1365) appends are unconditional string concatenations, so both
prompts changed byte-for-byte on every phase. The plan's End state 11 was
scoped to TESTS, which do pass unmodified — the blurb had upgraded that to a
byte claim about the prompts themselves.

Also in the same paragraph:
- item (2) cited #1160 (this run's WAR task issue) where its siblings cite
  origin issues; now cites #1114, landed as #1160
- 'string-arm args fallback tail' -> 'object-arm': the anchor is the FALSE
  arm of the typeof-string ternary, as workflow-template.js's own coupling
  comment already says
- 'neither substitution' -> 'neither the fallback rewrite nor the prelude
  injection': only one substitution was introduced earlier; the second
  operation is an insertion

Found by two auditor seats at the phase-3 gate-audit, both disposition
follow-up; reproduced at the landed tip before filing. Recurrence 8 of
docs/learnings/release-blurb-overstates-guard-semantics.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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