Commit ad3224c
## Summary
Two failing checks (Aspect 27 fails + E2E 1 fail) had four distinct root
causes. Each fixed at source:
### Aspect — Thread Safety + ABI Contract + SPDX (27 → 0 fails)
| # | Root cause | Fix |
|---|---|---|
| 1 | Comment filters broken — `^\s*--` / `^\s*\|\|\|` never matched
because `grep -rn` output starts with `path:lineno:`, not content |
Anchor at `:[[:space:]]*--` / `:[[:space:]]*\|\|\|` + add trailing `-- …
<pat>` comment filter, factored into `strip_comments_and_docstrings`
helper |
| 2 | `believe_me` check didn't exempt the 5 documented class-J axioms
in `src/abi/Boj/SafetyLemmas.idr` | Added `PROOF_EXEMPT` regex; passes
on documented axioms, fails on any new use elsewhere |
| 3 | Aspect 1 Mutex check fired on purely-functional FFI (e.g.
`burble_admin_ffi.zig` — 3 exports, zero file-scope globals — table
lookups over `i32`) | Refined to only fail when there's ALSO `^(pub
)?var <ident>` file-scope global state. Purely-functional exports now
get an explicit pass message |
| 4 | Aspect 4 had no concept of stub-or-by-design cartridges — 15 fails
for "incomplete layers" included 10 manifest-only stubs (cartridge.json
declares API; abi/ ffi/ not yet written) and 5 intentionally proof-free
observability/glue (boj-health, claude-ai-mcp, lang-mcp,
orchestrator-lsp-mcp, toolchain-mcp) | Added `"status": "stub" \|
"ffi_only" \| "complete"` (default `complete`) field to
`cartridge.json`. Aspect 4 honours it and reports `(N complete, M stub,
K ffi_only)` so categories stay visible in CI logs |
| 5 | **Real bug**: `cartridges/ums-mcp/ffi/ums_ffi.zig` has 15 C-ABI
exports operating on a global `var sessions: [MAX_SESSIONS]SessionSlot`,
no Mutex. Once the filter fixes narrow Aspect 1 to true positives, this
is the one that remains. | Added `var sessions_mu: std.Thread.Mutex` and
`sessions_mu.lock(); defer sessions_mu.unlock();` to all 14
sessions-touching exports. `ums_can_transition` is pure (enum→enum) and
stays lock-free. Mirrors `g_state_mu` in
`cartridges/007-mcp/ffi/oo7_mcp_ffi.zig:79`. `zig build` passes |
After all five: **115 passed / 0 failed / 1 warning** (was 87/27/1). The
one warning (`federation.zig` `catch unreachable`) was pre-existing —
out of scope here.
### E2E — Full REST + MCP Bridge (failing since 2026-05-20)
`tests/e2e_full.sh` requires `mix` to start the Elixir backend, but
`.github/workflows/e2e.yml` never installed Elixir/OTP. Added an
`erlef/setup-beam@v1.18.2` step (Elixir 1.18 + OTP 27 — matches the
estate convention used in every repo's hypatia-scan.yml) plus a `mix
deps.get` step before the test runs.
## Test plan
- [x] `bash tests/aspect_tests.sh` — 115/0/1 (was 87/27/1)
- [x] `cd cartridges/ums-mcp/ffi && zig build` — clean
- [x] All 15 `cartridge.json` files still valid JSON
- [x] `e2e.yml` YAML parses; step ordering correct (setup-beam before
build-FFI / run-e2e)
## Foundational follow-up (NOT in this PR — flagged)
Same gap as `r-g-t-v#89` and `absolute-zero#42`: `main` branch
protection has no `required_status_checks` block, so red-CI PRs can
merge despite three workflows (E2E + Aspect + Bench, OpenSSF Scorecard
Enforcer, Instant Sync) being persistently red on main. Hypatia PR #316
ships BH001/BH002/BH003 to detect this class estate-wide; the BH001 rule
fires on exactly this repo.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6626b52 commit ad3224c
20 files changed
Lines changed: 210 additions & 32 deletions
File tree
- .github/workflows
- cartridges
- boj-health
- chromadb-mcp
- claude-ai-mcp
- echidna-llm-mcp
- elevenlabs-mcp
- ffmpeg-mcp
- lang-mcp
- orchestrator-lsp-mcp
- pinecone-mcp
- qdrant-mcp
- replicate-mcp
- search-mcp
- toolchain-mcp
- ums-mcp/ffi
- weaviate-mcp
- whisper-mcp
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
59 | 68 | | |
60 | 69 | | |
61 | 70 | | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
62 | 81 | | |
63 | 82 | | |
64 | 83 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
56 | 63 | | |
57 | 64 | | |
58 | 65 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
0 commit comments