Skip to content

feat(routing): routing-metadata doctor + supported working_dir/task_list repairs + JSON/exit contract#40

Merged
andrei-hasna merged 4 commits into
mainfrom
chief-routing-doctor
Jul 5, 2026
Merged

feat(routing): routing-metadata doctor + supported working_dir/task_list repairs + JSON/exit contract#40
andrei-hasna merged 4 commits into
mainfrom
chief-routing-doctor

Conversation

@andrei-hasna

@andrei-hasna andrei-hasna commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Routing-metadata doctor + supported repairs + JSON/exit contract

Builds directly on PR #37 (route_state authoritative, released as 0.11.74). Ships first-class, deterministic routing-metadata drift detection and supported repairs so remediation never needs raw DB edits.

Closes the systemic gap behind the routing-hygiene cleanup: that run had to fall back to a scoped SQLite transaction because todos update rejected --working-dir ("unknown option") and there was no supported doctor/repair path.

What's here (3 batched tasks + 1 loop target)

todos doctor routing — drift detector (task 365eaee8)

  • Scans pending/in_progress tasks; builds on getTaskRouteState so the doctor and the OpenLoops drain agree on route enablement.
  • Finding categories: null_working_dir, wrong_working_dir, null_task_list_id, unresolvable_task_list, invalid_project_path, missing_project, no_auto_conflict, cross_repo_intent, route_not_enabled.
  • Each finding carries task id, project id/path, expected repo path, task_list state, route eligibility, and a repair_class: safe_auto | blocker_human | blocker_cross_repo | blocker_invalid_path | unsupported.
  • Deterministic and conservative: worktree working_dirs aren't flagged; cross-repo intent is heuristic-but-never-auto-repaired; ambiguous cases are reported, not guessed.
  • Scoping: project-stable --shard i/N, --project, --tag, --status, --no-verify-project-root, --limit.

Supported repairs (task 31529f3f)

  • todos update --working-dir <path> — closes the exact "unknown option --working-dir" gap.
  • todos update --clear-working-dir / --clear-list — explicit supported null-resets (the undo path for null-origin repairs; a bare --working-dir '' is falsy and was a silent no-op).
  • todos update --list now resolves exact UUID → partial UUID → project-scoped slug, is UUID-authoritative, and errors on unresolvable refs instead of silently succeeding.
  • todos doctor routing --apply applies only safe_auto findings via updateTask (no raw SQL), comments old/new/source/command on each task, writes a DB backup + undo record with honest per-repair undo_commands, and leaves every blocker untouched. Dry-run is the default.

JSON + exit contract (task 9b19a1cc)

  • --json emits todos.routing_doctor.v1: summary{inspected,eligible,findings_total,by_category,by_repair_class,safe_auto,blockers,unsupported,repaired,repair_failed}, findings[], repairs[].
  • Exit codes: 0 clean · 1 findings · 2 invalid invocation. Documented in --help for OpenLoops consumers.
  • Multi-MB reports are emitted through the flush-safe stdout writer (see review amendments below), so piped consumers never see truncated JSON.

Loop target (task e77ff621)

  • scripts/routing-health-scan.mjs — deterministic consumer that reads the doctor JSON + exit code (no text scraping) and upserts one deduped routing-health task per scope (stable fingerprint). Surfacing only; never dispatches implementation agents.
  • scripts/routing-remediation.workflow.json — validated 3-step planner→worker→adversarial-reviewer loops workflow spec (applies only safe_auto; files deduped blocker tasks).

