feat(routing): routing-metadata doctor + supported working_dir/task_list repairs + JSON/exit contract#40
Merged
Merged
Conversation
…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.
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.
Routing-metadata doctor + supported repairs + JSON/exit contract
Builds directly on PR #37 (
route_stateauthoritative, 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 updaterejected--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)getTaskRouteStateso the doctor and the OpenLoops drain agree on route enablement.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.repair_class:safe_auto | blocker_human | blocker_cross_repo | blocker_invalid_path | unsupported.--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 --listnow resolves exact UUID → partial UUID → project-scoped slug, is UUID-authoritative, and errors on unresolvable refs instead of silently succeeding.todos doctor routing --applyapplies onlysafe_autofindings viaupdateTask(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)
--jsonemitstodos.routing_doctor.v1:summary{inspected,eligible,findings_total,by_category,by_repair_class,safe_auto,blockers,unsupported,repaired,repair_failed},findings[],repairs[].--helpfor OpenLoops consumers.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)
ENOBUFS blocker fixed: both
spawnSynccall sites inrouting-health-scan.mjsnow pinmaxBuffer: 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).Scale test added for the real spawnSync path: a fake
--todos-binstreams a >1 MB doctor document through both call sites; verified the test fails 2/2 with the fix reverted and passes with it.Second defect found while verifying on the live corpus, fixed:
doctor routing --jsonused bareconsole.log, which intermittently truncated multi-MB output when stdout is a pipe (the pre-0.11.69list --jsonbug class). Now routed through the flush-safeoutput()writer; hammer-tested 10/10 sharded + 4/4 full-fleet green on the real spark01 corpus; added a >1 MB pipeddoctor routingregression test tocli.test.tsthat fails 5/5 with the fix reverted.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-listflags instead of the falsy''no-op. Full CLI round-trips covered by tests.R2 blocker fixed —
--applysilently dry-ran through the real CLI (reviewer find, task aca34bd7): the actionable parentdoctordeclares its own legacy--apply/--fixand Commander (non-positional default) strips them from argv before dispatching, sodoctor routing --applyreached 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 todoctor.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, assertsdry_run:false,repaired>0, the persisted mutation, the undo record, and that legacytodos doctor --applyis unregressed — fails with the fix reverted. The workflow's bakeddoctor 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)
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
Overlaps / seams reviewers should note
2560e003(--metadataflag) and3f707964(todos unassignfake-success no-op) are sibling routing-repo gaps tracked separately; this PR intentionally stays scoped and does not touch them. The doctor's--applyusesupdateTaskfield patches (working_dir/task_list_id), not--metadata, so it does not depend on2560e003.safe_autofindings and never assignments, so theunassignno-op (3f707964) does not affect this path.Safety
--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).