Skip to content

research(aif-handoff-bridge): Sub-wave A — Variant A (MCP-consumer) deep evaluation - #268

Merged
artyhoo merged 1 commit into
stagingfrom
research/aif-handoff-bridge-variant-a
May 29, 2026
Merged

research(aif-handoff-bridge): Sub-wave A — Variant A (MCP-consumer) deep evaluation#268
artyhoo merged 1 commit into
stagingfrom
research/aif-handoff-bridge-variant-a

Conversation

@artyhoo

@artyhoo artyhoo commented May 28, 2026

Copy link
Copy Markdown
Owner

Summary

R-phase Sub-wave A for umbrella aif-handoff-as-runtime-bridge. Evaluates Variant A: aif-handoff as MCP-consumer of meta-kickoffs (bridge script calls handoff_create_task → aif-handoff Planner/Implementer/Reviewer cycle → WebSocket tail → status write-back to state.md).

Verdict: REFERENCE (not ADOPT, not BUILD). Match score: 28%.

Body-format falsifier (kickoff line 76): CONDITIONAL PASShandoff_create_task description field = z.string().optional() with no .max() (Zod schema) — our kickoff body fits. BUT accept_existing_plan bypass requires physical PLAN.md on disk in .ai-factory/ (not pure MCP), and aif-handoff Reviewer in autoMode conflicts with reviewer-discipline.md §2 strategy-fork-surface gate.

Key findings:

  • MCP schema compatible: minimum call = {projectId, title}, description accepts arbitrary markdown
  • accept_existing_plan provides Planner-bypass but requires filesystem coupling (disk-resident PLAN.md)
  • WebSocket = broadcast channel (no topic filter — bridge must filter by taskId client-side)
  • Docker-free deployment feasible (Node.js + SQLite minimum)
  • Bridge LOC estimate: ~175 LOC, 3 MCP calls + 1 WebSocket (within targets)
  • Admission gate §2.4 CLEAR: PR Wave 10.6 — port hook-stub-completeness audit to principle 16 #127/docs(automerge): codify branch-from-main staging flow + resync discipline #128 touch packages/runtime/ only — no packages/mcp/ or apps/coordinator/ changes
  • SKILL.md:404 vs :429 inconsistency resolved: both consistent (BFR verdict = REFERENCE for SP skill; operational action = ADOPT template)

Evidence base: 7 DeepWiki probes + 2 WebSearch queries + SSOT rows #27/#28/#30/#43/#44/#46/#67/#80 consult + SKILL.md:404/429 + prior-art-evaluations.md:95-148 direct read.

Output

Single research-patch: docs/meta-factory/research-patches/2026-05-29-aif-handoff-bridge-variant-a-mcp.md (393 LOC). No code changes, no skill edits, no SSOT row landings — additive-note proposals only for Sub-wave D to land.

§1.7 Forward-check applied

  • build-first-reuse-default.md §1 (verdict ladder): REFERENCE chosen per §1 — ADOPT blocked by PLAN.md disk coupling + Reviewer autoMode conflict. BFR §3 6-layer search: (a) SSOT consult prior-art-evaluations.md:95-148; (b) DeepWiki ≥5 probes (7 executed with URLs); (c) WebSearch ≥2 phrasings (both executed); (d) own-stack sweep SKILL.md:404 + SKILL.md:429.
  • no-paid-llm-in-ci.md §1: all evidence via DeepWiki MCP + WebSearch + gh CLI + bash grep. Zero API-billed calls.
  • reviewer-discipline.md §2: patch surfaces aif-handoff Reviewer conflict as a risk to maintainer; does NOT pick between our Phase -1 and aif-handoff Reviewer. That is maintainer's decision.
  • phase-research-coverage.md §1.7: §7+§8 self-reflexive walk in the research-patch.
  • ai-laziness-traps.md §3: T1 (7 probes ≥5), T3 (all findings have file:line or DeepWiki URL), T7 (adversarial counter-probes 6-7), T11 (SSOT consult + WebSearch), T12 (DeepWiki at R-phase time), T13 (SP requesting-code-review re-verified at research-patches/2026-05-23-meta-orchestrator-prior-art.md:73), T15 (§7-§8 self-application), T16 (§3 T16 table), T17 (markdown only), T19 (cold-QA noted), T20 (§5 verdict cites SSOT row + DeepWiki URL + falsifier outcome).
  • Admission gate §2.4: gh api repos/lee-to/aif-handoff/commits?since=2026-04-29 run — commits = PR docs(automerge): codify branch-from-main staging flow + resync discipline #128 (51ce96a) touching packages/runtime/ only. Gate CLEAR.

