fix: make compiled dispatch exhaustive over TOOLS so native review briefs route (#1070) - #1115
Merged
Merged
Conversation
apackeer
requested review from
a team,
Kalindi-Dev,
harmjeff,
leandrodamascena,
raj-jain-aws,
scottschreckengaust and
spraja08
September 10, 2026 08:30
Type the compiled delegate table as Record<ToolFile, () => Promise<DelegateModule>> so adding a TOOLS entry without a loader or a delegate without export main fails typecheck under bun run check. Keep every import specifier literal for native bundling and reject unknown names before awaiting a delegate.
apackeer
force-pushed
the
fix/issue-1070-review-brief-dispatch
branch
from
September 12, 2026 20:48
6849b31 to
f71ab9d
Compare
The compiled dispatcher and aidlc-lib die() already emit JSON errors, and the generated parity test exposed the copy-channel mismatch.
…cher Generate sandboxed dev/compiled parity cases from TOOLS and ROUTES, requiring every delegate to execute or carry an explicit network-policy exception. Assert delegate resolution and reject missing in-process loaders so a routed-but-unbundled tool like review-brief fails at runtime.
The hand-maintained list had drifted to 23 of 33 delegates; deriving it from TOOLS covers every bare invocation while the leftover checks still reject surviving invocations and non-route rewrites.
apackeer
force-pushed
the
fix/issue-1070-review-brief-dispatch
branch
from
September 12, 2026 23:34
a42ffbf to
446dd4d
Compare
Following the review-brief precedent, the remaining copy-channel wrappers emit the compiled dispatcher JSON error shape while preserving their exit semantics.
Decode wrapper error messages before checking wizard recovery paths and session conflicts while preserving all state and audit assertions.
apackeer
added a commit
that referenced
this pull request
Sep 17, 2026
* origin/main: fix: make compiled dispatch exhaustive over TOOLS so native review briefs route (#1070) (#1115) test: skip POSIX gate-sensor fixture on Windows (#1208) fix: make /aidlc compose scopes durable across an engine reinstall (#1159) fix: refuse orphaned positionals at intent-create instead of storing a truncated description (#1114) (#1195) fix: route compiled gate-sensor dispatch through the engine namespace (#1166) fix: name the accepted values in review-path refusals (#1082) (#1194) fix: discover stage-level summary questions when units are skipped (#1110) fix: keep a JSON-scalar gate reply instead of parsing it away (#1186) fix: resolve the zero-Unit code-generation location in the traceability sensor (#1179) fix(config): one quiet line for --show, and honest source options on a copy-channel refresh (#1185) test(t238): normalize walkFiles separators in the invocation-surface selector (#1184) fix(config): Kiro provides its own model access, so the provider section has nothing to ask (#1183) chore: prepare 2.9.0 release (#1181) feat!: classic scope v1 parity with scope-owned ceremony switches (#1151) fix: publish changed previews without a daily cap (#1178) fix: separate Bun copy and native installer runtimes (#1174) fix: publish next-patch previews nightly (#1169) fix: keep review bookkeeping out of the artifact, and out of the reviewer's findings (#1160) fix: measure the review budget against the engine's own ordinal, not the caller's (#1158)
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.
Summary
Closes #1070. Native
aidlc engine review-briefcommands failed withaidlc-review-brief.ts does not export main(argv)even though the renderer exported the required entry point. The dispatcher declared the route but its compiled-mode delegate table omitted the tool, and the error text pointed at the wrong layer.This is the same defect class as the earlier knowledge-verb miss documented in the route table: a tool that works when invoked as
bun <tool>.ts(the copy channel every test and every e2e journey runs) but is unreachable through the compiled binary, which is the only path that consults the delegate table. Rather than add one arm, the PR closes the class: the table is typed so drift fails typecheck, t230 drives every delegate through the simulated compiled dispatcher so drift also fails a unit test, the packager's last hand-maintained tool list is derived fromTOOLS, and the copy-channel CLI wrappers emit uncaught errors in the shape the compiled dispatcher already uses.Changes
Dispatcher (
core/tools/aidlc.ts)loadDelegateswitchwithDELEGATES: Record<ToolFile, () => Promise<DelegateModule>>.DelegateModule.mainis required, so aTOOLSentry without a loader or a delegate module withoutexport mainfailstscunderbun run check. Import specifiers stay literal sobun build --compilestill bundles every delegate.has no in-process delegate; DELEGATES in aidlc.ts is out of step with TOOLSinstead of the misleading missing-export message.Tests (
tests/unit/t230-dispatcher-routes.test.ts)TOOLS×ROUTES. For each of the 33 tools it picks the first route/verb whoseresolveActionyields a delegate to that tool (two modes agreeing on a routing error can never pass vacuously), runs it in a fresh sandboxed project (AIDLC_INSTALL_ROOT,AIDLC_BIN_DIR,AIDLC_OFFLINE=1) through bothviaDispatcherandviaImportedCompiledMain, and asserts identical output. 30 tools exercised;doctor,init,workspace-syncare excused by an explicit map quoting their non-forbiddennetworkPolicy; a completeness test fails if a tool is neither exercised nor excused. Nobun build; ~12 s.dist-release/claude/.claude/tools/aidlc.ts, the entrybuild-binaries.tsships) into a real executable and exercisesreview,context, andsummaryfrom another cwd with an emptyPATH.Packager (
scripts/package.ts)delegateNames, the list driving the barebun aidlc-<name>.tsnative rewrite and its leftover check, had drifted to 23 of 33 tools (review-brief among the missing). It is now derived fromTOOLS. Output-neutral:dist-releasehashes identically before and after (the only bare form in any prose isaidlc-directive.ts, not a delegate); the existing leftover checks still reject a rewrite to a non-route.Copy-channel CLI wrappers
aidlc-review-brief.ts,aidlc-orchestrate.ts,aidlc-init.ts,aidlc-lifecycle.ts: theimport.meta.maincatch now writes{"error":"<message>"}to stderr, the shape the compiled dispatcher's in-process catch andaidlc-libdie()already use, sobun <tool>.tsandaidlc engine <tool>agree. The parity test found the review-brief case on its first run (aidlc-review-brief: Error: Missing --stage <slug>.vs{"error":"Missing --stage <slug>."}); the other three had the same latent divergence. In-maindiagnostics are untouched. t299 and t312 decoded that stderr as raw text and now readJSON.parse(stderr).errorfirst; every state, rollback, and audit assertion in them is unchanged.Docs
Evidence the guards work
Rebasing onto
main(which addedattesttoTOOLSin #1052) with the map lacking that entry:Deleting only the
"aidlc-review-brief.ts"line fromDELEGATESand runningbun test tests/unit/t230-dispatcher-routes.test.ts -t 'aidlc-review-brief.ts via':Both are the drift that shipped #1070, caught before a user could.
Test plan
main: exit code 1 and the exact missing-export message.bash tests/run-tests.sh --debug -P 8 --unit --filter '^(t230-dispatcher-routes|t304-review-brief|t299-first-run-wizard|t312-orchestrate-session-binding|t215-bolt-dag-selfheal)[.]test[.]ts$' --no-llm: 215 passed, 0 failed (t230 147, t304 32, t215 15, t299 12, t312 9).bun scripts/package.ts,bun scripts/package.ts --check(deterministic across two builds, all seven harnesses),bun run typecheck,bun run lint,git diff --checkpassed.Native execution was verified on Linux. No live-model tests were needed for this deterministic dispatcher change.
Checklist
Acknowledgment
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.