Skip to content

Commit 06834c4

Browse files
feat(catalog+fetcher): strict schema validation + bundle refresh + rename sync (closes #183) (#184)
## Summary Closes the boj-server side of the cartridge-schema-validation campaign that landed in boj-server-cartridges#21+#23+#25+#26+#27 this session. Three changes ship together: 1. **\`BojRest.Catalog\` validates strictly at boot** — adds \`ex_json_schema\`, compiles \`schemas/cartridge-v1.json\` once, validates every manifest against it on load, and rejects (does not insert into ETS, logs an error) any cartridge that fails. Strict from day one per owner direction. 2. **\`scripts/fetch-cartridges.sh\` runs registry-side strict validation** as a defense-in-depth pre-flight, and now copies the registry's \`schemas/\` directory beside the cartridges cache so the catalog's default \`:schema_path\` finds the mirror without configuration. 3. **In-tree \`cartridges/\` refreshed against the cleaned canonical** — the 2026-05-26 snapshot had 43/125 manifests failing current strict validation. Refresh script (\`scripts/refresh-bundled-cartridges.sh\`) preserves the 125-cartridge curation per the owner's \"curate-keep at 125\" direction; the three rename targets from boj-server-cartridges#27 propagate (\`boj-health\` → \`boj-health-mcp\`, \`origenemcp\` → \`origene-mcp\`, \`opendatamcp\` → \`opendata-mcp\`). Post-refresh: **125/125 strict-valid**. ## Tests \`elixir/test/catalog_test.exs\` updated: - \`boj-health\` references → \`boj-health-mcp\`. - \"auth method known value\" test tightened to the canonical schema enum \`[none, api-key, oauth2, vault]\` only. - New: every loaded cartridge carries every schema-required top-level field. - New: \`schemas/cartridge-v1.json\` SHA-256 equals the \`Pin SHA-256:\` line in \`schemas/PINNED-SHA\` — guards silent mirror drift. ## Compatibility Any external consumer that called \`BojRest.Catalog.get(\"boj-health\")\` / \`get(\"origenemcp\")\` / \`get(\"opendatamcp\")\` now gets \`:not_found\`. The old names violate the canonical schema's role-suffix pattern; alias support was deliberately not added because re-introducing the violating names defeats the strict gate. The fetcher remains backward-compatible: if the registry is an older snapshot without \`tools/validate-cartridges/\`, or if Deno isn't installed, the strict pre-flight is skipped with a clear log line and the catalog still validates at load. ## Test plan - [x] Refresh script run locally against current canonical; 125/125 strict-valid. - [x] All commits GPG-signed. - [ ] CI green (Elixir 1.18 / OTP 25; deno strict in fetcher path). Closes #183. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 272a1b6 commit 06834c4

144 files changed

Lines changed: 905 additions & 1523 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cartridges/007-mcp/cartridge.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"graceful_degrade": true
3434
},
3535
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
36-
"description": "007 agent meta-language cartridge \u2014 exposes the full oo7 CLI surface (parse/run/trace/build/test/lint/verify/contractile verbs/canonical-proof-suite/groove/self-assess) plus on-enter and on-exit lifecycle hooks that register the session as a coord peer, load the 6a2 methodology pack (STATE, META, ECOSYSTEM, AGENTIC, NEUROSYM, PLAYBOOK), and perform drift checks on exit.",
36+
"description": "007 agent meta-language cartridge exposes the full oo7 CLI surface (parse/run/trace/build/test/lint/verify/contractile verbs/canonical-proof-suite/groove/self-assess) plus on-enter and on-exit lifecycle hooks that register the session as a coord peer, load the 6a2 methodology pack (STATE, META, ECOSYSTEM, AGENTIC, NEUROSYM, PLAYBOOK), and perform drift checks on exit.",
3737
"domain": "dezig",
3838
"category": "domain",
3939
"federation": "none",
@@ -59,7 +59,7 @@
5959
"tier": "Ayo",
6060
"tools": [
6161
{
62-
"description": "Lifecycle hook \u2014 invoke when entering the 007-lang context. Registers this session as a coord peer (graceful degrade if local-coord-mcp is down), loads the 6a2 methodology pack (STATE, META, ECOSYSTEM, AGENTIC, NEUROSYM, PLAYBOOK), runs the memory auto-lift using repo-derived tags, and returns a structured A2ML payload with peer_id, session_token, methodology digests, and memory hits. Idempotent: calling twice returns the same peer_id/token.",
62+
"description": "Lifecycle hook invoke when entering the 007-lang context. Registers this session as a coord peer (graceful degrade if local-coord-mcp is down), loads the 6a2 methodology pack (STATE, META, ECOSYSTEM, AGENTIC, NEUROSYM, PLAYBOOK), runs the memory auto-lift using repo-derived tags, and returns a structured A2ML payload with peer_id, session_token, methodology digests, and memory hits. Idempotent: calling twice returns the same peer_id/token.",
6363
"inputSchema": {
6464
"properties": {
6565
"session_hint": {
@@ -73,7 +73,7 @@
7373
"name": "oo7_on_enter"
7474
},
7575
{
76-
"description": "Lifecycle hook \u2014 invoke before leaving the 007-lang context. Updates STATE.a2ml's last-session fields, runs a drift check (open claims? uncommitted contractile edits? stale 6a2 files?), releases any coord task claims held by this peer, and deregisters from local-coord-mcp. Returns A2ML summary with drift findings. Safe to call even if on_enter was never invoked.",
76+
"description": "Lifecycle hook invoke before leaving the 007-lang context. Updates STATE.a2ml's last-session fields, runs a drift check (open claims? uncommitted contractile edits? stale 6a2 files?), releases any coord task claims held by this peer, and deregisters from local-coord-mcp. Returns A2ML summary with drift findings. Safe to call even if on_enter was never invoked.",
7777
"inputSchema": {
7878
"properties": {
7979
"reason": {
@@ -557,7 +557,7 @@
557557
"name": "oo7_dust_status_local"
558558
},
559559
{
560-
"description": "Revert all source changes to last commit. DESTRUCTIVE \u2014 the adapter rejects this tool unless the caller holds a Tier-3 master approval. Wraps `just dust-source-rollback`.",
560+
"description": "Revert all source changes to last commit. DESTRUCTIVE the adapter rejects this tool unless the caller holds a Tier-3 master approval. Wraps `just dust-source-rollback`.",
561561
"inputSchema": {
562562
"properties": {},
563563
"required": [],
@@ -566,7 +566,7 @@
566566
"name": "oo7_dust_source_rollback"
567567
},
568568
{
569-
"description": "Verify OpenSSF Best Practices prerequisites \u2014 fails if required files are missing. Wraps `just verify`.",
569+
"description": "Verify OpenSSF Best Practices prerequisites fails if required files are missing. Wraps `just verify`.",
570570
"inputSchema": {
571571
"properties": {},
572572
"required": [],
@@ -575,7 +575,7 @@
575575
"name": "oo7_verify"
576576
},
577577
{
578-
"description": "Verify the Harvard architecture invariant \u2014 data expressions must not contain control flow. Wraps `just verify-harvard`.",
578+
"description": "Verify the Harvard architecture invariant data expressions must not contain control flow. Wraps `just verify-harvard`.",
579579
"inputSchema": {
580580
"properties": {},
581581
"required": [],
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
Mozilla Public License Version 2.0
1+
SPDX-License-Identifier: MPL-2.0
2+
SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
23

3-
This academic-workflow-mcp cartridge is licensed under the Mozilla Public
4-
License, Version 2.0 as the legal fallback. The preferred license is
5-
MPL-2.0.
4+
Academic Workflow Cartridge
65

7-
See SPDX-License-Identifier headers in source files.
8-
For MPL-2.0 text: https://opensource.org/licenses/MPL-2.0
6+
This software is licensed under the Mozilla Public License 2.0 (MPL-2.0).
7+
For the full licence text see the repository root LICENSE file, or
8+
https://www.mozilla.org/en-US/MPL/2.0/.

cartridges/academic-workflow-mcp/cartridge.json

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,80 @@
44
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
55
"name": "academic-workflow-mcp",
66
"version": "1.0.0",
7-
"description": "Academic workflow \u2014 Zotero integration, citations, paper review",
7+
"description": "Academic workflow Zotero integration, citations, paper review",
88
"domain": "Research",
99
"category": "domain",
1010
"tier": "Ayo",
11+
"protocols": [
12+
"MCP"
13+
],
1114
"auth": {
12-
"method": "none"
15+
"method": "none",
16+
"env_var": null,
17+
"credential_source": null
18+
},
19+
"api": {
20+
"base_url": "local://academic-workflow-mcp",
21+
"content_type": "application/json"
1322
},
14-
"author": "Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>",
15-
"license": "MPL-2.0",
1623
"tools": [
1724
{
1825
"id": "search_zotero",
1926
"name": "Search Zotero",
20-
"description": "Search papers and collections in Zotero library"
27+
"description": "Search papers and collections in Zotero library",
28+
"inputSchema": {
29+
"type": "object",
30+
"properties": {}
31+
}
2132
},
2233
{
2334
"id": "get_paper_metadata",
2435
"name": "Get Paper Metadata",
25-
"description": "Fetch title, authors, DOI, year, abstract from Zotero"
36+
"description": "Fetch title, authors, DOI, year, abstract from Zotero",
37+
"inputSchema": {
38+
"type": "object",
39+
"properties": {}
40+
}
2641
},
2742
{
2843
"id": "generate_citation",
2944
"name": "Generate Citation",
30-
"description": "Export citation in BibTeX/CSL/RIS/EndNote format"
45+
"description": "Export citation in BibTeX/CSL/RIS/EndNote format",
46+
"inputSchema": {
47+
"type": "object",
48+
"properties": {}
49+
}
3150
},
3251
{
3352
"id": "extract_bibkeys",
3453
"name": "Extract BibTeX Keys",
35-
"description": "Find citation keys in text"
54+
"description": "Find citation keys in text",
55+
"inputSchema": {
56+
"type": "object",
57+
"properties": {}
58+
}
3659
},
3760
{
3861
"id": "export_collection",
3962
"name": "Export Collection",
40-
"description": "Export entire collection as BibTeX"
63+
"description": "Export entire collection as BibTeX",
64+
"inputSchema": {
65+
"type": "object",
66+
"properties": {}
67+
}
4168
},
4269
{
4370
"id": "add_review_note",
4471
"name": "Add Review Note",
45-
"description": "Annotate papers with review comments"
72+
"description": "Annotate papers with review comments",
73+
"inputSchema": {
74+
"type": "object",
75+
"properties": {}
76+
}
4677
}
4778
],
79+
"author": "Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>",
80+
"license": "MPL-2.0",
4881
"abi": {
4982
"interface": "abi/AcademicWorkflow.idr",
5083
"loopback_proof": "IsLoopback 5174"

cartridges/aerie-mcp/README.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,5 @@ cd adapter && zig build
5454
== Status
5555

5656
Alpha (CRG D). Cartridge metadata declared in `cartridge.json`; 4 tool(s) exposed.
57-
Not yet dogfooded externally. See `docs/READINESS.adoc` at repo root for the
57+
Not yet dogfooded externally. See `docs/READINESS.md` at repo root for the
5858
project-wide grade table and `docs/practice/DOGFOOD-LOG.adoc` for usage evidence.

cartridges/affinescript-mcp/cartridge.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@
196196
},
197197
{
198198
"name": "affinescript_hover",
199-
"description": "Return type and symbol information for the symbol at a cursor position in AffineScript source code. Runs the full pipeline (parse \u2192 resolve \u2192 typecheck) and returns JSON hover info.",
199+
"description": "Return type and symbol information for the symbol at a cursor position in AffineScript source code. Runs the full pipeline (parse resolve typecheck) and returns JSON hover info.",
200200
"inputSchema": {
201201
"type": "object",
202202
"properties": {

cartridges/agent-mcp/README.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,5 @@ cd adapter && zig build
5757
== Status
5858

5959
Alpha (CRG D). Cartridge metadata declared in `cartridge.json`; 7 tool(s) exposed.
60-
Not yet dogfooded externally. See `docs/READINESS.adoc` at repo root for the
60+
Not yet dogfooded externally. See `docs/READINESS.md` at repo root for the
6161
project-wide grade table and `docs/practice/DOGFOOD-LOG.adoc` for usage evidence.

cartridges/airtable-mcp/cartridge.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"REST"
1414
],
1515
"auth": {
16-
"method": "bearer_token",
16+
"method": "api-key",
17+
"notes_method": "bearer_token",
1718
"env_var": "AIRTABLE_API_KEY",
1819
"credential_source": "vault-mcp"
1920
},
@@ -150,7 +151,7 @@
150151
},
151152
{
152153
"name": "airtable_update_record",
153-
"description": "Update an existing record's field values (PATCH \u2014 only specified fields are updated)",
154+
"description": "Update an existing record's field values (PATCH only specified fields are updated)",
154155
"inputSchema": {
155156
"type": "object",
156157
"properties": {

cartridges/bofig-mcp/LICENSE

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
SPDX-License-Identifier: MPL-2.0
2+
SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
23

34
Bofig Cartridge
4-
Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)
55

6-
This software is licensed under the MPL-2.0 license.
7-
8-
MPL-2.0 is a license supporting dual licensing with MPL-2.0 as automatic fallback.
9-
For the full license text, see: https://hyperpolymath.dev/standards/PMPL-1.0
10-
11-
Legal Notice:
12-
Until PMPL achieves formal recognition as a standalone license, this software is
13-
automatically operative under the Mozilla Public License 2.0 (MPL-2.0).
14-
15-
This is a legal fallback arrangement confirmed by legal counsel.
6+
This software is licensed under the Mozilla Public License 2.0 (MPL-2.0).
7+
For the full licence text see the repository root LICENSE file, or
8+
https://www.mozilla.org/en-US/MPL/2.0/.

cartridges/bofig-mcp/cartridge.json

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,80 @@
44
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)",
55
"name": "bofig-mcp",
66
"version": "1.0.0",
7-
"description": "Bofig Cartridge \u2014 Evidence graph query tools for investigative workflows",
7+
"description": "Bofig Cartridge Evidence graph query tools for investigative workflows",
88
"domain": "Research",
99
"category": "domain",
1010
"tier": "Ayo",
11+
"protocols": [
12+
"MCP"
13+
],
1114
"auth": {
12-
"method": "none"
15+
"method": "none",
16+
"env_var": null,
17+
"credential_source": null
18+
},
19+
"api": {
20+
"base_url": "local://bofig-mcp",
21+
"content_type": "application/json"
1322
},
14-
"author": "Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>",
15-
"license": "MPL-2.0",
1623
"tools": [
1724
{
1825
"id": "query_evidence",
1926
"name": "Query Evidence",
20-
"description": "Query evidence by ID from the graph database"
27+
"description": "Query evidence by ID from the graph database",
28+
"inputSchema": {
29+
"type": "object",
30+
"properties": {}
31+
}
2132
},
2233
{
2334
"id": "search_evidence",
2435
"name": "Search Evidence",
25-
"description": "Search evidence by keyword (title, description, source)"
36+
"description": "Search evidence by keyword (title, description, source)",
37+
"inputSchema": {
38+
"type": "object",
39+
"properties": {}
40+
}
2641
},
2742
{
2843
"id": "get_connections",
2944
"name": "Get Connections",
30-
"description": "Get all connections/relationships for an entity in the graph"
45+
"description": "Get all connections/relationships for an entity in the graph",
46+
"inputSchema": {
47+
"type": "object",
48+
"properties": {}
49+
}
3150
},
3251
{
3352
"id": "find_path",
3453
"name": "Find Path",
35-
"description": "Find shortest path between two entities in the evidence graph"
54+
"description": "Find shortest path between two entities in the evidence graph",
55+
"inputSchema": {
56+
"type": "object",
57+
"properties": {}
58+
}
3659
},
3760
{
3861
"id": "execute_query",
3962
"name": "Execute Query",
40-
"description": "Execute a custom graph query"
63+
"description": "Execute a custom graph query",
64+
"inputSchema": {
65+
"type": "object",
66+
"properties": {}
67+
}
4168
},
4269
{
4370
"id": "get_graph_stats",
4471
"name": "Get Graph Stats",
45-
"description": "Get overall statistics about the evidence graph"
72+
"description": "Get overall statistics about the evidence graph",
73+
"inputSchema": {
74+
"type": "object",
75+
"properties": {}
76+
}
4677
}
4778
],
79+
"author": "Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>",
80+
"license": "MPL-2.0",
4881
"abi": {
4982
"interface": "abi/Bofig.idr",
5083
"loopback_proof": "IsLoopback 5178"
Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,27 @@
22
"$schema": "https://boj.dev/schemas/cartridge/v1.json",
33
"spdx": "MPL-2.0",
44
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
5-
"name": "boj-health",
5+
"name": "boj-health-mcp",
66
"version": "0.1.0",
77
"status": "ffi_only",
8-
"description": "BoJ server self-health cartridge \u2014 status, ping, and uptime queries. Self-contained Zig FFI (.so) reference implementation: no external services required.",
8+
"description": "BoJ server self-health cartridge status, ping, and uptime queries. Self-contained Zig FFI (.so) reference implementation: no external services required.",
99
"domain": "infrastructure",
1010
"category": "cross-cutting",
1111
"tier": "Ayo",
12-
"protocols": [
13-
"MCP"
14-
],
12+
"protocols": ["MCP"],
1513
"auth": {
1614
"method": "none",
1715
"env_var": null,
1816
"credential_source": null
1917
},
2018
"api": {
21-
"base_url": "local://boj-health",
19+
"base_url": "local://boj-health-mcp",
2220
"content_type": "application/json"
2321
},
2422
"ffi": {
2523
"so_path": "ffi/zig-out/lib/libboj_health.so",
2624
"abi_version": "ADR-0006",
27-
"symbols": [
28-
"boj_cartridge_init",
29-
"boj_cartridge_deinit",
30-
"boj_cartridge_name",
31-
"boj_cartridge_version",
32-
"boj_cartridge_invoke"
33-
]
25+
"symbols": ["boj_cartridge_init", "boj_cartridge_deinit", "boj_cartridge_name", "boj_cartridge_version", "boj_cartridge_invoke"]
3426
},
3527
"tools": [
3628
{
@@ -43,7 +35,7 @@
4335
},
4436
{
4537
"name": "boj_health_ping",
46-
"description": "Ping the BoJ health cartridge \u2014 always returns pong",
38+
"description": "Ping the BoJ health cartridge always returns pong",
4739
"inputSchema": {
4840
"type": "object",
4941
"properties": {}

0 commit comments

Comments
 (0)