From 78618fef2a79ef349188996cbdbed776cab4e359 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 7 Aug 2026 12:34:16 +0100 Subject: [PATCH 1/7] fix(ci): stop two gates passing while verifying nothing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Retiring the bundled cartridges/ tree left two gates looping over a glob that now matches zero files. Both then exited 0 and reported success. - tests/truthfulness_check.sh walked cartridges/*/cartridge.json. It now resolves the catalogue the way the runtime does — BOJ_CARTRIDGES_PATH, else the tracked E2E fixture catalogue — and fails hard on zero manifests. A truthfulness gate that cannot fail is itself an untruth. Verified: 23 cartridges checked, was 0. - scripts/typecheck-proofs.sh advertised 'core + all cartridge ABIs' and claimed PASS=105 in PROOF-NEEDS.md; with the tree gone it checked one package. The dead loop is removed (the registry type-checks its own abi/ dirs in its own gate) and the vacuous-pass guard is ported from boj-server-cartridges' twin of this script, which already had it. Neither repo had both halves: this one lacked the vacuous-pass guard, the registry lacks the weekly schedule backstop. That gap is recorded in the new DEBT register. Co-Authored-By: Claude Opus 5 --- scripts/typecheck-proofs.sh | 31 +++++++++++++++++++------------ tests/truthfulness_check.sh | 24 ++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/scripts/typecheck-proofs.sh b/scripts/typecheck-proofs.sh index 8193b9c2..0274f598 100755 --- a/scripts/typecheck-proofs.sh +++ b/scripts/typecheck-proofs.sh @@ -41,20 +41,27 @@ check_idr() { # dir relfile echo "==> Core ABI package (src/abi/boj.ipkg)" check_ipkg src/abi boj.ipkg -echo "==> Cartridge ABIs" -for d in cartridges/*/abi; do - [ -d "$d" ] || continue - ipkg=$(find "$d" -maxdepth 1 -name '*.ipkg' | head -1) - if [ -n "$ipkg" ]; then - check_ipkg "$d" "$(basename "$ipkg")" - else - while IFS= read -r f; do - check_idr "$d" "${f#"$d"/}" - done < <(find "$d" -name '*.idr') - fi -done +# Cartridge ABIs used to be walked here (cartridges/*/abi). That tree was +# retired — the cartridges now live in hyperpolymath/boj-server-cartridges, +# which type-checks its own 126 abi/ dirs in its own proofs gate. The loop is +# deliberately NOT replaced with one over a fetched cache: a gate that only +# checks what happens to be on disk is not a gate. echo "────────────────────────────────────────" echo "Proof type-check: PASS=${pass} FAIL=${fail}" [ "$fail" -eq 0 ] || { echo "PROOF TYPECHECK FAILED"; exit 1; } + +# Vacuous-pass guard (ported from boj-server-cartridges' twin of this script). +# PASS=0/FAIL=0 means nothing was found to check — a moved directory, a bad +# checkout, or a refactor that renames src/abi. Without this the gate reports +# success having verified NOTHING, which is exactly the failure mode this +# script exists to prevent. A repo with zero proofs is not a passing repo; +# it is a broken gate. +if [ "$pass" -eq 0 ]; then + echo "PROOF TYPECHECK FAILED: no proofs were found to check." >&2 + echo " Expected the core ABI package at src/abi/boj.ipkg." >&2 + echo " A green run with zero proofs verified would be a false assurance." >&2 + exit 1 +fi + echo "All proofs type-check under the pinned toolchain." diff --git a/tests/truthfulness_check.sh b/tests/truthfulness_check.sh index 2296c05d..40e1160a 100755 --- a/tests/truthfulness_check.sh +++ b/tests/truthfulness_check.sh @@ -41,8 +41,15 @@ if [ "$PROBE" = 1 ]; then fi fi +# The bundled cartridges/ tree was retired; the catalogue now lives in +# hyperpolymath/boj-server-cartridges and is consumed from a fetched cache. +# Resolve the same way the runtime does (BojRest.Catalog / the bridge): +# BOJ_CARTRIDGES_PATH, else the tracked E2E fixture catalogue. +CATALOGUE_ROOT="${BOJ_CARTRIDGES_PATH:-tests/fixtures/cartridges}" + checked=0 -for f in cartridges/*/cartridge.json; do +for f in "$CATALOGUE_ROOT"/*/cartridge.json; do + [ -e "$f" ] || continue checked=$((checked + 1)) name=$(jq -r '.name // "?"' "$f") avail=$(jq -r '.available // false' "$f") @@ -105,8 +112,21 @@ for f in cartridges/*/cartridge.json; do done echo "---" + +# Vacuous-pass guard. Before the cartridges/ retirement this loop always had +# 125 manifests to walk; afterwards the glob silently matched nothing and the +# gate printed OK having verified NOTHING. A truthfulness gate that cannot +# fail is itself an untruth — so zero manifests is a hard failure. +if [ "$checked" -eq 0 ]; then + err "truthfulness: no cartridge manifests found under '$CATALOGUE_ROOT'" + err " Set BOJ_CARTRIDGES_PATH to a fetched cache (scripts/fetch-cartridges.sh)" + err " or restore tests/fixtures/cartridges. A green run over zero cartridges" + err " would be a false assurance." + exit 1 +fi + if [ "$fail" = 0 ]; then - note "truthfulness: OK — $checked cartridges checked (probe=$PROBE)" + note "truthfulness: OK — $checked cartridges checked from $CATALOGUE_ROOT (probe=$PROBE)" else note "truthfulness: FAILED — see FAIL lines above" fi From f6480790a995d60641c86d95983d0aa5689d5f91 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 7 Aug 2026 12:37:53 +0100 Subject: [PATCH 2/7] docs: add a technical-debt register with reproducible evidence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DEBT.md indexes known debt across seven domains (licence, proof, CI/CD, code, test, documentation, supply chain). Every item carries the command that produced its evidence, so any row can be re-checked or falsified in one step; unverified claims are labelled DIAGNOSIS (unconfirmed) rather than asserted. It links the existing registers (PROOF-NEEDS, TEST-NEEDS, proof-debt, tech-debt) instead of duplicating them. The register's headline finding is that the cartridges/ retirement is one incomplete migration wearing ten disguises — two permanently-off workflows, scripts looping over nothing, count claims in fourteen documents, and 1,346 files of build residue. Also corrects PROOF-NEEDS.md, which claimed 'exactly 5' sanctioned axioms and PASS=105. There are 4 (charEqSym was discharged 2026-06-24; check-trusted-base.sh has said EXPECTED_AXIOMS=4 ever since, and docs/proof-debt.md agrees), and the gate now covers 1 package because the 104 cartridge ABIs moved to the registry. Two documents that described themselves as in sync disagreed with each other and with the code. Co-Authored-By: Claude Opus 5 --- DEBT.md | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ PROOF-NEEDS.md | 23 +++++--- 2 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 DEBT.md diff --git a/DEBT.md b/DEBT.md new file mode 100644 index 00000000..ed55c7a7 --- /dev/null +++ b/DEBT.md @@ -0,0 +1,154 @@ + + + +# Technical debt register + +One index of known debt in this repository, measured 2026-08-07 against +`78c4a05a`. Every item carries **the command that produced the evidence**, so +any entry can be re-checked or falsified in one step. Claims that are not +verified are labelled **DIAGNOSIS (unconfirmed)** rather than asserted. + +This file is an index, not a replacement. The pre-existing registers remain +authoritative in their own domains and are linked, not duplicated: +[`PROOF-NEEDS.md`](PROOF-NEEDS.md) · [`TEST-NEEDS.md`](TEST-NEEDS.md) · +[`docs/proof-debt.md`](docs/proof-debt.md) · +[`docs/tech-debt-2026-05-26.md`](docs/tech-debt-2026-05-26.md). + +Severity: **HIGH** — actively misleads, or a gate that cannot fail · +**MEDIUM** — wrong but self-evident on contact · **LOW** — cosmetic or +historical. + +--- + +## The single largest item + +**The `cartridges/` retirement (#300) is incomplete.** Removing 128 cartridges +took the manifests but left every consumer behind: two permanently-off +workflows, scripts whose loops match nothing, Justfile recipes, test scripts, +count claims in fourteen documents, and 1,346 files of build residue. Items +C-1…C-6, D-1…D-4, T-1 and X-1 below are all one migration, not ten problems. + +```sh +git grep -nF 'cartridges/' -- ':!docs' ':!*.md' ':!*.adoc' ':!tests/fixtures' | wc -l +``` + +--- + +## Licence — L + +| ID | Sev | Item | Evidence | +|----|-----|------|----------| +| L-1 | MEDIUM | `glama.json` is the only packaging manifest with **no `license` field at all**. Every sibling declares MPL-2.0 (`package.json`, `jsr.json`, `smithery.yaml`, `CITATION.cff`, `guix.scm`, `elixir/mix.exs`). | `grep -L '"license"' glama.json package.json jsr.json` | +| L-2 | LOW | `ai-plugin.json` declares licence only as a URL (`legal_info_url`), with no SPDX key — inconsistent with the rest of the estate. | `grep -n 'legal_info_url\|license' ai-plugin.json` | +| L-3 | LOW | Four tracked source files of 500+ carry no `SPDX-License-Identifier`: `.github/copilot/coding-agent.yml`, `.github/funding.yml`, `.machine_readable/scripts/forge/git-cleanup.sh`, `configs/config.ncl`. | `git ls-files \| xargs grep -L 'SPDX-License-Identifier' 2>/dev/null` | + +**Not debt, recorded as the positive control:** the dual-licence posture is +correct and documented — `NOTICE` explains MPL-2.0 (code) / CC-BY-SA-4.0 +(prose), `LICENSES/` holds both texts, and `.reuse/dep5` covers headerless +config. 335 MPL / 184 CC-BY-SA headers, zero third licence, zero unattributed +vendored trees. **The sibling registry has neither `NOTICE` nor `.reuse/` — +see its own `DEBT.md` L-1.** + +--- + +## Proof — P + +The proofs themselves are in good order: **4** `believe_me` sites, all inside +the sanctioned module, all `%unsafe`-tagged; zero `postulate`, `assert_total`, +`assert_smaller`, `idris_crash`, `sorry`, `%default partial`, `?hole` anywhere +in `src/abi/`. **The debt is in the gates and the prose, not the proofs.** + +```sh +grep -rn 'believe_me' src/abi --include='*.idr' | grep -v '|||' # 4 sites +grep -n 'EXPECTED_AXIOMS=' scripts/check-trusted-base.sh # 4 +``` + +| ID | Sev | Item | Evidence | +|----|-----|------|----------| +| P-1 | HIGH | **`proofs.yml` can report success with no prover having run.** The `changes` job sets `run=false` for any PR outside its path set, and both proof jobs are `if: needs.changes.outputs.run == 'true'`; a skipped job reports SUCCESS to a required check. The weekly `cron` at `proofs.yml` is the only backstop. This is a deliberate design (documented in the workflow header) — recorded here because the failure mode is invisible to a reviewer reading a green tick. | `grep -n "run=false\|needs.changes.outputs.run" .github/workflows/proofs.yml` | +| P-2 | MEDIUM | `scripts/check-trusted-base.sh` still greps `src/ cartridges/ verification/`; one of the three no longer exists, so the scan surface is a third smaller than it reads. The axiom count itself still works. | `grep -n 'cartridges/' scripts/check-trusted-base.sh` | +| P-3 | MEDIUM | `PROOF-NEEDS.md` cites `cartridges/fleet-mcp/abi/FleetMcp/SafeFleet.idr lines 14 & 34` — a proof obligation anchored to a file in the *other* repo, so the line numbers cannot be checked from here. | `grep -n 'SafeFleet' PROOF-NEEDS.md` | +| P-4 | LOW | **FIXED 2026-08-07, retained for provenance.** `PROOF-NEEDS.md` asserted `PASS=105` and "**exactly 5**" axioms; the enforcing script has said `EXPECTED_AXIOMS=4` since `charEqSym` was discharged, and the gate now covers 1 package. Two "in sync" documents disagreed with each other and with the code. | `git log -1 --format=%h -- PROOF-NEEDS.md` | + +**Cross-repo:** `boj-server-cartridges/scripts/check-trusted-base.sh` still +says *"boj-server sanctions EXACTLY 5 class-(J) axioms"*. Fixing it there +needs this file's correction to land first. + +--- + +## CI/CD — C + +| ID | Sev | Item | Evidence | +|----|-----|------|----------| +| C-1 | HIGH | **`abi-drift.yml` is permanently off** — `printf 'run=false'` unconditionally, so job `Emit manifest + verify FFI` never runs while still satisfying its required check by skipping. Its subject (per-cartridge iseriser drift) must be ported to the registry before the workflow *and its required context* are deleted. The port has not happened. | `grep -n "run=false" .github/workflows/abi-drift.yml` | +| C-2 | HIGH | **`lsp-dap-bsp.yml` is permanently off** — same mechanism, **four** dead jobs: ABI Specification Check, FFI Build & Test, Panel Manifest Validation, Cartridge Completeness Check. | `grep -n "run=false" .github/workflows/lsp-dap-bsp.yml` | +| C-3 | HIGH | **`.github/workflows/main-estate-audit.yml` is untracked**, has **no `permissions:` block** (the only workflow in the repo without one), and pins **27 actions to `@main` / `@v4`** rather than SHAs. It has therefore never run. Same file, same defects, in the sibling repo. | `git status --porcelain .github/workflows/` · `grep -c '@main' .github/workflows/main-estate-audit.yml` | +| C-4 | MEDIUM | Five required status-check contexts correspond to jobs that are green-by-skip (C-1, C-2). A reviewer cannot distinguish "passed" from "never ran". | `gh api repos/:owner/:repo/branches/main/protection` | +| C-5 | MEDIUM | `fuzz.yml` suppresses failure twice over: `\|\| true` **and** `continue-on-error: true`, with stderr sent to `/dev/null`. A crash is invisible rather than merely non-blocking. The bridge probes (including a `../../../etc/passwd` traversal case) assert nothing. | `grep -n 'continue-on-error\|\|\| true' .github/workflows/fuzz.yml` | +| C-6 | LOW | `pages.yml` and `pages-deploy.yml` both fire on push to main, publishing different content to two different hosts with no coordination. | `grep -l 'branches: \[main' .github/workflows/pages*.yml` | + +**FIXED 2026-08-07** (recorded so the pattern is searchable): two gates — +`tests/truthfulness_check.sh` and `scripts/typecheck-proofs.sh` — looped over +the deleted tree, matched zero files, and exited 0 reporting success. Both now +fail hard on an empty subject. *A gate that cannot fail is worse than no gate, +because it is credited as assurance.* + +--- + +## Code — D + +| ID | Sev | Item | Evidence | +|----|-----|------|----------| +| D-1 | MEDIUM | Justfile recipes still operate on the deleted tree; `CART_COUNT=$(ls -d cartridges/*-mcp \| wc -l)` now reports 0 as though that were a fact about the system. | `grep -n 'cartridges/' Justfile` | +| D-2 | MEDIUM | `scripts/refresh-bundled-cartridges.sh` exists solely to sync the retired tree (it `rm -rf`s inside it). `scripts/boj-selinux-contexts.sh` labels `${BOJ_ROOT}/cartridges/`. | `grep -ln 'cartridges/' scripts/*.sh` | +| D-3 | MEDIUM | `mcp-bridge/lib/generate-offline-menu.js` falls back to `../../cartridges` when `BOJ_CARTRIDGES_PATH` is unset — so it regenerates an **empty menu** silently instead of failing. | `grep -n 'cartridges' mcp-bridge/lib/generate-offline-menu.js` | +| D-4 | MEDIUM | Test scripts still traverse the tree: `tests/aspect_tests.sh`, `tests/integration.sh`, `tests/federation_multinode.sh`. | `grep -ln 'cartridges/' tests/*.sh` | +| D-5 | MEDIUM | **Two git worktrees are committed as gitlinks (mode `160000`) with no `.gitmodules`.** A fresh clone gets two empty directories, and both show as permanently modified because neither matches its recorded commit. | `git ls-files -s .claude/worktrees/` · `ls .gitmodules` | +| D-6 | LOW | Machine-specific absolute paths baked into tracked files: `generated/alloyiser/run-analysis.sh` (`/var/mnt/eclipse/...`), `reports/maintenance/latest.json`. Unrunnable off the original machine. | `git grep -n '/var/mnt/eclipse'` | +| D-7 | LOW | TODO/FIXME/XXX/HACK density is genuinely near zero — all 63 matches are policy/tooling references to marker *scanning*, not markers. Recorded as a positive control. | `git grep -nE '\b(TODO\|FIXME\|XXX\|HACK)\b' \| wc -l` | + +--- + +## Test — T + +| ID | Sev | Item | Evidence | +|----|-----|------|----------| +| T-1 | MEDIUM | `tests/security_test.js` (313 lines) and `tests/federation_multinode.sh` (170 lines) are referenced by **no workflow and no Justfile recipe**. They exist and run nowhere. | `grep -rn 'security_test\|federation_multinode' .github/ Justfile` | +| T-2 | MEDIUM | A real `zig build test` invocation inside `lsp-dap-bsp.yml` is permanently unreachable behind C-2's hardcoded `run=false`. | `grep -n 'zig build test' .github/workflows/lsp-dap-bsp.yml` | +| T-3 | LOW | `TEST-NEEDS.md` documents that E2E tests skip cleanly when Deno is absent — a documented silent coverage reduction. | `grep -n 'Deno-gated' TEST-NEEDS.md` | + +--- + +## Documentation — X + +Full findings live in the docs refresh; only structural items are indexed here. + +| ID | Sev | Item | Evidence | +|----|-----|------|----------| +| X-1 | HIGH | **Cartridge counts disagree across the estate.** This repo asserts 125 in ~14 places; the registry's README asserts 139; disk says **142**. `README.md`'s own "Number transparency" clause makes this self-refuting. | `find ../boj-server-cartridges/cartridges -name cartridge.json \| wc -l` | +| X-2 | MEDIUM | `docs/AI-CONVENTIONS.adoc` opens agent onboarding by directing every AI agent to read three files that **do not exist** (`.machine_readable/STATE.a2ml`, `anchors/ANCHOR.a2ml`, `AGENTIC.a2ml`). | `ls .machine_readable/STATE.a2ml .machine_readable/AGENTIC.a2ml` | +| X-3 | MEDIUM | `docs/zig-ffi-verification.adoc` documents a Mutex migration **backwards** — it recommends `std.atomic.Mutex`, the symbol 0.16 removed, and names nine modules that use no such pattern. | `grep -n 'atomic.Mutex' docs/zig-ffi-verification.adoc` | +| X-4 | MEDIUM | `docs/wikis/` (7 `.adoc`) and the live GitHub wiki (6 `.md`) are **different page sets with no sync mechanism**, while `docs/wikis/README.adoc` claims to be "the sources for GitHub's wiki tab". | `git clone https://github.com/hyperpolymath/boj-server.wiki.git` | +| X-5 | MEDIUM | `CHANGELOG.md` has no `[0.5.0]` section though `package.json` says 0.5.0, and its `[Unreleased]` heading sits *below* the last release. 151 commits since the last dated entry, including two CWE-tagged security fixes. | `git log --oneline --since=2026-05-20 \| wc -l` | +| X-6 | LOW | `jsr.json` still says `0.4.7` while `package.json` says `0.5.0`. | `grep -h '"version"' package.json jsr.json` | + +--- + +## Supply chain — S + +| ID | Sev | Item | Evidence | +|----|-----|------|----------| +| S-1 | HIGH | See **C-3** — 27 mutable `@main` action pins in an untracked, permission-less workflow is the repo's largest supply-chain exposure. | `grep -c '@main' .github/workflows/main-estate-audit.yml` | +| S-2 | MEDIUM | 1,346 files of build residue survive under `cartridges/` on disk (226 `.so`), untracked and gitignored so `git status` stays silent about them. Confirmed: **no `.so` post-dates the retirement**, so nothing has been rebuilt there since — it is stale, not live. **DIAGNOSIS (unconfirmed):** a `local-coord-mcp.service` user unit was historically built from this tree and may still point at it; deletion is the owner's call. | `find cartridges -type f \| wc -l` · `find cartridges -name '*.so' -newermt 2026-08-03 \| wc -l` → 0 | +| S-3 | LOW | Release provenance is SLSA3 via `slsa-github-generator`, SHA-pinned. Recorded as a positive control. | `grep -n 'slsa' .github/workflows/release.yml` | + +--- + +## How to use this file + +Add an item when you find debt you are not fixing in the same change. Give it +the next ID in its domain, a severity, and — non-negotiably — **a command that +reproduces the evidence**. An item without a reproducible check is an opinion, +and opinions rot silently. Remove an item only when its command proves it gone; +where the fix is interesting, keep the row and mark it FIXED with the date, as +P-4 and the C-section note do. diff --git a/PROOF-NEEDS.md b/PROOF-NEEDS.md index c75c4b53..015e8d14 100644 --- a/PROOF-NEEDS.md +++ b/PROOF-NEEDS.md @@ -39,15 +39,22 @@ desk-read of the prior entry. Three checks, all green: - **Core ABI:** `cd src/abi && idris2 --typecheck boj.ipkg` → 17/17 modules clean, exit 0 (~6.5 s). -- **Full proof gate:** `bash scripts/typecheck-proofs.sh` → **PASS=105 - FAIL=0** (core package + all 104 cartridge ABIs) under the pinned - toolchain (~80 s). This is broader than the 2026-06-03 entry, which - exercised only the core package. +- **Full proof gate:** `bash scripts/typecheck-proofs.sh` → **PASS=1 + FAIL=0** (the core package). Historical note: this read PASS=105 + (core + 104 cartridge ABIs) until the bundled `cartridges/` tree was + retired in #300. The 104 cartridge ABIs are now type-checked by + `hyperpolymath/boj-server-cartridges` in its own proofs gate; this + repo no longer has them to check. The script grew a vacuous-pass + guard at the same time, so PASS=0 is now a hard failure rather than + a green run over nothing. - **Trusted base:** `bash scripts/check-trusted-base.sh` → PASS, - **exactly 5** sanctioned class-(J) axioms in `SafetyLemmas.idr`, zero - undocumented unsound constructs. Independently corroborated by a - `panic-attack assail` scan (MPL-2.0, built from source), which flags - the same 5 `believe_me` as `ProofDrift` and nothing else proof-shaped. + **exactly 4** sanctioned class-(J) axioms in `SafetyLemmas.idr`, zero + undocumented unsound constructs. (`charEqSym` was discharged + 2026-06-24, taking the count 5 → 4; `EXPECTED_AXIOMS=4` in the + enforcing script is the source of truth, and `docs/proof-debt.md` + agrees.) Independently corroborated by a `panic-attack assail` scan + (MPL-2.0, built from source), which flags the same `believe_me` sites + as `ProofDrift` and nothing else proof-shaped. The axiom budget and theorem statements are unchanged from the 2026-06-03 entry; this checkpoint records that the **full cartridge From d76d25f9f920edb14dba77c7de57f17109c2ee98 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 7 Aug 2026 12:58:21 +0100 Subject: [PATCH 3/7] docs(debt): record the container build failure and three more empty-set loops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found while finishing the retirement tails (#308): - D-8 (HIGH): container/Containerfile.fly cannot build. It COPYs cartridges/ from the host build context and never runs fetch-cartridges.sh, and COPY on a missing source is a hard failure. The main Containerfile is NOT affected — it fetches into the builder stage first — so this is one file, not both. - D-9 (MEDIUM): stapeln.toml, coord-tui/install.sh, guix.scm and an Elixir test still traverse the deleted tree. stapeln.toml is the same empty-loop class plus `|| true`, so it can never fail. - D-7 (LOW): dead entries left in .hypatia-ignore and .gitleaksignore make the allowlists look larger than the real exposure. Co-Authored-By: Claude Opus 5 --- DEBT.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/DEBT.md b/DEBT.md index ed55c7a7..af7e1dbc 100644 --- a/DEBT.md +++ b/DEBT.md @@ -104,8 +104,11 @@ because it is credited as assurance.* | D-3 | MEDIUM | `mcp-bridge/lib/generate-offline-menu.js` falls back to `../../cartridges` when `BOJ_CARTRIDGES_PATH` is unset — so it regenerates an **empty menu** silently instead of failing. | `grep -n 'cartridges' mcp-bridge/lib/generate-offline-menu.js` | | D-4 | MEDIUM | Test scripts still traverse the tree: `tests/aspect_tests.sh`, `tests/integration.sh`, `tests/federation_multinode.sh`. | `grep -ln 'cartridges/' tests/*.sh` | | D-5 | MEDIUM | **Two git worktrees are committed as gitlinks (mode `160000`) with no `.gitmodules`.** A fresh clone gets two empty directories, and both show as permanently modified because neither matches its recorded commit. | `git ls-files -s .claude/worktrees/` · `ls .gitmodules` | +| D-8 | HIGH | **`container/Containerfile.fly:80` cannot build.** It does `COPY cartridges/ /tmp/carts-meta/` from the host build context and never runs `fetch-cartridges.sh`; `COPY` on a missing source is a hard failure. (The main `container/Containerfile` is **fine** — it fetches into the builder stage first, so its `COPY --from=zig-builder` is populated. One file, not both.) | `grep -n 'COPY cartridges/' container/Containerfile.fly` · `grep -c fetch-cartridges container/Containerfile.fly` → 0 | +| D-9 | MEDIUM | More empty-set loops outside the fixed set: `stapeln.toml:44` iterates `cartridges/*/ffi` **and** suffixes `\|\| true`, so it can never fail; `coord-tui/install.sh:28` builds from a path that no longer exists; `guix.scm:34` chdirs into it; `elixir/test/js_worker_pool_test.exs:6` resolves a missing module but passes today by short-circuiting when Deno is absent. | `git grep -n 'cartridges/\*' stapeln.toml guix.scm coord-tui/install.sh` | +| D-7 | LOW | Dead exemption entries left behind by the retirement: 9 in `.hypatia-ignore`, 5 in `.gitleaksignore`, plus `.dockerignore` headers still claiming "Stage 3 needs `cartridges/`". Harmless, but they make the allowlists look larger than the real exposure. | `grep -c cartridges .hypatia-ignore .gitleaksignore` | | D-6 | LOW | Machine-specific absolute paths baked into tracked files: `generated/alloyiser/run-analysis.sh` (`/var/mnt/eclipse/...`), `reports/maintenance/latest.json`. Unrunnable off the original machine. | `git grep -n '/var/mnt/eclipse'` | -| D-7 | LOW | TODO/FIXME/XXX/HACK density is genuinely near zero — all 63 matches are policy/tooling references to marker *scanning*, not markers. Recorded as a positive control. | `git grep -nE '\b(TODO\|FIXME\|XXX\|HACK)\b' \| wc -l` | +| D-10 | LOW | TODO/FIXME/XXX/HACK density is genuinely near zero — all 63 matches are policy/tooling references to marker *scanning*, not markers. Recorded as a positive control. | `git grep -nE '\b(TODO\|FIXME\|XXX\|HACK)\b' \| wc -l` | --- From 0b83a2b98e7eba6a8b0a99b6a505830cc67e98f5 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 7 Aug 2026 13:11:21 +0100 Subject: [PATCH 4/7] docs(debt): main-estate-audit.yml points at a repository that does not exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sharpens C-3. The finding was 'unpinned actions'; the truth is worse — all 26 gates are hyperpolymath/cicd-suite/actions/*@main and hyperpolymath/cicd-suite returns 404, anonymously and to a token that can see all 35 private repos in the account. The workflow has never run in either repo. This matters for the remediation: it cannot be SHA-pinned, because there is nothing to pin to. Committing it as-is would add a workflow that fails on every run in both repos. It needs an owner decision — delete, or create cicd-suite first — not a mechanical pinning sweep. Co-Authored-By: Claude Opus 5 --- DEBT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEBT.md b/DEBT.md index af7e1dbc..fca61582 100644 --- a/DEBT.md +++ b/DEBT.md @@ -82,7 +82,7 @@ needs this file's correction to land first. |----|-----|------|----------| | C-1 | HIGH | **`abi-drift.yml` is permanently off** — `printf 'run=false'` unconditionally, so job `Emit manifest + verify FFI` never runs while still satisfying its required check by skipping. Its subject (per-cartridge iseriser drift) must be ported to the registry before the workflow *and its required context* are deleted. The port has not happened. | `grep -n "run=false" .github/workflows/abi-drift.yml` | | C-2 | HIGH | **`lsp-dap-bsp.yml` is permanently off** — same mechanism, **four** dead jobs: ABI Specification Check, FFI Build & Test, Panel Manifest Validation, Cartridge Completeness Check. | `grep -n "run=false" .github/workflows/lsp-dap-bsp.yml` | -| C-3 | HIGH | **`.github/workflows/main-estate-audit.yml` is untracked**, has **no `permissions:` block** (the only workflow in the repo without one), and pins **27 actions to `@main` / `@v4`** rather than SHAs. It has therefore never run. Same file, same defects, in the sibling repo. | `git status --porcelain .github/workflows/` · `grep -c '@main' .github/workflows/main-estate-audit.yml` | +| C-3 | HIGH | **`.github/workflows/main-estate-audit.yml` references a repository that does not exist.** All 26 of its gates are `hyperpolymath/cicd-suite/actions/*@main`, and **`hyperpolymath/cicd-suite` returns 404** — anonymously, and to a token that can see all 35 private repos in the account. It is also untracked, has no `permissions:` block, and pins `actions/checkout@v4` by tag. It has never run in either repo. **It cannot be SHA-pinned: there is nothing to pin to.** Decision needed — delete it, or create `cicd-suite` first. Identical file, identical defect, in the sibling repo. | `gh api repos/hyperpolymath/cicd-suite` → 404 · `gh repo list hyperpolymath --limit 500 \| grep cicd-suite` → absent | | C-4 | MEDIUM | Five required status-check contexts correspond to jobs that are green-by-skip (C-1, C-2). A reviewer cannot distinguish "passed" from "never ran". | `gh api repos/:owner/:repo/branches/main/protection` | | C-5 | MEDIUM | `fuzz.yml` suppresses failure twice over: `\|\| true` **and** `continue-on-error: true`, with stderr sent to `/dev/null`. A crash is invisible rather than merely non-blocking. The bridge probes (including a `../../../etc/passwd` traversal case) assert nothing. | `grep -n 'continue-on-error\|\|\| true' .github/workflows/fuzz.yml` | | C-6 | LOW | `pages.yml` and `pages-deploy.yml` both fire on push to main, publishing different content to two different hosts with no coordination. | `grep -l 'branches: \[main' .github/workflows/pages*.yml` | From da9ee34ae96a7bee20d57153f2e320aec795bc28 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 7 Aug 2026 13:18:40 +0100 Subject: [PATCH 5/7] =?UTF-8?q?docs(debt):=20correct=20C-3=20=E2=80=94=20c?= =?UTF-8?q?icd-suite=20is=20unpublished,=20not=20fictional?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit My previous revision said the audit workflow points at a repository that does not exist. True of GitHub, but misleading about the cause and the cure. A local checkout at developer/hyper-repos/cicd-suite holds all 26 referenced actions, each with an action.yml, matching the workflow's references exactly — but it has 0 commits and no remote. The workflow is correct; the repository was simply never published. That makes the item actionable rather than mysterious, and fixes the remediation order: publish cicd-suite, then SHA-pin against a real commit, then commit the workflow. Pinning first is impossible; committing first adds a workflow that fails on every run. Co-Authored-By: Claude Opus 5 --- DEBT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEBT.md b/DEBT.md index fca61582..c8e9c7ce 100644 --- a/DEBT.md +++ b/DEBT.md @@ -82,7 +82,7 @@ needs this file's correction to land first. |----|-----|------|----------| | C-1 | HIGH | **`abi-drift.yml` is permanently off** — `printf 'run=false'` unconditionally, so job `Emit manifest + verify FFI` never runs while still satisfying its required check by skipping. Its subject (per-cartridge iseriser drift) must be ported to the registry before the workflow *and its required context* are deleted. The port has not happened. | `grep -n "run=false" .github/workflows/abi-drift.yml` | | C-2 | HIGH | **`lsp-dap-bsp.yml` is permanently off** — same mechanism, **four** dead jobs: ABI Specification Check, FFI Build & Test, Panel Manifest Validation, Cartridge Completeness Check. | `grep -n "run=false" .github/workflows/lsp-dap-bsp.yml` | -| C-3 | HIGH | **`.github/workflows/main-estate-audit.yml` references a repository that does not exist.** All 26 of its gates are `hyperpolymath/cicd-suite/actions/*@main`, and **`hyperpolymath/cicd-suite` returns 404** — anonymously, and to a token that can see all 35 private repos in the account. It is also untracked, has no `permissions:` block, and pins `actions/checkout@v4` by tag. It has never run in either repo. **It cannot be SHA-pinned: there is nothing to pin to.** Decision needed — delete it, or create `cicd-suite` first. Identical file, identical defect, in the sibling repo. | `gh api repos/hyperpolymath/cicd-suite` → 404 · `gh repo list hyperpolymath --limit 500 \| grep cicd-suite` → absent | +| C-3 | HIGH | **`.github/workflows/main-estate-audit.yml` references a repository that was never published.** Its 26 gates are `hyperpolymath/cicd-suite/actions/*@main`; `hyperpolymath/cicd-suite` **404s on GitHub**. The actions are not fictional — a local checkout at `developer/hyper-repos/cicd-suite` holds **all 26, each with an `action.yml`, matching the references exactly** — but it has **0 commits and no remote**. So the workflow is *correct* and simply unrunnable. It is also untracked here, has no `permissions:` block, and pins `actions/checkout` by tag. **Remediation order: publish `cicd-suite` → SHA-pin against a real commit → commit the workflow in both repos.** Pinning first is impossible; committing first adds a workflow that fails every run. | `gh api repos/hyperpolymath/cicd-suite` → 404 · `ls ../cicd-suite/actions \| wc -l` → 26 · `git -C ../cicd-suite log --oneline \| wc -l` → 0 | | C-4 | MEDIUM | Five required status-check contexts correspond to jobs that are green-by-skip (C-1, C-2). A reviewer cannot distinguish "passed" from "never ran". | `gh api repos/:owner/:repo/branches/main/protection` | | C-5 | MEDIUM | `fuzz.yml` suppresses failure twice over: `\|\| true` **and** `continue-on-error: true`, with stderr sent to `/dev/null`. A crash is invisible rather than merely non-blocking. The bridge probes (including a `../../../etc/passwd` traversal case) assert nothing. | `grep -n 'continue-on-error\|\|\| true' .github/workflows/fuzz.yml` | | C-6 | LOW | `pages.yml` and `pages-deploy.yml` both fire on push to main, publishing different content to two different hosts with no coordination. | `grep -l 'branches: \[main' .github/workflows/pages*.yml` | From b0dbc229f17aab0ffb3a6917bba22bdda2f0cc0b Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:22:01 +0100 Subject: [PATCH 6/7] docs(debt): cicd-suite is published; the gates are still not safe to arm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C-3: the 404 is fixed — hyperpolymath/cicd-suite is published at 11b5ab51 and all 26 referenced actions resolve. The workflow stays untracked deliberately, because running its hard gates against this repo today fails both: required-files-check on 3 missing files, and code-hygiene-check on 112 files — including the four sanctioned, documented, CI-counted believe_me axioms that ARE this repo's declared trusted base. Satisfying required-files-check means adding presence-only filler, which is exactly how the ARCHITECTURE.md / MAINTAINERS boilerplate on fix/zig-ptr-cast-shim came to exist. C-7 (new): 13 of the 26 actions cannot fail at all, and the suite contradicts itself — one gate hard-fails you for lacking GOVERNANCE.md while another warns it should be .adoc. rollout_estate.sh has already placed the consuming workflow in 199 repos, untracked in 198. Co-Authored-By: Claude Opus 5 --- DEBT.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DEBT.md b/DEBT.md index c8e9c7ce..2933ac18 100644 --- a/DEBT.md +++ b/DEBT.md @@ -82,7 +82,8 @@ needs this file's correction to land first. |----|-----|------|----------| | C-1 | HIGH | **`abi-drift.yml` is permanently off** — `printf 'run=false'` unconditionally, so job `Emit manifest + verify FFI` never runs while still satisfying its required check by skipping. Its subject (per-cartridge iseriser drift) must be ported to the registry before the workflow *and its required context* are deleted. The port has not happened. | `grep -n "run=false" .github/workflows/abi-drift.yml` | | C-2 | HIGH | **`lsp-dap-bsp.yml` is permanently off** — same mechanism, **four** dead jobs: ABI Specification Check, FFI Build & Test, Panel Manifest Validation, Cartridge Completeness Check. | `grep -n "run=false" .github/workflows/lsp-dap-bsp.yml` | -| C-3 | HIGH | **`.github/workflows/main-estate-audit.yml` references a repository that was never published.** Its 26 gates are `hyperpolymath/cicd-suite/actions/*@main`; `hyperpolymath/cicd-suite` **404s on GitHub**. The actions are not fictional — a local checkout at `developer/hyper-repos/cicd-suite` holds **all 26, each with an `action.yml`, matching the references exactly** — but it has **0 commits and no remote**. So the workflow is *correct* and simply unrunnable. It is also untracked here, has no `permissions:` block, and pins `actions/checkout` by tag. **Remediation order: publish `cicd-suite` → SHA-pin against a real commit → commit the workflow in both repos.** Pinning first is impossible; committing first adds a workflow that fails every run. | `gh api repos/hyperpolymath/cicd-suite` → 404 · `ls ../cicd-suite/actions \| wc -l` → 26 · `git -C ../cicd-suite log --oneline \| wc -l` → 0 | +| C-3 | HIGH | **`main-estate-audit.yml` is still untracked here, deliberately — arming it today would fail `main` immediately.** The referenced suite is now published (`hyperpolymath/cicd-suite`, `11b5ab51`, all 26 actions resolve), so the 404 is fixed. But running its two relevant hard gates against this repo: `required-files-check` fails on 3 missing files (`CODEOWNERS`, `ARCHITECTURE.md`, `MAINTAINERS.adoc`), and `code-hygiene-check` matches **112 files** — including this repo's four *sanctioned, documented, CI-counted* `believe_me` axioms, which are its declared trusted base, not debt. Satisfying `required-files-check` means adding presence-only filler, which is how the template boilerplate on `fix/zig-ptr-cast-shim` was generated. **Fix the gates (see cicd-suite's README), then pin to `11b5ab51` and commit.** | `for f in CODEOWNERS ARCHITECTURE.md MAINTAINERS.adoc; do [ -f $f ] \|\| echo MISSING $f; done` · `git grep -Eic 'TODO\|FIXME\|STUB\|sorry\|believe_me\|admit' \| wc -l` → 112 | +| C-7 | HIGH | **13 of `cicd-suite`'s 26 actions cannot fail** — they emit `::warning::` and exit successfully while being named "Gate". The suite also contradicts itself: `required-files-check` hard-fails a repo lacking `GOVERNANCE.md`/`ARCHITECTURE.md`, while `formatting-check` warns those files should be `.adoc`. Estate-wide: `rollout_estate.sh` has copied the consuming workflow into **199 repos**, untracked in **198**. | `for a in ../cicd-suite/actions/*/; do grep -q 'exit 1' $a/action.yml \|\| echo $a; done \| wc -l` → 13 | | C-4 | MEDIUM | Five required status-check contexts correspond to jobs that are green-by-skip (C-1, C-2). A reviewer cannot distinguish "passed" from "never ran". | `gh api repos/:owner/:repo/branches/main/protection` | | C-5 | MEDIUM | `fuzz.yml` suppresses failure twice over: `\|\| true` **and** `continue-on-error: true`, with stderr sent to `/dev/null`. A crash is invisible rather than merely non-blocking. The bridge probes (including a `../../../etc/passwd` traversal case) assert nothing. | `grep -n 'continue-on-error\|\|\| true' .github/workflows/fuzz.yml` | | C-6 | LOW | `pages.yml` and `pages-deploy.yml` both fire on push to main, publishing different content to two different hosts with no coordination. | `grep -l 'branches: \[main' .github/workflows/pages*.yml` | From c069c2815718f66dc0274b536cf4504ba2f859ca Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:39:25 +0100 Subject: [PATCH 7/7] docs(debt): two of the three cicd-suite gate defects are fixed cicd-suite#1 repairs code-hygiene-check (whole-tree case-insensitive grep: 112 matching files here, now 2 true positives) and required-files-check (presence-only checking that rewarded template filler), and ends the contradiction where one gate hard-failed a repo for lacking GOVERNANCE.md while another warned it should be .adoc. C-7 drops HIGH to MEDIUM: what remains is the advisory/enforcing split, 13 of 26 actions that cannot fail. Co-Authored-By: Claude Opus 5 --- DEBT.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DEBT.md b/DEBT.md index 2933ac18..9927a221 100644 --- a/DEBT.md +++ b/DEBT.md @@ -82,8 +82,8 @@ needs this file's correction to land first. |----|-----|------|----------| | C-1 | HIGH | **`abi-drift.yml` is permanently off** — `printf 'run=false'` unconditionally, so job `Emit manifest + verify FFI` never runs while still satisfying its required check by skipping. Its subject (per-cartridge iseriser drift) must be ported to the registry before the workflow *and its required context* are deleted. The port has not happened. | `grep -n "run=false" .github/workflows/abi-drift.yml` | | C-2 | HIGH | **`lsp-dap-bsp.yml` is permanently off** — same mechanism, **four** dead jobs: ABI Specification Check, FFI Build & Test, Panel Manifest Validation, Cartridge Completeness Check. | `grep -n "run=false" .github/workflows/lsp-dap-bsp.yml` | -| C-3 | HIGH | **`main-estate-audit.yml` is still untracked here, deliberately — arming it today would fail `main` immediately.** The referenced suite is now published (`hyperpolymath/cicd-suite`, `11b5ab51`, all 26 actions resolve), so the 404 is fixed. But running its two relevant hard gates against this repo: `required-files-check` fails on 3 missing files (`CODEOWNERS`, `ARCHITECTURE.md`, `MAINTAINERS.adoc`), and `code-hygiene-check` matches **112 files** — including this repo's four *sanctioned, documented, CI-counted* `believe_me` axioms, which are its declared trusted base, not debt. Satisfying `required-files-check` means adding presence-only filler, which is how the template boilerplate on `fix/zig-ptr-cast-shim` was generated. **Fix the gates (see cicd-suite's README), then pin to `11b5ab51` and commit.** | `for f in CODEOWNERS ARCHITECTURE.md MAINTAINERS.adoc; do [ -f $f ] \|\| echo MISSING $f; done` · `git grep -Eic 'TODO\|FIXME\|STUB\|sorry\|believe_me\|admit' \| wc -l` → 112 | -| C-7 | HIGH | **13 of `cicd-suite`'s 26 actions cannot fail** — they emit `::warning::` and exit successfully while being named "Gate". The suite also contradicts itself: `required-files-check` hard-fails a repo lacking `GOVERNANCE.md`/`ARCHITECTURE.md`, while `formatting-check` warns those files should be `.adoc`. Estate-wide: `rollout_estate.sh` has copied the consuming workflow into **199 repos**, untracked in **198**. | `for a in ../cicd-suite/actions/*/; do grep -q 'exit 1' $a/action.yml \|\| echo $a; done \| wc -l` → 13 | +| C-3 | HIGH | **`main-estate-audit.yml` is still untracked here, deliberately — arming it today would fail `main` immediately.** The referenced suite is now published (`hyperpolymath/cicd-suite`, `11b5ab51`, all 26 actions resolve), so the 404 is fixed. But running its two relevant hard gates against this repo: `required-files-check` fails on 3 missing files (`CODEOWNERS`, `ARCHITECTURE.md`, `MAINTAINERS.adoc`), and `code-hygiene-check` matched **112 files** before cicd-suite#1; **2** after — including this repo's four *sanctioned, documented, CI-counted* `believe_me` axioms, which are its declared trusted base, not debt. Satisfying `required-files-check` means adding presence-only filler, which is how the template boilerplate on `fix/zig-ptr-cast-shim` was generated. **Fix the gates (see cicd-suite's README), then pin to `11b5ab51` and commit.** | `for f in CODEOWNERS ARCHITECTURE.md MAINTAINERS.adoc; do [ -f $f ] \|\| echo MISSING $f; done` · `git grep -Eic 'TODO\|FIXME\|STUB\|sorry\|believe_me\|admit' \| wc -l` → 112 | +| C-7 | MEDIUM | **13 of `cicd-suite`'s 26 actions cannot fail** — they emit `::warning::` and exit successfully while being named "Gate". *(Was HIGH and three-part; two of the three are fixed — cicd-suite#1 repaired `code-hygiene-check`'s whole-tree grep and `required-files-check`'s presence-only filler, and ended their mutual contradiction. The advisory/enforcing split is what remains.)* Estate-wide: the consuming workflow sits in **199 repos**, untracked in **198**. | `for a in ../cicd-suite/actions/*/; do grep -q 'exit 1' $a/action.yml \|\| echo $a; done \| wc -l` → 13 | | C-4 | MEDIUM | Five required status-check contexts correspond to jobs that are green-by-skip (C-1, C-2). A reviewer cannot distinguish "passed" from "never ran". | `gh api repos/:owner/:repo/branches/main/protection` | | C-5 | MEDIUM | `fuzz.yml` suppresses failure twice over: `\|\| true` **and** `continue-on-error: true`, with stderr sent to `/dev/null`. A crash is invisible rather than merely non-blocking. The bridge probes (including a `../../../etc/passwd` traversal case) assert nothing. | `grep -n 'continue-on-error\|\|\| true' .github/workflows/fuzz.yml` | | C-6 | LOW | `pages.yml` and `pages-deploy.yml` both fire on push to main, publishing different content to two different hosts with no coordination. | `grep -l 'branches: \[main' .github/workflows/pages*.yml` |