Skip to content

Gate the reverse lot index exactly as /traceforward is gated - #19

Open
sumerjohal wants to merge 1 commit into
mainfrom
fix/reverse-index-gated
Open

sumerjohal wants to merge 1 commit into
mainfrom
fix/reverse-index-gated

Conversation

@sumerjohal

Copy link
Copy Markdown
Contributor

What

GET /list-artifact/reverse/{geoid} answered "which lots is this field in" for any hub login: no grant for the seed, no authority credential, no MEAL entry. It is the first hop of the question POST /traceforward answers, and /traceforward requires a verified grant for the seed or an authority credential. Measured on the live node, the open door returned five of the six lots the gated one does (review ledger AG-015).

A second door to a gated answer has to carry the same gate.

Change

  • get_list_artifact_reverse calls authorize_artifact with the seed (same call as /traceforward), requires ?scope= when an authority credential is presented, and writes the MEAL entry on the authority path before returning. A login alone gets 403; a grant for a different field gets 403.
  • MCP tool get_list_artifact_reverse takes grant_token, authority_token, scope; docs/MCP_SURFACE.md regenerated with the gating note (it was blank where the next row said "Gated twice").
  • README endpoint table corrected: it described a gate the code did not have. /traceforward and /traceback rows added.

Behaviour change for callers

Pancake routers/audit.py calls this index and already forwards the caller's x-authority-token. Audit lookups by a caller with no authority credential will no longer include lot-indexed events; that is the gate working.

Tests

  • Six direct tests of the route. The control, test_reverse_refuses_a_bare_login, fails against main; its sibling returns the same lot with a grant, so the control is not passing against an empty index. Authority path: scope required (400), answer audited. Grant path: not audited, matching Tier 1. Agreement test: the reverse answer is a strict subset of /traceforward's for the same seed.
  • Grant minter moved to app/tests/testkit/grants.py; three suites share it. Three existing tests that used the open door to check alias equivalence now present a grant.

harness/bin/stomata run: 12/12. Suite 178 passed, 1 xfailed (was 172). Lint 36, unchanged.

Closes AG-015 in the review ledger once merged. Review finding A1, 2026-10-08.

Made with Cursor

GET /list-artifact/reverse/{geoid} answered "which lots is this field in"
for any hub login: no grant for the seed, no authority credential, no MEAL
entry. It is the first hop of the question POST /traceforward answers, and
/traceforward requires a verified grant for the seed or an authority
credential. Measured on the live node, the open door returned five of the
six lots the gated one does (review ledger AG-015). A second door to a
gated answer has to carry the same gate.

The route now calls authorize_artifact with the seed, requires ?scope= when
an authority credential is presented, and writes the MEAL entry on the
authority path before returning. A login alone gets 403. Pancake's audit
route, which calls this index, already forwards x-authority-token.

Tests: six direct tests of the route in test_traceforward.py. The control,
test_reverse_refuses_a_bare_login, fails against the previous code; its
sibling proves the same lot is returned with a grant, so the control is
not passing against an empty index. The grant minter moved to
app/tests/testkit/grants.py so three suites share one copy. Three existing
tests that used the open door to check alias equivalence now present a
grant, which is what they were implicitly relying on anyway.

docs/MCP_SURFACE.md regenerated from scripts/mcp_surface.py with a gating
note; the MCP tool takes grant_token, authority_token and scope. The README
endpoint table had described a gate the code did not have; corrected, and
/traceforward and /traceback rows added.

stomata run: 12/12. Suite: 178 passed, 1 xfailed (was 172). Lint: 36, unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant