Repository navigation
feat(spec)!: retire the docs-viewer keys — ApiDocumentationConfig.ui and the REST API plugin's openApi.uiPath / uiFramework (ADR-0049) - #25180
Conversation
Claude-Session: https://claude.ai/code/session_01T1Y1g92DfSEz93iuCisju4 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T1Y1g92DfSEz93iuCisju4 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T1Y1g92DfSEz93iuCisju4 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T1Y1g92DfSEz93iuCisju4 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T1Y1g92DfSEz93iuCisju4 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T1Y1g92DfSEz93iuCisju4 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T1Y1g92DfSEz93iuCisju4 Co-authored-by: Claude <noreply@anthropic.com>
…i-docs-viewer-keys-retired
📓 Docs Drift CheckThis PR changes 1 package(s): 6 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 144 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 85ad6a36605d770dec7ce9d6a8607413d4247bf5 && git checkout 85ad6a36605d770dec7ce9d6a8607413d4247bf5
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 72a302a9dde3347e15a971c5da28df205496a217 21ed122c3a750ba711a08c78c8f2d54c3ef39d4c && git checkout -B drift-repro 72a302a9dde3347e15a971c5da28df205496a217 && git merge --no-ff 21ed122c3a750ba711a08c78c8f2d54c3ef39d4c
node scripts/docs-audit/affected-docs.mjs --json 72a302a9dde3347e15a971c5da28df205496a217
|
Contract reviewServed-tier: Inputs: card #25159 (body and all three comments: triage ① Derived judgments
Check-runs on ② Semver level
③ Boundary flagsEvery dev flag from report
Implemented-by: VERDICT: PASS Generated by Claude Code |
席位核对ACCEPT ·
Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 39739741966 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
Queue ejection ·
Generated by Claude Code |
Fixes #25159
Clause-②: no (narrowing)
Metadata-protocol: narrowed
Dispatched by the
domain:specseat 1 PM (claim6333051310), executed through thespec-property-retirementkit. Ruling executed: triage route A, record6332269878(retire with tombstones and an ADR-0087 entry, no staged window), following the maintainer's 「C 下线页面」 on #25104 (6317642533).What changed
Three keys declared an HTML API documentation viewer that nothing ever served. Each is now a
retiredKey()tombstone: atscerror at the authoring site and a parse error at the key's path whose message is the prescription.ApiDocumentationConfig.uiapi/ApiDocumentationConfig:uiApiTestingUiConfigSchema.optional(), "Testing UI configuration"RestApiPluginConfig.openApi.uiPathapi/OpenApiGenerationConfig:uiPathz.string().default('/api/docs'), "URL path to serve documentation UI"RestApiPluginConfig.openApi.uiFrameworkapi/OpenApiGenerationConfig:uiFrameworkz.enum(['swagger-ui','redoc','rapidoc','elements']).default('swagger-ui')The orphan value defs
api/ApiTestingUiConfigandapi/ApiTestingUiTypeleave whole, with their exportsApiTestingUiConfigSchema,ApiTestingUiConfig,ApiTestingUiConfigParsedandApiTestingUiType(kit §4, "orphan value schema").Each prescription names the mechanism that is live: the OpenAPI document is served at
GET /api/v1/openapi.jsonunder the REST server's defaultapi.basePathandapi.version(the path follows both) whileapi.enableOpenApiis on. Example,uiPath: "RestApiPluginConfig.openApi.uiPathwas removed in @objectstack/spec 18.1.0 (ADR-0049 enforce-or-remove) — nothing ever read it: no documentation viewer was ever served at its path, the/api/docsdefault included, and the platform serves no HTML API documentation viewer at all, only the machine-readable OpenAPI document. Delete the key. The OpenAPI document is served at …"uiFramework: an in-place addition, not named on the carduiFrameworksits one line belowuiPathon the same schema and selects the vieweruiPathwould have served. All four in-place conditions hold: ① same defect class (a viewer declaration with no viewer); ② mechanical, with the shape fixed byuiPathbeside it; ③ the file is inside this claim's surface; ④ same gates, no new verification surface. Evidence: zero identifier hits outsidepackages/spechere and in objectui at its pin (readings below). Leaving it would keep the declaration the ruling removed: a framework choice for a viewer the platform does not serve, with aswagger-uidefault materialised on every parse. It is a third narrowed key, so the maintainer report for this round should list it.Hypotheses, as measured
origin/mainb93c750c7,git grep -nE "ApiTestingUi|uiPath|documentation\.ui"outsidepackages/spec,content/docs/referencesandCHANGELOG.mdfinds 2 hits, bothpackages/rest/src/ui-routes.ts:79,85: a localuiPathvariable for the unrelated/ui/viewroute.uiFramework,enableTryItOutandOpenApiGenerationConfigfind 0 each. Controls on the same instrument:enableOpenApi16 andgenerateOpenApi8. objectui at the pinned.objectui-sha56cf4d8e89: 0 forApiTestingUi|uiPath|uiFramework|documentation\.ui|ApiDocumentationConfig|OpenApiGenerationConfig|enableTryItOut, against controls@objectstack/spec/api103 andopenapi\.json12. So no objectui follow-up is owed. Insidepackages/spec, nothing parsesApiDocumentationConfigSchema,OpenApiGenerationConfigSchemaorRestApiPluginConfigSchemaoutside their own unit tests. The only importer is theapibarrel.uiPathis onOpenApiGenerationConfigSchema(api/OpenApiGenerationConfig:uiPath), whichRestApiPluginConfigSchema.openApiembeds, so an author writesRestApiPluginConfig.openApi.uiPath. The pin asserts the refusal at both doors, the second located atopenApi.uiPath.ApiTestingUiConfigSchema/ApiTestingUiTypehave no consumer besidesui. In this tree the only other references were their own unit tests and the ADR-0122 isomorphic pin line. They leave whole, soapi-surface/moves./openapi.json" is incomplete.registerRoutescallsregisterOpenApiEndpoints(getApiBasePath())whileapi.enableOpenApiis on, andgetApiBasePath()=apiPath ?? basePath/version, so the route isGET /api/v1/openapi.jsonby default (packages/rest/src/openapi-endpoints-read-decorations.test.ts:221reads that route). The prescription spells the default path and says it followsapi.basePath/api.version.api-docs-viewer-keys-retired. It is not folded intorest-api-config-dead-keys-retired(PR docs(spec): name only the OpenAPI document where the retired /docs viewer page was named #25162), for three reasons. Those keys sit onRestApiConfigSchema, the REST server's construction argument, and were dead in therest_apiliveness census. These sit on two other schemas and retire because the viewer was taken offline. Different surface, different ruling. That landed entry is not edited.Kit surfaces
documentation.zod.ts/plugin-rest-api.zod.ts, and the module and@exampledocblocks no longer show a viewer.json-schema.manifest/ratchet fired first, as the kit predicts for a whole-def removal, and the two manifest keys are removed deliberately.RETIRED_KEYS_BY_MAJOR[18]gets 3 entry files andRETIRED_DEFS_BY_MAJOR[18]gets 2. There is one D3 semantic entry, plus itsSTEP18_RATIONALEfragment (order: 108, inserted at its id's sort position). No D2 conversion: neither config is a stack collection member or asys_metadatarow, so no conversion seam would ever see one. This is thekernel/Manifest:loadingdisposition, the same one thehandlerStatusandrest-api-configretirements on these files took. The defaults onuiPath/uiFrameworkleave no residue window, because nothing parses this config into a stored or built artifact. The old defaults are refused like any other value.ApiDocumentationConfigSchemaorOpenApiGenerationConfigSchema: neither is a registry type nor inSPEC_ONLY_SCHEMAS. So there is no row to keepdead.authorable-surface/api.jsonhas 3[RETIRED]rows and the 12api/ApiTestingUiConfig:*rows deleted. Gate (a) printed them, and check (c) accepted the deletion because the whole def leaves. Also regenerated:authorable-defaults/api.json(10 default rows),json-schema.manifest/api.json(2 defs),api-surface/api.json(5 exports),export-origins/anddeclaration-map/, the strictness-ledger counts, and the reference pagesapi/documentation,api/plugin-rest-apiandreferences/index(1544 to 1542 schemas). All of these came fromcheck:generated --fix.REST_API_PLUGIN.md: the example dropsuiPath/uiFramework, the "Multiple UI frameworks" feature bullet is gone, and a paragraph names the document path.$commentties an entry to a downstream objectui card, and objectui has zero readers..changeset/25159-api-docs-viewer-keys-retired.md,@objectstack/specminor, with both declaration lines, the ADR-0087 marker (registered api-docs-viewer-keys-retired), the BREAKING banner, FROM → TO and the one-line fix.Tests
packages/spec/src/api/docs-viewer-keys-retirement.test.ts(22 cases, in therepovitest project because it reads outside the package):codeinvalid_type,pathand the prescription at each door, for every former value including the old defaults;tscchannel, with three@ts-expect-errorchecks (the file is intsconfig.test.json's program;--listFilesOnlyfinds it);uiPath/uiFramework/ a vieweruiblock.@objectstack/specinscripts/cross-package-test-inputs.mjsandturbo.json. One structural exclusion,authorable-surface.base.json: the published-surface anchor, which onlygen:authorable-surface-basewrites.check:cross-package-test-inputsis green with the pin added tovitest.repo-tests.json.documentation.test.tsandplugin-rest-api.test.tsno longer author the retired keys.type-alias-convention.pin.test.tsdropsIso_api_documentation__ApiTestingUiType, and its count goes from 789 to 788, with the history line added.scripts/ablation-replace.mjs):uiPath: retiredKey(...)was put back toz.string().default('/api/docs'). Predicted direction red; observed red, 6 failed / 16 passed of 22. Restored blobf365b815fca0equals HEAD andgit diff HEADis empty.examples/app-crm/zz-probe-25159.yamlauthoringuiPath, plus acontent/docs/zz-probe-25159.mdfence importingApiTestingUiConfigSchema. Both legs fired (...yaml:3 authors a retired docs-viewer key,... references { ApiTestingUiConfigSchema }). The probes were deleted afterwards and the tree was clean.Readings at head
21ed122c3The head is this branch merged with
origin/mainab488d9b7, which moved nopackages/specpath.pnpm --filter @objectstack/spec test(vitestlocalproject): Test Files 706 passed (706), Tests 21456 passed and 1 todo (21457).repo-project files this diff touches or reads (docs-viewer-keys-retirement,scripts/step18-rationale-merge,shared/retired-key-migrate-sentence,api/rest-api-config-dead-keys-retirement): Test Files 4 passed (4), Tests 69 passed (69). The rest oftest:repois CI's.pnpm --filter @objectstack/spec typecheck: exit 0, test layer included (check:test-typecheckOK, no new debt).pnpm --filter @objectstack/spec check:generated: exit 0.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths: 113 derived, 113 run, all exit 0.--ranreports "113 derived famil(ies) accounted for, 113 run, 0 NOT-MEASURED".distolder than my last test-file edits; four needed@objectstack/lint/@objectstack/objectql/ every package built (check:dual-build-cjs-loads); one, the teardown self-test, needed a pinned commit the shallow clone lacked. A freshcheck:generatedalso reported the same staledist(exit 1).621a48760.pnpm check:dev-prereqsexit 0;node scripts/check-platform-checklist.mjs --changed-from origin/mainexit 0 (0 anchored files in the change set).pnpm --filter @objectstack/dogfood testunder the verify lock, no shard:VERDICT command-exit 0, Test Files 287 passed and 3 skipped (290), Tests 2395 passed and 18 skipped (2413)....@objectstack/spec): measured by the tree-scoped pin and the grep with controls above, not by rebuilding the consumer closure (kit §4). Zero readers outsidepackages/spec.Acceptance notes
OpenApiGenerationConfigSchemaandRestApiPluginConfigSchemaas a whole, and every other key ofApiDocumentationConfigSchema, are parsed by nothing outside their own unit tests in this tree. The REST plugin's real config is the separateRestApiPluginConfiginterface inpackages/rest, which carriesapi?: RestServerConfig. Example:openApi.outputPathdefaults to/api/docs/openapi.json, while the document is served atGET {basePath}/openapi.json. This is a dormant, zero-pull declaration, out of this card's scope. It is noted here and not filed: no named producer and no measured public-door reach.Generated by Claude Code