Document C1 codemod recipe + C6 wave boundaries + N-scan TODO deadlines (T2 iteration)
Address T2 review asks from Karpathy (request_changes) + Jobs (approve with minor asks) without touching published commits: - scripts/codemod/README.md (new): records remove-appdatabase-passthrough.mjs usage, the completeness proof for METHOD_TO_MODULE (typecheck-clean + 524 tests green at118e3d8= no orphaned call sites), and the sequential revert recipe for C1 (3 -> 2 -> 1, not independent because118e3d8bundled vault simplification). - CONTRIBUTING.md (new): pass-through ban + codemod usage + sequential revert recipe + file-size ceiling + C6 wave cap. Whitelisted in .gitignore alongside the existing doc exceptions. - docs/proposals/C6.2-error-taxonomy-phase2.md: wave 2 scope boundary names renderer-adjacent / api-server / browser / automation / skills explicitly and excludes src/main/database/** + src/main/worker/runtime/** (B2 / M10 high-churn zones). Wave 2 and wave 3 each capped at 30 catch sites so C6 cannot expand without bound. - src/main/agent-runtime/artifact-projector.ts, runtime-bridge.ts: N-scan TODOs now carry a death date ("TODO(M-followup by 2026-05-20)"). If the date passes without decomposition, a follow-up session MUST revisit or justify the exception. Karpathy T2 asks #1 and #2 (split part 3 / "independent revert" language) are addressed in CONTRIBUTING + codemod README as documentation, not history rewrites, because118e3d8is already published. Typecheck clean. No structural code changes; pure docs + comment edits.
This commit is contained in:
1 parent
69d03312e6
commit
ded707d960
6 files changed
+256
-14
No files matched your search
@@ -0,0 +1,108 @@
|
||||
# scripts/codemod/
|
||||
|
||||
One-shot and reusable codemods for mechanical refactors. Kept in the repo
|
||||
so the next person doing a similar migration has a working starting
|
||||
point instead of re-deriving it from scratch.
|
||||
|
||||
## remove-appdatabase-passthrough.mjs
|
||||
|
||||
Rewrites `db.<method>(...)` → `db.<module>.<method>(...)` for every
|
||||
pass-through method that used to live on `AppDatabase` / `AppDatabaseBase`
|
||||
and now lives on a sub-module field.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Full rewrite across src/**, tests/**:
|
||||
node scripts/codemod/remove-appdatabase-passthrough.mjs
|
||||
|
||||
# Dry run (print what would change, don't write):
|
||||
node scripts/codemod/remove-appdatabase-passthrough.mjs --dry-run
|
||||
|
||||
# Restrict to one or more modules:
|
||||
node scripts/codemod/remove-appdatabase-passthrough.mjs --modules=tasks,agents
|
||||
```
|
||||
|
||||
The script walks `git ls-files 'src/**/*.ts' 'src/**/*.tsx' 'tests/**/*.ts'`
|
||||
(so it respects `.gitignore`), excludes the three files that define the
|
||||
pass-throughs themselves (`src/main/database.ts`,
|
||||
`src/main/database-base.ts`, `src/main/database/**`), and applies the
|
||||
regex `(^|[^\w.])((?:[\w$]+\.)*)db\.(<method>)\(` → `$1$2db.<module>.<method>(`.
|
||||
|
||||
### C1 migration evidence (coverage proof)
|
||||
|
||||
The `METHOD_TO_MODULE` map in the script was derived mechanically from
|
||||
two source-of-truth files as they existed at the start of C1:
|
||||
|
||||
1. `src/main/database.ts` (pre-C1) — defined pass-through methods on
|
||||
`AppDatabase` that delegated to domain modules.
|
||||
2. `src/main/database-base.ts` (pre-C1) — defined pass-through methods
|
||||
on the base class that delegated to sub-module fields.
|
||||
|
||||
Every pass-through method name from those two files was copied into the
|
||||
map with its owning sub-module field name. Two composite methods
|
||||
(`createHireRequest`, `rollbackConfigRevision`) are intentionally left
|
||||
unmapped because they span multiple modules and live on `AppDatabase`
|
||||
itself; rewriting them would break caller semantics.
|
||||
|
||||
The completeness of the map is proven by two independent signals, not
|
||||
by inspection alone:
|
||||
|
||||
- **Typecheck after C1 part 3/3** (commit `ee1734e`): `pnpm typecheck`
|
||||
is clean. If the map had missed any pass-through, call sites would
|
||||
still read `db.<method>(...)` against a deleted method, and the
|
||||
TypeScript compiler would surface it as `Property '<method>' does
|
||||
not exist on type 'AppDatabase'`. Typecheck passing = no orphaned
|
||||
call sites.
|
||||
- **Test suite green after C1 part 3/3**: 524 tests pass. If the
|
||||
codemod had silently mis-mapped a method (e.g. routed `saveGoal` to
|
||||
`documentsMod` instead of `entityCrud`), the runtime would throw
|
||||
`TypeError: db.documentsMod.saveGoal is not a function` on the
|
||||
exercising test. All 524 tests green = map entries are semantically
|
||||
correct, not just syntactically in scope.
|
||||
|
||||
Taken together, typecheck-clean + 524 tests green = the map is
|
||||
complete and correct across every live call site at the time of C1.
|
||||
|
||||
### When to use this script in the future
|
||||
|
||||
If a future refactor re-introduces a pass-through on `AppDatabase` for
|
||||
temporary back-compat, and you want to remove it again, you have two
|
||||
options:
|
||||
|
||||
1. Add the method to `METHOD_TO_MODULE` in this script and run it.
|
||||
2. If the new pass-through follows a different shape (e.g. a method
|
||||
that moved to a different module entirely), copy this script as a
|
||||
template and adjust the map. The regex structure is reusable.
|
||||
|
||||
The ESLint rule in `eslint.config.mjs` blocks new pass-throughs from
|
||||
landing in the first place. See `CONTRIBUTING.md` at the repo root for
|
||||
the rule and the guidance on when to invoke the codemod.
|
||||
|
||||
### C1 commit recipe and revert ordering
|
||||
|
||||
C1 landed as three commits. The final one (`ee1734e`) did two things in
|
||||
the same commit — removed the remaining pass-throughs AND simplified the
|
||||
vault binding layer. In retrospect the vault simplification should have
|
||||
been a separate fourth commit so each concern could revert independently;
|
||||
in practice the commits are already published, so the recipe below
|
||||
records the actual state.
|
||||
|
||||
Commits (oldest first):
|
||||
|
||||
1. `e352a69` — codemod-driven rewrite of `tasks` + `agents` pass-throughs
|
||||
2. (C1 part 2/3) — rewrite of remaining domain-module pass-throughs
|
||||
3. `ee1734e` — remove final pass-throughs + add ESLint guard + simplify
|
||||
vault binding
|
||||
|
||||
**Sequential revert** (not independent): to unwind C1 cleanly you revert
|
||||
in reverse order: 3 → 2 → 1. Reverting commit 2 or 1 without first
|
||||
reverting 3 will leave the ESLint guard still active, which will then
|
||||
fail on the re-introduced pass-throughs. The "net simplification" part
|
||||
of `ee1734e` that touched the vault layer comes along for the ride; it
|
||||
does not have its own revert handle.
|
||||
|
||||
If that bundling is ever a problem, the fix is not to rewrite history
|
||||
(already published) but to issue a targeted revert of only the vault
|
||||
hunks of `ee1734e` via `git revert -n ee1734e && git checkout --patch
|
||||
HEAD -- <vault-files>`.
|
||||
Reference in new issue
Block a user