Corrective plan — TFW-60 / Phase A, against TS §6¶
Written: 2026-08-26, after
evidence/census.mdand before any AC-12 edit. Against: TS revision 3, approved. Work order as revised at R3. Not a re-run. The RF is not the starting point; the REVIEW's 15 findings and the R3 clause changes are.
Status of each step in the revised order¶
| # | Step | State | Evidence |
|---|---|---|---|
| 1 | evidence/census.md |
✅ done — landed at 1917615 before any further edit |
census.md |
| 2 | new lifecycle id in tfw.statuses |
⬜ next — must precede the templates, or the sweep runs twice | — |
| 3 | templates and new carriers | 🟡 partly — grammar and identity fields done; second precision and phase state remain | journal_event.md, status.md |
| 4 | generator and migration scripts | 🟡 partly — resolver, schema, journal, board source done; second precision, phase rows, remaining hardcodes remain | gen_index.py, migrate_board.py |
| 5 | migration run + index generation | 🟡 re-run needed after steps 2–4 | — |
| 6 | snapshot verified BY COUNT | ✅ gate passes — 61 = 61, side by side | census.md §2 |
| 7 | board removal | ✅ done in the rejected pass; the trace it destroyed is restored | BOARD-SNAPSHOT.md |
| 8 | canonical rules → workflows → adapters → root | 🟡 done for the grammar; re-sweep needed for the new lifecycle id | — |
| 9 | release surface | 🟡 CHANGELOG updated for the grammar; needs the lifecycle id and second precision | .tfw/CHANGELOG.md |
Step 6 is behind step 7 in the tree only because the board was removed in the rejected pass.
The gate is satisfied on the restored artifact, verified by count against
git show b094943:README.md, not by assertion.
What each review finding required, and where it stands¶
| # | Finding | Disposition |
|---|---|---|
| F1 | seconds-only identifier cannot promise offline uniqueness | ✅ identifier is the whole directory name; bare stamp refused by the resolver; tested |
| F2 | creation protocol absent from shipped workflows | ✅ full create-or-retry algorithm now inline in plan.md, with the bound and the failure |
| F3 | event filename collides on same second + same kind | ✅ filename gains the actor; next-second on conflict; both cases tested |
| F4 | participant resolution only in a harness | ✅ a Who Is Acting block in all six workflows that write durably |
| F5 | .user_preferences.md visible to sync peers |
⬜ transferred to TFW-61 by R3 — a file-sync concern, settled by .gitignore in Git mode |
| F6 | status reader does not enforce the closed schema | ✅ validate_status enforces required keys, vocabulary, conditional keys both ways, dates, directory↔id agreement; 11 tests |
| F7 | gen_docs.py not migrated |
✅ container- and year-aware _task_glob; year no longer read as a task |
| F8 | 10 states ship, not 11; TFW-54 authority absent from Git | ✅ 11 tracked; authority now prefers what a clone will have |
| F9 | accounting overwritten; script hardcodes | ✅ board source explicit, zero rows refused, --today defaults to today, snapshot path from config. Remaining: index link and title hardcodes |
| F10 | release residue | ✅ template 2.0.0; initial_seq and {PREFIX}-1 gone from six files and every copy |
| F11 | AC-7 contradicts AC-1 | ✅ clause deleted by R3; nothing to execute |
| F12 | evidence numbers stale | 🟡 census regenerated; EV and RF still to rebuild from current commands |
| F13 | coverage gaps | 🟡 same-second creation, same-kind append, full schema, snapshot count, empty-board refusal all covered. Remaining: docs resolution under clock IDs and year nesting |
| F14 | broad staging | ✅ every commit this pass staged by explicit path, staged set diffed against intent before commit |
| F15 | index is a shared transition hot spot | ✅ the forcing test deleted and replaced by two that assert the opposite; build.verify now --validate, which reads task-local truth |
Remaining work, in order¶
- Step 2 — the lifecycle id. Add one value to
tfw.statusesfor phases running, in both config files,conventions.md§5,glossary.md, and every workflow, template and adapter copy that enumerates the vocabulary. Then set TFW-60's ownlifecycleto it — today it readsRF, which is a fragment of phase A's state standing in for a three-phase task. - Step 3 — second precision.
createdandupdatedbecomeYYYYMMDD-HHMMSS. The status template, its reader, its validator and the migration all change together. The migration must write a declared zero time where the legacy source carried only a date, and the RF must say so rather than imply second-accurate history. - Step 3 — phase state. One
status.mdper phase directory, same closed schema. The task-levellifecyclenever rolls phase state up. - Step 4 — index phase rows, rendered beneath their task row. Remaining
migrate_boardhardcodes removed. - Step 5 — re-run migration from the pre-removal board and regenerate the index.
- Step 8/9 — re-sweep for the new vocabulary value; CHANGELOG.
- F13 remainder — docs-resolution tests for clock IDs and year nesting.
- F12 — rebuild EV and RF with every number regenerated from current commands, and the AC-12 gate: a three-phase fixture driven concurrently under two owners.
Two rules held throughout¶
No typed timestamp. Every time value written this pass is read from the system clock and
the read is shown in evidence. The rejected pass shipped one event stamped 23:20:00 — round
seconds, dated after the review that consumed it. The ownership_changed event written this
pass shows its read: datetime.now().astimezone() -> 2026-08-26T22:46:47+05:00.
No broad staging. No git add -A, no git add ., no directory-wide add. Paths are
named, and the staged set is diffed against the intended set before every commit.
Standing question for the owner¶
The census puts the total at 75 now, 76 on completion, against a ruling of 68. Raised in
census.md §1 and §7 with every excess file named. Work continues on everything that does
not depend on the answer; the count is not trimmed to reach 68, because S44 forbids meeting
the number by delivering less.
Corrective plan — TFW-60 / Phase A | 2026-08-26