Skip to content

feat(spec,platform-objects): add degraded to the job status vocabulary (#7072) - #7340

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-7072-degraded-status
Aug 10, 2026
Merged

feat(spec,platform-objects): add degraded to the job status vocabulary (#7072)#7340
os-zhuang merged 1 commit into
mainfrom
claude/issue-7072-degraded-status

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes #7072

Mechanical execution of the 2026-08-08 maintainer ruling on #5548 — the consumer-side half of the job outcome channel whose producer half #6617 already shipped. Quoted verbatim from that ruling:

Vocabulary stays minimal — one additional outcome meaning "completed without accomplishing the work". ⛔ Do not open an enum family; a second key would need its own pull.

Nothing here reopens that decision, and no second key was added.

Premise re-measured on origin/main

Re-verified at 3e8e669c0 (the card measured 2c7e62d5, triage 2f3e793) before any edit — premise holds, unchanged:

Site Declaration on origin/main Carried degraded?
packages/spec/src/system/job.zod.ts:178 z.enum(['running','success','failed','timeout']) no
packages/platform-objects/src/audit/sys-job-run.object.ts:49 Field.select(['running','success','failed','timeout'], …) no
packages/platform-objects/src/audit/sys-job.object.ts:73 Field.select(['success','failed','timeout','running'], …) no

The six-item change set

  • 1. job.zod.ts'degraded' added to JobExecutionStatus, with TSDoc citing DbJobAdapter 把「handler 没抛错」记成 sys_job_run.status='success' —— 内部自行降级的 job(如 wait 唤醒打空)在作业审计面上仍显示成功 #5548's ruling and stating: degraded is not a failure and never retries; reason rides the existing error / last_error columns with failure_count flat; and the cost of that choice in place — a column labelled "Error" may carry a non-error note when status === 'degraded'.
  • 2. job.test.ts — accept/reject pins and the round-trip list extended to five values, plus a new pin on the exact vocabulary and a degraded round-trip case.
  • 3. sys-job-run.object.tsstatus select.
  • 4. sys-job.object.tslast_status select.
  • 5. i18n bundles regenerated — en / zh-CN / ja-JP / es-ES, exactly the four predicted, two option maps each.
  • 6. Spec artifacts regenerated — see the correction below; the two files the card named are name-level indexes and legitimately do not change.

Why sites 1 and 3–4 could not be split

The two platform-object selects are enforced, not merely declared: ObjectQL's record validator (validation/record-validator.ts:578) refuses an out-of-vocabulary select value with invalid_option, and DbJobAdapter.finishRun wraps its update in a best-effort try/catch that only logs. A commit where the spec enum permits a value the selects refuse is therefore a silently dropped write leaving the run row running forever — not a type error. One card, per the filer's recommendation A and the services seat's endorsement.

Correction to change-set item 6

Item 6 named packages/spec/json-schema.manifest/system.json and packages/spec/api-surface/system.json. Both were rebuilt and neither changes, by design: they index the export name only — literally "system/JobExecutionStatus" and "JobExecutionStatus (type)" — never the enum members. The artifact that does carry the value list, packages/spec/json-schema/, is gitignored (.gitignore:61, 0 tracked files).

Item 6 is nonetheless not a no-op. check:generated proved one tracked generated artifact stale, and it is the one that carries the values — content/docs/references/system/job.mdx:

-| **status** | `Enum< 'running' \| 'success' \| 'failed' \| 'timeout' >` | ✅ |
+| **status** | `Enum< 'running' \| 'success' \| 'failed' \| 'timeout' \| 'degraded' >` | ✅ |

Regenerated via pnpm --filter @objectstack/spec gen:docs. content/docs/releases/ was not touched.

Reverse verification — direction predicted before running

Prediction recorded first: with site 1 alone reverted to origin/main and the new tests in place, the degraded accept pin, the five-value order pin and the degraded round-trip must go red, and nothing else may move.

Measured — exactly that, no collateral:

FAIL src/system/job.test.ts > JobExecutionStatus > should accept valid execution statuses
FAIL src/system/job.test.ts > JobExecutionStatus > should carry exactly the five ruled values, in declaration order
FAIL src/system/job.test.ts > JobExecutionSchema > should accept degraded execution
FAIL src/system/job.test.ts > JobExecutionSchema > should accept all execution statuses
Tests  4 failed | 43 passed (47)

Restored → Tests 47 passed (47).

Honest note on one pin's direction: the added reject assertions (partial, skipped, Degraded) are green both before and after — they are refused by the four-value and five-value enums alike. They pin the ruling's closure ("do not open an enum family") against a future widening, and cannot go red on this change. They are coverage against drift, not evidence for this diff, and are labelled as such rather than presented as verification.

Gates

Run on the rebased tree (branch is rebased onto f3f855ac1):

Gate Result
pnpm --filter @objectstack/spec build pass — run before every dist-derived regen
check:generated ✓ All 11 generated artifacts are up to date
check:i18n OK (9 package(s) — all bundles in sync, no undeclared authoring keys)
check:i18n-coverage OK (12 config(s), 660 baselined untranslated string(s), none new)
check:nul-bytes OK (scanned 6593 text file(s) … no raw ASCII control bytes)
@objectstack/spec test Test Files 359 passed (359) / Tests 9383 passed (9383)
@objectstack/platform-objects test Test Files 11 passed (11) / Tests 289 passed (289)
spec + platform-objects typecheck pass

Translations — a judgement call worth a reviewer's eye

The bundle generator seeds a new key with its source text and says so: "new schema keys are added filled with the source text, and they still need translating." It produced degraded: "degraded" in all three non-English locales, beside fully translated siblings. I translated them rather than ship the raw seed:

Locale Value Siblings, for register
zh-CN 降级 运行中 / 成功 / 失败 / 超时
ja-JP 縮退 実行中 / 成功 / 失敗 / タイムアウト
es-ES Degradado En ejecución / Correcto / Fallido / Tiempo de espera agotado

There is no prior in-repo translation of this term to follow, so these are my choice, not a precedent lookup — flagging explicitly for a native reviewer, especially ja-JP 縮退.

Targeted in-flight check (metadata lane)

Run against all 20 open PRs by diffing each PR head against origin/main:

Scope

Six items, nothing else. Deliberately not here: the DbJobAdapter / bumpJob wiring that maps a resolved outcome onto these values (that is #5548, which this unblocks), and objectui's Studio jobs view meeting a fifth value it has no label or colour for (separate repo, now fileable since the value exists).

Nothing yet writes degraded, so this is additive and inert until #5548 lands. No docs/adr/** or content/docs/releases/ changes.


Generated by Claude Code

…ary (#7072)

Executes the 2026-08-08 maintainer ruling on #5548 — one additional outcome
meaning "completed without accomplishing the work", and no enum family.
This is the consumer-side half of the `JobRunOutcome` producer shape #6617
shipped on `contracts/job-service.ts`.

Three declaration sites move together because the two platform-object selects
are enforced by ObjectQL's record validator (`invalid_option`) while
`DbJobAdapter.finishRun` swallows the rejection in a best-effort try/catch —
a value legal in the spec enum but absent from the selects is a silently
dropped write that strands the run row at `running`, not a type error.

- packages/spec/src/system/job.zod.ts       — JobExecutionStatus + TSDoc
- packages/platform-objects/.../sys-job-run.object.ts — status select
- packages/platform-objects/.../sys-job.object.ts     — last_status select

`degraded` is not a failure and never retries; its `reason` rides the existing
`error` / `last_error` columns with `failure_count` flat, and the TSDoc records
the cost of that (an "Error" column may carry a non-error note).

Also regenerated: i18n bundles (en/zh-CN/ja-JP/es-ES, translated rather than
left at the raw seed) and content/docs/references/system/job.mdx.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PiRUoQkTSBBmpyXBY3cVn2
@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 10, 2026 7:35am

Request Review

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation protocol:system tests tooling labels Aug 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/platform-objects, @objectstack/spec.

106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via @objectstack/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/permissions/system-context.mdx (via packages/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/platform-objects, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/apps.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/field-grouping-and-order.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/platform-objects, @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

7 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

Advisory only. 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.

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

Labels

documentation Improvements or additions to documentation protocol:system size/m tests tooling

Projects

None yet

2 participants