11.7.9 End-to-end conformance — walk the whole work loop as an EXTERNAL HTTP client with a real PAT
This story's E2E, in the form it has: no UI, so the end-to-end proof is a stranger with a token walking the loop over HTTP — the same shape 11.2.12 and 11.3 used, extended to the operations that make the loop closable.
The walk
As an external client holding only a PAT — no session, no internal import, nothing the shipped route wrapper would not see:
- Find ready work (
…/ready, already shipped). - Fetch its dispatch prompt.
- Read the item in full, including its children's dependency edges and its readiness verdict.
- Read its activity.
- Record it integrated on a session branch.
- Close the branch out and read the per-item outcomes.
- Separately: open a plan session by scope, append a turn, submit it, poll the outcome, read the resulting plan's proposals.
Then the states a happy path skips: an empty ready set, a token missing a required scope on each distinct scope the story uses, a cross-tenant key, a rate-limited call, an unknown work-item key, a submit on an empty thread, and a plan whose job died while generating.
What makes this different from 11.7.8
That card drives services and schemas in-process. This one goes over the wire, through withV1Route — auth, scope gate, rate limiter, error envelope, request id — and therefore is the only test that exercises the surface a third party actually meets. A route can be perfect in-process and unreachable in practice: mis-declared scope, a path that does not match, a param that arrives undecoded. Only this catches that.
Assert the loop CLOSES
The point of the walk is that step 6 leaves the item done and the branch cleared, reachable entirely over /api/v1 with no MCP call and no web-app action anywhere in the sequence. That property — a third party can run the whole loop — is the story's headline, and it deserves an explicit assertion rather than being implied by seven passing steps.
Scope BOUNDARY
Ends at the conformance walk. It does NOT re-test individual endpoint behaviour (11.7.8 and the endpoint cards own that). It does NOT drive the CLI — that binary is 11.5.8's subject and does not speak v1 yet. It does NOT change product code: a failure here is a defect to file against the owning card.
No acceptance video — no user-observable surface, exempt under the non-UI carve-out exactly as 11.1–11.3 were. This run is the receipt.
Acceptance criteria
- The full seven-step walk completes over real HTTP with a real PAT against real Postgres, using no internal import and no cookie session.
- The loop demonstrably CLOSES: the item ends
donewith its session branch cleared, and the assertion says so explicitly. - Every refusal case returns its intended status and error
code: missing scope (asserted once per distinct scope this story uses), cross-tenant, unknown key, rate limit, empty-thread submit. - A plan whose job died while
generatingis reported as dead rather than pending — the case a client would otherwise poll forever on. - Every response in the walk validates against the operation's declared schema, read from the emitted document rather than from the code that produced it.
- No step in the walk touches
/api/mcpor a web-app route — asserted, since "a third party can do this" is the claim being proven. - The suite runs in the CI lane with Postgres and is a required check.
Context refs
- 11.2.12 — the shipped external-client conformance suite whose shape this follows.
tests/api/v1/— the idiom for driving v1 as an outside caller.lib/api/v1/route.ts— everything this walk exercises that an in-process test skips.app/api/openapi/v1.json/route.ts— the emitted document responses are validated against.- Subjects: every endpoint card in this story, 11.7.2 through 11.7.7.
- Story: 11.7.