Skip to content

Commit 7084347

Browse files
docs+test: ROADMAP truthfulness audit + drift-detection aspect (closes Phase 0 housekeeping) (#60)
## Summary Phase 0 housekeeping — the ROADMAP truthfulness audit that `docs/PRODUCTION-PATH.adoc` §Phase 0 requires before advancing to Phase 1. Three real drifts found and fixed, plus a new aspect-test section that catches this drift class going forward. ## Drifts found and fixed ### 1. `spec/10-levels-for-wasm.adoc` → `spec/type-safety-levels-for-wasm.adoc` The file was renamed but 5 callers still pointed at the old path: - `ROADMAP.adoc` - `README.adoc` - `EXPLAINME.adoc` (twice) - `.claude/CLAUDE.md` All updated. ### 2. `EXPLAINME.adoc` Idris2 ABI table out of date EXPLAINME described a pre-restructure architecture (Types.idr / Layout.idr / Access.idr / Effects.idr / Linearity.idr / Foreign.idr). The actual structure is `src/abi/TypedWasm/ABI/{Region, TypedAccess, Pointer, Levels, Effects, Lifetime, Linear, MultiModule, Layout, Proofs, SessionProtocol, ResourceCapabilities, Choreography, Tropical, Epistemic, Echo, ModuleIsolation}.idr`. Rewrote claim 3's evidence sentence and the full file table to match reality, with each entry naming the actual load-bearing types from each file (`Region.idr` → Schema, sizeOf, alignOf; `TypedAccess.idr` → HostType, RegionPredicate; `Levels.idr` → Level1_InstructionValidity through Level10_Linear data types; etc.). ### 3. `src/abi/Foreign.idr` doesn't exist EXPLAINME's file table claimed `Foreign.idr` provided "FFI declarations: C header generation from Idris2 ABI". The file doesn't exist (the FFI surface is `ffi/zig/src/main.zig`, hand-maintained per the comment in that file's header). Removed the stale row. ## Drift-detection: claim-envelope §8 To prevent this class of drift recurring, `tests/aspect/claim-envelope.mjs` gets a new section 8 — "Path references in docs resolve to real files": - Scans README.adoc, ROADMAP.adoc, EXPLAINME.adoc, .claude/CLAUDE.md - Matches repo-relative path tokens with extensions: adoc/md/mjs/res/idr/zig/rs/ebnf/toml/ipkg - Allowlist: cross-repo paths (`typedqliser/`, `affinescript/`, `ephapax/`, `standards/`, `hypatia/`, `typell/`, `vql-ut/`, `echidna/`), templated paths (`{{...}}`), well-known non-repo paths (`github.com`, `/home/runner/`) - Skip filter: bare filenames without `/` (those are prose conventions like "see PROOF-NEEDS.md") - Prints every stale reference inline (not first-5-only) since rename drift is what reviewers must see in full Section 8 now finds 31 path references across the 4 docs, all resolving. Before this PR's fixes: 7 stale (the EXPLAINME refs to old `src/abi/` paths). ## Verification All test surfaces green after the changes: | Test | Result | |---|---| | claim-envelope.mjs | **53 passed, 0 failed, 0 skipped** (was 52; +1 from new section 8) | | property_test.mjs | 29 passed, 0 failed, 0 skipped | | security-envelope.mjs | 10 passed, 0 failed, 0 skipped | | regression.mjs | 25 passed, 0 failed, 1 skipped (idris2 not on PATH) | | smoke/e2e-smoke.mjs | 40 passed, 0 failed | | Structural E2E | 53 passed, 0 failed, 1 skipped | ## Files changed - `.claude/CLAUDE.md` — spec path fix - `EXPLAINME.adoc` — spec path fix + claim 3 evidence rewrite + file table restructure - `README.adoc` — spec path fix in Quick Tour - `ROADMAP.adoc` — spec path fix in Current State - `tests/aspect/claim-envelope.mjs` — new section 8 (path-reference drift detection) ## Closes Phase 0 This PR completes the ROADMAP truthfulness audit checklist item in #48. After it lands, Phase 0's housekeeping subsection is fully closed. Remaining Phase 0 items are Track A's multi-PR codegen pipeline work and Track B's cross-repo AffineScript migration — both outside what one session can ship. --- _Generated by [Claude Code](https://claude.ai/code/session_01ExgUTJmU5UQQNLKynwxDjm)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7260383 commit 7084347

5 files changed

Lines changed: 101 additions & 14 deletions

File tree

.claude/CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ TypeLL's 10-level type safety for WebAssembly linear memory.
1313
- **Idris2 ABI** (`src/abi/`) — Formal proofs: region schemas, typed access, 10-level verification
1414
- **Zig FFI** (`ffi/zig/`) — C-ABI bridge: runtime region management, typed load/store
1515
- **Grammar** (`spec/grammar.ebnf`) — The `.twasm` surface syntax (EBNF)
16-
- **Spec** (`spec/10-levels-for-wasm.adoc`) — How each level maps from DB to WASM
16+
- **Spec** (`spec/type-safety-levels-for-wasm.adoc`) — How each level maps from DB to WASM
1717
- **Examples** (`examples/`) — `.twasm` files demonstrating all features
1818

1919
## Build & Test

EXPLAINME.adoc

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ image:https://img.shields.io/badge/Levels-L1--10_checked_core_(L11--12_published
1818
L11 (tropical cost-tracking) and L12 (epistemic safety) are formally specified and published.**
1919
____
2020

21-
**Evidence**: `/var/mnt/eclipse/repos/typed-wasm/src/abi/Levels.idr` defines Idris2 dependent types for all 10 checked levels: L1 (instruction validity), L2 (region binding), L3 (type compatibility), ..., L10 (linearity). `src/abi/Proofs.idr` contains zero `believe_me`, `assert_total`, or escape hatches. LEVEL-STATUS.md confirms "checked L1-L10 core."
21+
**Evidence**: `/var/mnt/eclipse/repos/typed-wasm/src/abi/Levels.idr` defines Idris2 dependent types for all 10 checked levels: L1 (instruction validity), L2 (region binding), L3 (type compatibility), ..., L10 (linearity). `src/abi/TypedWasm/ABI/Proofs.idr` contains zero `believe_me`, `assert_total`, or escape hatches. LEVEL-STATUS.md confirms "checked L1-L10 core."
2222

2323
L11 and L12 are formally specified in `src/abi/TypedWasm/ABI/Tropical.idr` (L11: AllPairsCosts + Level11KleeneProof) and `src/abi/TypedWasm/ABI/Epistemic.idr` (L12: Level12Proof + freshness witnesses). The full 12-level type hierarchy is given by the `fullCert12` top-level certificate type in `Proofs.idr`.
2424

@@ -35,13 +35,13 @@ When Module A (compiled from Rust) shares memory with Module B (compiled from Re
3535
typed-wasm declares the shared schema once. Both modules import it. The typed-wasm checker verifies structural agreement at compile time, before any module runs.
3636
____
3737

38-
**Evidence**: `examples/02-multi-module.twasm` demonstrates: Module A exports a `region Entity` with fields (pos_x, pos_y, hp); Module B imports the same region and defines typed load/store operations. `src/abi/Proofs.idr` proves field offset and alignment agreement.
38+
**Evidence**: `examples/02-multi-module.twasm` demonstrates: Module A exports a `region Entity` with fields (pos_x, pos_y, hp); Module B imports the same region and defines typed load/store operations. `src/abi/TypedWasm/ABI/Proofs.idr` proves field offset and alignment agreement.
3939

4040
**Caveat**: Schema agreement proof is _type-level_ (compile-time). Does NOT verify that actual Rust/AffineScript compiled code respects field layout — correspondence is manual. Runtime behavior depends on correct field packing across compilers.
4141

4242
=== Claim 3: "Checked L1-L10 Proof Core — All 10 Levels Integrated"
4343

44-
**Evidence**: `spec/10-levels-for-wasm.adoc` maps each level from database (TypedQL) to WASM. `src/abi/` contains proof files for each: L1-L3 in Types.idr, L4-L5 in Layout.idr, L6-L7 in Access.idr, L8-L10 in Linearity.idr.
44+
**Evidence**: `spec/type-safety-levels-for-wasm.adoc` maps each level from database (TypedQL) to WASM. The Idris2 proofs live under `src/abi/TypedWasm/ABI/`: `Region.idr` + `TypedAccess.idr` define L1-L3 schema and access typing; `Pointer.idr` defines L4 nullability kinds; `Levels.idr` enumerates `Level1_InstructionValidity` through `Level10_Linear` as data types; `Effects.idr` covers L8; `Lifetime.idr` covers L9; `Linear.idr` covers L10; `Proofs.idr` carries the composed certificates.
4545

4646
**Caveat**: Proofs are _about abstract WASM models_, not actual WebAssembly instruction sequences. Translation from `.twasm` (typed-wasm surface syntax) to WASM bytecode is NOT mechanically verified.
4747

@@ -64,25 +64,28 @@ All share: _Progressive safety levels, mechanized proofs in Idris2, no escape ha
6464

6565
| `spec/grammar.ebnf` | The `.twasm` surface syntax in EBNF: region declarations, typed load/store operations, effect annotations, module imports/exports
6666

67-
| `spec/10-levels-for-wasm.adoc` | Mapping document: each of the 12 levels from TypedQL (database) → typed-wasm (WASM), with rationale and examples
67+
| `spec/type-safety-levels-for-wasm.adoc` | Mapping document: each of the 12 levels from TypedQL (database) → typed-wasm (WASM), with rationale and examples
6868

69-
| `src/abi/Types.idr` | Idris2 dependent types: L1-L3 proof definitions (instruction validity, region binding, type compatibility) with witness types
69+
| `src/abi/TypedWasm/ABI/Region.idr` | Schema type, field accessors (`sizeOf`, `alignOf`, `fieldName`, `fieldType`) — load-bearing for L1-L3
70+
| `src/abi/TypedWasm/ABI/TypedAccess.idr` | Load/store typing: `HostType`, `RegionPredicate`, typed projections through the schema (L2-L3)
71+
| `src/abi/TypedWasm/ABI/Levels.idr` | The canonical L1-L10 data types — `Level1_InstructionValidity` through `Level10_Linear` and `Nullability` / `RefKind` / `MemEffect` enumerations
7072

71-
| `src/abi/Layout.idr` | Idris2 memory layout proofs: L4 (null safety via opt<T>), L5 (compile-time bounds proofs via offset witnesses)
73+
| `src/abi/TypedWasm/ABI/Pointer.idr` | L4 nullability + L7 aliasing kinds: `OwnPtr`, `BorrowRef`, `UniquePtr`, `OptRef`, `checkNull`
74+
| `src/abi/TypedWasm/ABI/Layout.idr` | Cross-language layout contracts (aggregate-library role): `Subtype`, `WasmGCEq`, `subTrans`, `optionSubtype`
7275

73-
| `src/abi/Access.idr` | Idris2 access correctness: L6 (result-type inference), L7 (aliasing safety via exclusive refs)
76+
| `src/abi/TypedWasm/ABI/MultiModule.idr` | Cross-module sharing (the killer feature): `LinkGraph`, `SchemaSub`, `schemaSubRefl`, `schemaSubTrans`
7477

75-
| `src/abi/Effects.idr` | Idris2 effect tracking: L8 (effect type annotations), L9 (lifetime safety via resource tracking)
78+
| `src/abi/TypedWasm/ABI/Effects.idr` | L8 effect tracking: `EffectSet`, `pureEffects`, `readOnly`, `readWrite`, `allocEffects`
79+
| `src/abi/TypedWasm/ABI/Lifetime.idr` | L9 lifetime tracking: `Outlives`, `outlivesRefl`, `outlivesTrans`, `outlivesTransitive`
7680

77-
| `src/abi/Linearity.idr` | Idris2 linear type proofs: L10 (exactly-once resource usage via linear arrows)
81+
| `src/abi/TypedWasm/ABI/Linear.idr` | L10 linearity: `LinHandle`, `allocRegion`, `freeRegion`, `immBorrow` — exactly-once resource usage
7882

7983
| `src/abi/TypedWasm/ABI/Tropical.idr` | L11: tropical cost-tracking — AllPairsCosts + Level11KleeneProof (min-plus semiring, bounded memory access cost)
8084

8185
| `src/abi/TypedWasm/ABI/Epistemic.idr` | L12: epistemic safety — Level12Proof + freshness witnesses (prevents stale-state reads across modules)
8286

83-
| `src/abi/Proofs.idr` | Machine-checked proofs for L1-L10. `fullCert12` top-level certificate for all 12 levels. Zero `believe_me`.
87+
| `src/abi/TypedWasm/ABI/Proofs.idr` | Machine-checked proofs for L1-L10. `fullCert12` top-level certificate for all 12 levels. Zero `believe_me`.
8488

85-
| `src/abi/Foreign.idr` | FFI declarations: C header generation from Idris2 ABI
8689

8790
| `ffi/zig/src/main.zig` | Zig FFI implementation: runtime region management, typed load/store operations, C-ABI compatible interface
8891

README.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ in name, type, offset, and alignment.
161161
[source,bash]
162162
----
163163
spec/grammar.ebnf # The grammar — core intellectual artifact
164-
spec/10-levels-for-wasm.adoc # Checked L1-L10 mapping from DB to WASM
164+
spec/type-safety-levels-for-wasm.adoc # Checked L1-L10 mapping from DB to WASM
165165
src/abi/*.idr # Idris2 formal proofs
166166
ffi/zig/src/main.zig # Zig C-ABI implementation
167167
examples/01-single-module.twasm # Basic typed regions

ROADMAP.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Key capabilities delivered:
4545
* Idris2 ABI proofs (src/abi/) -- checked L1-L10 region, access, and proof core
4646
* Zig FFI (ffi/zig/) -- C-ABI bridge for runtime region management, typed load/store
4747
* `.twasm` grammar (spec/grammar.ebnf) -- EBNF surface syntax
48-
* 10-level spec (spec/10-levels-for-wasm.adoc) -- checked DB-to-WASM core mapping
48+
* 10-level spec (spec/type-safety-levels-for-wasm.adoc) -- checked DB-to-WASM core mapping
4949
* Example `.twasm` files for the checked core, plus draft higher-level examples
5050
* Whitepaper drafts (docs/WHITEPAPER.md + docs/arxiv/typed-wasm.tex) under audit
5151
* No unsound escape hatches in the checked Idris2 core (`believe_me`, `assert_total`)

tests/aspect/claim-envelope.mjs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,90 @@ for (const f of rsrFiles) {
309309
else bad(`RSR file missing: ${f}`);
310310
}
311311

312+
// ----------------------------------------------------------------------
313+
// 8. Path references in docs resolve to real files
314+
//
315+
// Catches the rename-drift class: a file gets renamed but doc references
316+
// keep pointing at the old path. Caught by Phase 0 housekeeping that
317+
// found 5 stale references to spec/10-levels-for-wasm.adoc after it
318+
// became spec/type-safety-levels-for-wasm.adoc.
319+
//
320+
// We scan README.adoc, ROADMAP.adoc, EXPLAINME.adoc, and CLAUDE.md for
321+
// repo-relative path-ish tokens matching common source-file extensions
322+
// and verify each resolves on disk.
323+
// ----------------------------------------------------------------------
324+
section("8. Path references in docs resolve to real files");
325+
326+
function maybeRead(rel) {
327+
try { return readFileSync(join(ROOT, rel), "utf8"); } catch { return null; }
328+
}
329+
330+
const docsToScan = [
331+
"README.adoc",
332+
"ROADMAP.adoc",
333+
"EXPLAINME.adoc",
334+
".claude/CLAUDE.md",
335+
];
336+
337+
const PATH_LIKE = /(?<![A-Za-z0-9_./-])([a-z0-9][a-z0-9._/-]*\.(?:adoc|md|mjs|res|idr|zig|rs|ebnf|toml|ipkg))(?![A-Za-z0-9_./-])/gi;
338+
339+
const ALLOWLIST_FRAGMENTS = [
340+
"rsr-template-repo",
341+
"github.com",
342+
"node_modules/",
343+
"{{",
344+
"example.com",
345+
"/home/runner/",
346+
// Cross-repo references (different repos in the hyperpolymath ecosystem)
347+
"typedqliser/",
348+
"affinescript/",
349+
"ephapax/",
350+
"hypatia/",
351+
"standards/",
352+
"typell/",
353+
"vql-ut/",
354+
"echidna/",
355+
];
356+
357+
// Skip bare filenames without a directory part — those are conventional
358+
// references in prose (e.g. "see PROOF-NEEDS.md") that may live anywhere
359+
// in the tree. Only check refs with at least one `/` (an actual path).
360+
function isFullPath(ref) {
361+
return ref.includes("/");
362+
}
363+
364+
let docPathRefsChecked = 0;
365+
const missingRefs = [];
366+
367+
for (const doc of docsToScan) {
368+
const content = maybeRead(doc);
369+
if (content === null) {
370+
skip(`${doc}: doc absent — cannot scan`);
371+
continue;
372+
}
373+
const seen = new Set();
374+
for (const match of content.matchAll(PATH_LIKE)) {
375+
const ref = match[1];
376+
if (seen.has(ref)) continue;
377+
seen.add(ref);
378+
if (ALLOWLIST_FRAGMENTS.some((f) => ref.includes(f))) continue;
379+
if (ref.includes("*") || ref.includes("?")) continue;
380+
if (!isFullPath(ref)) continue; // bare filenames are prose conventions
381+
docPathRefsChecked++;
382+
if (!existsSync(join(ROOT, ref))) {
383+
missingRefs.push(`${doc}: ${ref}`);
384+
}
385+
}
386+
}
387+
388+
// Print full list inline so reviewers see each failure, not just first-5.
389+
if (missingRefs.length === 0) {
390+
ok(`All ${docPathRefsChecked} path references across ${docsToScan.length} docs resolve on disk`);
391+
} else {
392+
bad(`${missingRefs.length} of ${docPathRefsChecked} doc path references are stale:`);
393+
for (const r of missingRefs) console.log(` - ${r}`);
394+
}
395+
312396
// ----------------------------------------------------------------------
313397
// Summary
314398
// ----------------------------------------------------------------------

0 commit comments

Comments
 (0)