Skip to content

[Decision] the export-job API contract family (ScheduledExport / ScheduleExportRequest / ExportJob…) has zero consumers and, after #16320, an empty schedule block — retire the family, keep the contract, or build the scheduler? #17158

Closed

Description

@os-bill

Ruled: 5815151991 · letter A (cross-repo landing; objectui retires first) · 2026-09-24T13:36Z
Blocked-by: objectstack-ai/objectui#10247

Decision needed

The export-job API contract family in packages/spec/src/api/export.zod.ts (the file's own comment calls it ExportJobApiContracts: ExportJob…, ScheduledExport, ScheduleExportRequest and the request / response bodies of POST /api/v1/data/export/…) declares an API that nothing on the platform serves: rest-server has no /api/v1/data/export route, IExportService (contracts/export-service.ts:15) records "no evidenced provider binding", and no package, example, app or skill outside packages/spec names any of the family's schemas or types.

#16320 (PR #17146) retired the family's two cron positions (ScheduledExport.schedule.cronExpression, ScheduleExportRequest.schedule.cronExpression) under the #15954 ruling. That ruling retires POSITIONS, not defs, so the PR left the blocks — and the tree it leaves makes the family-level question visible:

  • ScheduledExport.schedule and ScheduleExportRequest.schedule are now REQUIRED objects whose only key is an optional timezone (defaulting to UTC): a schedule block with no schedule.
  • ScheduleState (automation/execution.zod.ts, same ruling, same PR) keeps timezone, status and nextRunAt, which describe a cadence the row no longer declares.

Whether to retire the family is a maintainer decision — ADR-0049 enforce-or-remove applied to a def family rather than a key — and the contract review on #17146 asked for it to be filed as a decision, not decided by a dev seat. Nothing here is decided; the dev-seat reading at the end is non-binding.

Options

option what it means cost / risk
A. Retire the family the export-job contracts (and IExportService / ScheduleExportInput) leave the public surface: RETIRED_DEFS_BY_MAJOR[18] rows, one D3 semantic entry, refusal pins, the api-surface/ and json-schema.manifest/ ratchets move, generated reference pages regenerate a **BREAKING** minor on @objectstack/spec (launch-window convention); zero measured in-repo consumers (control below), out-of-repo NOT MEASURED; objectui at the pinned .objectui-sha must be grepped before landing (Post-Task Checklist step 4)
B. Keep the contract, declared-but-unserved no change; the family stays a declared API with no server and the empty schedule blocks stay the ADR-0049 posture this repo has been retiring elsewhere (declared ≠ enforced); the reference page keeps advertising an export scheduler that does not exist
C. Build the export scheduler a rest-server route family plus a provider for IExportService, with Job.schedule.expression as the cadence the largest cost; #15954 rejected "build the schedulers" (its option D) for the cron positions — the family-level question was not put to the maintainer there

Dev-seat reading, non-binding: A is consistent with the rulings that already retired the positions; B is the status quo; C contradicts the #15954 direction unless an export scheduler is wanted on a roadmap.

Evidence (every zero beside a lit control; #17146 branch at 90377d224)

Filed from #16320 (PR #17146) as the boundary flag its contract review asked to become a decision card; not in that card's scope.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    os-dev-report
    {
    "issue": [
    17158,
    17707
    ],
    "status": "needs_decision",
    "status_by_issue": {
    "17158": "needs_decision — stopped before any edit: the pinned objectui checkout imports three of the family's names (details under open_questions[0])",
    "17707": "done — CONCURRENT_LIMIT_EXCEEDED retired in draft PR #19957; CI in_progress at head"
    },
    "branch": "claude/issue-17158-export-job-family-retired",
    "pr": "#19957",
    "head_sha": "e9f9b060f3a3b0f5f34892eaa4e45c0527df5abf",
    "session": "session_01Sfe5YjBLwB9J3y8fvm2xq1",
    "premise_still_valid": false,
    "premise_by_issue": {
    "17158": "PARTLY FALSE. Inside objectstack the zero holds: at base b7c792b, no code outside packages/spec names any family name (declaration, tests, generated, docs and comments only; lit control ImportJobProgress(Schema) = 7 files outside spec). But the triage and ruling premise that nothing consumes the family 'in or out of the repo' is false for objectui. At the pin .objectui-sha 62597c5880 (== objectui origin/main in this container), the published @object-ui/types imports ExportJobStatus from @objectstack/spec/api and CreateExportJobInput + CreateExportJobResult from @objectstack/spec/contracts, and re-exports them publicly.",
    "17707": "TRUE as narrowed. CONCURRENT_LIMIT_EXCEEDED: 0 producers and 0 readers in objectstack outside the declaration, docs and baseline; 0 files in objectui at the pin (controls: RATE_LIMIT_EXCEEDED 1, QUOTA_EXCEEDED 3, GetMetaItemLayeredResponseSchema 14). cloud NOT READABLE from this session; the director's record 5807013768 reads 0 producers there (non-test files)."
    },
    "summary": "#17707 is implemented in draft PR #19957. CONCURRENT_LIMIT_EXCEEDED leaves StandardErrorCode and is refused with its prescription at all three catalogue doors (StandardErrorCode/EnhancedApiErrorSchema, ErrorCode/ApiErrorSchema, makeApiErrorSchema). The error map lives in a package-internal module, so api-surface does not move. The PR also carries the hand-written catalogue entry removal (wire count 52 to 51), the regenerated reference pages and unpinned baseline, a D3 semantic entry, a BREAKING minor changeset, and a fix to check-error-status-conformance's vocabulary parse, which the new enum options object would otherwise have fooled. QUOTA_EXCEEDED is untouched. #17158 STOPPED before any edit, per the dispatch rule to stop and not pick a side when two items conflict. Ruling A retires the ExportJob family whole, but the pinned objectui checkout imports ExportJobStatus, CreateExportJobInput and CreateExportJobResult as TYPES in its published @object-ui/types. AGENTS.md Post-Task Checklist step 4 then says the removal ships with the sibling fix and pin bump, and this dispatch forbids objectui writes. ScheduleState has no live consumer and is retire-eligible; it is held with the family. The PR body says 'Fixes #17707' and '#17158 remains open' (it does NOT say Fixes #17158).",
    "enumeration_17158": {
    "tree": "objectstack at base b7c792b (git grep -c over the 43 names: every schema/type/Parsed alias in api/export.zod.ts's export-job sections, ExportApiContracts, the 7 interfaces in contracts/export-service.ts, ScheduleState/ScheduleStateSchema)",
    "declaration": [
    "packages/spec/src/api/export.zod.ts (62 refs: ExportJobStatus, CreateExportJobRequest/Response, ExportJobProgress, ScheduledExport, GetExportJobDownloadRequest/Response, ListExportJobsRequest/Response, ExportJobSummary, ScheduleExportRequest/Response + Schema/Parsed forms, ExportApiContracts; ImportJobStatus's docblock names ExportJobStatus)",
    "packages/spec/src/contracts/export-service.ts (23: IExportService, CreateExportJobInput, CreateExportJobResult, ExportJobDownload, ListExportJobsOptions, ExportJobListResult, ScheduleExportInput)",
    "packages/spec/src/automation/execution.zod.ts (4: ScheduleStateSchema, ScheduleState, ScheduleStateParsed)"
    ],
    "consumer": [
    "none in code outside packages/spec",
    "packages/spec/src/contracts/automation-service.ts:589 — a comment naming ExportJobListResult as the sibling shape (comment, not code)"
    ],
    "generated": [
    "packages/spec/api-surface/{api,contracts,automation}.json (34/7/2)",
    "authorable-surface/{api,automation}.json (67/16)",
    "authorable-defaults/{api,automation}.json (7/4)",
    "authorable-surface.base.json (83; gen:authorable-surface-base only)",
    "declaration-map/{api,automation}.json (23/2)",
    "export-origins/{api,contracts,automation}.json (33/7/2)",
    "json-schema.manifest/api.json (12 defs: api/CreateExportJobRequest, CreateExportJobResponse, ExportJobProgress, ExportJobStatus, ExportJobSummary, GetExportJobDownloadRequest, GetExportJobDownloadResponse, ListExportJobsRequest, ListExportJobsResponse, ScheduleExportRequest, ScheduleExportResponse, ScheduledExport)",
    "json-schema.manifest/automation.json (1: automation/ScheduleState)",
    "content/docs/references/api/export.mdx (35), references/automation/execution.mdx (3), references/index.mdx (2)",
    "packages/spec/src/migrations/registry.ts (1: history prose in the cron-positions semantic entry)"
    ],
    "test": [
    "packages/spec/src/api/export.test.ts (70)",
    "packages/spec/src/contracts/export-service.test.ts (5)",
    "packages/spec/src/cron-typed-positions-retirement.test.ts (23)",
    "packages/spec/src/automation/execution.test.ts (8, ScheduleState)",
    "packages/spec/src/type-alias-convention.pin.test.ts (3: Iso93 ExportJobStatus, Iso106 GetExportJobDownloadRequestSchema, Iso107 ExportJobSummarySchema; hand-maintained)",
    "packages/qa/dogfood/test/expression-conformance.ledger.ts (3, comment lines)"
    ],
    "docs": [
    "docs/qa/platform-checklist/FOLLOW-UPS.md:472-474",
    ".changeset/cron-typed-positions-retired.md (13), .changeset/19365-automation-runs-cursor-hasmore.md (1) — unreleased changeset inputs",
    "packages/spec/CHANGELOG.md (5, release-owned)"
    ],
    "registries": "no RETIRED_KEYS_BY_MAJOR / RETIRED_DEFS_BY_MAJOR row names any family def today (the cron positions were deleted without registration)"
    },
    "enumeration_17707": {
    "tree": "objectstack at base b7c792b, case-insensitive also checked",
    "declaration": [
    "packages/spec/src/api/errors.zod.ts:107"
    ],
    "consumer": [
    "none"
    ],
    "generated": [
    "content/docs/references/api/contract.mdx:83",
    "references/api/error-code-ledger.mdx:250,618",
    "references/api/errors.mdx:105,324",
    "scripts/error-status-unpinned-baseline.json:4 (gate-generated via --update)"
    ],
    "docs": [
    "content/docs/api/error-catalog.mdx:473-476 (hand-written entry) + the pinned wire count on line 6"
    ],
    "test": [
    "none named it"
    ]
    },
    "objectui_grep": {
    "pin": ".objectui-sha 62597c588072636e9c30ea35b3d89b1e46fd765d (read-only git grep over the commit; identical counts at objectui origin/main and local HEAD 0cf2d66)",
    "live_imports_of_the_17158_family": [
    "packages/types/src/data.ts:22-37 — import type { ExportJobStatus, ExportFormat as ExportJobFormat, … } from '@objectstack/spec/api' and import type { CreateExportJobInput as SpecCreateExportJobInput, CreateExportJobResult } from '@objectstack/spec/contracts'; line 1257 export type CreateExportJobRequest = Omit IDENT (SpecCreateExportJobInput minus object); line 1268 export type { CreateExportJobResult } from '@objectstack/spec/contracts'; line 37 re-exports ExportJobStatus",
    "packages/types/src/index.ts:391-394 — public re-export of ExportJobStatus, CreateExportJobRequest, CreateExportJobResult",
    "packages/components/src/hooks/use-export-job.ts:30-35 — type imports via @object-ui/types; useExportJob is exported from packages/components/src/index.ts:104",
    "tests: packages/types/src/tests/spec-derived-unions.test.ts:80,172 and page-nav-misc-spec-parity.test.ts:71,524-539"
    ],
    "runtime_reach": "type-level only. No objectui DataSource implements createExportJob: 0 hits in packages/data-objectstack/src, whose ObjectStackAdapter exports through GET /api/v1/data/:object/export (exportDownload.test.ts:43). useExportJob reports isSupported=false without the method.",
    "other_hits": "CreateExportJobRequest/CreateExportJobResponse/ExportJobProgress also appear as objectui's OWN local names, in comments, ROADMAP.md and CHANGELOGs; ScheduleState appears only in ROADMAP.md:63",
    "17707": "CONCURRENT_LIMIT_EXCEEDED 0 files; QUOTA_EXCEEDED 3 (plugin-chatbot tool-display.ts:314-321 + its test, a changeset)",
    "controls": "GetMetaItemLayeredResponseSchema 14 files, ExportFormat 8, RATE_LIMIT_EXCEEDED 1",
    "cloud": "NOT READABLE from this session — not measured by me"
    },
    "schedule_state_verdict": "NO live consumer: declaration + spec tests + generated + docs in objectstack, ROADMAP.md only in objectui at the pin; cloud not readable. Retire-eligible under ruling item 2. NOT retired here, because the ruling binds it to the family PR and the family is stopped.",
    "files_touched": {
    "packages/spec/src/api/errors.zod.ts": "member removed; error: retiredStandardErrorCodeMessage option; retirement comment",
    "packages/spec/src/api/retired-error-codes.ts": "NEW, package-internal (not in api/index.ts): the prescription table + error map",
    "packages/spec/src/api/error-code-ledger.zod.ts": "ErrorCode enum passes the same error map",
    "packages/spec/src/api/contract.zod.ts": "makeApiErrorSchema enum passes the same error map",
    "packages/spec/src/api/retired-error-codes.test.ts": "NEW refusal pins",
    "packages/spec/src/migrations/entries/semantic/18.standard-error-code-concurrent-limit-exceeded-retired.ts": "NEW D3 entry",
    "packages/spec/src/migrations/registry.ts": "generated — gen:migration-registry",
    "content/docs/api/error-catalog.mdx": "hand-written: entry removed, wire count 52 to 51 (pinned by error-catalog-docs.test.ts)",
    "content/docs/references/api/{contract,error-code-ledger,errors}.mdx": "generated — check:generated --fix (only check:docs stale)",
    "scripts/error-status-unpinned-baseline.json": "generated — node scripts/check-error-status-conformance.mjs --update (one row out; QUOTA_EXCEEDED row stays)",
    "scripts/check-error-status-conformance.mjs": "parseStandardErrorCodes anchors on the array's own closing bracket; self-test battery 27 (2 cases), floor 27 to 28, CASES 58 to 60",
    ".changeset/17707-concurrent-limit-exceeded-retired.md": "NEW"
    },
    "pins_and_ablation": {
    "pins": "packages/spec/src/api/retired-error-codes.test.ts (8 tests): is no longer a catalogue member · door 1 StandardErrorCode · door 1 EnhancedApiErrorSchema.code · door 2 ErrorCode · door 2 ApiErrorSchema.code · door 3 makeApiErrorSchema · a typo keeps zod's own message (no false 'was removed') · QUOTA_EXCEEDED still parses at every door. Each refusal pin asserts the prescription text (not a bare success:false).",
    "ablations": [
    "A1 errors.zod.ts delete error: retiredStandardErrorCodeMessage, (anchor 1 to 0, blob cb2f18b7 to 37685583) → RED: 'door 1 — StandardErrorCode refuses it with the prescription', 'door 1 — EnhancedApiErrorSchema.code refuses it with the prescription'; 6 green; restore blob == HEAD cb2f18b7, git diff HEAD empty",
    "A2 error-code-ledger.zod.ts delete { error: retiredStandardErrorCodeMessage }, (blob 63acea2e to 91e20d43) → RED: 'door 2 — ErrorCode (catalogue ∪ framework ledger) …', 'door 2 — ApiErrorSchema.code …'; restore proven",
    "A3 contract.zod.ts delete , { error: retiredStandardErrorCodeMessage } (blob 16f785fd to 161871a7) → RED: 'door 3 — makeApiErrorSchema …'; restore proven",
    "A4 errors.zod.ts re-plant the member beside RATE_LIMIT_EXCEEDED (blob cb2f18b7 to 48c15d7b) → RED 6: membership + all five door pins; typo and QUOTA pins green; restore proven",
    "A5 check-error-status-conformance.mjs revert the parse anchor to the trailing ]); (blob 32e64ab9 to 5a2ea1e8) → self-test '27 an options object after the array adds no member…' RED (parse read TIMEOUT, VALIDATION_ERROR, RETIRED_SPELLING, VALIDATION_ERROR, TIMEOUT, NOT_A_MEMBER), 1/60 failed; error-catalog-docs.test.ts RED on 'the derivation … agrees with the enum' and 'the advertised code count matches'; restore proven"
    ],
    "method": "scripts/ablation-replace.mjs wrap mode, each under os-verify-lock, wrapper with trap 'git checkout HEAD -- ABS_PATH' EXIT INT TERM; the fix was committed first. The subjects import from src by relative path (not via dist), so no rebuild was needed per leg.",
    "reverse_type_check": "tsc probe against the rebuilt packages/spec/dist/api/index.d.mts: c === 'CONCURRENT_LIMIT_EXCEEDED' with c: ErrorCode gives TS2367 and assigning to StandardErrorCode gives TS2820 (exit 2); QUOTA_EXCEEDED control exit 0"
    },
    "quota_exceeded_identity": "Every file carrying QUOTA_EXCEEDED at base has the identical QUOTA_EXCEEDED line set at head (per-file sha256 of the matching lines equal: error-catalog.mdx, error-handling.mdx, the 3 reference pages, error-code-ledger.test.ts waiver case, unpinned baseline row). errors.zod.ts: the member line is unchanged; the only +1 is the new retirement comment. git diff base..head has zero '-' lines naming it.",
    "changeset": ".changeset/17707-concurrent-limit-exceeded-retired.md — '@objectstack/spec': minor; BREAKING banner; FROM → TO table + one-line fix; What stays; ⚠️ out-of-repo consumers NOT MEASURED sentence; D3 id; Clause-②: no; ADR-0087 marker registered standard-error-code-concurrent-limit-exceeded-retired. check:adr-0087-registration: '1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … (new here …)'; check:changeset-no-major: 'no major bump'.",
    "tests": "All at head e9f9b06, under os-verify-lock, VERDICT command-exit 0. spec build (dist .d.ts regenerated). spec test --project local: 528 files, 15519 passed + 1 todo. spec test:repo --project repo: 35 files, 602 passed. spec typecheck (tsc + scripts + test-typecheck; the new test file is compiled by tsconfig.test.json): exit 0. check:generated: all 15 up to date after --fix regenerated check:docs only. api-surface/json-schema.manifest/authorable-surface unchanged — expected for an enum-value narrowing (skill section 2). Direction-stated downstream: suffix-free, the packages that consume the vocabulary. types unit 22 files/685; rest unit 194/3265 (+1 skipped); runtime unit 273/3816 (+1 skipped); test:repo of types 1/7, core 3/48, runtime 2/69, objectql 1/5, rest 1/8. The five test:repo suites are the ones whose turbo inputs read packages//*.ts or content/. Blind spot: turbo ls --affected is package-graph based, root suites are off the graph.",
    "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (first stderr line names objectstack-ai/objectstack @ e9f9b06) derived 133. All run; --ran reconciliation: '133 derived famil(ies) accounted for — 130 run, 3 NOT-MEASURED'. The 130 exit 0; 5 of them first exited 3 on prerequisites, then went green after turbo run build of formula/lint/client/client-react/objectql (34 tasks). NOT MEASURED: check:dual-build-cjs-loads and check:type-check-debt, reason PREREQUISITE NOT MET (whole-tree build); check:pm-dispatch-gates, reason: the self-test exceeded the foreground cap on a shared box (1907 assertions passed, 0 failed before timeout 570s). check:error-status-conformance --self-test: 60 cases pass. Live citation gate node scripts/check-issue-citations.mjs: 'every citation this change adds resolves'. Lint, narrowed and proven: population read from eslint --print-config (the 8 changed JS/TS files resolve a config; .md/.mdx 'File ignored'); eslint --no-inline-config --format json → 8 files, 0 errors, 0 warnings; invariance: resolved parserOptions carry only ecmaVersion/sourceType (no project/projectService), so no untouched file's verdict can move. Driverless merge-tree against origin/main f5a7250: clean, so no merge was made.",
    "ci": "in_progress at e9f9b06 when read: 32 check runs — 6 success, 2 skipped (incl. Console Pin Gate, filter), 22 in_progress, 2 queued; required Lint & Repo Gates / TypeScript Type Check / Test Core / Build Core / Temporal Conformance / Governed Surface Queue Guard not concluded. Not waited on, per the report contract.",
    "mcp_calls": "0",
    "api_writes": "2 relay writes + 1 git push stream. (1) POST /repos/objectstack-ai/objectstack/dispatches → fleet-write run 35970771956 → POST /repos/objectstack-ai/objectstack/pulls (draft, PR #19957, body read back byte-identical). (2) this os-dev-report comment on #17158 via scripts/pm/post-stamped.mjs (relay). git push: branch create + 2 commits (not REST). Zero label, ready, auto-merge or merge writes.",
    "open_questions": [
    {
    "question": "#17158: ruling A retires the export-job family whole, but objectui at the pin imports ExportJobStatus (@objectstack/spec/api), CreateExportJobInput and CreateExportJobResult (@objectstack/spec/contracts) as types, and re-exports them from its published @object-ui/types. AGENTS.md Post-Task Checklist step 4 says a removal the pinned sibling imports ships together with the sibling fix and the pin bump, or does not ship. This dispatch forbids objectui writes. Which way does the retirement go?",
    "options": [
    "A. Cross-repo landing (the step-4 path). First an objectui PR replaces the three imports with local declarations, or retires its unimplemented async-export surface: the optional DataSource createExportJob/getExportJobProgress family and useExportJob, which no objectui DataSource implements. Then this repo's retirement PR bumps .objectui-sha (and regenerates sdui.manifest.json) and retires the whole family plus ScheduleState. Cost: one objectui PR + a pin bump + seat coordination; the retirement waits on it.",
    "B. Narrow the ruling. Retire everything objectui does not import (ScheduledExport, ScheduleExportRequest/Response, CreateExportJobRequest/Response, ExportJobProgress, ExportJobSummary, Get/List ExportJob*, ExportApiContracts, IExportService, ScheduleExportInput, ExportJobDownload, ListExportJobsOptions, ExportJobListResult, ScheduleState), and keep ExportJobStatus + CreateExportJobInput + CreateExportJobResult. Cost: a status enum and a service input/result pair stay declared with no server and no service interface — a partial family, against ruling A's family-level intent.",
    "C. Retire the whole family now, with the objectui fix as a follow-up. Static reading (NOT MEASURED — build-console.sh not run): all three objectui imports are type-only, the Console Pin Gate bundles with vite (types erased), and it builds objectui's workspace deps against objectui's own lockfile spec 17.4.0, so the gate should stay green. But objectui's next @objectstack/spec bump then fails @object-ui/types (TS2305 ×3), and its public type exports lose their source. Cost: ships a known break to the sibling, contrary to the step-4 rule."
    ],
    "recommendation": "A. It keeps ruling A whole and follows the landing rule AGENTS.md already names for exactly this case, and the objectui side is small (three type imports plus an optional, unimplemented DataSource method family). ⚠️ The four-axis decision framework was not carried in this dispatch, so this recommendation is NOT axis-structured. Per the os-dev contract, the PM supplies the axes; I did not invent a set."
    }
    ],
    "out_of_scope_findings": [
    "class: a · content/docs/protocol/kernel/error-handling.mdx:709-719 tells readers QUOTA_EXCEEDED is 'Not emitted today … no ObjectStack producer emits it … do not write a client branch against it'. The director's record 5807013768 reads cloud's service-ai agent-routes.ts:572 emitting sendError(429, 'QUOTA_EXCEEDED', …), and objectui at the pin branches on it (plugin-chatbot/src/tool-display.ts:314-321, pinned in tool-display.test.ts:357-369). Following the page drops a branch a live route needs. Out of this PR: the narrowing says no QUOTA_EXCEEDED wording change here. Seam: spec:StandardErrorCode.QUOTA_EXCEEDED → runtime:cloud service-ai agent route | renderer:objectui plugin-chatbot tool-display. dedupe words: 'QUOTA_EXCEEDED not emitted today', 'error-handling.mdx QUOTA_EXCEEDED', 'QUOTA_EXCEEDED producer agent route docs'",
    "noted, not filed · scripts/check-dispatcher-error-vocabulary.mjs parseStandardCodes uses the same lazy close anchor (\]\)) and now reads past the StandardErrorCode array into the next declarations. Its result is a Set, so the derived member set is still exact (49 unique; measured). Fragility, not a defect; also in the PR's Acceptance notes. carrier: 承接者:无",
    "noted, not filed · check-error-status-conformance printed a wrong member count ('64 StandardErrorCode member(s)', 'reconciled: 41') with a GREEN verdict while its parse was misreading — the gate itself had no guard against a duplicate-bearing parse; error-catalog-docs.test.ts caught it. Fixed in this PR (battery 27), so no card. carrier: this PR"
    ],
    "deviations": [
    "The dispatch said the PR body carries 'Fixes #17158'. It does NOT: #17158 stopped on the objectui conflict, and a Fixes line would close an unimplemented card on merge. The body says '#17158 remains open'.",
    "scripts/check-error-status-conformance.mjs was edited although it is outside the claimed file surface. The new enum options object made its vocabulary parse read 64 entries for 49 members, and error-catalog-docs.test.ts went red. The change this PR makes turned that parse false, so the fix is owed here. Its self-test (60/60) and the test that imports it (error-catalog-docs.test.ts) were run.",
    "Refusal pins are package-local (spec). No tree-scoped absence pin was added: it would need scripts/cross-package-test-inputs.mjs + turbo.json edits outside the claimed surface (the #19937 precedent made the same call)."
    ],
    "cleanup": "Dev worktree /home/user/objectstack-issue-17158: node_modules removed, then git worktree remove without --force → exit 0 (the tree was clean; the branch head e9f9b06 is on the remote). This comment was posted from a scratch detached worktree at origin/main f5a7250, which is removed after posting. No dev server or background monitor was started. The only background item was the spec test:repo run, which the harness moved to the background at the 600s tool cap; I waited on its PID in the foreground and read its verdict (exit 0)."
    }

  2. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Release: session session_01Sfe5YjBLwB9J3y8fvm2xq1 · claim 5808492355 (seat 5) · 因: 裁决 A 的前提有一部分不成立(见下),需要重新裁定 · 去向: needs-user-decision

    #17158 开发在动手之前停下:objectui 在用这一族里的三个类型

    domain:spec seat 5(session_01Sfe5YjBLwB9J3y8fvm2xq1),2026-09-24T07:46Z。开发报告见 5809956647。本席已按 git 复核:objectui 固定版本为 .objectui-sha 62597c5880。

    实测

    • objectstack 内部: packages/spec 之外,没有任何代码用到这一族的名字。开发做了对照,ImportJobProgress 在 spec 之外能搜到 7 个文件。裁决 A 在本仓库之内的前提成立。
    • objectui(固定版本): packages/types/src/data.ts:22-37 以类型方式引用了 ExportJobStatus(来自 @objectstack/spec/api),以及 CreateExportJobInput、CreateExportJobResult(来自 @objectstack/spec/contracts)。这三个类型经公开包 @object-ui/types 对外转出(index.ts:391-394),useExportJob 用到了它们。
    • 运行时: 没有影响。objectui 的所有 DataSource 都没有实现 createExportJob。
    • ScheduleState: 没有活的使用方,满足裁决第 2 项的退役条件,暂时随这一族一起搁置。
    • AGENTS.md 发布后检查清单第 4 步:如果移除的东西正被固定版本的兄弟仓库引用,就必须和兄弟仓库的修复、固定版本的升级一起发布,否则就不发布。本席不做 objectui 的工作(维护者原话:「你只负责处理 spec@objectstack」)。

    选项(交维护者或董事席定)

    • A(推荐): 先由 objectui 那边提一个 PR,把这三个类型改为本地声明,或者连同它那套没有实现的异步导出接口一起退役。然后本仓库再退役整个一族加 ScheduleState,并升级 .objectui-sha。这条路完整保留了裁决 A,也正是第 4 步写明的路径,但要等 objectui 那边先做完。
    • B: 缩小范围,只退役 objectui 没用到的部分,留下这三个类型。这会剩下一个残缺的族:一个没有服务端、也没有服务接口的状态枚举,加一对输入/输出类型。
    • C: 现在就整族退役,objectui 的修复留作后续。这是明知会让兄弟仓库坏掉还照样发,违反第 4 步。objectui 下次升级 spec 时,@object-ui/types 会编译报错。

    同一次派发里的 #17707

    已完成,在 PR #19957 里,只退役 CONCURRENT_LIMIT_EXCEEDED。该 PR 写的是 Fixes #17707,⛔ 没有写 Fixes #17158。


    Generated by Claude Code

  3. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Ruling: batch #221 item 2 · letter A (cross-repo landing; objectui retires its side first) · maintainer 「同意」 (chat, director seat summon #29, session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-24T13:34Z

    Director seat, summon #29. Re-decides the landing route that seat 5's release (5810005336) put back in the box. Presented with recommendation A (fallback B; ⛔ C refused); the maintainer agreed. Thread re-read to its last comment (5810005336) in this act. Read on objectui origin/main: useExportJob and ExportProgressDialog consume ExportJobStatus / CreateExportJobInput / CreateExportJobResult, and no DataSource implements createExportJob, so the path has never run.

    Ruled: A. Batch #122's ruling A (retire the family) stands in full. The landing is two ordered steps:

    1. objectui#10247 (filed in this stroke) retires the unimplemented async-export path: the hook, the dialog, the two optional DataSource members and the export-job types with their re-exports, as a BREAKING changeset. Protocol first: ⛔ not a local re-declaration of the types, which would keep a capability the protocol no longer carries.
    2. Then this card retires the whole family plus ScheduleState (no live consumer, per ruling item 2) and bumps .objectui-sha to a SHA that carries objectui#10247, in the same PR (Post-Task Checklist step 4).

    ⛔ B not taken: it leaves a status enum and an input/output pair with no server and no service, which is declared ≠ enforced again. ⛔ C refused: it ships a removal that the pinned sibling still references. #17707 is done separately in PR #19957 and is not affected.

    Execution: needs-user-decision → pm:blocked in this stroke, with Blocked-by: objectstack-ai/objectui#10247 at the top of the body. Unblocks when objectui#10247 closes and a SHA carrying it is installable. priority:p2 and domain:spec stand.


    Generated by Claude Code

  4. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Unblock re-derivation: pm:blocked → pm:queue · 2026-09-24T23:55Z

    Acting on the maintainer's instruction. Provenance: who — the maintainer; verbatim — 「帮我排查一下 blocked 卡片,哪些需要更新状态帮我更新。」; where — the maintainer's chat with session session_013RWUA7bNq5bRhehLPqXwMg, 2026-09-24. ⛔ Not a claim and not a dispatch: the card returns to its lane's take order. Candidate surfaced by check-half-states.mjs H19 on this sweep.

    State: pm:blocked → pm:queue; domain:spec, priority:p2 unchanged; no assignee.


    Generated by Claude Code

  5. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    Contributor

    Scope note: the export-job LIST schemas are in this retirement · 2026-09-25T02:45Z

    Acting on the maintainer's instruction. Provenance: who — the maintainer; verbatim — 「同意」, approving this session's proposal to absorb objectstack#19543's door ② into this card; where — the maintainer's chat with session session_013RWUA7bNq5bRhehLPqXwMg, 2026-09-25. ⛔ No label, state or assignee change.


    Generated by Claude Code

  6. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 1 · 2026-09-27T03:35Z
    Session: session_01Rjy9MeetSfq34PKn81CRiN
    Account: os-zhuang
    Branch: claude/issue-17158-export-family-retire
    Worktree: objectstack-issue-17158
    Domain: domain:spec
    Seat: domain:spec#1
    File surface: packages/spec/src/api/export.zod.ts (the export-job family including the list pair; ⛔ not the import-job family); packages/spec/src/contracts/export-service.ts (IExportService, ScheduleExportInput); packages/spec/src/automation/execution.zod.ts (ScheduleState, only if no live consumer is measured); packages/spec/src/migrations/ (retired-defs entries + one D3 semantic entry + registry) and refusal pins; the generated artefacts and reference pages that follow, regenerated and never hand-edited; .changeset/. ⛔ Not .objectui-sha, and ⛔ not the branch claude/issue-17158-export-job-family-retired (that is PR #19957, #17707's). (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: default judgment tier (dispatch-gates.mjs --tier at 9401b842: 「no path-derived mandate」, the default slot taken; a published surface is removed, so it is reviewed at CONTRACT_REVIEW_TIER before enqueue). Verify-lock arrival depth 1 at the gate read.
    Clause-②: no
    Thread-read: 5825830323
    Serial constraints cleared: Ruling-ref: 5644350616 (A, batch #122 item 3), 5815151991 (landing route A, batch #221 item 2) and 5825830323 (scope note), all retrieved this act. Seat 5's claim 5808492355 on this card carries its Release 5810005336. Ruling step 1 is done: objectui#10247 closed; objectui PR #10264 merged as 8b1f066192a4, and the current .objectui-sha f8a9d0fb0596 is 58 ahead / 0 behind it. At the pin, grep of ExportJobStatus / CreateExportJobInput over objectui packages/types/src exits 1 (control: 11 spec import lines in data.ts). So the pin-bump condition is already met and .objectui-sha (the single-claim path) is not touched. Open PR #19957 (seat 5, #17707) touches api/{contract,errors,error-code-ledger}.zod.ts, which are not on this surface. This seat's #19543 dev adds retired-defs files under migrations/entries/retired-defs/ and moves the same generated api.json surfaces; those are per-entry files plus generated outputs, so this is ordinary concurrency and they are regenerated. Clause-② no, as ruled: a removal widens nothing.

  7. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    os-dev-report
    {
    "issue": 17158,
    "status": "done",
    "branch": "claude/issue-17158-export-family-retire",
    "pr": "#20194",
    "head_sha": "a050a8a7",
    "session": "session_01Rjy9MeetSfq34PKn81CRiN — mode:subagent, the PM's session; identity = branch, claim 5852337804",
    "premise_still_valid": true,
    "summary": "Retired the export-job API family whole (12 api defs, 32 exported names, and ExportApiContracts), IExportService with its six types (ScheduleExportInput included; contracts/export-service.ts deleted), and automation/ScheduleState, under ADR-0049 route 3. That is 13 RETIRED_DEFS_BY_MAJOR[18] entry files, the D3 semantic entry export-job-family-retired, and a retirement pin (export-origins holders, runtime namespaces, file deletion, shard absences, registration, and a tree-scoped absence leg inside spec's already-declared radius) proven by three ablations. The regenerated manifest, authorable-surface, authorable-defaults, api-surface, export-origins, declaration-map, reference pages and strictness counts are all removals, and there is a BREAKING minor changeset with the ADR-0087 registered marker and Clause-②: no. Zone 2 held throughout: the pin f8a9d0fb0596 already carries objectui#10247 (.objectui-sha untouched), and no code in objectstack, objectui at the pin, or cloud main names any of the 43 names.",
    "zone2_measurements": {
    "1_objectui_pin": "HOLDS. .objectui-sha f8a9d0fb0596 (unchanged at base 49144fc). git merge-base --is-ancestor 8b1f066192a4 f8a9d0fb0596 → exit 0 (self-proving); rev-list 58 ahead / 0 behind. All 43 family names grepped at the pin: whole tree, non-markdown files → exit 1 (0 files); under packages/ the only hits are 6 CHANGELOG.md files (prose recording objectui#10247). Controls at the pin, non-md: ImportJobProgress 7, GetMetaItemLayeredResponseSchema 9, '@objectstack/spec/api' 34. The PM's control reading '11 spec import lines in data.ts' measured as 10 lines by git grep -c '@objectstack/spec' (spelling difference; control lit either way).",
    "2_objectstack_and_cloud_zero": "HOLDS. objectstack at 49144fc: no code file outside packages/spec names a family name; the 7 hits are prose (2 unreleased changesets, 3 generated reference pages, docs/qa FOLLOW-UPS.md, 3 comment lines in the dogfood D7 ledger). Control ImportJobProgress(Schema): 7 files (8 after the main merge). cloud main 48d70663 (readable this time): 0 files, git grep exit 1; control '@objectstack/spec' 537 files.",
    "3_ScheduleState": "HOLDS: no live consumer in objectstack (spec tests plus prose only), in objectui at the pin (0 non-md), or in cloud (0). Retired per ruling item 2.",
    "4_retired_defs_layout": "HOLDS: per-entry files plus generated registry.ts. The origin/main merge (369bcbe) went through scripts/pm/os-regen-merge.sh. registry.ts text-merged clean (+206/−0 against origin/main; main's ui-report-joined-container-selection-refused entry present). The one deferred shard, authorable-surface/automation.json, came back as main's side with the 16 retired ScheduleState rows resurrected. I removed those rows (the gate-prescribed baseline deletion, which check (c) proof 3 then re-proved against the new merge base), kept main's DecisionConfig:mode row, and committed in its own regen commit; check:generated gave 15/15 current.",
    "5_PR_19957_files": "HOLDS: api/{contract,errors,error-code-ledger}.zod.ts are not in the 46-file diff (grep exit 1). export.zod.ts imports BaseResponseSchema from contract.zod.ts, unchanged."
    },
    "files_changed": {
    "count": 46,
    "lines": "+969 / −2074 (3043 changed, under 5000)",
    "source": [
    "packages/spec/src/api/export.zod.ts (family removed; module docblock rewritten; ImportJobStatus docblock)",
    "packages/spec/src/contracts/export-service.ts (deleted)",
    "packages/spec/src/contracts/index.ts (barrel line to note)",
    "packages/spec/src/contracts/automation-service.ts (RunListResult docblock no longer cites ExportJobListResult)",
    "packages/spec/src/automation/execution.zod.ts (ScheduleState section and Parsed alias removed)"
    ],
    "registry": [
    "13 × packages/spec/src/migrations/entries/retired-defs/18.{api__…,automation__ScheduleState}.ts",
    "packages/spec/src/migrations/entries/semantic/18.export-job-family-retired.ts",
    "packages/spec/src/migrations/registry.ts (generated)"
    ],
    "tests": [
    "packages/spec/src/api/export-job-family-retirement.test.ts (NEW pin)",
    "packages/spec/vitest.repo-tests.json (+1, repo project)",
    "packages/spec/src/api/export.test.ts (family blocks removed)",
    "packages/spec/src/automation/execution.test.ts (ScheduleState block removed)",
    "packages/spec/src/contracts/export-service.test.ts (deleted)",
    "packages/spec/src/cron-typed-positions-retirement.test.ts (3 sites moved to LEFT_WITH_THEIR_DEFS, def-grain assertion added)",
    "packages/spec/src/type-alias-convention.pin.test.ts (3 pins out, 790→787 + receipt)"
    ],
    "generated": [
    "json-schema.manifest/{api,automation} −12/−1",
    "authorable-surface/{api,automation} −67/−16",
    "authorable-defaults/{api,automation} −7/−4",
    "api-surface/{api,automation,contracts} −34/−3/−7",
    "export-origins/{api,automation,contracts} −33/−3/−7",
    "declaration-map/{api,automation} −23/−2",
    "content/docs/references/{api/export,automation/execution,index}.mdx",
    "docs/audits/2026-07-unknown-key-strictness-ledger.counts.md"
    ],
    "changeset": ".changeset/17158-export-job-family-retired.md ('@objectstack/spec': minor, BREAKING banner, FROM→TO table, one-line fix, out-of-repo NOT MEASURED sentence, supersedes the unreleased cron-positions rows, Clause-②: no, ADR-0087 marker registered export-job-family-retired)"
    },
    "tests": "Final head a050a8a, each under os-verify-lock with its VERDICT read. spec check:generated --fix (rebuild first): 15/15 current, only check:docs regenerated. spec test (local): 539 files, 15777 passed, 2 todo, exit 0. spec test:repo: 32 files, 586 passed, exit 0. Pre-merge at 6c35939: local 539/15754, repo 32/586. At d08bc4e (commits since are comment/prose only): spec typecheck (tsc + check:scripts-typecheck + check:test-typecheck) exit 0; consumer suites @objectstack/vitest-filter-preflight test/config-wiring-sweep.test.ts (reads spec's vitest.repo-tests.json) 65/65, and @objectstack/dogfood test/expression-conformance.test.ts (D7 ledger, in the retirement radius) 7/7. Targeted at 6c35939: export/execution/cron/type-alias/migrations/contracts 52 files/672 passed; new pin 7/7. Consumer direction: no package outside spec imports a removed name (measured), so no downstream closure was rebuilt for the absence. Ablation at 6c35939, via scripts/ablation-replace.mjs wrap mode under trap EXIT INT TERM with absolute paths; subject resolves src + committed JSON, so no dist and no rebuild per leg. A1b re-plant ExportJobStatus const+type in export.zod.ts (anchor 1→0, blob 501ee4a5→2d84be39) went RED 2: 'runtime namespaces agree' and tree-scoped ('export.zod.ts references typeof ExportJobStatus'). A2 delete 'automation/ScheduleState' from the generated RETIRED_DEFS_BY_MAJOR[18] region (6a3b0b58→58ab1619) went RED 2: the pin's registration test and the cron file's def-grain test. A3b add "api/ExportJobStatus" to json-schema.manifest/api.json (8c11f3d0→5ea54e58) went RED 2: shards leg and tree-scoped leg. Every restore was proven by blob == HEAD and an empty git diff HEAD. The first A1/A3 attempts were no-ops (each replacement contained its own anchor; the tool refused and restored, and no test ran); those readings are void, and A1b/A3b are the re-runs. Under A1b the export-origins holders leg stayed green by design (it reads the committed artifact; CI's check:api-surface/check:export-origins catch an un-regenerated re-plant).",
    "gates": {
    "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths), first stderr line: 'derived from the tree of objectstack-ai/objectstack at commit a050a8a'. 111 commands, a superset of the dispatch lead's 77.",
    "reconciliation": "--ran: '111 derived famil(ies) accounted for — 109 run, 2 NOT-MEASURED (0 DERIVED from a recorded exit 3, 2 claimed)', 0 UNRUN, at a050a8a; each exit code captured to disk before any pipe.",
    "all_run_exit_0": 109,
    "not_measured": [
    "pnpm check:dual-build-cjs-loads — PREREQUISITE NOT MET (exit 3): needs a whole-workspace build",
    "pnpm check:type-check-debt — PREREQUISITE NOT MET (exit 3): needs a whole-workspace build (turbo build ./packages/* closure); CI builds it first in lint.yml"
    ],
    "prerequisite_builds_run": "turbo build of formula, lint, client, client-react, objectql and verify (36/36 tasks), which cleared check:doc-formula-expressions, check:doc-security-posture, check:skill-examples, check:docs-transcript-drift and check:lean-entry-closure (all now exit 0).",
    "real_findings_fixed_during_run": "check:future-spec-major flagged 4 sites that dated the removal '@objectstack/spec 18'. Under ADR-0087 (amended) the tombstone names the release line, so they now say 17 (registry rows stay under major 18).",
    "verdict_lines": [
    "check-adr-0087-registration: 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition",
    "check-changeset-no-major: This diff introduces no major bump",
    "check-empty-changeset: no changeset from the merge base modified or deleted",
    "check:api-surface: public API surface + factory signatures unchanged ✓ (against the regenerated snapshot)",
    "check:spec-parsed-alias: 1446 bare aliases, 787 pinned isomorphic, 659 paired",
    "check:nul-bytes OK (9579 files)",
    "check:cross-package-test-inputs OK",
    "live node scripts/check-issue-citations.mjs: every citation this change adds resolves"
    ],
    "lint": "Narrowed and proven: (1) population: eslint --print-config resolves the config for all 24 changed JS/TS files, none ignored; (2) eslint --no-inline-config --format json gives 24 files, 0 errors, 0 warnings; (3) invariance: resolved parserOptions are {ecmaVersion: latest, sourceType: module} with no project/projectService, so no untouched file's verdict can move.",
    "ci": "in_progress at a050a8a when read once after PR creation: 32 check runs, 12 success, 2 skipped, 18 in_progress, 0 failed. Not waited on, per the report contract."
    },
    "line_budget": "n/a: no skills/** or governed surface touched (docs/audits and content/docs/references are not governed). Diff 3043 changed lines, under the 5000 human-merge threshold.",
    "mcp_calls": "0 — no GitHub MCP tool was called (reads used curl REST; one SendMessage reply to the PM's status probe is not a GitHub call)",
    "api_writes": "3 relay writes, each one repository_dispatch plus a fleet-write run: (1) POST /repos/objectstack-ai/objectstack/dispatches → run 36302232507 → POST /repos/objectstack-ai/objectstack/pulls (draft PR #20194; body read back byte-identical, 14925 chars, footer intact); (2) scripts/pm/label-write.mjs --issue 20194 --assign os-zhuang → POST /dispatches → run 36302276940 → POST /repos//issues/20194/assignees (readback MATCHES; zero labels written, the labeler set documentation/size/xl/tests/tooling); (3) this os-dev-report comment via scripts/pm/post-stamped.mjs → POST /repos//issues/17158/comments. Plus git push (7 pushes: the empty-branch probe and 6 commit pushes; not REST). Zero ready, auto-merge, merge or card-assignee writes.",
    "open_questions": [],
    "out_of_scope_findings": [
    "noted, not filed · class: none (read-only inference, no public-door measurement) · GET /api/v1/data/:object/export reads ?format= as csv | json | xlsx and silently falls back to csv for anything else (packages/rest/src/rest-server.ts:10324-10326), while spec's ExportFormat declares csv/json/jsonl/xlsx/parquet and binds to no route. A first draft of this PR's prose tied the served door to ExportFormat and was corrected before opening. In PR Acceptance notes. carrier: 承接者:无 · dedupe words: 'export format fallback csv', 'ExportFormat jsonl parquet unserved', 'data export unknown format value'",
    "noted, not filed · ExportFormat and ExportImportTemplateSchema have no reader outside packages/spec (objectstack: only this PR's changeset and FOLLOW-UPS prose; objectui pin: 0 non-md files). Declared and unconsumed, but outside ruling A's scope (dead surface is not filed per contract). carrier: 承接者:无 · dedupe words: 'ExportImportTemplate zero consumers', 'ExportFormat retire'",
    "noted, not filed · .changeset/19365-automation-runs-cursor-hasmore.md:98 (another PR's unreleased changeset) cites 'the shape IExportService.listExportJobs already uses'; once this lands it names a removed contract. Not editable here (check-empty-changeset refuses modifying a merge-base changeset). carrier: 承接者:无 — the release compiler or the maintainer at release",
    "noted, not filed · docs/qa/platform-checklist/FOLLOW-UPS.md §9c lists the async export-job surface and ScheduleStateSchema.status as enforce-or-remove candidates, now resolved; §9d is append-only and outside this card's surface. carrier: 承接者:无"
    ],
    "deviations": [
    "Files outside the claim's listed surface, each owed by this change: contracts/automation-service.ts (a docblock citing the retired ExportJobListResult), contracts/index.ts (the barrel export of the deleted module), vitest.repo-tests.json (registers the new walking pin in the repo project), docs/audits/2026-07-unknown-key-strictness-ledger.counts.md (generated; ScheduleState was one strip site), and the test triage in export.test.ts / execution.test.ts / cron-typed-positions-retirement.test.ts / type-alias-convention.pin.test.ts.",
    "authorable-surface/{api,automation}.json lost 83 rows by deliberate baseline deletion. That is the gate's prescribed route for a whole-def removal: check (a) refuses a vanished key while its row stands, and check (c) proof 3 then verified each deletion. It is not a hand-resolved merge. After the origin/main merge the same 16 ScheduleState rows came back from main's side and were deleted again, the same way.",
    "Merged origin/main (369bcbe) before opening; main has since moved to e2c4e12 (core security only, no overlapping path), which is not merged.",
    "The harness attribution reminder asked for a model-named Co-Authored-By trailer. Commits carry the AGENTS.md model-free pair (Co-authored-by: Claude …, Claude-Session: …); the one unpushed commit that briefly carried the model-named line was amended before any push.",
    "os-verify-lock queue-timeout (exit 99) three times, each time never acquired and nothing measured. One queued run of mine (PID 14409) was stopped by me before it acquired, because a prose correction was about to change the tree it would have tested.",
    "The step-18 rationale in registry.ts was deliberately not extended (a contended hand-written string; recent semantic-only retirements leave it too). The D3 entry is the declaration."
    ],
    "cleanup": "Dev worktree /home/user/objectstack-issue-17158: node_modules removed, then git worktree remove without --force after this comment is read back. No dev server or monitor started. Background items were all my own lock runs (PIDs 8894, 22479, 14992, 31494, 14409, 17057), each waited to exit in the foreground or stopped by me; none remains."
    }

  8. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    Review: ACCEPT · PR #20194 at head a050a8a7f3fd3d9cbd95d68f8c230b99b21355d8 · 2026-09-27T07:18Z

    domain:spec seat 1 (session_01Rjy9MeetSfq34PKn81CRiN), reviewer of record, on claim 5852337804. Checked against GitHub, ⛔ not against the report (5853681100).

    Checklist

    • Shape: draft, base main, first line Fixes #17158. It is the body's only closing keyword, and ruling A (5644350616, landing route 5815151991, scope note 5825830323) is delivered whole, so the merge should close the card.

    • Scope: 46 files, +970/−2074, and all of it is removal apart from the registration and the pin:

      • Source: api/export.zod.ts, the family removed; contracts/export-service.ts and its test deleted; the contracts/index.ts barrel line; a docblock in contracts/automation-service.ts; the ScheduleState section of automation/execution.zod.ts.
      • Registration: 13 RETIRED_DEFS_BY_MAJOR[18] entry files, the semantic entry export-job-family-retired, and the generated registry.ts.
      • Pins: a new walking pin export-job-family-retirement.test.ts, registered in vitest.repo-tests.json.
      • Generated shards and reference pages: all removals.
      • No governed path, and no content/docs/releases/.
    • Reference surface, measured by the seat on main: outside packages/spec, the retired names appear only in:

      • two unreleased changesets;
      • three generated reference pages;
      • docs/qa/platform-checklist/FOLLOW-UPS.md;
      • comment lines in the dogfood expression-conformance.ledger.ts.

      No code imports them. The dev's objectui reading at pin f8a9d0fb (0 non-markdown hits, controls lit) and cloud main (0) are recorded in the PR body.

    • Tests: spec local 539 files / 15777 passed; spec repo 32 / 586; the spec typecheck exits 0. Consumers: vitest-filter-preflight 65/65, and dogfood expression-conformance 7/7. Three ablations each went red 2 and were restored clean:

      • a re-planted ExportJobStatus;
      • the ScheduleState registry row deleted;
      • a manifest def re-added.
    • Gates: 111 derived, 109 run, all exit 0 at a050a8a7. Two NOT MEASURED (whole-workspace build prerequisites) are left to CI.

    • CI at this head: 14 success / 2 skipped / 16 in progress / 0 failing (an honest in-progress reading).

    Contract review: owed on the path limb. An isolated at-tier reviewer is running on this head. needs:contract-review is hung on PR #20194 in the same act.

    Landing order: this PR text-conflicts with PR #20192 (#19543, p1) in packages/spec/src/migrations/registry.ts and packages/spec/src/type-alias-convention.pin.test.ts. PR #20192 lands first. This PR then merges origin/main forward through scripts/pm/os-regen-merge.sh, re-deriving the type-alias pin count from the merged tree, not by arithmetic. The merged head gets a delta at-tier review before it is readied.

    Deviations

    • origin/main was merged once (369bcbed). The ScheduleState rows that main's side resurrected were removed again by the gate's baseline deletion, in its own regen commit.
    • check:future-spec-major findings were fixed: the tombstones name the release line 17.
    • Commits carry the model-free trailer pair.

    Findings, one line each

    • GET /api/v1/data/:object/export reads ?format= as csv, json or xlsx and falls back to csv for any other value (rest-server.ts:10324-10326). Reach is unmeasured, so ⛔ not filed → Acceptance notes.
    • ExportFormat and ExportImportTemplateSchema have no reader outside spec. They are outside ruling A's scope → Acceptance notes.
    • .changeset/19365-…:98 cites IExportService.listExportJobs, which this removes. The changeset cannot be edited here → Acceptance notes for release compilation.
    • FOLLOW-UPS.md §9c lists candidates this resolves → Acceptance notes.
  9. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    Landed: PR #20194 → 4db1bf1715 · 2026-09-27T08:14Z

    domain:spec seat 1 (session_01Rjy9MeetSfq34PKn81CRiN), claim 5852337804. Landing record.

  10. added 3 commits that reference this issue on Sep 28, 2026
    4db1bf1
    3875ae6
    6d2571f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions