Problem
/v1/public/decision-ledger/verify — the endpoint #8837 shipped as the public, third-party
chain-verification surface for the decision ledger — requires an API token in production. It is not
publicly verifiable by anyone.
requiresApiToken (src/api/routes.ts ~6632-6660) exempts public routes by exact match or regex and
falls through to return path.startsWith("/v1/"). Its sibling public routes are all named explicitly:
if (path === "/v1/public/subnet-interface") return false;
if (path === "/v1/public/stats") return false;
if (/^\/v1\/public\/repos\/[^/]+\/[^/]+\/quality$/.test(path)) return false;
/v1/public/decision-ledger/verify is not in that list, so it falls through to the startsWith("/v1/")
default and is gated. The route's own comment (src/api/routes.ts ~1266) asserts the opposite:
public chain-verification for the decision ledger. Hashes/ids only — no record contents — so it is
safe unauthenticated; any observer can confirm no decision was deleted, reordered, or rewritten.
Verified live against api.loopover.ai (2026-07-26):
| path |
status |
/v1/public/subnet-interface |
200 |
/v1/public/stats |
200 |
/v1/public/decision-ledger/verify |
401 |
There is a second, independent reason the guarantee is inoperative: on the self-hosted ORB — the
instance holding the real contributor decisions (184 chain rows on edge-nl-01) — the Cloudflare tunnel
publishes exactly one path, ^/loopover/shot.*$. Even with the auth bug fixed, that ledger is
unreachable from the internet.
Why it matters
This is the non-repudiation surface behind a publicly advertised statistical guarantee, and the exact
artifact an external party (a subnet, a contributor disputing an auto-close, a hosted tenant) would be
pointed at to check that ORB's history has not been rewritten. Today that check cannot be performed by
anyone outside the deployment. The trust claim is documented, implemented, tested for chain logic — and
inert at the edge.
No test asserts the route's reachability or auth posture (grep -rn "decision-ledger" test/ → no hits),
which is why this survived: the chain math is well covered, the exposure never was.
Requirements
- Add
/v1/public/decision-ledger/verify to the requiresApiToken exemption list beside its siblings.
- Decide and record the exposure posture for the self-hosted instance's ledger — either publish the
verify path through the tunnel, or mirror the chain tip/rows to the cloud instance that is reachable.
A ledger nobody can read is not a public guarantee; whichever way this resolves, the public docs must
match it.
- Add a route-level test that asserts the endpoint answers without credentials, and a companion test
for each currently-exempt /v1/public/* route so the next public route added cannot regress the same
way. A table-driven test over the exemption list is the shape that would have caught this.
- Audit the remaining
/v1/public/* routes for the same mismatch between comment and exemption list.
Test Coverage Requirements
99%+ patch coverage, branch-counted; both arms of the auth branch covered (token present / absent) for
the newly exempted path.
Links & Resources
Boundaries
Auth-exemption + exposure decision + tests only. No change to the chain algorithm or the record schema —
verify's missing record/digest reconciliation is #9078's scope, not this issue's.
maintainer-only — public trust-surface and edge-exposure authority.
Problem
/v1/public/decision-ledger/verify— the endpoint #8837 shipped as the public, third-partychain-verification surface for the decision ledger — requires an API token in production. It is not
publicly verifiable by anyone.
requiresApiToken(src/api/routes.ts~6632-6660) exempts public routes by exact match or regex andfalls through to
return path.startsWith("/v1/"). Its sibling public routes are all named explicitly:/v1/public/decision-ledger/verifyis not in that list, so it falls through to thestartsWith("/v1/")default and is gated. The route's own comment (
src/api/routes.ts~1266) asserts the opposite:Verified live against
api.loopover.ai(2026-07-26):/v1/public/subnet-interface/v1/public/stats/v1/public/decision-ledger/verifyThere is a second, independent reason the guarantee is inoperative: on the self-hosted ORB — the
instance holding the real contributor decisions (184 chain rows on
edge-nl-01) — the Cloudflare tunnelpublishes exactly one path,
^/loopover/shot.*$. Even with the auth bug fixed, that ledger isunreachable from the internet.
Why it matters
This is the non-repudiation surface behind a publicly advertised statistical guarantee, and the exact
artifact an external party (a subnet, a contributor disputing an auto-close, a hosted tenant) would be
pointed at to check that ORB's history has not been rewritten. Today that check cannot be performed by
anyone outside the deployment. The trust claim is documented, implemented, tested for chain logic — and
inert at the edge.
No test asserts the route's reachability or auth posture (
grep -rn "decision-ledger" test/→ no hits),which is why this survived: the chain math is well covered, the exposure never was.
Requirements
/v1/public/decision-ledger/verifyto therequiresApiTokenexemption list beside its siblings.verify path through the tunnel, or mirror the chain tip/rows to the cloud instance that is reachable.
A ledger nobody can read is not a public guarantee; whichever way this resolves, the public docs must
match it.
for each currently-exempt
/v1/public/*route so the next public route added cannot regress the sameway. A table-driven test over the exemption list is the shape that would have caught this.
/v1/public/*routes for the same mismatch between comment and exemption list.Test Coverage Requirements
99%+ patch coverage, branch-counted; both arms of the auth branch covered (token present / absent) for
the newly exempted path.
Links & Resources
verifydoes not check once you can reach it — the two compose: an unreachable endpointrunning an incomplete check)
src/api/routes.ts~1266 (route + comment), ~6632 (requiresApiToken)Boundaries
Auth-exemption + exposure decision + tests only. No change to the chain algorithm or the record schema —
verify's missing record/digest reconciliation is #9078's scope, not this issue's.maintainer-only — public trust-surface and edge-exposure authority.