diff --git a/docs/struct-map.md b/docs/struct-map.md index 78d3917cd7..831aabdb47 100644 --- a/docs/struct-map.md +++ b/docs/struct-map.md @@ -1,6 +1,6 @@ # The struct map — the types the fleet's cast sites need (Phase 37 T1) -> **Generated by `tools/type_census.py` at `09b00a443` (2026-09-30T02:32:09Z); never typed (R75).** Every raw pointer-cast dereference in `src/` was assigned to a base (a parameter, a local, a global by value or by address, an absolute address) and the bases were clustered by EVIDENCE only — the same global symbol, an argument passed to a callee's parameter, an assignment or return, a pointer field read, a shared body's fleet-wide identity — never by a similar offset signature. Each cluster is one type the tree needs. Names are placeholders (`Unkstruct_`: the lowest global instance's address, else the lowest member function's); fields are placeholders (`unk`) until Phase 38 cites evidence. +> **Generated by `tools/type_census.py` at `3ac7abee7` (2026-09-30T02:38:06Z); never typed (R75).** Every raw pointer-cast dereference in `src/` was assigned to a base (a parameter, a local, a global by value or by address, an absolute address) and the bases were clustered by EVIDENCE only — the same global symbol, an argument passed to a callee's parameter, an assignment or return, a pointer field read, a shared body's fleet-wide identity — never by a similar offset signature. Each cluster is one type the tree needs. Names are placeholders (`Unkstruct_`: the lowest global instance's address, else the lowest member function's); fields are placeholders (`unk`) until Phase 38 cites evidence. **18739 types explain 498866 of 502985 dereference sites (99.2 %); 4119 sites have a base the census could not classify; 727 types carry a width conflict.** Merges by evidence: param 36454, assign 14664, arg 10168, field 9613, ret-of 3373, return 1524, assign& 1050, arg& 270. diff --git a/phase-ends/current/logs/T2.md b/phase-ends/current/logs/T2.md new file mode 100644 index 0000000000..474d1bd3fb --- /dev/null +++ b/phase-ends/current/logs/T2.md @@ -0,0 +1,9 @@ +# T2 log — --check-structs instrument and actor-struct fix +- Start: read card slice, plan Context/Interfaces/Cookbook/Research, T2 entry, tasks/T1.md, docs/actor-struct.md. +- Hook denied a sed read of tools/restruct.py source (expert learns tools from --help); design delegated whole to coder. +- Coder brief T2.c1 (opus55): add --check-structs (gating dup_classes, outside_canon, dead, variants, pad_names via restruct's own audit, parse_error_decls via restruct's latest-verdict function, controls); non-gating conflicting_types/tu_conflict/types_floor_lying; CANON_HEADERS single source; ≥2 selftests; actor-struct +0x108/+0x10C s16→s32; --check unchanged. +- T2.c1 returned done, commit 3ac7abee7: restruct gains ledger_latest (one latest-row function; ledger_index, settled-set and apply_batch --redraw use it) and audit_type_violations; type_census --check-structs + 3 selftests (24/24); restruct selftest 54/54; --check line identical before/after; control list was hard-coded (not doc-parsed) so D_80078F08/F0C moved into PLAYER_BLOCK at width 4, doc_disputed=0; audit-types 26 violations all pad-name kind. +- Verify (run.sh t2verify, .run/logs/t2verify.log): selftest OK; --check-structs FAIL dup_classes=206 outside_canon=6076 dead=141 variants=40 pad_names=26 parse_error_decls=1106 controls=4/4; doc_disputed=0; non-gating conflicting_types=160 tu_conflict=0 types_floor_lying=1796; rc=1. +- Known-true vs T1 baseline: 206/6,076 (4,085+1,904+63+24)/141/40/26/4-4 all equal. parse_error_decls 1,106 latest-row (1,107 all-rows); P37's 1,120 was a pre-latest-row figure, T1 recorded none. +- docs/struct-map.md regenerated by the verify census (stamp line) committed with the task. +- Retrievers: none. Report ids: none. diff --git a/phase-ends/current/tasks/INDEX.md b/phase-ends/current/tasks/INDEX.md index e57b71c8e5..87ba83ed9a 100644 --- a/phase-ends/current/tasks/INDEX.md +++ b/phase-ends/current/tasks/INDEX.md @@ -1,3 +1,4 @@ T1 | done | phase-start health and baselines | - | tasks/T1.md | logs/T1.md | - +T2 | done | --check-structs instrument and actor-struct fix | - | tasks/T2.md | logs/T2.md | - diff --git a/phase-ends/current/tasks/T2.md b/phase-ends/current/tasks/T2.md new file mode 100644 index 0000000000..a56fccfa9d --- /dev/null +++ b/phase-ends/current/tasks/T2.md @@ -0,0 +1,25 @@ +# T2 — --check-structs instrument and actor-struct fix + +Status: done | expert: expert-opus55 | ctx-at-completion: n/a | commit: see COMMIT | coder runs: c1 opus55 done (3ac7abee7) +Done: `type_census.py --check-structs` gates the struct milestone's counts; on the T1 tree it FAILS with T1's baseline; actor-struct doc fixed so controls show 0 doc-disputed. +Files: +- tools/type_census.py — `--check-structs` mode, counts/controls/non-gating lines, 3 new selftests (24 total); CANON_HEADERS the single canonical list +- tools/restruct.py — `ledger_latest` (the one latest-row-per-unit function; ledger_index, settled-set, `--redraw` use it); `audit_type_violations` (the --audit-types rule, imported by census) +- docs/actor-struct.md — +0x108/+0x10C s16 → s32 +- docs/struct-map.md — regenerated stamp +Decisions: +- binding: every "latest ledger verdict" reader goes through `restruct.ledger_latest`; no second filter. +- pad_names gates all restruct --audit-types violations; today all 26 are pad-name kind (`audit_other=0` reported non-gating to expose any other kind). +Deviations: +- The census control's doc-disputed list was hard-coded in type_census, not parsed from the doc; D_80078F08/F0C moved into PLAYER_BLOCK at width 4 alongside the doc edit. +- `tu_conflict=0`: the restruct ledger has no TU-CONFLICT verdicts; P37's 45 TU-CONFLICT rows live elsewhere (census/logs). Non-gating, left for T6. +Findings: +- Baseline counts: dup_classes=206 outside_canon=6076 dead=141 variants=40 pad_names=26 parse_error_decls=1106 controls=4/4; non-gating conflicting_types=160 tu_conflict=0 types_floor_lying=1796. +- parse_error_decls 1,106 latest-row vs 1,107 all-rows; the P37 "1,120" predates latest-row counting. conflicting_types 160 latest-row vs P37's "417". +- `--check` output identical before/after. +Gotchas: +- harness: the expert's Bash hook denies reading tool source even by line range (sed); code facts must come via coder or retriever-code. +- generalizable: a census "control" that compares against a doc may be a hard-coded list, not a parse; fixing the doc alone does not move it. +Next task needs: `--check-structs` is the phase gate; baseline above; census at .run/P38/census. +Verified: .venv/bin/python tools/type_census.py --selftest && .venv/bin/python tools/type_census.py --out-dir .run/P38/census --check-structs; test $? -eq 1 → selftest OK, rc=1 with the baseline counts, doc_disputed=0 (.run/logs/t2verify.log) +Full log: phase-ends/current/logs/T2.md