§1.7 Backward-check applied

Pre-flight grep

grep -nE '^### §1\.7 (Forward|Backward)-check applied$' — PR body (this body):
  line: "### §1.7 Forward-check applied" ✓
  line: "### §1.7 Backward-check applied" ✓

file:line citations in §1.7 sections:
  prior-art-evaluations.md:95-148 ✓
  SKILL.md:404 ✓
  SKILL.md:429 ✓
  research-patches/2026-05-23-meta-orchestrator-prior-art.md:73 ✓

Test plan

  • Research-patch first line = <!-- scope:aif-handoff-bridge-variant-a-mcp --> (principle 10 regex)
  • §0-§9 sections present (12 elements per kickoff §11)
  • §4 5-criteria scoring with file:line evidence per cell (15 cells)
  • §5 verdict (REFERENCE) per BFR-default ladder
  • Falsifier explicitly applied and stated as CONDITIONAL PASS
  • §1.7 Forward + Backward in research-patch (§7+§8) AND PR body
  • ≥5 DeepWiki probes cited with quoted excerpts (7 probes)
  • ≥2 WebSearch queries cited (2 executed)
  • Admission gate §2.4 re-verified (CLEAR)
  • markdownlint-cli2: 0 errors (pre-commit hook passed)
  • All principle tests: 153 passed / 4 skipped
  • PR opened against staging
  • Phase -1 cold-review by orchestrator/maintainer before merge (T19 — worker does not self-approve)

…eep evaluation

Variant scored: MCP-consumer bridge (handoff_create_task + accept_existing_plan +
WebSocket tail + handoff_sync_status). 7 DeepWiki probes + 2 WebSearch queries +
SSOT #27/#28/#30/#43/#44/#46/#67/#80 consult + SKILL.md:404/429 disambiguation.

Verdict: REFERENCE (not ADOPT). Body-format falsifier PASSES — description field
accepts arbitrary markdown (z.string().optional(), no .max()). Minimum call =
{projectId, title}. BUT full pipeline bridge blocked by three structural issues:
(1) accept_existing_plan requires physical PLAN.md on disk in .ai-factory/ —
filesystem coupling beyond MCP boundary; (2) WebSocket broadcast channel has no
topic filter — client must filter by taskId; (3) aif-handoff Reviewer (autoMode)
conflicts with reviewer-discipline.md §2 strategy-fork-surface gate.

Admission gate §2.4: PR #127/#128 touch packages/runtime/ only — no packages/mcp/
or apps/coordinator/ changes. Gate CLEAR.

SKILL.md:404 vs :429 inconsistency resolved analytically (both consistent — BFR
verdict = REFERENCE for SP skill; operational action = ADOPT SP dispatch template).

Prior-art: prior-art-evaluations.md#44 (DEFER, body-format now confirmed compatible);
prior-art-evaluations.md#30 (DEFER, accept_existing_plan bypass documented);
prior-art-evaluations.md#67 (REJECT unchanged — Variant A is optional layer, not
replacement). Sub-wave D proposes new SSOT row for Variant A bridge vocabulary.
@artyhoo
artyhoo merged commit 22ce0c2 into staging May 29, 2026
22 checks passed
artyhoo added a commit that referenced this pull request May 29, 2026
#269)

Mechanical corrections to merged SW-A (#268) + SW-B (#267) research-patches per
Phase -1 Stage 1→2 cold-review. No verdict changes — SW-A REFERENCE and SW-B
REJECT both unaffected.

- B1: SW-B :39, :117 — PR #128 IS merged. Original record used jq camelCase
  '.mergedAt' which returns null; the actual snake_case '.merged_at' returns
  2026-05-26T08:07:12Z (merge SHA 51ce96a). Verified 2026-05-29 via
  'gh api repos/lee-to/aif-handoff/pulls/128 --jq .merged_at'.
- M1: SW-A :343 — gate-4 evidence said "all are from PR #128" but BOTH
  PR #127 (e1ffa70, merged 2026-05-15) AND PR #128 (51ce96a, merged
  2026-05-26) are in the 30-day window. Both touch packages/runtime/ only.
