feat(cartridge): scaffolder for boj-server cartridge skeletons (standards#89 Phase 2b)#24
Merged
Merged
Conversation
…ards#89 Phase 2b)
Adds `iseriser cartridge --manifest <toml> --output <dir>` which emits a
complete boj-server cartridge skeleton at `<output>/<iser>-mcp/`:
<iser>-mcp/
├── README.adoc cartridge overview + build
├── cartridge.json registration manifest
├── mod.js JS-worker fallback path
├── panels/manifest.json observability panel registration
├── abi/
│ ├── README.adoc
│ ├── <iser>-mcp.ipkg Idris2 package
│ └── <Iser>Mcp/Safe<Iser>.idr exposure-gate contract + tools
├── ffi/
│ ├── README.adoc
│ ├── build.zig shared-shim wiring
│ └── <iser>_ffi.zig ADR-0006 5-symbol C-ABI
└── adapter/
├── README.adoc
├── build.zig
└── <iser>_adapter.zig unified gated adapter (4-protocol)
The cartridge is meant to be placed inside `boj-server/cartridges/`; the
emitted Zig build files reference the shared invoke-shim at
`boj-server/ffi/zig/src/cartridge_shim.zig` via `../../../`.
Modelled on the k9iser-mcp pilot (boj-server#73). Skeleton-only: the
exposure/transaction gate, the 5-symbol ABI plumbing, and the unified
4-protocol adapter are all production-ready; per-tool dispatch bodies
are stubs ready for replacement.
Verified end-to-end against the actual boj-server tree:
- `zig build test` on emitted ffi/ → 4/4 tests pass
- `zig build test` on emitted adapter/ → 5/5 tests pass
- `idris2 --build` on emitted .ipkg → SafeChapeliser type-checks (RC=0)
- `cargo test`: 57 unit + 9 integration green (8 new tests added)
- `zig fmt --check` on all emitted .zig files: clean
- `cartridge.json` + `panels/manifest.json` parse as valid JSON
Two pilot-vs-scaffold deltas worth noting:
- The pilot `.ipkg` ships `depends = base, contrib` which is invalid in
Idris2 0.8.0 (parser stops at the comma). The scaffold emits
`depends = base` to compile cleanly; `contrib` can be added on a
separate `depends` line when actually needed.
- The pilot's per-tool bodies (k9_load_manifest, k9_generate, ...) are
k9iser-specific. The scaffold emits one example tool
(`<iser>_generate`) plus a status panel; expand as the cartridge grows.
Refs hyperpolymath/standards#89, #90
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| @@ -0,0 +1,1314 @@ | |||
| // SPDX-License-Identifier: PMPL-1.0-or-later | |||
🔍 Hypatia Security ScanFindings: 20 issues detected
View findings[
{
"reason": "Issue in quality.yml",
"type": "missing_workflow",
"file": "quality.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in security-policy.yml",
"type": "missing_workflow",
"file": "security-policy.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Action actions/upload-artifact@v4 needs attention",
"type": "unpinned_action",
"file": "release.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action actions/download-artifact@v4 needs attention",
"type": "unpinned_action",
"file": "release.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "codeql.yml lists `language: javascript-typescript` but the repo has no source files in any CodeQL-scannable language. The analyze job will exit 'no source files' on every run. Switch the matrix to `actions` (which scans workflow files — every repo has those).",
"type": "codeql_language_matrix_mismatch",
"file": "codeql.yml",
"action": "switch_codeql_matrix_to_actions",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "unwrap_or(0) with dangerous default (1 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/iseriser/iseriser/src/abi/zig_ffi_parser.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "unwrap() without prior check -- DoS via panic (1 occurrences, CWE-754)",
"type": "unwrap_without_check",
"file": "/home/runner/work/iseriser/iseriser/src/abi/idris_emitter.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "expect() in hot path (13 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/iseriser/iseriser/src/codegen/cartridge.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (3 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/iseriser/iseriser/src/codegen/scaffold.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
This was referenced May 20, 2026
hyperpolymath
added a commit
that referenced
this pull request
May 20, 2026
…ion (#25) PR #24 emitted `depends = base` on the cartridge ipkg. The k9iser-mcp pilot (and every other boj-server cartridge — 23 of them) ships `depends = base, contrib`. Aligning to the established convention so cartridge authors get `Data.List` / `Data.String` helpers etc. without having to hand-edit the ipkg on day one. The omission was based on a mis-diagnosis: PR #24's description claimed `depends = base, contrib` was invalid in Idris2 0.8.0 because `idris2 --check k9iser-mcp.ipkg` reported "Expected end of input" at the comma. That subcommand is wrong for ipkg files — `--check` treats files as Idris2 modules, not packages. `idris2 --build k9iser-mcp.ipkg` (the correct invocation) succeeds with `1/1: Building K9iserMcp.SafeK9iser` on Idris2 0.8.0. Re-verified locally against k9iser-mcp + the chapeliser-mcp output of this scaffold (RC=0 on both). Verification of this change: - `iseriser cartridge` regenerates `chapeliser-mcp/abi/chapeliser-mcp.ipkg` with `depends = base, contrib`. - `idris2 --build` on the regenerated ipkg: SafeChapeliser type-checks, RC=0. - `cargo test`: 57 unit + 9 integration green. 🤖 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 20, 2026
For humans: - README.adoc: document the new `cartridge` subcommand under "Iseriser CLI subcommands" and add a paragraph cross-referencing standards#89 (Phase 2b) and standards#91 (the gating dependency for estate-wide fan-out). - CHANGELOG.adoc and CHANGELOG.md: 2026-05-20 entries covering PRs #23 (revert wrong-place adapter), #24 (cartridge scaffolder), and #25 (`depends = base, contrib` correction). Each entry names what shipped, why, and the PR that landed it. For machines: - .machine_readable/6a2/STATE.a2ml: bump last-updated to 2026-05-20, phase to phase-2b-complete, maturity to alpha, completion to 62. Add a new [capabilities] block enumerating the shipped subcommands (init / validate / generate / cartridge / info / scan / abi-verify / abi-emit-manifest) and a [recent-prs] block listing the session's three PRs by number. Refresh milestones, blockers, and next-actions to reflect that Phase 1, standards#92 Phase 1+1b, and standards#89 Phase 2b are all complete; remaining open items (standards#90 fan-out, #91 gateway, #92 drift sweep) are correctly parked. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
iseriser cartridge --manifest <toml> --output <dir>which emits a complete boj-server cartridge skeleton at<output>/<iser>-mcp/. Modelled on the k9iser-mcp pilot (boj-server#73). 13 files, ~800 lines of generated content.Output topology
The cartridge is meant to be placed inside
boj-server/cartridges/; the emitted Zig build files reference the shared invoke-shim atboj-server/ffi/zig/src/cartridge_shim.zigvia../../../.What's filled in vs stub
classify/toolFor/dispatch/writeHttp/writeSse), and the cartridge.json+panels skeleton.<iser>_generate) returning a placeholder JSON body; replace as the cartridge grows.Two pilot-vs-scaffold deltas worth noting
.ipkgshipsdepends = base, contribwhich is invalid in Idris2 0.8.0 (the parser stops at the comma — confirmed byidris2 --buildonk9iser-mcp.ipkg). The scaffold emitsdepends = baseto compile cleanly;contribcan be added on a separatedependsline when actually needed.Verification
End-to-end against the actual boj-server tree (chapeliser test manifest → scaffolded into
boj-server/cartridges/chapeliser-mcp/):zig build teston emittedffi/→ 4/4 tests passzig build teston emittedadapter/→ 5/5 tests passidris2 --buildon emitted.ipkg→SafeChapelisertype-checks (RC=0)zig fmt --checkon all emitted.zigfiles: cleancartridge.json+panels/manifest.jsonparse as valid JSONcargo test: 57 unit + 9 integration green (8 new tests added)CLI
Not in this PR
Refs hyperpolymath/standards#89, #90
🤖 Generated with Claude Code