rfc: ADR-0007 trust-tier policy DSL + ADR-0008 cartridge marketplace (epic #87 items 4 + 10)#92
Merged
Conversation
…arketplace Two coupled RFCs for epic #87 Tier B (items 4 + 10). Coupled because they share trust-tier vocabulary — the marketplace submission protocol in 0008 requires each cartridge to ship a default policy bundle in the schema defined by 0007. ADR-0007 — Trust-tier policy DSL - Adopt Nickel as the policy DSL (extends existing coord-messages.ncl investment) - PEP/PDP split: PEP stays in mcp-bridge/main.js; PDP is a new policy-mcp cartridge consulted per tools/call - Schema: per-cartridge × per-tool × {tier, rate_limit, required_role, master_approval, allowed_args, side_effect} - Verdicts: allow / deny / rate_limit / require_approval (with master-approval quarantine integration) - Default bundle covers all 41 bridge tools; ships at repo root - BOJ_POLICY_MODE = enforce | audit | off; BOJ_POLICY_FAIL_MODE for cold-start posture - Aligns with NIST RBAC 4.0 reference architecture so future migration to OPA/Rego (if needed) is mechanical ADR-0008 — Cartridge marketplace - Activates the Ayo tier (currently inactive) - New hyperpolymath/cartridge-index repo holds signed entries pointing to source repos at content-pinned revs - Submission protocol: PR against cartridge-index/inbox/ with signed entry + ML-DSA-87 signature + manifest_sha256 + abi_sha256 + policy - CI verifies hashes, signatures, policy schema, license, file structure - Promotion path: outside → Ayo → Shield (security-reviewed) → Teranga (formally verified); recorded in index, not source repo - New bridge tools: boj_marketplace_search, boj_marketplace_install - New MCP resources: boj://marketplace/index, boj://marketplace/cartridges/<name> - Default-safe: Ayo cartridges never auto-loaded; explicit user opt-in - Reuses estate's quantum-safe-provenance (ML-DSA-87) signature standard Both RFCs include consequences (positive + negative), explicit non-goals, and open questions calling out decisions deferred until implementation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🔍 Hypatia Security ScanFindings: 29 issues detected
View findings[
{
"reason": "Stale AI session file -- delete",
"type": "stale",
"file": "GEMINI.md",
"action": "delete",
"rule_module": "root_hygiene",
"severity": "medium"
},
{
"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": "Python file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/.github/scripts/validate-eclexiaiser.py",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/cartridges/sanctify-mcp/adapter/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/cartridges/academic-workflow-mcp/adapter/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/cartridges/fireflag-mcp/adapter/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/cartridges/ephapax-mcp/adapter/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/boj-server/boj-server/cartridges/bofig-mcp/adapter/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
May 20, 2026
…epic #87 items 5 + 6) (#95) ## Summary Third and final RFC pair for epic #87 Tier B. Both ADRs concern **server-initiated MCP messages** — webhooks fan out \`notifications/event\` to clients; sampling sends \`sampling/createMessage\` to clients. Both are opt-in per client and require graceful fallback when the client doesn't cooperate. **No code in this PR.** Pure design docs. ## ADR-0011 — Webhooks inbound + MCP notifications Closes the agent feedback loop: external events surface as MCP \`notifications/event\` instead of forcing agents to poll. - **Six providers v1**: github, gitlab, cloudflare, sentry, stripe, generic - **Single listener**: \`POST /webhooks/{provider}/{token}\` on the existing Cowboy endpoint (ADR-0004 preserved) - **Per-provider signature verification** — HMAC-SHA256, JWS as appropriate; signature-rejected events never reach the notification path - **Subscription persistence** at \`~/.boj/webhooks/\` (chmod 0600); managed via 5 new bridge tools (\`boj_webhook_subscribe/list/unsubscribe/rotate/replay\`) - **Bounded replay buffer** (100 events × N subscriptions) so reconnecting clients catch up - **Fan-out by selector** — broadcast, by \`client_kind\`, or by \`peer_token\` ## ADR-0012 — Server-initiated sampling \`sampling/createMessage\` is MCP's underused reverse path. BoJ uses it for **two specific patterns**, both opt-in per call site: | Pattern | When | |---|---| | Composition router | \`boj_cartridge_invoke\` against an ambiguous intent (e.g. "deploy and monitor") — ask the LLM which cartridge fits | | Clarification | An argument could match multiple backends — ask the LLM (which knows the user) which one | **Budget-bounded**: \`BOJ_SAMPLING_BUDGET_PER_SESSION\` (default 50); exceeded → deterministic fallback. **Always has fallback**: client rejection or timeout never blocks. **Hard NO list**: never in security-critical paths, never to ask "should I proceed?", never for input validation. Per-call OTel span (depends on PR #91) so sampling activity is observable in the user's existing telemetry. ## Why this pair Both are **server-initiated**, both are **opt-in per client**, both **degrade gracefully**. Coupling them in one review surfaces the shared protocol concerns (client cooperation, fallback discipline, audit attribution) in one place. ## Review focus Recommend reading **Open questions** in both: - ADR-0011: subscription persistence across restarts; backpressure on slow clients; provider extensibility (config vs code); authorization tier for subscription creation - ADR-0012: system-prompt safety; sampling-decision caching; multi-client target heuristic; cost attribution; fallback determinism ## What this doesn't change - No code touched. - No existing tools or cartridges affected. - ADR-0004 (single listener) preserved by 0011; ADR-0007 (policy DSL) extended by both (sampling result feeds a policy-gated tool call; webhook subscriptions are policy-gated artefacts). ## Sequencing This completes epic #87 Tier B (all 6 RFCs across PRs #92, #93, this one). Tier A is complete in code (#89, #91). Tier C is the long-running proof campaigns — separate work, no RFCs needed at this stage. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 20, 2026
hyperpolymath
added a commit
that referenced
this pull request
May 20, 2026
## Summary `.github/scripts/validate-eclexiaiser.py` was the residual baseline-rot that surfaced after #114 (ReScript exemption) removed the fail-fast — the `governance / Language / package anti-pattern policy` step then reached its Python sub-check and flagged it. This was the blocker on #115. Per the canonical Hyperpolymath Language Policy, Python is wholly outlawed estate-wide with zero exemptions (only carve-out is SaltStack `_states`/`_modules`/`pillar`, which this file isn't). Replace with a POSIX-shell + awk validator doing the same three checks: 1. `[project]` section has a non-empty `name` 2. At least one `[[functions]]` table is declared 3. Each function table has a non-empty `name` and `source` The new script has no TOML-parser dependency. ## Test plan - [x] Local: happy path on current eclexiaiser.toml -> Valid: boj-server (1 function(s)) exit 0 - [x] Local: 3 failure modes each return exit 1 with the correct error message - [ ] CI: Validate eclexiaiser manifest step (Dogfood Gate) continues to pass - [ ] CI: governance / Language / package anti-pattern policy step now passes Refs hyperpolymath/standards#67 (Estate Language Policy). Refs hyperpolymath/standards#89 (was blocking the #92 allowlist work). 🤖 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
Two coupled RFCs for epic #87 Tier B. Coupled because they share trust-tier vocabulary — ADR-0008's submission protocol requires every cartridge to ship a default policy bundle in the schema ADR-0007 defines.
No code in this PR. Pure design docs. Implementation tracked separately in epic #87 (items 4 and 10).
ADR-0007 — Trust-tier policy DSL
Adopt Nickel as the policy DSL (extends the existing `coord-messages.ncl` investment), with a clean PEP/PDP split:
Schema: per-cartridge × per-tool × `{tier, rate_limit, required_role, master_approval, allowed_args, side_effect}`. Verdicts: `allow` / `deny` / `rate_limit` / `require_approval` (the last routes through `coord_send_gated`-style quarantine).
Default policy bundle covers all 41 bridge tools out of the box. Migration sequence covered explicitly in the ADR's "Open questions" section.
ADR-0008 — Cartridge marketplace
Activates the Ayo tier, which currently has exactly one member and no protocol. New repo `hyperpolymath/cartridge-index` holds signed entries (ML-DSA-87 per EXHIBIT-B) pointing to source repos at content-pinned revs.
Promotion path: outside → Ayo → Shield → Teranga. Promotion is recorded in the index, not the source repo, so cartridges don't need to "know" their tier.
Critically: respects ADR-0002 (BoJ-only MCP). Community capabilities flow into BoJ as cartridges, never as standalone MCPs.
Default-safe posture: Ayo cartridges are visible via `boj_marketplace_search` but never auto-loaded; user must explicitly `boj_marketplace_install --accept-ayo-tier`.
Why this pair, this order
The epic specifies they ship together: "Items 4 + 10 RFCs together (they share the trust-tier vocabulary)." 0007 defines what a policy bundle looks like; 0008 requires every submission to ship one. Either alone leaves a hole.
Review focus
The ADRs are formatted for substantive engagement, not rubber-stamp. Each has explicit:
Recommend reading the Open questions sections — that's where the load-bearing choices that need your call live.
What this doesn't change
Sequencing
Per epic #87: this is Tier B step 1 of 3. Next pair (items 2 + 3: sandbox cartridge + cross-machine federation) follows in a sibling PR; the third pair (items 5 + 6: webhooks + sampling) after that. All three pairs are independent of each other and of the code PRs (#88/#89/#91).
🤖 Generated with Claude Code