- m1: SW-A :392 — Probe 6 URL hash typo ae7472a9 -> ae7072a9 (aligned to
  line 119 body-text canonical version; inferred from internal consistency,
  not externally re-verified due to DeepWiki client-side rendering).
- m2: SW-B :210 — overclaim "≥4 distinct phrasings on dir-watch" corrected
  to actual breakdown: 2 direct + 2 adjacent DeepWiki + 1 file-tree +
  1 gh + 3 WebSearch = 9 channels. Multi-channel triangulation noted.
- m3: SW-B §0 falsifier (:17) — aligned to §5 specificity ("…and creates
  tasks via the internal createTask function — re-evaluate as ADAPT with
  three criteria 1/2/4 re-scored…").

Phase -1 Stage 1→2 cold-review verdict was REVISE; this patch closes
B1+M1+m1/m2/m3 dispositions per state.md §3.4. DN-1 and DN-2 remain
maintainer-call; SW-C dispatch still blocked on those answers.

Prior-art: skipped — mechanical text correction, no capability commit, no
new dependency, no new file ≥50 LOC. Per CLAUDE.md capability-commit
definition, this is a refactor/typo-fix grade change to existing artifacts.
artyhoo added a commit that referenced this pull request May 29, 2026
… Implementer-equivalent only) value-add audit (#276)

R-phase patch for Sub-wave C of the aif-handoff-as-runtime-bridge umbrella.
Evaluates Variant C (kickoff §3 lines 124-145): aif-handoff as Implementer-
equivalent only, bypass Planner+Reviewer cycle, thin CLI wrapper for kickoff
dispatch + kanban status tracking.

Verdict: REJECT (BFR-default §1 ladder). Rationale:
- The kickoff-framed "aif-handoff exec --kickoff <path>" CLI does not exist
  in lee-to/aif-handoff (DeepWiki probes 1+5, 2026-05-29).
- No first-class Implementer-only mode; skipReview:true bypasses Reviewer but
  Planner is mandatory unless accept_existing_plan with on-disk PLAN.md
  (same disk coupling SW-A flagged for Variant A).
- BEFORE/AFTER maintainer-action count: 25% literal / 0% cognitive reduction
  (T-AIF-BRIDGE-C table §4) — below kickoff §8 STOP 30% threshold → verdict
  "Variant C value-add insufficient".
- Pure-tracker pattern (paused:true + autoMode:false + manual state-machine
  transitions) IS shipped but adds zero automation beyond UI tracking;
  Docker+SQLite infra unjustified.

Cites:
- SW-A merged PR #268 (Variant A REFERENCE, 28% match, 3 ADOPT-blockers)
- SW-B merged PR #267 (Variant B REJECT, ~5% match, no dir-watch capability)
- PR #269 follow-up (mechanical corrections, no verdict changes)
- DN-1=B-constrained input consumed in criterion 5 (mooted for Variant C
  which bypasses aif-handoff Reviewer entirely)
- Gate-4 admission re-sweep: PR #127+#128 touch packages/runtime/ only
  (no MCP/coordinator drift in 30-day window)

5 distinct DeepWiki probes + 2 WebSearches + cross-ref to SW-A/SW-B/PR #269
= 19+ evidence channels (T1 floor exceeded 3.8x). §1.7 forward+backward +
§self-application + T-trap walk per ai-laziness-traps.md §3.

Single output file under docs/meta-factory/research-patches/. No code, skill,
agent, install.sh, or .claude/rules/ modifications.

### §1.7 Forward-check applied

build-first-reuse-default.md §1 verdict ladder applied; BFR §3 6-layer search
performed (SSOT rows #27/#28/#29/#30/#43/#44/#46/#67/#80 reviewed at
prior-art-evaluations.md:95-148; DeepWiki >=5 probes; WebSearch >=2 phrasings;
own-stack sweep at .claude/skills/meta-orchestrator/SKILL.md:441 anti-scope +
:404+:429 SP requesting-code-review). no-paid-llm-in-ci.md §1 enforced (all
evidence via subscription-bundled DeepWiki/WebSearch + free gh CLI + bash).
reviewer-discipline.md §2 respected (DN-1=B-constrained consumed as fact, not
re-litigated; verdict is research finding against §8 STOP, not strategy
choice). ai-laziness-traps.md §3 active T-traps applied (T1, T3, T7, T11,
T12, T13, T15, T16, T17, T19, T20, T-AIF-BRIDGE-C MANDATORY BEFORE/AFTER
table at patch §4). Evidence: see patch §8 file:line citations.

### §1.7 Backward-check applied

SSOT #27/#28/#67 receive additive notes (additive-only; no verdict changes).
Original DEFER/DEFER/REJECT rationales reviewed at prior-art-evaluations.md:
95, 96, 135 — consistent with Sub-wave C findings (reinforce existing
classifications, do not re-litigate). No .claude/rules/* modified; no
.claude/skills/* modified; no agents/* modified; no packages/* modified;
no install.sh modified; no kickoff.md modified. Single output file in
docs/meta-factory/research-patches/. Scope strictly bounded to Variant C;
SW-A/SW-B/SW-B2/SW-D out of scope. T15 self-application confirmed in
patch §10. Memory not written (Sub-wave D synthesis is the natural
codification surface). Evidence: see patch §9 file:line citations.
artyhoo added a commit that referenced this pull request May 29, 2026
…verdict (DEFER-all-with-updated-triggers) (#281)

Cross-variant synthesis consolidating Sub-waves A/B/B'/C (merged PRs #267/#268/#275/#276). Per-variant verdicts re-derived independently per T15: A=REFERENCE (28%), B=REJECT (~5%), B'=REFERENCE conditional ADOPT VOCABULARY (~35%), C=REJECT (~22%). Cross-variant recommendation per kickoff §6.5: DEFER all variants with updated SSOT «Trigger to revisit» fields.

Includes 20-cell comparison table (4 variants × 5 criteria, file:line citation per cell), 4-row T16 problem-class match table, DN-1 (B-constrained) + DN-2 (B' is operative B-path) reflections, hook-discipline (Decision 10) analysis (no equipoise → recommend on clearly-better evidence; DECISION-NEEDED NOT warranted), consolidated SSOT additive notes for #27/#28/#30/#44/#67/#80, proposed new SSOT row #85 (next-after-#84 verified).

Prior-art: prior-art-evaluations.md#27, #28, #30, #44, #67, #80 (existing aif-handoff entries, additive-note-only — no verdict changes); SSOT row #85 PROPOSED, not landed.
artyhoo added a commit that referenced this pull request May 29, 2026
…DONE (#283)

Per umbrella's post-GO directive (Phase -1 Stage 3 close-review GO 2026-05-29 on
PR #281 SW-D synthesis), update wave-sequencing-plan.md §0 to reflect umbrella
closure:

- Row update: stale 🟡 «Sub-wave A + B R-phase done / synthesis pending» →
  ✅ DONE 2026-05-29 with verdict DEFER ALL. Full per-variant scoring
  (A REFERENCE 28% / B REJECT ~5% / B' REFERENCE 35% conditional / C REJECT 22%)
  + 3 ADOPT-blockers shared across A/B'/C + 6 evidence PRs (#267/#268/#269/
  #275/#276/#281) + SSOT additive notes status (proposed, not landed).
- Renamed row to canonical umbrella name (`aif-handoff-as-runtime-bridge`).
- «What actually remains» — remove the umbrella entry; add to deferred-decisions
  parenthetical at bottom of the line.
- Plan revision history — add this PR.

No verdict changes to any other §0 row. No edits outside §0. Broader 40+ UNTRACKED
PRs in §0 (recordkeeping debt per state.md Decision 2) stay deferred — out of
scope for this umbrella's closure per CLAUDE.md PR strategy.

Prior-art: skipped — recordkeeping update for completed umbrella, no capability
commit, no new dependency, no new file ≥50 LOC. Per CLAUDE.md capability-commit
definition, this is a docs-edit grade change.
artyhoo added a commit that referenced this pull request Sep 5, 2026
…yer (#1597 ledger A6-* R-6 R-7 S-4) (#1625)

## Summary

Nine findings from the #1597 promote review's runtime-bridge CLI share (A6-1 A6-2 A6-4 A6-6 A6-7 A5-7/A6-5 R-6 R-7 S-4, plus the D-4 src twin of A6-4), fixed in `packages/runtime-bridge/src/cli/` and re-vendored into `packages/runtime-bridge/vendor/` — the copy a factory-profile install places at `.claude/vendor/runtime-bridge/`, i.e. the code a consumer actually runs. Includes the routed port of #1618's four src fixes to the vendored twins, which that PR left behind (C13 → C12 handoff).

The through-line is one defect class: the same helper hand-copied per CLI, diverging silently. Four copies of a main-module guard (one form correct since #968, four naive, one file with no guard at all), five copies of an argv lookup, three copies of an HTTP request + BackendError mapping. Each is now one module the others import.

## Changes

- **New `src/cli/cliEntry.ts`** — shared entrypoint plumbing.
  - `isMain()` realpaths BOTH sides, so a CLI invoked through a symlink still runs (A6-1 / R-6). Applied to all eight CLIs ([park.ts:227](packages/runtime-bridge/src/cli/park.ts), answer:269, questions:228, ensure-parallel:135, dispatch:322, claim:190, harvest:689, await:154).
  - `parseCliArgs()` wraps `node:util` `parseArgs` (built-in, no dependency) and replaces five hand-rolled `argv.indexOf(flag) + 1` lookups; rejects unknown flags, a flag whose value is the next flag, a flag value hijacking a positional, empty `--flag=`, and positional junk (A6-4 / A6-7 / D-4 / R-6).
- **`dispatch.ts`** exits 1, not 0, when the kickoff path is absent or unreadable (A6-2). The PostToolUse hook is unaffected — it reads stdout in a command substitution and exits 0 unconditionally.
- **`park.ts`** is idempotent: a repeat park of the same question issues no PUT and reports `alreadyParked` (A6-6).
- **`harvest.ts`** `main()`: `getTask` and the `--body-file` read moved inside the try that owns the `[harvest] FAILED:` line and the Channel-A fallback (A5-7 / A6-5); the bare top-level `void main()` is now guarded.
- **`cli/aifHttp.ts`** is the single request implementation: `answer.ts`'s verbatim copy (S-4) and `aifWsStatus.getTaskStatus`'s third hand-written `GET /tasks/:id` (R-7) both call it. One timeout policy and one 429 → `quota_exceeded` mapping, where the copies had already diverged.
- **Vendored twins** re-synced (`cp` + `scripts/format-shipped.sh --write`, P4 still parked), and #1618's four src fixes ported to them in their own commit.

## Prior-art consult

- [x] Capability commits in this PR carry a `Prior-art:` trailer citing SSOT entries by ID.
- [x] A new capability area surfaced (argv parsing + ESM main-module detection for a dependency-free vendored CLI tree): entries **#268** (`node:util parseArgs` — ADOPT; `commander`/`yargs`/`minimist` REJECTED in the same consult) and **#269** (`es-main` — ADAPT: its realpath-both-sides mechanism, not the dependency) added to [prior-art-evaluations.md](docs/meta-factory/prior-art-evaluations.md) in the same commit as `cliEntry.ts`, each with Verdict / Rationale / Trigger to revisit.
- [x] No existing entry matched the area (searched the §4 table for CLI/argv/entrypoint capability rows).
- [x] context7 (`/nodejs/node`, `util.parseArgs` strict mode / allowPositionals / missing-value errors) plus two WebSearch phrasings (ESM main-module detection under symlinks; `parseArgs` vs `minimist`/`commander`/`yargs`), all 2026-09-05, cited in entry #268/#269 rationales.

## Test plan

- [x] `npm test` in `packages/runtime-bridge` — **337 passed, 1 skipped** (was 317 before; 20 new assertions).
- [x] `npx tsc --noEmit` in `packages/runtime-bridge` — clean; **and the vendored tree typechecks standalone** with `vendor/` un-excluded (it is outside the framework's `tsc` scope by design).
- [x] `npm run format:check` (shipped surface, includes the vendor drop) — clean.
- [x] `bash scripts/build-getff-dist.sh --check` — in sync, 1060 files.
- [x] `bash tests/install-sh/gh-531-shipped-prettier.test.sh` — PASS=48 FAIL=0.
- [x] `bash tests/hooks/runtime-bridge-dispatch-optin.test.sh` — PASS=5 FAIL=0.
- [x] `packages/core` — `hooks/runtime-bridge-dispatch.test.ts` + `hooks/checks/prior-art.test.ts` — 126 passed.
- [x] Manual smoke: each of the four naive-guard CLIs driven through a real symlink (`test/cli-symlink-entry.test.ts`) — RED before this change with empty stderr and exit 0.

## Provenance

n/a

## Review findings

Fixed here (each verified by a test that was RED on the pre-change code):

- **A6-1 — four CLIs silently no-op under a symlinked path.** Failure-scenario: an agent runs `npx tsx /tmp/<worktree>/…/park.ts --task X --question '…'` where the absolute path crosses a symlink (macOS `/tmp` → `/private/tmp`, a `bin/` shim, `node_modules/.bin`); the guard compares a resolved path against an unresolved one, is false, and the process exits 0 with no stdout and no stderr — the task is never paused, and `questions.ts` reads the same way as "no parked questions".
- **A6-2 — dispatch exits 0 on an unreadable kickoff.** Failure-scenario: `/dispatcher` or a night loop runs `dispatch.ts` with a mistyped kickoff path; stderr carries the ENOENT but `$?` is 0 and stdout is empty, so a wrapper checking the exit code records the stage as dispatched while no task exists.
- **A6-4 / D-4 — a flag value before the task id becomes the task id.** Failure-scenario: `harvest.ts --base staging f1010da4` harvests task `staging` → `GET /tasks/staging` 404s outside the try → raw stack; the real task is never harvested.
- **A6-7 — a flag whose value is the next flag.** Failure-scenario: `park.ts --task --question 'Fork…'` yields `taskId='--question'`, passes validation, and `GET /tasks/--question` 404s as `dispatch_failed` instead of reporting the missing `--task`.
- **A6-6 — park is not idempotent.** Failure-scenario: an agent retry or night-loop re-entry runs `park.ts --task X --question Q` a second time; the plan gains a second identical OPEN QUESTION block and `blockedReason` is overwritten, so the operator sees one fork twice.
- **A5-7 / A6-5 — harvest failures bypass the classified exit path.** Failure-scenario: an unreachable aif, an unknown taskId, or a mistyped `--body-file` throws before the try opens, so the operator gets a raw unhandled-rejection stack with no `[harvest] FAILED:` line and no Channel-A fallback commands — exactly when they need the manual egress.
- **R-6 — the guard and the argv lookup copied 4×/5×.** Failure-scenario: the realpath fix from #968 reached two of six CLIs, and harvest's argv copy had additionally dropped the truthiness guard (`--base ""` → empty base branch); a fix in one copy does not reach the others by construction.
- **R-7 — `getTaskStatus` re-implements `getTask` + its mapping.** Failure-scenario: the copies had already diverged — the status probe aborts after 5 s while the CLI copy had no timeout at all, so `park`/`answer`/`harvest`/`ensure-parallel` hang forever on a wedged aif API that the probe of the same URL times out against; and `getTaskStatus` had no 429 branch, reporting a rate-limited API as `dispatch_failed`.
- **S-4 — `answer.ts post()` duplicates `aifHttp request()`.** Failure-scenario: the aif error-mapping contract lives in two functions per tree and the tree is vendored, so four copies; adding a timeout or changing 429 handling must be replayed per copy or they diverge (which R-7 shows already happened).

Ported from #1618 (routed by C13, not re-derived here): unscoped `GET /runtime-profiles`, missing-`projectId` classification, the unguarded cancel DELETE, and the silent `exit(0)` on a non-BackendError — all four still live in the vendored twins at that PR's merge. Verification that the port is a port: prettier@3.8.3 over the HEAD `src` of all ten vendored modules reproduces the committed vendor byte-for-byte for seven and differs for exactly the three #1618 touched.

Not fixed here, surfaced for routing:

- **A6-6 residue** — parking a `done`/`verified`/`backlog` task still sets `paused:true` on a terminal task, and `answer.ts` `resumePark` still rewrites plan/paused on a task that is not paused. Narrowed deliberately: refusing a terminal-status park changes the `/pipeline` `done` → `request_changes` flow, which is outside this PR's scope.
- **`AifHandoffBackend._rest`** ([AifHandoffBackend.ts:530](packages/runtime-bridge/src/AifHandoffBackend.ts)) is a fourth copy of the same request + mapping, left untouched: backend semantics are C13's ownership zone and #1618 was in flight on that file.
- **E-1** — `vendor/src/idempotency.ts` still hardcodes the `/tmp` dedup path the vendor README documents as `RUNTIME_BRIDGE_DEDUP_PATH`-driven. Consumer-fit item, C14's zone.

## Fidelity verdict

FIDELITY: skipped — no kickoff: this is a review-ledger fix batch dispatched from the #1597 finding list, not a stage of an umbrella

## Parked questions

none

## §1.7 Self-discipline check (REQUIRED if PR touches discipline-bearing files)

### §1.7 Forward-check applied

This PR touches [docs/meta-factory/prior-art-evaluations.md](docs/meta-factory/prior-art-evaluations.md) (two new rows), which is discipline-bearing, so the Forward+Backward pair applies rather than the Skipped line. Disciplines checked before adding them:

- **Build-vs-reuse / own-stack-first** — [.claude/rules/build-first-reuse-default.md:46](.claude/rules/build-first-reuse-default.md) §1.1. The capability (argv parsing) was resolved by a Node built-in and an existing in-repo implementation, not by a new dependency and not by a new module of our own invention; both candidate families are recorded with verdicts rather than silently skipped.
- **SSOT entry procedure** — [prior-art-evaluations.md:51](docs/meta-factory/prior-art-evaluations.md) §3: entries added in the SAME commit as the capability artifact (`cliEntry.ts`), each carrying Verdict / Rationale / Trigger to revisit, with the rationale citing external links (nodejs/node#57616) and measured evidence rather than «didn't fit».
- **`#sync-by-copy-paste`** — [.claude/rules/dual-implementation-discipline.md:199](.claude/rules/dual-implementation-discipline.md) §8. The defect class this PR fixes is exactly that anti-pattern; the counter applied is the one the rule names — extract the shared implementation, make one channel the SSOT and have the others import it.
- **Attention is not a mechanism** — [.claude/rules/attention-is-not-a-mechanism.md:17](.claude/rules/attention-is-not-a-mechanism.md) §1. Every finding lands as a deterministic test that was RED on the pre-change code, not as a comment warning future readers; the symlink case in particular is driven through a real symlink rather than asserted about.
- **Capability-commit definition** — [CLAUDE.md](CLAUDE.md) «What is a capability commit?»: `cliEntry.ts` is a new ≥80 LOC file under `packages/`, so it takes the SSOT-citation path, not the escape hatch (the pre-push gate rejected the escape hatch and that rejection is what produced entries #268/#269).

### §1.7 Backward-check applied

Sweep of the existing artefacts under the same scope, before and after:

- **Every CLI in the tree, not only the four the ledger named.** Enumerated all of `packages/runtime-bridge/src/cli/*.ts` for the guard defect: four naive (park, answer, questions, ensure-parallel), two already correct since #968 ([dispatch.ts:322](packages/runtime-bridge/src/cli/dispatch.ts), [claim.ts:190](packages/runtime-bridge/src/cli/claim.ts)), and two the ledger did not report — [harvest.ts:689](packages/runtime-bridge/src/cli/harvest.ts) had a bare top-level `void main()` and [await.ts:154](packages/runtime-bridge/src/cli/await.ts) had no guard at all, both found by the import side-effect their absence produced. All eight now share the one helper.
- **Every copy of the argv lookup**: five sites (park, answer, questions, ensure-parallel, harvest), all replaced; `await.ts`'s own `parseArgs` is a different shape (`--timeout-ms` numeric coercion) and was left, noted here rather than silently.
- **Every copy of the request + BackendError mapping**: three folded into [aifHttp.ts](packages/runtime-bridge/src/cli/aifHttp.ts) (`answer.post`, `aifWsStatus.getTaskStatus`, plus `getTask`/`putTask` which already lived there); the fourth, [AifHandoffBackend.ts:530](packages/runtime-bridge/src/AifHandoffBackend.ts) `_rest`, is out of ownership and is reported above rather than left undiscovered.
- **The vendored twins of every file touched**, plus the three that still carried #1618's defects — verified by reformatting the HEAD `src` of all ten vendored modules and diffing against the committed vendor, which isolates semantic drift from print-width drift.
- **The getff payload manifest**: `cliEntry.ts` was absent from the first manifest rebuild because it was still untracked at build time, which would have shipped a vendored tree whose CLIs import a file the package does not deliver. Caught by re-running `build-getff-dist.sh --check` after the file was tracked; manifest now carries it.

---

Prior-art: prior-art-evaluations.md#268 (node:util parseArgs, verdict ADOPT — built-in argv parsing replacing five hand-rolled copies; commander/yargs/minimist rejected in the same consult as runtime deps in a dependency-free vendored tree that runs from a bare consumer checkout with tsx as its only peer requirement).
Prior-art: prior-art-evaluations.md#269 (es-main, verdict ADAPT — realpath-both-sides ESM main-module detection adopted as mechanism, not as a dependency; the repo already carried that implementation in cli/dispatch.ts and cli/claim.ts since #968).
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