Skip to content

fix(dispatcher): ignore narrative branch phrases - #2171

Merged
justinhelmer merged 1 commit into
mainfrom
plan/fix-issue-2161-the-deter-3befe1/u1
Sep 21, 2026
Merged

justinhelmer merged 1 commit into
mainfrom
plan/fix-issue-2161-the-deter-3befe1/u1

Conversation

@coreplane-switchboard

@coreplane-switchboard coreplane-switchboard Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Base refs now come only from typed branch forms, pull requests, or tree URLs; narrative prose cannot select a ship base. Missing refs continue on the repository default instead of refusing the request.

Why: #2161 showed the pre-model resolver reading with from prose, contrary to record 0057. This closes the gap between typed target binding and ship preflight.

Where to look

  1. Typed base-ref extraction Accepts the delimited head routing clause or branch: token while leaving task prose outside the ref slot. ⚠ An overly narrow grammar could ignore a legitimate typed branch.
  2. Missing-ref fallback Treats a positive missing-ref lookup as a default-branch entry and records the word the door read. ⚠ The wrong fallback could base new work on an unintended default.
  3. Byte-exact incident regression Runs the recorded 20:05Z input through resolver and preflight, proving no ref lookup and a default-branch entry.
  4. Recorded-input hygiene exception Names the exact fixture as deliberate public-tree provenance so the hygiene gate can keep byte parity.
  5. Typed clarification answer Keeps the legacy no-default question usable with the accepted branch: token rather than prose phrasing.
  6. Typed-slot specification Binds the allowed ref sources and narrative regression to exact unit proofs.
  7. Preflight specification Requires missing typed refs to fall back with narration, never a refusal or recovery command.

Feedback wanted: Judge whether the typed head-clause delimiter and the byte-exact recorded request fully pin the narrative-ref regression.

Risk: Old prose forms such as “on main” no longer select a branch; generated child clauses and branch: remain supported. Missing refs use the repository default. Revert the commit to restore fail-closed behavior.

Verified: 707 focused tests, root TypeScript, formatting, hygiene, spec bindings, and title gate passed on the rebased head; pushed CI is pending.

Decisions (4)
  • Require the routing-clause delimiter. Scanning every “on branch X” phrase was rejected because the incident proves those words cannot distinguish routing from narrative. The colon already terminates generated and documented head-of-ask clauses.
  • Fall back after a positive missing-ref answer. Refusing and handing back syntax was rejected because the request may be correct while the binding is stale or wrong. The entry retains the requested ref so the hand-off can narrate the default-branch choice.
  • Keep pull-request heads authoritative. Nearby branch prose never becomes a fallback when a pull-request fetch fails. An open pull request's fetched head remains the typed ref; an unavailable fetch degrades to repository-only.
  • Allow the recorded request by exact line. Obfuscating the organization and issue references was rejected because review required byte-exact parity with the input event. The named hygiene exception remains stale-sensitive and limited to this regression fixture.
Validation (7 criteria)
Criterion Proof
Recorded input parity Compared the template literal to the fenced block in PR comment 5768451510: exact match, 2,000 UTF-8 bytes.
Narrative, token, URL, fallback, and dispatcher flows npx vitest run on the four changed test files → 4 files and 707 tests passed after rebasing.
Root TypeScript contract NODE_OPTIONS=--max-old-space-size=6144 npx tsc --noEmit -p tsconfig.json → passed with no output.
Changed-set formatting npx prettier --check on all 11 format-supported changed files → all matched; .allow has no Prettier parser.
Public-tree hygiene npm run hygiene:check → passed with 37 listed hits and 139 allowed lines.
Spec proof bindings npm run specs:check → 51 specs and 5,666 proof references checked; every Code/Tests path exists.
PR title contract npm run check:pr-title -- "fix(dispatcher): ignore narrative branch phrases" → passed.
For agents

Rebased onto origin/main at 4bf464f immediately before the final gate run and force-pushed coherent head 34a66de. F1 is fixed from #2171 (comment); the test fixture matches its fenced input byte-for-byte and retains both no-ref-scan and default-branch assertions. scripts/public-hygiene.allow is intentionally outside Prettier's parser set and is validated by hygiene:check.
Requested by @justinhelmer in slack:C0BRRHKFLCB

🤖 Generated with Claude Code

@coreplane-switchboard coreplane-switchboard Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changes requested: The behavior change is sound, but the contract-required exact incident regression fixture is missing.

Warning

Changes requested · head 2bf29aa · 1 finding: 1 minor

Severity Finding Where
minor F1 Contract — test scenario missing: exact 20:05Z input-event fixture src/core/ship/preflight.test.ts:413
Full review

F1 — The contract requires the exact text from door run 524cc39e’s input event, but this fixture reconstructs only the sentence published in issue #2161. The omitted prefix and surrounding prose are load-bearing for the anchored, directive-aware parser, so this does not prove the production ask binds no ref. Replace it with the complete recorded input event.

@coreplane-switchboard
coreplane-switchboard Bot force-pushed the plan/fix-issue-2161-the-deter-3befe1/u1 branch from 2bf29aa to f932b83 Compare September 21, 2026 22:23