Review amendments (reviewer: chief-review-routing-doctor, #loops-logic 24004 / task 8f5e5168)

  1. ENOBUFS blocker fixed: both spawnSync call sites in routing-health-scan.mjs now pin maxBuffer: 256 MB (doctor JSON is 8.99 MB full-fleet vs the 1 MB runtime default — the scan previously died with exit 2 and upserted nothing at exactly the scale it exists for).

  2. Scale test added for the real spawnSync path: a fake --todos-bin streams a >1 MB doctor document through both call sites; verified the test fails 2/2 with the fix reverted and passes with it.

  3. Second defect found while verifying on the live corpus, fixed: doctor routing --json used bare console.log, which intermittently truncated multi-MB output when stdout is a pipe (the pre-0.11.69 list --json bug class). Now routed through the flush-safe output() writer; hammer-tested 10/10 sharded + 4/4 full-fleet green on the real spark01 corpus; added a >1 MB piped doctor routing regression test to cli.test.ts that fails 5/5 with the fix reverted.

  4. Hardening (from 8f5e5168, non-blocking item): undo records now emit real undo commands — value-origin repairs restore the prior value; null-origin repairs use the new --clear-working-dir/--clear-list flags instead of the falsy '' no-op. Full CLI round-trips covered by tests.

  5. R2 blocker fixed — --apply silently dry-ran through the real CLI (reviewer find, task aca34bd7): the actionable parent doctor declares its own legacy --apply/--fix and Commander (non-positional default) strips them from argv before dispatching, so doctor routing --apply reached the subcommand as a dry-run — repairs never ran, no undo record, no error, and the remediation workflow's baked invocation would have repaired zero while looking green. Fixed by falling back to doctor.opts() (apply: opts.apply || opts.fix || parentOpts.apply || parentOpts.fix). Added a CLI-level e2e regression test that drives the REAL binary: seeded scratch db, asserts dry_run:false, repaired>0, the persisted mutation, the undo record, and that legacy todos doctor --apply is unregressed — fails with the fix reverted. The workflow's baked doctor routing --apply --shard i/N --undo-record … invocation verified binary-to-binary on all six shard forms (Mode: apply).

Live evidence (spark01 production todos DB)

  • Full-fleet scan via the loop consumer: exit 1, 10879 findings, 4880 safe_auto, 3481 blockers (8390 inspected) — deterministic across repeated runs.
  • Scoped to the open-todos project: 48 tasks, 71 safe_auto (22 wrong + 9 null working_dir, 40 null task_list_id) — matches the shard-0 corpus classes, incl. the known chief-repo working_dir drift.

Test / verify

bun run typecheck
bun test src/lib/routing-doctor.test.ts        # 24 pass — detection + safe repair + sharding + undo commands
bun test scripts/routing-health-scan.test.ts   # 8 pass  — dedupe/shard core + >1MB spawnSync scale tests
bun test src/cli/cli-qol.test.ts -t "update"   # 11 pass — --working-dir/--clear-* + --list UUID/slug/unresolvable/conflicts
bun test src/cli/cli.test.ts -t "doctor routing report over a pipe"  # >1MB piped JSON never truncated
bun test src/cli-mcp-parity.test.ts            # parity green, 0 regressions
# live full-fleet (read-only):
bun scripts/routing-health-scan.mjs --todos-bin <todos> --dry-run

Overlaps / seams reviewers should note

  • 2560e003 (--metadata flag) and 3f707964 (todos unassign fake-success no-op) are sibling routing-repo gaps tracked separately; this PR intentionally stays scoped and does not touch them. The doctor's --apply uses updateTask field patches (working_dir/task_list_id), not --metadata, so it does not depend on 2560e003.
  • Repairs mutate only safe_auto findings and never assignments, so the unassign no-op (3f707964) does not affect this path.

Safety

  • Every mutation is gated behind --apply (default dry-run), backed up, undo-recorded with honest undo commands, and comment-evidenced. Blockers (cross-repo, invalid-path, unsupported, human) are never auto-mutated. No raw SQLite writes. Staged secrets scan: 0 findings on all changed files.

Follow-ups after merge+publish: activate the deterministic health loop + the planner→worker→adversarial-reviewer remediation workflow via the loops CLI (tasks e77ff621 / 3d61d12f), then the shard-0 cleanup (46fcea02) + cross-shard verification (5b28ca34).

…st repairs, JSON/exit contract

Adds `todos doctor routing` — a deterministic routing-metadata drift detector built on the PR#37 route_state contract — plus first-class supported repairs so remediation never needs raw DB edits.

Doctor (365eaee8): scans pending/in_progress tasks; classifies wrong/null working_dir, null/unresolvable task_list_id, invalid project paths, cross-repo intent, no-auto conflicts, and route_not_enabled-after-tag contradictions. Each finding carries task id, project id/path, expected repo path, task_list state, route eligibility, and a repair_class (safe_auto | blocker_human | blocker_cross_repo | blocker_invalid_path | unsupported). Deterministic; refuses to guess ambiguous cases. Project-stable sharding (--shard i/N), --project/--tag/--status scoping, --no-verify-project-root, --limit.

Supported repairs (31529f3f): `todos update --working-dir <path>` (closes the 'unknown option --working-dir' gap); `todos update --list` resolves exact UUID -> partial UUID -> project-scoped slug, UUID-authoritative, and errors on unresolvable refs instead of silently succeeding; `todos doctor routing --apply` applies ONLY safe_auto repairs via updateTask (no raw SQL), comments old/new/source/command per task, writes a DB backup + undo record, and leaves every blocker untouched.

JSON + exit contract (9b19a1cc): --json emits todos.routing_doctor.v1 (summary counts, by_category, by_repair_class, per-finding details). Exit 0 clean / 1 findings / 2 invalid invocation. Documented in --help for OpenLoops consumers.

Loop target (e77ff621): scripts/routing-health-scan.mjs — deterministic consumer that reads the doctor JSON + exit code (no text scraping) and upserts one deduped routing-health task per scope.

Tests: routing-doctor (22), consumer core (5), update CLI flags (6); tsc clean; cli-mcp-parity 0 regressions.
…ner -> worker -> adversarial-reviewer)

Validated loops workflow (chief-routing-remediation, steps=3, codewith moderate): planner reads the doctor JSON, worker applies ONLY safe_auto repairs via 'todos doctor routing --apply' (+ files deduped blocker tasks), adversarial reviewer re-runs the doctor and verifies safe_auto dropped, blockers untouched, and undo/backup/evidence complete. Loop target for task 3d61d12f; activates post-publish.
… undo commands (review amendments)

Amendments from adversarial review of PR#40 (#loops-logic 24004 / task 8f5e5168):

1. ENOBUFS blocker: both spawnSync call sites in scripts/routing-health-scan.mjs now pin maxBuffer=256MB. Doctor JSON is 8.99MB full-fleet (789KB per 1/6 shard) vs the 1MB runtime default, so the scan deterministically died with exit 2 and upserted nothing at the exact scale it exists for. Scale tests drive the real script through a fake --todos-bin streaming >1MB across both call sites; verified failing 2/2 with the fix reverted.

2. Second defect found while verifying full-fleet on the live corpus: doctor routing --json used bare console.log, which intermittently truncated multi-MB output when stdout is a pipe (the pre-0.11.69 list --json bug class). Now routed through the flush-safe output()/writeStdoutSync writer; hammer-tested 10/10 sharded + 4/4 full-fleet green on spark01's real corpus (exit 1, 10879 findings / 8390 inspected, deterministic). Added a >1MB piped doctor-routing regression test (fails 5/5 with the fix reverted).

3. Hardening (8f5e5168 non-blocking item): undo records now emit REAL undo commands. New supported null-resets todos update --clear-working-dir / --clear-list (with conflict guards + UpdateTaskInput.task_list_id widened to string|null); null-origin repairs undo via the clear flags instead of the falsy --working-dir '' no-op; value-origin repairs restore the prior value. Unit + CLI round-trip tests.

Verification: tsc clean; routing-doctor 24, scan 8 (incl. scale), cli.test+cli-qol 130, doctor+parity green; staged secrets scan 0 findings.
…ry-run (parent-option shadowing)

R2 review blocker (#loops-logic 24040 / task aca34bd7): the actionable parent 'doctor' declares its own legacy --apply/--fix, and without positional options Commander strips every option the parent recognizes from argv BEFORE dispatching the subcommand — so 'todos doctor routing --apply' delivered opts={verifyProjectRoot:true}, repaired nothing, wrote no undo record, and raised no error. The remediation workflow's baked invocation would have applied zero repairs while looking green. Library API was unaffected, which is why all suites passed.

Fix: the routing action reads doctor.opts() as fallback (apply = opts.apply || opts.fix || parentOpts.apply || parentOpts.fix), per the reviewer-proven patch. Legacy bare 'todos doctor --apply' unregressed.

Regression test: new CLI-level e2e in cli.test.ts drives the REAL binary — seeded scratch db, asserts dry_run:false + repaired>0 + persisted mutation + undo record + legacy doctor --apply unregressed; verified failing with the fix reverted. Workflow's exact baked shape (--apply --shard i/N --undo-record) probed binary-to-binary on all six shard forms: Mode apply.

Verification: tsc clean; cli.test+routing-doctor+doctor 126 pass / 0 fail; staged secrets scan 0 findings.
@andrei-hasna
andrei-hasna merged commit e67e442 into main Jul 5, 2026
1 of 2 checks passed
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