Skip to content

spec(api): after #25104 retires the docs viewer, api.documentation.ui (ApiTestingUiConfigSchema) and the REST API plugin's uiPath are declared and read by nothing; retire them (ADR-0049 enforce-or-remove) #25159

Closed

Description

@objectstack-fleet

Filing gate ①, declared ≠ enforced (ADR-0049), reach through the authoring door. Filed by domain:spec seat 2 (seat post #18549), os-bill, session session_01B2EeooonSXrANpkpgUSfFZ, from #25121's card and pointer 6319661846, which noted both and left them undecided. ⛔ Not a claim. Lane and grade are triage's.

Reader (who acts): triage grades it and, since a retirement narrows what an author can write, puts the route to the maintainer (「协议变更直接处理,排查相关的任务,和我沟通」, as recorded in 6313218686). Then the domain:spec seat dispatches it through the spec-property-retirement kit.

What is declared (origin/main 23540582f)

  • packages/spec/src/api/documentation.zod.ts:488: ApiDocumentationConfigSchema.ui: ApiTestingUiConfigSchema.optional() ("Testing UI configuration"; a viewer type that includes 'scalar', path default /api-docs).
  • packages/spec/src/api/plugin-rest-api.zod.ts:592: uiPath: z.string().default('/api/docs') ("URL path to serve documentation UI"), echoed by packages/spec/REST_API_PLUGIN.md.

Who reads it

Routes

  • A, retire both (tombstones carrying the prescription "the docs viewer was retired; the OpenAPI document is served at /openapi.json", an ADR-0087 entry, no staged window). This is the seat's reading. Startup axis: zero producers, so it retires at once. AI-error axis: an author, or an AI, can no longer declare a viewer that is never served.
  • B, keep and mark them [PLANNED]. Nothing pulls a viewer back, and the maintainer chose 「C 下线页面」 on rest: the API docs viewer page loads a third-party script by an unpinned URL with no integrity check #25104 (6317642533).

Dedupe

MCP search_issues for "ApiTestingUiConfigSchema uiPath docs viewer retire enforce-or-remove", objectstack, open and closed: 20 hits, none of them this (all spec(ui) retirements). New.

Dedupe words: ApiTestingUiConfigSchema retire · plugin-rest-api uiPath dead key · api.documentation.ui no reader.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: graded p1 · domain:spec · area:api · enhancement · pm:queue, route A

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-22T03:53Z. ⛔ Not a claim.

  2. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01T1Y1g92DfSEz93iuCisju4
    Account: os-bill
    Branch: claude/issue-25159-api-docs-viewer-keys-retired
    Worktree: objectstack-issue-25159
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface: packages/spec/src/api/documentation.zod.ts (ApiDocumentationConfigSchema.ui, and ApiTestingUiConfigSchema / ApiTestingUiType if the retirement orphans them), packages/spec/src/api/plugin-rest-api.zod.ts (uiPath), packages/spec/REST_API_PLUGIN.md, the ADR-0087 kit (packages/spec/src/conversions/**, packages/spec/src/migrations/**), packages/spec/liveness/**, the spec's generated baselines and content/docs/references/**, scripts/ci/spec-shape-retirements.json, the keys' tests, one changeset (stop on breach; explain in the report)
    Container & model: M, mode:subagent (the surface is packages/spec alone: on origin/main 425c743fd9 no other package reads either key), model: default (dispatch-gates --tier: "no path-derived mandate"); a CONTRACT_REVIEW_TIER review of record on the narrowing face is owed before the queue, run as an isolated at-tier subagent
    Clause-②: no (narrowing)
    Metadata-protocol: narrowed
    Responsibility: n/a — not a defect card
    Thread-read: 6332269878
    Serial constraints cleared: none in flight on the surface. The file lists of all 14 open PRs, read 2026-10-22T04:52Z, touch none of the expected paths. #25121's PR #25162 (rest-server.zod.ts, liveness/rest_api.json, migrations/entries/semantic/18.rest-api-config-dead-keys-retired.ts) has merged, so the dev starts from a main that carries it.
    Ruling: triage route A, 6332269878 (from the maintainer's 「C 下线页面」 on #25104, 6317642533): retire both keys with tombstones and an ADR-0087 entry, no staged window, through the spec-property-retirement kit.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 25159,
    "status": "done",
    "branch": "claude/issue-25159-api-docs-viewer-keys-retired",
    "pr": "#25180",
    "session": "session_01T1Y1g92DfSEz93iuCisju4",
    "premise_still_valid": true,
    "summary": "Route A executed through the spec-property-retirement kit. ApiDocumentationConfig.ui, RestApiPluginConfig.openApi.uiPath and RestApiPluginConfig.openApi.uiFramework are retiredKey() tombstones; each prescription names the live document, GET /api/v1/openapi.json under the default api.basePath and api.version while api.enableOpenApi is on. The orphan defs api/ApiTestingUiConfig and api/ApiTestingUiType leave whole (ApiTestingUiConfigSchema, ApiTestingUiConfig, ApiTestingUiConfigParsed, ApiTestingUiType). Registration: 3 RETIRED_KEYS_BY_MAJOR[18] entries, 2 RETIRED_DEFS_BY_MAJOR[18] entries, a new family D3 entry api-docs-viewer-keys-retired with its STEP18_RATIONALE fragment, no D2 conversion (neither config is a stack member or a stored row), a minor changeset, a tree-scoped absence pin, and regenerated artifacts. uiFramework was not on the card: it was added in place under the four-condition exemption as the same viewer declaration one line below uiPath, with zero readers. It is a third narrowed key for the maintainer report. Hypotheses: H1 holds (2 unrelated hits in packages/rest/src/ui-routes.ts; objectui at pin 56cf4d8e89 has 0, so no objectui follow-up); H2 holds; H3 holds; H4 refined (/openapi.json is under the API base, /api/v1 by default); H5 own family, the landed entry untouched; H6 re-measured.",
    "tests": "At head 21ed122. (1) pnpm --filter @objectstack/spec test: Test Files 706 passed (706), Tests 21456 passed and 1 todo (21457). (2) vitest --project repo on the four 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 of test:repo is declared to CI. (3) pnpm --filter @objectstack/spec typecheck: exit 0, check:test-typecheck OK, and the new pin is in tsconfig.test.json's program (tsc --listFilesOnly: 1 hit). (4) Reverse verification, committed first, via scripts/ablation-replace.mjs on packages/spec/src/api/plugin-rest-api.zod.ts: the uiPath tombstone was put back to z.string().default('/api/docs'). Anchor x1 to x0, blob f365b815fca0 to d7fd0846ba5b. Predicted red, observed red: 6 failed / 16 passed of 22. Restored blob f365b815fca0 equals HEAD and git diff HEAD is empty. No build or dist leg was needed: the pin imports src by relative path. (5) Walk probe: an untracked examples/app-crm/zz-probe-25159.yaml authoring uiPath and a content/docs/zz-probe-25159.md fence importing ApiTestingUiConfigSchema. Both legs fired; both probes were deleted and the tree was clean.",
    "gates": "Derivation: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths, at 21ed122, gave 113 commands (26 paths, 1325 changed lines vs the 3000 threshold). Each was run with its exit captured before any pipe. 101 exited 0 on the first pass, 11 exited 3 and check:generated exited 1. The exit-3 refusals: six spec gates over a dist older than my last test-file edits, which my own concurrent lint-closure build then rewrote mid-run; four needing @objectstack/lint, @objectstack/objectql or every package built; one teardown self-test whose pinned commit 621a487 was missing from the shallow clone. check:generated exit 1 named the same stale dist. All twelve were re-run green after a spec build, the lint and objectql closure builds, pnpm turbo run build (77/77, 75 cached) and a depth-1 fetch of 621a487. Reconciliation: dispatch-gates --ran gave 113 derived famil(ies) accounted for, 113 run, 0 NOT-MEASURED. Outside the derivation: pnpm check:dev-prereqs exit 0; node scripts/check-platform-checklist.mjs --changed-from origin/main exit 0 (0 anchored files). CI on PR #25180 at 21ed122, read once at open, in_progress: 38 check-runs, 5 success, 6 skipped, 18 in_progress, 9 queued; Build Core queued and Governed Surface Queue Guard in_progress. No conclusion yet.",
    "dogfood_battery": "21ed122c3 · os-verify-lock: VERDICT command-exit 0 (held the lock 18m24s) · Test Files 287 passed and 3 skipped (290) · Tests 2395 passed and 18 skipped (2413) · no failures",
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write as objectstack-fleet[bot]. (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls (draft) plus the relay's assignee leg POST /repos//issues/25180/assignees [os-bill]; run 39735472840, read back identical (12660 bytes). (2) comment: POST /repos//issues/25159/comments (this report). git push is not counted.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none (no named carrier) · noted in PR #25180 Acceptance notes, not filed · OpenApiGenerationConfigSchema and RestApiPluginConfigSchema as a whole, and every other key of ApiDocumentationConfigSchema, are parsed by nothing outside their own unit tests. The REST plugin's runtime config is the separate RestApiPluginConfig interface in packages/rest/src/rest-api-plugin.ts. Example: openApi.outputPath defaults to /api/docs/openapi.json while the document is served at GET {basePath}/openapi.json. Dormant, zero pull, no named producer, no measured public-door reach, so it is not filable under classes a, b or c."
    ],
    "deviations": [
    "In-place addition: RestApiPluginConfig.openApi.uiFramework (api/OpenApiGenerationConfig:uiFramework) was retired beside uiPath under the bounded four-condition exemption; the PR body names it with evidence. Claim key set grows by one; the file is unchanged and already in the claim surface. It is a third metadata-protocol narrowing for this round's maintainer report.",
    "Files outside the claim's declared surface, all mechanical consequences: docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md (gen:strictness-ledger, named stale by check:generated); packages/spec/src/type-alias-convention.pin.test.ts (the ADR-0122 isomorphic pin line for the retired ApiTestingUiType, count 789 to 788 with a history line); packages/spec/vitest.repo-tests.json (the new pin reads outside the package, so it belongs to the repo project roster check:cross-package-test-inputs holds).",
    "Suggested-route items measured not owed: no D2 conversion (neither config is a stack collection member or stored row; the handlerStatus and rest-api-config precedents on the same files); no liveness rows (no ledger walks ApiDocumentationConfigSchema or OpenApiGenerationConfigSchema); no scripts/ci/spec-shape-retirements.json entry (its $comment ties an entry to a downstream objectui card, and objectui has zero readers at the pin).",
    "Sequencing error, mine: a lint-closure build launched during the gate re-run rewrote packages/spec/dist mid-run, so the spec gates refused a second time with exit 3. They were re-run after the build finished. No verdict was taken against a half-written dist.",
    "Commit trailers use the AGENTS.md model-free pair (Claude-Session plus Co-authored-by: Claude). The harness reminder's model-named Co-Authored-By was not used; AGENTS.md wins and the pre-push hook refuses a model identifier.",
    "Branch history: 8 commits (7 WIP plus a merge of origin/main ab488d9, which moved no packages/spec path). The landing is a squash."
    ],
    "line_budget": "26 files, 1325 changed lines (+979 / -346) vs origin/main merge base ab488d9; under the 3000 human-merge threshold; no governed surface touched",
    "files_changed": [
    ".changeset/25159-api-docs-viewer-keys-retired.md",
    "content/docs/references/api/documentation.mdx",
    "content/docs/references/api/plugin-rest-api.mdx",
    "content/docs/references/index.mdx",
    "docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md",
    "packages/spec/REST_API_PLUGIN.md",
    "packages/spec/api-surface/api.json",
    "packages/spec/authorable-defaults/api.json",
    "packages/spec/authorable-surface/api.json",
    "packages/spec/declaration-map/api.json",
    "packages/spec/export-origins/api.json",
    "packages/spec/json-schema.manifest/api.json",
    "packages/spec/src/api/docs-viewer-keys-retirement.test.ts",
    "packages/spec/src/api/documentation.test.ts",
    "packages/spec/src/api/documentation.zod.ts",
    "packages/spec/src/api/plugin-rest-api.test.ts",
    "packages/spec/src/api/plugin-rest-api.zod.ts",
    "packages/spec/src/migrations/entries/retired-defs/18.api__ApiTestingUiConfig.ts",
    "packages/spec/src/migrations/entries/retired-defs/18.api__ApiTestingUiType.ts",
    "packages/spec/src/migrations/entries/retired-keys/18.api__ApiDocumentationConfig__ui.ts",
    "packages/spec/src/migrations/entries/retired-keys/18.api__OpenApiGenerationConfig__uiFramework.ts",
    "packages/spec/src/migrations/entries/retired-keys/18.api__OpenApiGenerationConfig__uiPath.ts",
    "packages/spec/src/migrations/entries/semantic/18.api-docs-viewer-keys-retired.ts",
    "packages/spec/src/migrations/registry.ts.template",
    "packages/spec/src/type-alias-convention.pin.test.ts",
    "packages/spec/vitest.repo-tests.json"
    ]
    }

  4. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #25180 comment 6335086667 · contract review 6335062098 (PASS, CONTRACT_REVIEW_TIER, head 21ed122c3a) · domain:spec seat 1 · session session_01T1Y1g92DfSEz93iuCisju4 · 2026-10-22T07:18Z. Readied, auto-merge armed; this seat follows it to MERGED.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Queue ejection of PR #25180 · domain:spec seat 1 · session session_01T1Y1g92DfSEz93iuCisju4 · 2026-10-22T07:56Z

    • Signature (new: the triage comment 6335689882 counts it once in 24 h): queue run 39739741966, Test Core (3/6), step "Run this shard's tests": create-objectstack:test: FAIL src/banner-version.test.ts > the real CLI banner (#10325, wiring) > names the version create-objectstack's own package.json actually declares — Error: Test timed out in 20000ms.
    • First judgment: not this PR's. The three facts that allow one re-queue all hold:
      1. The failing file's import closure is disjoint from this diff. This PR changes packages/spec and docs only. banner-version.test.ts imports ./banner.js and node builtins and spawns the package's own CLI. packages/create-objectstack/src imports @objectstack/spec only in scaffold template files (src/templates/blank/**), which a version banner never loads.
      2. The queue base is green on the same shard. Base f7d740376d (fix(platform-objects): distinct zh-CN/ja-JP labels for the two Setup organization nav entries #25177's queue build, run 39739595869): Test Core (3/6) success, every Test Core job success.
      3. The first error is a timeout, not an assertion: "Test timed out in 20000ms".
    • Act: auto-merge re-armed once on the unchanged head 21ed122c3a. A second ejection on this signature is not re-queued; it goes to the next seat to re-diagnose, per the landing rules.

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 1 · session session_01T1Y1g92DfSEz93iuCisju4 · 2026-10-22T08:33Z

    probe reading
    PR #25180 merged through the queue on its second entry (the first was ejected on a create-objectstack banner-test timeout, record 6335734834); merge commit 14e7239e737ccf9b4a3a253f34164a4cda1e527d
    origin/main carries it (merge-base --is-ancestor exit 0). retiredKey(API_DOCUMENTATION_UI_RETIRED) hits 1 in packages/spec/src/api/documentation.zod.ts; the ApiTestingUiConfigSchema declaration hits 0
    merge-queue branches no gh-readonly-queue/main/pr-25180-* ref remains
    lane recount 8 open domain:spec cards. #25159 is gone, as expected. #25092 closed at 08:30:02Z through spec seat 2's own landing, before this merge (08:32Z)

    State: closed completed by Fixes #25159; pm:dispatched removed in this act (domain:spec, area:api and the type label stay). Three keys narrowed in all: ApiDocumentationConfig.ui, openApi.uiPath and openApi.uiFramework.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsdomain:specenhancementNew feature or requestpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions