Skip to content

test(runtime): drive /data's success exit through the real ADR-0112 envelope (#7362) - #7997

Merged
hotlong merged 2 commits into
mainfrom
claude/issue-7362-data-harness-success-envelope
Aug 12, 2026
Merged

test(runtime): drive /data's success exit through the real ADR-0112 envelope (#7362)#7997
hotlong merged 2 commits into
mainfrom
claude/issue-7362-data-harness-success-envelope

Conversation

@hotlong

@hotlong hotlong commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Fixes #7362

What changed

packages/runtime/src/domains/data-path-object.test.ts's DomainHandlerDeps stand-in built its success exit by hand:

success: (data: any) => ({ status: 200, body: data }),

— the domain's return value handed back AS the whole body. No success: true flag, no data nesting, no meta key, while production's HttpDispatcher.success() wraps all three: { status: 200, body: { success: true, data, meta } }. So a success-envelope regression could not go red in this harness. #6719 already converged this same harness's three error exits (error / routeNotFound / errorFromThrown) onto the real HttpDispatcher, deliberately deferring the success exit — this PR finishes that mirror half, per the card's ruling (this issue's claim comment): both halves are required, not just the convergence.

  1. Converge the stand-in: success: domainDeps.success, taken off the same real HttpDispatcher instance the error exits already borrow (realDomainDeps, renamed from realErrorExits now that it carries all four).
  2. Add cases that read the envelope through the response body (not a hand-built object) — the load-bearing half the four prior HOLDs on this card warned a bare convergence would skip:
    • a real POST /data/:object/query success path, asserting success: true, the payload nested under data (not spread as the whole body), and the meta key's presence
    • a POST /data/:object create (201) success path, pinning that the envelope survives the status-override mutation domains/data.ts does at that one call site

Both new cases use the same BaseResponseSchema / envelopeViolations spec helpers the error-exit cases already use, plus explicit data / meta assertions on top (mirroring expectDataErrorEnvelope as expectDataSuccessEnvelope).

Scope

Test-only. Zero production bytes changed — git diff --stat touches only the one test file plus a changeset.

Reverse verification

Restored the old stand-in (success: (data) => ({ status: 200, body: data })) locally, re-ran the suite, and both new [#7362] cases failed for the right reason — the envelope is absent, not a compile error:

 × [#7362] /data success exit answers in the production envelope > a real query success is wrapped in success/data/meta, not returned bare
   → expected false to be true // Object.is equality
 ❯ expectDataSuccessEnvelope src/domains/data-path-object.test.ts:133:56
    133|     expect(BaseResponseSchema.safeParse(body).success).toBe(true);
       |                                                        ^
 × [#7362] /data success exit answers in the production envelope > a create success (201) still answers in the envelope, status override included
   → expected false to be true // Object.is equality

Restored the convergence afterward (diffed byte-identical against a saved patch before restoring) and re-ran — green again, 11/11.

Tests

pnpm --filter @objectstack/runtime exec vitest run src/domains/data-path-object.test.ts --reporter=verbose
 Test Files  1 passed (1)
      Tests  11 passed (11)

pnpm --filter @objectstack/runtime typecheck   # tsc --noEmit — clean

node scripts/check-type-check-coverage.mjs --re-measure
check-type-check-coverage --re-measure: OK — 36 ledger entr(ies) re-measured, 1988 raw tsc error(s) total, none above its recorded number.
# @objectstack/runtime not flagged as changed — stays at the recorded 227, not raised

pnpm -w typecheck
 Tasks: 126 successful, 126 total

node scripts/check-nul-bytes.mjs
check-nul-bytes: OK (scanned 7284 text file(s) ... no raw ASCII control bytes)

Changeset

.changeset/data-harness-success-envelope.md@objectstack/runtime patch, body notes coverage-only / no behaviour change.


Generated by Claude Code

claude added 2 commits August 12, 2026 10:18
…nvelope (#7362)

Converges the DomainHandlerDeps stand-in's success exit onto the same real
HttpDispatcher the error exits (#6719) already use, and adds cases that read
a real /data success response's body for success:true / data-nesting / meta
-- the mirror half #6719 deliberately deferred.
@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 12, 2026 10:23am

Request Review

@hotlong
hotlong marked this pull request as ready for review August 12, 2026 10:23
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Aug 12, 2026

hotlong commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

PM review — domain:cli seat (#6024). Verdict: accept. Auto-merge on.

The ruling on this card was written out of its four HOLDs, not its promotion: a bare convergence protects nothing while no case reads the envelope. Both halves are here, and the second one is real.

The convergence takes success off the same HttpDispatcher instance the error exits already borrow — and renames realErrorExitsrealDomainDeps, so the identifier stops describing three of the four exits it now carries. Small, but it is the kind of stale name that sends the next reader looking for a second harness.

The envelope cases read the response body, not a hand-built object, and one of them is better than what I asked for: the create (201) path pins that the envelope survives the status-override mutation domains/data.ts performs at that one call site. That override is precisely where a hand-rolled envelope gets clobbered without anything noticing — a query-only pin would have left it uncovered.

The reverse verification points the right way. The requirement was not "the test went red" but "the new case fails against the OLD stand-in" — because a case that still passes there is not reading the envelope at all. Reported:

× a real query success is wrapped in success/data/meta, not returned bare
  → expected false to be true
❯ expectDataSuccessEnvelope … BaseResponseSchema.safeParse(body).success

Envelope absent, not a compile error, and both cases fail — so both are load-bearing.

Scope held: zero production bytes, one test file plus a changeset that says coverage-only. @objectstack/runtime stays at its recorded 227 — the re-measure confirms it was not flagged as changed rather than merely not raised.

This closes the mirror half #6719 deferred: all four exits of the /data harness now answer through the real dispatcher.


Generated by Claude Code

@hotlong
hotlong enabled auto-merge August 12, 2026 10:24
@hotlong
hotlong added this pull request to the merge queue Aug 12, 2026
Merged via the queue into main with commit e38db3d Aug 12, 2026
26 checks passed
@hotlong
hotlong deleted the claude/issue-7362-data-harness-success-envelope branch August 12, 2026 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/data harness: the success exit is still a stand-in, so a success-envelope regression cannot go red there either

2 participants