Uh oh!
There was an error while loading. Please reload this page.
fix(spec,rest): declare api.enableSearch, delete the three as-any config reads (#11983) - #12605
Conversation
…fig reads (#11983) - RestApiConfigSchema declares enableSearch: z.boolean().default(true) beside enableOpenApi, so the deployment-wide search opt-out survives its own contract's parse instead of being stripped by the non-strict object (the measured ADR-0104 silent-strip trap). - packages/rest normalizeConfig drops all three as-any reads (enableOpenApi stale residue, enableSearch newly declared, metadata.maskObjectFields already declared); the normalized api.enableSearch is a required boolean and both read sites drop their now-dead ?? true. - Spec pins: materialized default, parse-survival of the opt-out, cast-free authorability. Stale #11637 pin prose updated. - Regenerated: authorable-surface/api.json, authorable-defaults/api.json, content/docs/references/api/rest-server.mdx. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012xGvxcwPRTJfA7RfjXEYA4
📓 Docs Drift CheckThis PR changes 2 package(s): ⛔ 4 release-owned page(s) name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 128 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 6b789f9b687d107dac7a486474dfa64452f3683f && git checkout 6b789f9b687d107dac7a486474dfa64452f3683f
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 5a22dd7622c16efed197e9c562f6543cefb11f13 b3357c6ea9cacababff70330f5442af6ebc9342b && git checkout -B drift-repro 5a22dd7622c16efed197e9c562f6543cefb11f13 && git merge --no-ff b3357c6ea9cacababff70330f5442af6ebc9342b
node scripts/docs-audit/affected-docs.mjs --json 5a22dd7622c16efed197e9c562f6543cefb11f13
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11983
Charter route (triage comment 2026-08-26T01:56Z): declare the live keys with the defaults the runtime already applies, then delete the three
as anyreads. Clause-②: yes — stays draft for the contract-review enqueue gate; no ready-flip, no auto-merge.Premise re-verification (issue body is a lead, not a spec)
git grep enableSearch -- packages/spec/srcat basef93df4d→ zero hits; positive controlenableDiscovery→ hits inpackages/spec/src/api/rest-server.zod.ts. Premise held forenableSearch.MetadataEndpointsConfigSchema.maskObjectFieldsis already declared (.default(true), ADR-0106 D8) with its own pin tests. Only the rest-side cast for it was still stale. So this PR declares one key, not two, and deletes all three casts.normalizeConfig:enableOpenApi/enableSearchonapi,maskObjectFieldsonmetadata).isObjectSchemaMaskingEnableditself: default ON,configured === falseopts out,OS_ALLOW_UNMASKED_OBJECT_METADATAescape hatch honoured — the declared.default(true)matches.What changed
packages/spec/src/api/rest-server.zod.ts:RestApiConfigSchemadeclaresenableSearch: z.boolean().default(true)besideenableOpenApi, with a doc block stating the runtime meaning (deployment-wide search mount switch; discovery reports the conjunction) and the silent-strip history.packages/rest/src/rest-server.ts: all threeas anyreads deleted —normalizeConfignow reads typed fields forenableOpenApi,enableSearch,maskObjectFields.NormalizedRestServerConfig.api.enableSearchbecomes a required boolean like its siblings, and the two read sites drop their now-dead?? true(the discovery-capability comment updated to keep the two read sites pinned together). TheassertDeclaredApiConfigdoc's staleenableSearchbullet rewritten — the parse stays validation-only for the.omit()ed keys (requireAuth把 public 从"全局开关的副产品"升级为声明式能力,然后删掉 api.requireAuth 开关 #3963 posture,projectResolutionprojectResolution: 'none'is shipped by@objectstack/runtimeand forwarded byos serve, butRestApiConfigSchemadeclares onlyrequired|optional|auto— accepted only because the schema was never executed #11999).packages/spec/src/api/rest-server.test.ts: three pins mirroring the landedmaskObjectFieldspins — materialized default; the card's flip measurement (RestApiConfigSchema.parseofenableSearch: falsenow RETURNS the key,hasOwnPropertyasserted); cast-free authorability (compile-time).packages/rest/src/rest-config-parse-not-cast.test.ts: theRestApiConfigSchemaconstrainsapi.versionwith a regex the REST server never runs — the seam casts instead of parsing, soapi.version: ''is accepted and mounts the whole API at/api//#11637 pin titled "which no schema declares" kept its assertion (opt-out reaches normalized config) but its prose now states the declared reality. Not a debt-ledger file; the ledger, its 12 listed files andrest.test.tsare untouched.packages/spec/authorable-surface/api.json,authorable-defaults/api.json(both gain theenableSearchrow),content/docs/references/api/rest-server.mdx. Theauthorable-surface.base.jsonanchor was not rewritten (lags by design;check:authorable-surfacegreen is the assertion).@objectstack/spec+@objectstack/rest(additive declaration + cast removal; no landed changeset precedent for themaskObjectFieldsdeclaration was findable in the grafted history — divergence flagged per dispatch, patch chosen as dispatched).No runtime behavior changes: defaults are identical; the change moves the keys from cast-reachable to declared = enforced.
Verification (all at final head
b3357c6eunless noted)pnpm --filter @objectstack/spec build && check:generated— all 14 artifact gates green (gate's own summary line; earlier run had proved onlycheck:docsstale, regenerated bygen:docs).pnpm --filter @objectstack/spec typecheck— green incl.check:test-typecheck: OK(spec test layer compiles; ledger unchanged).src/api/rest-server.test.ts: 53 passed, incl. the three new[#11983]pins (verbose reporter listing captured).pnpm --filter @objectstack/rest typecheck— green (check:test-typecheck: OK — 13 file(s) / 37 error(s) held, unchanged).discovery-search-capability-agreement,rest-config-parse-not-cast,discovery-per-request-protocol,meta-object-fls): 4 files, 123 passed.check:authz-resolver,check:route-envelope,check:spec-parsed-alias,check:nul-bytesgreen; convention gates for edited test files:check:where-matcher,check:query-options-erasure("baseline key set verified against dfebfc8: no files added"),check:engine-double-contractgreen; changeset gatescheck-adr-0087-registration("no declared-breaking changeset"),check-changeset-no-major,check-empty-changesetgreen.enableSearchgrep count 0) → exactly the two parse pins failed, 51 passed; restored via checkout from HEAD,git diff HEADempty.enableSearchX(confirmed on disk) →tscerror TS2551 with suggestion namingenableSearch— proving rest's typecheck reads the REBUILT spec.d.ts; restored from HEAD, tree clean.node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstackrun from the worktree at my commit (no hand-fed paths); the families it named for this diff are the ones above. Full-farm convergence is CI's, per dispatch.Out of scope, not touched here: sibling sub-object parses (
crud/metadata/batch/routesstill cast — same class, tracked by the card family that #11637 filed),projectResolutionvocabulary (#11999).Generated by Claude Code