Commit aa2484c
feat(abi-emit-manifest): emit ABI manifest from Idris2 source (standards#92 Phase 1b) (#14)
Phase 1b of standards#89 sub-issue 3 / standards#92. Adds the
`abi-emit-manifest` subcommand, which parses a cartridge's `Safe*.idr`
and emits the JSON manifest the existing `abi-verify` subcommand
consumes. Together with Phase 1 this closes the loop: the Idris2 source
is now the **single authority** — the manifest is derived, not
hand-authored.
## Scope
Parses the cartridge convention shape:
* `data <Enum> = A | B | C` (one-line or multi-line; with or without
parameterised variants like `Custom String`)
* `<fn> : <Enum> -> Int` type signatures (associates each enum with
its `*ToInt` function; necessary because the convention is loose —
`SsgEngine` uses `engineToInt`, `K9Format` uses `formatToInt`,
not the naive `ssgEngineToInt` etc.)
* `<fn> <variant> = <int>` value-encoding equations (including
parameterised forms like `(Custom _) = 99`)
* `canTransition <From> <To> = True` allowed-transition equations
(catch-all `_ _ = False` skipped; the verifier already catches
accept-by-omission as drift)
Not a general Idris2 parser; deliberately shape-specific.
## End-to-end smoke
```
$ iseriser abi-emit-manifest \
--idris ../boj-server/cartridges/ssg-mcp/abi/SsgMcp/SafeSsg.idr \
--cartridge ssg-mcp \
--source-path "boj-server/cartridges/ssg-mcp/abi/SsgMcp/SafeSsg.idr" \
--out /tmp/ssg.json
abi-emit-manifest: wrote /tmp/ssg.json (2 enums, 11 transitions)
$ iseriser abi-verify --manifest /tmp/ssg.json \
--zig-ffi ../boj-server/cartridges/ssg-mcp/ffi/ssg_ffi.zig
abi-verify: OK — cartridge `ssg-mcp` ABI manifest agrees with `…/ssg_ffi.zig`
```
Same for `k9iser-mcp` (2 enums, 10 transitions, verify clean).
The diff between hand-authored and emitted manifests is just JSON
formatting + the absence of the `allowed:false` safety-invariant rows
(documented in README.adoc — the verifier's
`transition-accepted-but-undeclared` finding covers the same drift
class, so safety is preserved). Verify result is identical.
## Tests
6 new unit tests in `idris_emitter::tests`:
* one-line data declaration
* multi-line data declaration with parameterised variant
* type-signature-based fn↔enum association (the SsgEngine→engineToInt case)
* variant without ToInt mapping is dropped
* canTransition parsing skips the catch-all
* Idris2 doc-comment stripping
39 lib tests green (was 33).
Next: Phase 2 — wire the emit→verify pair into per-cartridge CI.
Refs hyperpolymath/standards#92
Refs hyperpolymath/standards#89
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 89cbe0c commit aa2484c
4 files changed
Lines changed: 630 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
37 | 79 | | |
38 | 80 | | |
39 | 81 | | |
| |||
0 commit comments