@coreplane-switchboard coreplane-switchboard Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changes requested: The expanded regression still cannot establish the contract-required exact 20:05Z input-event fixture.

Warning

Changes requested · head f932b83 · 1 finding: 1 minor

Severity Finding Where
minor F1 Contract — test scenario missing: exact 20:05Z input-event fixture src/core/ship/preflight.test.ts:413
Full review

F1 (minor, high confidence): The expanded text is a stronger reconstruction, but the disposition confirms it cannot establish byte-exact parity with run 524cc39e. The contract explicitly requires that input event as the fixture, so this remains unresolved until someone with access supplies or verifies the exact text.

@coreplane-switchboard

Copy link
Copy Markdown
Contributor Author

Plan runner — U1 held

⏸️ Changes requested but held after 2 review rounds: #2171 — every finding of review round 2 is human-gated, a receipt only a person can produce: F1 (minor) — Contract — test scenario missing: exact 20:05Z input-event fixture. No fix round was opened: a coding child cannot produce the receipt.

Severity addressed: minor and above (set by org).

Next step: produce the receipt each finding names and post it on the pull request. To continue, re-issue agent:ship in this thread with only the PR URL (#2171) — no new task text. The re-issued pipeline resumes at the review round — no coding round runs first.

@justinhelmer

Copy link
Copy Markdown
Contributor

The exact fixture for the human-gated F1 (the 20:05Z input text of door run 524cc39e). Copied byte-for-byte from the run record's input event (Slack message ts 1790021125.042999, the bot mention stripped by the door as it always is). Use this string verbatim as the regression fixture in src/core/ship/preflight.test.ts (the test at ~line 413): the ref scan must bind NO base ref from it and the ask must run on the default branch.

in coreplanelabs/switchboard: fix issue #2154 — a human-gated review finding has no way back into the pipeline once the person answers. Today on PR #2140 the review found F2 "cold-reader acceptance gate was not independently run" (minor, humanGated: true); the coding child rightly declined it ("this coding context cannot manufacture independent evidence") and the pipeline ended held; the maintainer posted the receipt as a PR comment; a re-issue (attempt 3, run d69afa9a) adopted the PR and went straight to a review round, the reviewer re-raised the same human-gated finding, and the pipeline ended held again three minutes later, having never read the comment that answered it. The recovery took two hand-posted steps (a directive coding run on the branch with the answer, then another re-issue). Hold the invariant from record 0054: a human-gated finding is a question to a person, and the person's answer resumes the unit. Direction: when a review round yields only human-gated findings, the unit does not end — it parks with the question (record 0051's idle state, the finding as the pending state on the thread) and resumes on the next human input on the pull request or in the unit thread (a PR comment or a thread reply from a person), which becomes the fix round's brief (the finding plus the answer); an adopted attempt on a pull request whose newest human comment postdates the last verdict runs that fix round before the review, never review-first. Tests: a review with one human-gated finding parks the unit instead of ending it held; a person's PR comment resumes it into a fix round carrying the comment; an adopted attempt with a newer human comment runs fix-then-review; a human-gated finding alone never ends a pipeline held. Spec rows in agent-ship.md (the round's endings) and agent-review.md (humanGated). Receipt runnable when: worker:bot ≥ this PR's merge sha and a review posts a human-gated finding on a live unit (the next record acceptance is the natural fixture).

The refusal it produced (seq 2 of the same run): 🚫 The branch \with` does not exist on `coreplanelabs/switchboard` — nothing was started. Name an existing branch, or drop it to run on the default branch.` — the phrase the scan matched is "…a directive coding run on the branch with the answer…".

Co-Authored-By: coreplane-switchboard[bot] <318072483+coreplane-switchboard[bot]@users.noreply.github.com>
@coreplane-switchboard
coreplane-switchboard Bot force-pushed the plan/fix-issue-2161-the-deter-3befe1/u1 branch from f932b83 to 34a66de Compare September 21, 2026 22:40

@coreplane-switchboard coreplane-switchboard Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

LGTM: The typed ref extraction, default-branch fallback, exact incident regression, and updated specs are consistent and complete.

Note

Approved · head 34a66de · no findings

Full review

No findings; the change is ready to merge.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Auto-approved: coreplane-switchboard[bot] reviewed this PR and posted an LGTM verdict (see its review). This repository opted in through its REVIEW_BOT_LOGIN and REVIEW_BOT_ID variables.

@coreplane-switchboard coreplane-switchboard Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

LGTM: The typed-ref fix is correct; one retired refusal-code artifact remains as non-blocking cleanup.

Note

Approved · head 34a66de · 1 finding: 1 nit

Severity Finding Where
nit F1 Remove the retired base-missing refusal code src/core/refusal.ts:93
Full review

F1 (nit): ship_preflight_base_missing no longer has a producer, but remains in the refusal-code table and is still listed as “proven elsewhere.” Remove both stale entries so the closed inventory accurately reflects the nine current preflight refusals.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Auto-approved: coreplane-switchboard[bot] reviewed this PR and posted an LGTM verdict (see its review). This repository opted in through its REVIEW_BOT_LOGIN and REVIEW_BOT_ID variables.

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