Skip to content

Commit 12f29e2

Browse files
docs: close cartridge-scaffolder loose ends (example + ROADMAP) (#27)
PR #26 cross-referenced `examples/cartridge-skeleton/README.adoc` from `README.adoc` but never created it. ROADMAP.adoc still ended at Phase 0 even though Phase 2b (standards#89) and standards#92 Phase 1+1b both landed today. Cleaning both up. - `examples/cartridge-skeleton/README.adoc`: a full worked example — manifest, CLI invocation, expected output, the three end-to-end verification commands (`idris2 --build`, `zig build test` on `ffi/` and `adapter/`), a customising-the-cartridge guide for adding tools, and the cross-references (standards#89/#90/#91, ADR-0004, ADR-0006, k9iser-mcp pilot). Mirrors the style of the existing `examples/abi-manifests/README.adoc`. - `ROADMAP.adoc`: new "Phase 2b: BoJ-server cartridge skeleton" section marking the cartridge scaffolder COMPLETE with checked boxes for each piece (13-file emit, Idris2 ABI, ADR-0006 5-symbol C ABI, unified gated adapter, end-to-end build verification, docs). Also a new "ABI verification harness" section marking standards#92 Phase 1 + 1b COMPLETE (`abi-verify` + `abi-emit-manifest` + four emitter/verifier fixes from iseriser #15/#20/#21/#22 + the `abi-manifests` docs). Notes that the standards#90 fan-out across the 28 -isers stays correctly gated on standards#91. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1c83882 commit 12f29e2

2 files changed

Lines changed: 174 additions & 0 deletions

File tree

ROADMAP.adoc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,27 @@
1515
* [x] README with architecture, use cases, and -iser family table
1616
* [x] Machine-readable governance (STATE, META, ECOSYSTEM, contractiles)
1717

18+
== Phase 2b: BoJ-server cartridge skeleton (COMPLETE — 2026-05-20)
19+
* [x] `iseriser cartridge` subcommand — scaffolds a complete boj-server cartridge for an -iser
20+
* [x] Emits 13 files: `cartridge.json`, `mod.js`, `panels/manifest.json`, top-level `README.adoc`
21+
* [x] Idris2 ABI: `<iser>-mcp.ipkg` + `<Iser>Mcp/Safe<Iser>.idr` (exposure-gate contract + tool enum)
22+
* [x] Zig FFI: ADR-0006 5-symbol C ABI (`boj_cartridge_init/deinit/name/version/invoke`) via `cartridge_shim`
23+
* [x] Unified gated adapter: REST + SSE + GraphQL + gRPC-compat behind the transaction gate
24+
* [x] End-to-end verified: `idris2 --build` on emitted ipkg, `zig build test` on `ffi/` (4/4) and `adapter/` (5/5)
25+
* [x] Documented: `examples/cartridge-skeleton/README.adoc`
26+
* [x] Implements https://github.com/hyperpolymath/standards/issues/89[standards#89] sub-issue 1, scaffold side
27+
28+
NOTE: Estate-wide fan-out of the regeneration-cartridge pattern across the 28 existing -isers is OWED, but is correctly gated on https://github.com/hyperpolymath/standards/issues/91[standards#91] (http-capability-gateway tier-2 production-wiring). Until #91 lands, the unified core stays internal/loopback.
29+
30+
== ABI verification harness (standards#92 Phase 1 + 1b — COMPLETE — 2026-05-20)
31+
* [x] `abi-verify` subcommand — diffs an Idris2-derived ABI manifest against a cartridge's Zig FFI; reports drift across five categories. Phase 1.
32+
* [x] `abi-emit-manifest` subcommand — emits the manifest from `Safe*.idr` so the Idris2 source is the single authority. Phase 1b.
33+
* [x] Zig reserved-word converter (iseriser#15)
34+
* [x] GADT-style `data … where` declarations skipped in the emitter (iseriser#20)
35+
* [x] Multi-cap acronym variants accept the runtogether form (iseriser#21)
36+
* [x] Non-canonical Zig switch arms (`false` shorthand) tolerated (iseriser#22)
37+
* [x] Documented: `examples/abi-manifests/README.adoc`
38+
1839
== Phase 1: Language Model Parser
1940
* [ ] Define `LanguageDescription` struct: name, type system features, compilation target, key primitives, calling convention
2041
* [ ] Parse language descriptions from `iseriser.toml` `[language]` section
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
= Cartridge skeleton scaffolder
2+
:source-highlighter: pygments
3+
4+
Phase 2b of https://github.com/hyperpolymath/standards/issues/89[standards#89]
5+
sub-issue 1 / https://github.com/hyperpolymath/standards/issues/90[standards#90].
6+
7+
== Purpose
8+
9+
`iseriser cartridge` scaffolds a complete `boj-server` cartridge skeleton
10+
for an -iser, modelled on the
11+
https://github.com/hyperpolymath/boj-server/tree/main/cartridges/k9iser-mcp[k9iser-mcp
12+
pilot] (boj-server#73).
13+
14+
The output is a 13-file directory tree ready to be placed inside
15+
`boj-server/cartridges/`. Out of the box:
16+
17+
- The 5-symbol ADR-0006 cartridge C ABI is wired up.
18+
- The unified transaction-gated adapter routes REST + SSE + GraphQL +
19+
gRPC-compat behind the exposure gate (Idris2 contract + Zig mirror +
20+
4-row truth-table tests).
21+
- Both Zig build trees compile and pass `zig build test` against the
22+
shared invoke-shim.
23+
- The Idris2 ABI type-checks via `idris2 --build`.
24+
25+
Per-tool dispatch bodies are stubs returning a placeholder JSON body —
26+
replace as the cartridge grows.
27+
28+
== Topology
29+
30+
The unified transaction-gated adapter belongs to the boj-server
31+
cartridge for the -iser, NOT to the -iser repo itself:
32+
33+
[source]
34+
----
35+
boj-server/cartridges/<iser-name>-mcp/ <-- scaffolded by `iseriser cartridge`
36+
├── cartridge.json # registration manifest (boj.dev schema v1)
37+
├── mod.js # Deno module (JS-worker fallback path)
38+
├── README.adoc
39+
├── panels/
40+
│ └── manifest.json # observability panel registration
41+
├── abi/ # Idris2 — source of truth
42+
│ ├── README.adoc
43+
│ ├── <iser>-mcp.ipkg
44+
│ └── <Iser>Mcp/
45+
│ └── Safe<Iser>.idr # exposure-gate contract + tool enum
46+
├── ffi/ # Zig — ADR-0006 5-symbol C ABI
47+
│ ├── README.adoc
48+
│ ├── build.zig
49+
│ └── <iser>_ffi.zig # boj_cartridge_{init,deinit,name,version,invoke}
50+
└── adapter/ # Zig — unified gated adapter
51+
├── README.adoc
52+
├── build.zig
53+
└── <iser>_adapter.zig # loopback :9390, 4-protocol routing
54+
----
55+
56+
The -iser repo itself (`hyperpolymath/<iser-name>iser`) emits the
57+
`.github/workflows/<iser>-regen.yml` central-trigger workflow (via
58+
`iseriser generate`); the workflow fires the boj-server cartridge over
59+
the gateway.
60+
61+
== Usage
62+
63+
Given an `iseriser.toml` manifest for the target language:
64+
65+
[source,toml]
66+
----
67+
[project]
68+
name = "chapeliser"
69+
version = "0.1.0"
70+
71+
[language]
72+
name = "Chapel"
73+
paradigm = "imperative"
74+
type-system = "simple"
75+
compilation-target = "native"
76+
key-primitives = ["task", "locale", "domain"]
77+
78+
[output]
79+
repo-name = "chapeliser"
80+
github-org = "hyperpolymath"
81+
description = "Chapel distributed-computing -iser"
82+
----
83+
84+
Scaffold the cartridge into your local `boj-server` clone:
85+
86+
[source,shell]
87+
----
88+
iseriser cartridge \
89+
--manifest iseriser.toml \
90+
--output /path/to/boj-server/cartridges
91+
----
92+
93+
Output:
94+
95+
[source]
96+
----
97+
Generated cartridge chapeliser-mcp (13 files) at /path/to/boj-server/cartridges/chapeliser-mcp
98+
----
99+
100+
Verify the scaffold builds end-to-end:
101+
102+
[source,shell]
103+
----
104+
cd /path/to/boj-server/cartridges/chapeliser-mcp
105+
106+
# Idris2 ABI type-checks (NB: use --build for .ipkg files, not --check)
107+
idris2 --build abi/chapeliser-mcp.ipkg
108+
109+
# Zig FFI: ADR-0006 5-symbol ABI + dispatch table
110+
( cd ffi && zig build test )
111+
112+
# Unified adapter: classify / toolFor / dispatch / gate truth-table
113+
( cd adapter && zig build test )
114+
----
115+
116+
Expected on a clean scaffold: `idris2 --build` returns RC=0, FFI tests
117+
4/4 pass, adapter tests 5/5 pass.
118+
119+
== Customising the cartridge
120+
121+
The skeleton has one example tool (`<iser>_generate`) wired through the
122+
full pipeline. To add tools:
123+
124+
1. Declare the tool in `abi/<Iser>Mcp/Safe<Iser>.idr` — extend `McpTool`
125+
and `toolName`.
126+
2. Add a `cartridge.json` `tools[]` entry with the JSON-schema
127+
`inputSchema`.
128+
3. Wire the dispatch arm in `ffi/<iser>_ffi.zig`'s `boj_cartridge_invoke`
129+
— `shim.toolIs(tool_name, "<new_tool>")` returns the appropriate
130+
stub or real body.
131+
4. For tools requiring state (sessions, locks, etc.), follow the
132+
`k9iser-mcp` pilot's pattern: declare a state machine in the Idris2
133+
module + mirror it in Zig.
134+
135+
The adapter (REST + SSE + GraphQL + gRPC-compat routing) needs no
136+
changes — it forwards every tool to the FFI dispatch table via
137+
`boj_cartridge_invoke`.
138+
139+
== Cross-references
140+
141+
- https://github.com/hyperpolymath/standards/issues/89[standards#89] —
142+
epic: -iser regeneration-cartridge pattern.
143+
- https://github.com/hyperpolymath/standards/issues/90[standards#90] —
144+
sub-issue 1: scaffold side (this work).
145+
- https://github.com/hyperpolymath/standards/issues/91[standards#91] —
146+
sub-issue 2: http-capability-gateway tier-2 production-wiring. The
147+
estate-wide fan-out of the regeneration-cartridge pattern across the
148+
28 existing -isers is gated on this.
149+
- https://github.com/hyperpolymath/boj-server/tree/main/cartridges/k9iser-mcp[boj-server/cartridges/k9iser-mcp]
150+
— the reference pilot (boj-server#73).
151+
- ADR-0004 (boj-server) — http-capability-gateway tier-2. Cartridge
152+
adapters are internal/loopback; the public surface is the gateway.
153+
- ADR-0006 (boj-server) — five-symbol cartridge C ABI.

0 commit comments

Comments
 (0)