Skip to content

fix(qa): HttpTestAdapter resolves the Data Protocol mount from discovery, and degrades loudly - #9385

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-7983-http-adapter-mount-resolution
Aug 17, 2026
Merged

fix(qa): HttpTestAdapter resolves the Data Protocol mount from discovery, and degrades loudly#9385
os-zhuang merged 2 commits into
mainfrom
claude/issue-7983-http-adapter-mount-resolution

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#7983

The record-shaped os test action types (create_record, read_record, update_record, delete_record, query_records) built their URLs from the defaults of RestApiConfigSchema.apiPath and CrudEndpointsConfigSchema.dataPrefix, because HttpTestAdapter is handed an origin and nothing else. A deployment that moved the mount got a 404 that reads like the suite author's own URL mistake rather than a platform limitation.

The adapter now asks the server, following the getRoute precedent in @objectstack/client (copied from, never edited — that package is another card's this round): one memoised GET {apiBase}/discovery per run, addressing whatever routes.data advertises, with the schema-derived convention as the fallback.

What this closes, and what it does not

Measured per config off RestServer's own normalized config — both bases read back from the server, never recomputed by the harness:

deploymentserver servesbeforeafter
stock/api/v1/datacreatedcreated
crud.dataPrefix: '/objects'/api/v1/objectsHTTP Error 404created
api.apiPath: '/api/2026-01'/api/2026-01/dataHTTP Error 404HTTP Error 404, now naming the mount

The apiPath row is not closed, and the reason is structural rather than an oversight: registerDiscoveryEndpoints mounts the document at ${basePath}/discovery (rest-server.ts), so apiPath moves the base that discovery itself sits under — the document that would name the new mount is behind the very prefix the probe is missing. The dataPrefix row closes exactly because the discovery handler substitutes the configured prefix into routes.data (rest-server.ts), so reading it beats recomputing it here.

The one discovery document at a fixed path does not rescue the apiPath case, and is deliberately not probed: /.well-known/objectstack is the runtime dispatcher's, and getDiscoveryInfo composes data: ${prefix}/data from the dispatcher's own prefix — it never reads crud.dataPrefix or the REST apiPath, so it reports /api/v1/data whatever the REST server serves. Trusting it would attach a false provenance ("discovery told us") to the same 404.

So that case degrades loudly instead (Route and surface ownership section 3): the fallback prints a warning naming the mount it will address, the probe that failed and the remedy, and every 404/405 from a record action carries the mount it addressed and where that mount came from. A 400/422 is left undecorated — it reached the right route and got a real answer, so burying the server's own message under a URL would mislead.

api_call is unchanged, issues no probe at all, and remains the escape hatch for a host the probe cannot reach. Per the Zone 1 ruling on the card, no os test --api-path flag is added — that would widen the public CLI surface.

Docs and checklist

Both places this limitation was written down are narrowed, not deleted, because the apiPath row is still a real gap: the fixtures.knownGaps entry in docs/qa/platform-checklist/areas/cli.json (item revision 3, with its history row) and the paragraph in content/docs/deployment/cli.mdx.

Tests

packages/core/src/qa/http-adapter.test.ts pins the record URLs against a discovery document that deliberately advertises a non-default mount, so a pin that ignored the probe would still pass and does not. Also pinned: one probe per run including concurrent starts, the bearer token on the probe, the dispatcher's { data: ... } envelope as well as the bare document, four distinct fallback modes each asserting mount plus evidence plus remedy, warn-once-per-run, that /.well-known/ is never probed, and that api_call neither probes nor gets decorated.

Verification

All run on 99592d0ab, the head of this branch:

  • pnpm --filter @objectstack/core test — 35 files, 857 tests passed.
  • pnpm check:type-check-debt — the ratchet re-measured 33 ledger entries, 1926 raw tsc errors, none above its recorded number, "surplus: none". This is the real typecheck for this package: @objectstack/core has no typecheck script, so a filtered invocation would match zero scripts and exit 0 without checking anything.
  • Gate union re-derived on the actual changed paths with node scripts/pm/dispatch-gates.mjs and run: check:changeset-gate-self-tests, check:cross-package-test-inputs, check:docs-audit-scope, check:docs-redirects, check:role-word, check:kernel-hook-pairs, check:test-source-alias, check:objectui-changeset, the four @objectstack/spec liveness checks, check:adr-0087-registration, check:changeset-no-major, check:empty-changeset, check:cross-package-test-inputs, docs-audit/check-affected-docs, plus the convention-triggered test-file family check:query-options-erasure, check:engine-double-contract, check:where-matcher, check:type-check-coverage. All green.
  • packages/restdirect-mount-base-follows-apipath.test.ts — 6/6, corroborating that discovery follows apiPath.

No gate was weakened, no threshold lowered, no baseline rebaselined, no test skipped.


Generated by Claude Code

…degrades loudly (#7983)
The record action types built their URLs from the DEFAULTS of
RestApiConfigSchema.apiPath and CrudEndpointsConfigSchema.dataPrefix, so a
deployment that moved the mount got a 404 that reads like the suite author's
own URL mistake. The adapter now probes `{apiBase}/discovery` once per run and
addresses whatever `routes.data` advertises, following the getRoute precedent
in @objectstack/client; the schema-derived convention stays as the fallback and
taking it is announced, naming the mount, the evidence and the remedy.
Co-Authored-By: Claude <noreply@anthropic.com>
)
The knownGaps entry and the deployment/cli.mdx paragraph both said the record
action types address the DEFAULT mount only. The discovery probe closes the
crud.dataPrefix row, so both are NARROWED rather than deleted: api.apiPath moves
the discovery document itself out from under the probe and is still out of
reach, and that row must keep saying so. Adds the changeset with the measured
before/after table.
Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/core, touching 29 documentable anchor(s).

23 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive: node scripts/docs-audit/affected-docs.mjs --json origin/main.

3 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.

What this run could not see
  • 1 anchor(s) matched too much of the corpus to be a work list: /api/v1/data (route, 31 pages)
  • 1 name(s) were too generic to anchor anything (single lowercase words)

Coarse fallback — 23 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json origin/mainpackageMentionDocs.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Aug 17, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review August 17, 2026 22:03
@os-zhuang
os-zhuang enabled auto-merge August 17, 2026 22:03
@os-zhuang
os-zhuang added this pull request to the merge queueAug 17, 2026
Merged via the queue into main with commit e1bb0caAug 17, 2026
28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-7983-http-adapter-mount-resolution branch August 17, 2026 22:34
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HttpTestAdapter's record action types resolve the DEFAULT API mount only — a deployment that sets api.apiPath or crud.dataPrefix is unreachable

2 participants

@os-zhuang@claude