Prove the Path, Not the POST

Chains beat endpoints

Share

Teams report "API tested" while users see a session lose its state mid-path, or a write silently fail. The gap is definitional: a passing smoke test on /health or a single POST does not prove a user capability. Real workflows are chains of HTTP calls with IDs passed forward.

This insight unlocked the whole SIT program. I formalized it in docs/SIT Plan/00-sit-plan-overview.md in April 2026 - weeks after the master map and integration surface work.

Here's what this piece covers: green endpoints / red paths, chain testing, one failed handoff, and three lead gates.

Part of Field Notes: agentic delivery.


1. The leadership problem

Integration defects surface in UAT when they are expensive to fix. By then, teams argue whose environment is "ready" instead of naming the broken hop.

Wrong: "We have 95% test pass rate."
Right: "Phase 2 failed at the handoff between records and entitlement - here is the chain diagram and workflow ID WF-REG-1."

The anti-pattern is isolated green - teams optimize local pass rates while seams rot.


2. What the docs show

Planning work in early April revealed multi-hop paths. The SIT overview doc states the thesis plainly:

Each workflow is a chain of HTTP calls with IDs passed forward - not a single-endpoint smoke test.

Three concepts I still enforce:

Term Meaning
Chain Ordered calls with shared state - tokens, record IDs, entitlement IDs
Endpoint smoke Single call returns 200 - necessary, not sufficient
Read-back assertion After a compound workflow, verify state via GET

Phase 3 adds the user lens: User gets - not "service responds," but "the account shows the result."

flowchart LR subgraph wrong["Endpoint thinking"] E1[POST /write → 200] end subgraph right["Chain thinking"] C1[Create session / record] --> C2[Complete primary step] C2 --> C3[Write entitlement] C3 --> C4[GET account - assert result] end

3. Example chain

Start session → create upstream record → complete → write entitlement → confirm in account.

async function assertEntitlementChain({ api, session }) {
  const record = await api.post('/records', { sessionId: session.id });
  await api.post(`/records/${record.id}/complete`);
  const write = await api.post('/entitlements', { recordId: record.id });
  const account = await api.get(`/accounts/${session.accountId}`);

  if (!account.items.some((item) => item.id === write.id)) {
    throw new Error(`write ${write.id} missing on account read-back`);
  }
}
Failure mode What the user sees Broken hop
Record not bound to session Empty state mid-path Identity ↔ records
Upstream record not attached Write succeeds, nothing owned Records ↔ entitlement
Read-back missing "Success" toast, empty list Entitlement write vs read
CRM async lag Account OK, support sees nothing Entitlement ↔ CRM

Mocking every peer in unit tests hides seam bugs. That is why Phase 2 exists - shared coordinators, real handoffs, TEST environment.


4. Named pattern: chain testing

Chain testing - prove the path, not the endpoint. Phase 2 fails at handoffs, not 200s.

Environment ladder from the SIT overview:

flowchart LR L[Local / CI optional] --> T[TEST - SIT] T --> U[UAT sign-off] subgraph TEST["TEST - SIT"] P1[Phase 1 team gates] P2[Phase 2 shared gates] P3[Phase 3 user paths] end L -.-> P1 P1 --> P2 --> P3 P3 --> U

Same suite IDs promote TEST → UAT. Different environment, same workflow names - traceability survives.


5. What I'd do as a lead

  1. Ban "we tested the API" without naming the chain ID. If nobody can cite WF-* or UJ-*, you do not have integration proof.
  2. Fund seam tests before expanding feature count. Endpoints scale faster than handoffs; that asymmetry is the constraint.
  3. Align workflow names to master-map nodes from article 01. "Entitlement CRUD" ≠ "user gets the result from an upstream record."

Further reading