Skip to content

docs(spec): document wire-level carrier sections (proposals 0001 §4 + 0002 §5)#108

Merged
hyperpolymath merged 1 commit into
mainfrom
spec-doc-carrier-sections
May 30, 2026
Merged

docs(spec): document wire-level carrier sections (proposals 0001 §4 + 0002 §5)#108
hyperpolymath merged 1 commit into
mainfrom
spec-doc-carrier-sections

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Closes the remaining doc gate for both proposals:

  • Proposal 0001 §Acceptance criterion 4 (spec section in `spec/type-safety-levels-for-wasm.adoc`)
  • Proposal 0002 §Gate 5 (same)

Adds a new top-level "Wire-Level Carrier Sections" section after "Implementation Architecture" with all 4 carriers documented: `typedwasm.ownership` (existing), `typedwasm.regions` + `typedwasm.capabilities` (proposal 0001 `[review]`), `typedwasm.access-sites` (proposal 0002 `[review]`).

Content

Per-section: full wire format (verbatim from the proposals), Idris2 spec-type mappings, codec entry points (`parse_` / `build_` in `crates/typed-wasm-verify/src/section.rs`). Plus overview table, versioning policy, and cross-references to #106 roadmap + #94 / #95 / #96 / #97 open questions.

Net +187 lines of doc, no code change.

What this leaves for [accepted]

Per proposal 0001 §Acceptance criteria:

Per proposal 0002 §Acceptance criteria:

Remaining for both proposals to flip to `[accepted]`: the verifier-pass plumbing (`verify_capabilities` for 0001, `verify_access_sites` for 0002 — both cross-section). Tracked under #106.

Test plan

🤖 Generated with Claude Code

…0002 §5)

Closes proposal 0001 §Acceptance criterion 4 (spec section in
type-safety-levels-for-wasm.adoc) and proposal 0002 §Gate 5 (same).

Adds a new top-level "Wire-Level Carrier Sections" section after
"Implementation Architecture" with:

- One-table-row overview of all 4 carriers (ownership / regions /
  capabilities / access-sites) — status, levels covered, codec entry
  points
- Per-section subsections with the full wire format (matching the
  proposal text verbatim) + how each field maps to Idris2 spec types
- Versioning policy (additive vs breaking; ownership stays unversioned
  as the original carrier)
- Cross-references to codec source, proposals, #106 roadmap, and the
  four open-question follow-ups (#94 / #95 / #96 / #97)

Net +136 lines of doc, no code change.

Refs #34 #76 #78
Refs #86 #106

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath hyperpolymath enabled auto-merge (squash) May 30, 2026 13:43
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 96 issues detected

Severity Count
🔴 Critical 8
🟠 High 19
🟡 Medium 69

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Action perpolymath/standards/.github/workflows/governance-reusable.yml@main\n needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in boj-build.yml",
    "type": "unknown",
    "file": "boj-build.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in c5-regenerate.yml",
    "type": "unknown",
    "file": "c5-regenerate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in cargo-audit.yml",
    "type": "unknown",
    "file": "cargo-audit.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in codeql.yml",
    "type": "unknown",
    "file": "codeql.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath merged commit 4436e1e into main May 30, 2026
31 checks passed
@hyperpolymath hyperpolymath deleted the spec-doc-carrier-sections branch May 30, 2026 13:46
hyperpolymath added a commit that referenced this pull request May 30, 2026
…sal 0002 §Gate 4) (#109)

## Summary

Closes proposal 0002 §Gate 4 (\`verify_access_sites\` cross-section
pass) and the equivalent for proposal 0001's capabilities carrier. Both
proposals are now ~95% through acceptance criteria.

## New public API

- \`CapabilitiesError\` + \`verify_capabilities_from_module\` (gated
\`unstable-l15\`)
- \`AccessSiteError\` + \`verify_access_sites_from_module\` (gated
\`unstable-l2\`)
- Section-name constants for both

## Checks performed

### \`verify_capabilities\`
- Per-function \`func_idx\` is within module function count (import +
locally-defined)
- Per-function \`required\` capability index is within capability-table
bounds

### \`verify_access_sites\`
- **\`MissingDependentRegions\`** (proposal 0002 §"Producer obligations"
#2): access-sites without regions is a hard error. Also fires if regions
present but unparseable (version mismatch).
- Per-entry \`func_idx\` in module function count
- Per-entry \`region_id\` in regions table
- Per-entry \`field_id\` in target region's field table (skipped if
region_id was out of range)

### Deliberately out of scope (deferred)

- **DistinctCaps**: codec parser already normalises \`required\` to
sorted+deduped form. Verifying strictly-increasing wire emission would
need pre-normalisation byte access. Defer as a producer-side property
test.
- **AccessSiteMisalignment**: would require parsing function bodies to
verify \`instruction_byte_offset\` lands on a typed access opcode.
Proposal 0002 explicitly defers this.

## Tests (+11)

5 capabilities + 6 access-sites verifier tests using \`wasm-encoder\` to
build minimal valid modules with the relevant custom sections (and
matching Function+Code sections — required for wasm validation).

| features                       | tests passed |
|--------------------------------|--------------|
| (default)                      | 43           |
| \`unstable-l2\`                | 65 (+6)      |
| \`unstable-l15\`               | 55 (+5)      |
| \`unstable-l2,unstable-l15\`   | 77 (+11)     |

## Acceptance progress after this lands

**Proposal 0001** (regions + capabilities):
- ✅ Criterion 1 — paired sign-off
- ⏳ Criterion 2 — wire-vs-Idris2-spec review (proof-side write-up)
- ✅ Criterion 3 — codec landed
- ✅ Criterion 4 — spec doc (#108)
- ✅ Criterion 5 — cross-repo issues filed
- ✅ + capabilities verifier pass (this PR, not in criteria but completes
the matching pair to regions parsing)

**Proposal 0002** (access-sites):
- ✅ Gates 1, 2, 3, 5
- ✅ **Gate 4** — this PR
- ⏳ Gate 6 — producer codegen issues for access-sites

## Test plan

- [x] \`cargo build\` (default features) succeeds
- [x] \`cargo test --lib\` (4 feature combos): 43 / 65 / 55 / 77 pass /
0 fail
- [x] No regression in integration suite

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 30, 2026
…#110)

## Summary

Closes proposal 0001 §"Acceptance criteria" Criterion 2 — the last
write-up gate before `[review] → [accepted]`. Adds a 247-line "Appendix
A — Wire-vs-Idris2-spec mapping" to
`docs/proposals/0001-multi-producer-carrier-section.adoc`.

### Appendix structure

| Section | Coverage |
|---------|----------|
| A.1 | `typedwasm.regions` wire fields ↔ `Region.idr` + `Pointer.idr` —
per-field table (version, region_count, name, field_count, field_name,
kind, wasm_ty, target_region, nullability, cardinality,
region_byte_size) |
| A.2 | `typedwasm.capabilities` wire fields ↔
`ResourceCapabilities.idr` — capability table + per-function required
list; documents that strict-increasing `required[]` encodes DistinctCaps
+ ContainedIn + canonical-order at once |
| A.3 | What is NOT carried on the wire (deliberate): `ContainedIn`
proof witnesses (verifier reconstructs), `CallCompatible` (L15-C
deferred to #96), `LayoutValid` (verifier recomputes), `SchemaEq`
(single-module v1), `RegionDisjoint` (runtime concern),
`ExclusiveWitness` (in ownership section) |
| A.4 | Soundness shape — single NOTE listing per-emission proof
obligations PR #107 (codec) + PR #109 (verifier) already enforce |

Criterion 2 line in §"Acceptance criteria" updated to "*(Satisfied — see
Appendix A below.)*".

### Why a write-up not a property test

Criterion 2's text reads "every wire field maps cleanly to a spec
witness" — a *write-up* satisfies it (and is what a reviewer reads). A
future task (filed in the appendix's closing paragraph, not blocking
`[accepted]`) is to encode the same mapping as Idris2 property tests in
`src/abi/` (`WireSchemaEquiv.idr` showing `encode/decode` round-trips
preserve the spec witnesses).

### Acceptance-roadmap state after this PR

| | 0001 (regions+capabilities) | 0002 (access-sites) |

|----------------------|------------------------------|----------------------|
| Codec | ✅ #107 | ✅ #107 |
| Verifier | ✅ #109 | ✅ #109 |
| Spec doc | ✅ #108 | ✅ #108 |
| Wire-vs-spec review | ✅ **this PR** | n/a |
| Cross-repo issues | ✅ affinescript#444 + ephapax#221 | ✅
affinescript#462 / ephapax pending |
| Open Qs | ⚠️ #94, #95, #96 still open | n/a |

After this lands, proposal 0001's only remaining gate is the open
questions converging (`WBool` wire-width pin, region-imports proposal
placeholder, capability-grants v1.4.x). The acceptance criteria
themselves are all green.

## Test plan

- [x] Local proof-doc render check: appendix renders with
cleanly-formatted cols=2,3,2 + cols=2,3 tables.
- [x] Cross-reference links resolve (Region.idr:253, Region.idr:127,
Pointer.idr:74, ResourceCapabilities.idr:67/104/218/241/248/312, etc.).
- [x] No code changes — no Cargo build required.
- [ ] Reviewer cross-check: confirm A.3 is exhaustive (no missed
spec-side relation that v1 silently drops).

## Related

- #34 (proposal 0001 umbrella)
- #106 (acceptance roadmap tracker)
- PR #104 ([draft] → [review])
- PR #107 (codec) / PR #108 (spec doc) / PR #109 (verifier)
- #94 / #95 / #96 (acceptance preconditions filed)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 30, 2026
## Summary

Closes [#94](#94) —
the only remaining open question on proposal 0001 before `[review] →
[accepted]` flip.

**Decision: WBool is 4 bytes on the wire** (i32.store/load; 0 = false,
nonzero = true). The narrower 1-byte encoding is reserved for a future
`WBoolPacked` variant in v2.

## Two changes

| File | Change |
|---|---|
| `docs/proposals/0001-multi-producer-carrier-section.adoc` | New
`§"WBool wire width — pinned at 4 bytes"` subsection (~36 LOC) inside
`§"Wire format — typedwasm.regions"`. Documents rationale, reserves
`WBoolPacked` v2, references the rejected lenient alternative. |
| `src/abi/TypedWasm/ABI/Region.idr` | `sizeOf WBool = 4` (was `1`) with
inline comment pointing at the proposal text and producer-side evidence
files. |

## Why 4-byte, not 1-byte, not mixed-width

1. **Producer reality**: both shipping producers already emit 4-byte
`i32.store` for boolean fields (AffineScript
`lib/codegen.ml:180-190+:373`; Ephapax
`src/ephapax-wasm/src/lib.rs:2937-2944`). Pinning at 4 = zero codegen
changes.
2. **Spec self-consistency**: `Region.idr` was the outlier at 1 byte;
this PR brings spec into alignment with producer reality. `alignOf =
sizeOf` (Region.idr:113) carries through to field-alignment math. No
proofs or tests hardcode `WBool=1` — verified by grep.
3. **Verifier simplicity**: single canonical width means no new
`MixedWidthBoolean` error variant; `region_byte_size` cross-check is
deterministic per schema.
4. **Future flexibility**: a 1-byte `WBoolPacked` (or named-equivalent)
remains the v2 escape hatch as a new `WasmType` constructor, NOT a width
flag on the existing `WBool` codepoint. Additive, not breaking.

## Rejected: lenient mixed-width

The `§A` sketch in #94's recommendation (allow either width per field,
validate consistency) is rejected because:

- `region_byte_size` becomes producer-choice-dependent — same schema →
different `schemaSize` values
- Forces a new `MixedWidthBoolean` verifier error variant for marginal
flexibility
- Complicates cross-module schema agreement: a 1-byte WBool field in one
module is structurally incompatible with a 4-byte WBool field of the
same name in another module

## Risk assessment

- Idris2 `sizeOf` change cascades to `schemaSize` / `computeOffsets` /
`alignOf` — none of these is hardcoded against `WBool=1` in any test or
proof. `MultiModule.idr`'s `Example` schema uses WBool but only via
`SchemaEq`/`SchemaSub` structural relations.
- `TypedAccess.idr:51` (`HostType WBool = Bool`) is host-side type
mapping; unaffected by wire width.
- `crates/typed-wasm-verify` `region_byte_size` validation is currently
`MAY cross-check` (not enforced) — when implemented later, the canonical
4-byte rule makes the check deterministic.

## Acceptance update for #94

- [x] Proposal 0001 amended with explicit `WBool` wire width.
- [n/a] No `MixedWidthBoolean` error variant (strict resolution chosen).
- [x] Forward-pointer to `WBoolPacked` future-extension added.

## What this means for 0001 [review] → [accepted]

This was the last load-bearing open question on proposal 0001. After
merge:

| Acceptance gate | State |
|---|---|
| Criterion 1 (producer signoff) | ✅ |
| Criterion 2 (wire↔spec mapping) | ✅ Appendix A (PR #110) |
| Criterion 3 (draft codec) | ✅ PR #107 |
| Criterion 4 (draft spec doc) | ✅ PR #108 |
| Criterion 5 (cross-repo issues filed) | ✅ affinescript#444 +
ephapax#221 |
| OQ #94 (WBool width) | ✅ **this PR** |
| OQ #95 (region-imports) | ✅ proposal 0003 [draft] (PR #112) |
| OQ #96 (capability-grants) | ✅ proposal 0004 [draft] (PR #111) |

Proposal 0001 is **fully ready for `[accepted]`** after this lands —
owner decision is the only remaining step.

## Test plan

- [x] `git grep` confirms no hardcoded `WBool=1` size assertions in
proofs or tests.
- [x] `sizeOf WBool` only used via
`computeOffsets`/`alignOf`/`fieldSize` (derived, not hardcoded).
- [ ] Idris2 build passes (CI will verify).
- [ ] Cargo build + test passes (no Rust code changes — should be a
no-op).

## Related

- #94 (this PR closes it)
- #106 (acceptance roadmap tracker)
- #34 (proposal 0001 umbrella)
- ephapax#165 §2-Q1 / affinescript#402 §3-Q1 — paired producer reviews
- PR #76 (proposal 0001 original landing)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 30, 2026
…115)

## Summary

Owner-decision close of the proposal-acceptance arc. Both proposals
satisfied every acceptance gate this session ([see #106 wrap-up
comment](#106 (comment)));
this PR applies the status flip.

## Status changes

- `docs/proposals/0001-multi-producer-carrier-section.adoc` — `review →
accepted`
- `docs/proposals/0002-access-site-carrier.adoc` — `review → accepted`
- `docs/proposals/README.adoc` — "Current proposals" table updated; NOTE
block clarifies files remain in `docs/proposals/` (ADR promotion is a
separate file-restructure follow-up).

## LEVEL-STATUS.md updates

| Level | Before | After |
|-------|--------|-------|
| L2 (region binding) | proposal-stage | **YES** (carrier-backed) —
`verify_access_sites_from_module` (PR #109); gated `unstable-l2` |
| L3–L6 (type-compat, null, bounds, result-type) | proposal-stage |
**YES** (carrier-backed, schema half) — regions codec PR #107;
per-access enforcement gated on producer codegen |
| L15-A/B (capabilities) | proposal-stage | **YES** (carrier-backed) —
`verify_capabilities_from_module` (PR #109); gated `unstable-l15` |
| L13 cross-module (positive form) | — | proposal-stage — proposal 0003
`[draft]` (new row) |

"Open gating items" section rewritten to remove obsolete pre-acceptance
gates (all shipped via #107/#109) and enumerate the remaining
producer-side prerequisites + [draft] proposal 0003/0004 work.

## What this DOES NOT change

- **File locations**: proposals stay in `docs/proposals/`. ADR promotion
to `docs/decisions/` (with renumbering — existing ADR 0001 is
"adopt-rsr-standard", so proposals 0001/0002 would become ADRs
0002/0003) is a deliberate separate PR to keep the status flip cleanly
auditable.
- **Code**: no source or test changes. Verifier passes already shipped
in #107/#109 behind `unstable-l2` / `unstable-l15` feature flags.
- **Producer-side codegen**: still pending per Appendix B prerequisites
in proposal 0001.

## Test plan

- [x] Status field flipped on both proposals.
- [x] README table reflects new statuses with date.
- [x] LEVEL-STATUS L2/L3-L6/L15 rows show carrier-backed YES.
- [x] Open gating items rewritten (4 items: producer codegen, L13
cross-module, L15-C, ADR promotion).
- [ ] CI passes (doc-only changes; no Cargo/Idris2 build risk).

## Related

- #34 (proposal 0001 umbrella)
- #78 (proposal 0002 RFC)
- #106 (acceptance roadmap tracker — full wrap-up comment)
- This session's 5-PR sprint that satisfied every gate: #107 (codec),
#108 (spec doc), #109 (verifier), #110 (Criterion 2 appendix), #111
(proposal 0004 draft for #96), #112 (proposal 0003 draft for #95), #113
(WBool pin for #94), #114 (producer-readiness for #97).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant