Skip to content

feat(spec)!: retire the incident-response, training and change-management families whole and the ESignatureConfig deadline pair (#15513, #14477, ADR-0049) - #15973

Draft
claude[bot] wants to merge 9 commits into
mainfrom
claude/issue-15513-compliance-families-retirement
Draft

feat(spec)!: retire the incident-response, training and change-management families whole and the ESignatureConfig deadline pair (#15513, #14477, ADR-0049)#15973
claude[bot] wants to merge 9 commits into
mainfrom
claude/issue-15513-compliance-families-retirement

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #15513
Fixes #14477

Two-card fold, one branch, one PR (domain:spec, mode subagent). The three compliance-shaped families — system/incident-response.zod.ts, system/training.zod.ts, system/change-management.zod.ts — leave @objectstack/spec/system whole under ADR-0049 enforce-or-remove via RETIRED_DEFS_BY_MAJOR[18] with one D3 semantic entry per family (the integration/ErrorMappingConfig / PR #15299 precedent), and the ESignatureConfig deadline pair (data/document.zod.ts expirationDays / reminderDays) becomes retiredKey() tombstones with two RETIRED_KEYS_BY_MAJOR[18] entries and one D3 entry (the PR #15514 precedent). Clause-②: yes — published exported symbols and two authorable keys leave; the seat hangs and clears needs:contract-review itself. ⛔ content/docs/releases/** untouched.

Rulings executed (verbatim)

#15513, director ruling 5548577921 (2026-09-05T01:57Z; maintainer, decision batch #40, verbatim 「同意」 — answering "not roadmapped"):

Ruled: A. Each def in the three families leaves the public surface through RETIRED_DEFS_BY_MAJOR with an ADR-0087 conversion per family (D3 semantic entries; no D2 migration sentence, since none is a stack collection member — the same shape PR #15514 used for the deadline keys), the generated reference docs stop advertising a compliance subsystem that does not exist, and the api-surface / declaration-map / export-origins shards regenerate by the repo tooling. Not taken: B ([EXPERIMENTAL — not enforced] tags plus liveness-ledger entries — a human-only signal; an AI generating from the schema still writes notifyRegulators: true and believes it), leaving it (the ~100-key exported surface any future consumer could start depending on with no designed semantics).

Execution: domain:spec lane, M–L, the spec-property-retirement playbook and the #14477 / PR #15514 precedent (same seat, same tooling: mandatory reader census first over packages/** outside packages/spec, tests and changelogs excluded, plus objectui at its pinned sha, with a lit control; regenerate with the repo tooling; pins for refusal through every carrier and a tree-scoped absence scan; check:generated, check:api-surface, check:authorable-surface, check:liveness green). Clause-②: yes (published exported symbols removed) ⇒ needs:contract-review on the PR. Changeset: @objectstack/spec minor with a BREAKING banner naming the 15 retired defs and an adr-0087 disposition registered for the three semantic ids. ⛔ content/docs/releases/** untouched.

#14477, director comment 5548578591 (same batch, same verbatim reply), the 2026-09-02 ruling's own conditional:

The held question is answered — no roadmap ⇒ the ESignatureConfig pair (document.zod.ts expirationDays, reminderDays) retires with the rest, per the ruling's own branch (5518646938)

Execution: domain:spec lane, S, same seat and same playbook as PR #15514: retiredKey() tombstones for the two sites, RETIRED_KEYS_BY_MAJOR[18] entries plus one D3 semantic entry, authorable-surface / reference docs regenerated by the tooling, pins for refusal through every carrier, the reader census the PR #15514 reviewer already measured to zero re-taken on today's origin/main with a control. Clause-②: yesneeds:contract-review on the PR. Changeset: @objectstack/spec minor with a BREAKING banner and the adr-0087 registration. The PR may say Fixes #14477 — nothing else is held on this card.

The def list — nineteen, not fifteen (M2)

The ruling names the families and says "15 defs"; the files and json-schema.manifest/system.json count 19. Every one of them is retired — the number was the card's reading, the families are the ruling's. All forty-five exported names (19 *Schema consts, 20 z.input aliases, 6 *Parsed aliases) leave with them.

file manifest defs (19)
incident-response.zod.ts (8) system/Incident, IncidentCategory, IncidentNotificationMatrix, IncidentNotificationRule, IncidentResponsePhase, IncidentResponsePolicy, IncidentSeverity, IncidentStatus
training.zod.ts (5) system/TrainingCategory, TrainingCompletionStatus, TrainingCourse, TrainingPlan, TrainingRecord
change-management.zod.ts (6) system/ChangeImpact, ChangePriority, ChangeRequest, ChangeStatus, ChangeType, RollbackPlan

Reader census (M1) — three takes, zero readers, every leg with a lit control

Word-bounded grep over all 45 exported names; tests and CHANGELOGs excluded; objectui read at the pinned sha a472b07 (the sibling checkout is exactly at the pin). Taken at b398ad258 (branch base), 82e5f28ca (first merge of main) and 70582583f (final head, origin/main 0cf086759 merged) — identical each time.

leg families control (ObjectSchema, FieldSchema, defineStack / ViewSchema)
packages/** outside packages/spec (+ packages/drivers/driver-turso/src/spec, re-added after the --exclude-dir=spec sweep) 0 336
apps/**, examples/**, skills/** 0 readers (one word-bounded line: the English word inside examples/app-showcase/src/automation/flows/index.ts:1237, title: 'Incident push failed: …' — a notify-message string literal, not a reference to the type) 192
objectui at a472b07 0 342
pair (ESignatureConfig*, eSignature, expirationDays, reminderDays), all three legs 0 / 0 / 0 inside packages/spec/src: document.zod.ts, document.test.ts (+ the new kit files)

cloud and real customer configurations are UNMEASURED (the changeset says so verbatim). skills/, docs/, .claude/, README.md, ROADMAP.md: zero mentions.

What changed

Hot file (M5)

packages/spec/src/migrations/registry.ts is generated from entries/; my edits there are 25 new entry files plus one appended sentence in the hand-written step-18 rationale — add-only, no reordering. Main's own new entry (18.plugin-security-scanner-retired.ts, PR #15930) text-merged clean beside them (check:migration-registry: current, 161 semantic / 105 retired-key / 116 retired-def). The #14478 stack (PRs #15626, #15814) merges main after this lands through scripts/pm/os-regen-merge.sh.

Verification (final head 70582583f, origin/main 0cf086759 merged via os-regen-merge.sh, both times)

  • pnpm --filter @objectstack/spec build — VERDICT command-exit 0 (2m24s held).
  • check:generated — "✓ All 15 generated artifacts are up to date." check:migration-registry current; check:adr-0087-registration ✓.
  • Targeted vitest under the verify lock: 13 files / 351 tests passed (the two new pins, document.test.ts, the type-alias pin, message-queue-retirement, migrations, strictness-ledger, retired-key-migrate-sentence, alias-integrity, export-list, root-index, category-title, file-description).
  • pnpm --filter @objectstack/spec typecheck — exit 0 (tsc, scripts, test layer: "54 file(s) / 261 error(s) … held", unchanged).
  • Reverse verification (downstream direction, pnpm --filter '...@objectstack/spec' = consumers): a probe file under packages/core importing IncidentSchema, TrainingCourseSchema, ChangeRequestSchema, type IncidentResponsePolicy and authoring expirationDays on an ESignatureConfigtsc exit 2 with TS2305 ×3, TS2724 (ChangeRequestSchema — "Did you mean ChangeSetSchema?") and TS2322 (the pair's never input); the survivor control (DataClassificationSchema, ComplianceFrameworkSchema, ESignatureConfigSchema) → exit 0. Probe removed under an EXIT trap; git status clean.
  • Gate families derived by node scripts/pm/dispatch-gates.mjs on the final tree and reconciled with --ran: 116 derived, 116 run, 0 UNRUN. 113 green, including check:api-surface, check:authorable-surface, check:liveness, check:docs, check:variant-docs, check:dts-closure, check:doc-anchors, check:quick-reference-counts, check:cross-package-test-inputs ("27 package(s) read outside themselves, all declared"), ci-filter parity ("all 162 declared cross-package glob(s) … covered"), check:nul-bytes, the three lint-doc gates (lint closure built). 3 NOT MEASURED, all exit-3/prerequisite refusals needing the whole-repo dist (check:dual-build-cjs-loads, check:skill-examplespackages/client-react/dist unbuilt, check:type-check-debt --re-measure — 32 unbuilt dependencies; its coverage half passed): CI's Lint & Repo Gates runs them.
  • Lint: pnpm lint is CI's; locally the 32 changed source files + the generated registry.ts under the repo config with --no-inline-config: 0 errors / 0 warnings (--format json); the config is not type-aware (eslint.config.mjs:328), so this diff moves no untouched file's verdict.
  • turbo ls --affected vs the merge base: 78 of 79 packages (everything downstream of spec) — the farm run is CI's.
  • Liveness (M8): none of the families, document or ESignatureConfig is an enrolled packages/spec/liveness/ type, so check:liveness walks none of them; green, no rows invented.

Not in this PR

🤖 Generated with Claude Code

https://claude.ai/code/session_01M59rPZZFzqhfMUPFqqZTkf


Generated by Claude Code

…ment families whole and the ESignatureConfig deadline pair (ADR-0049)

Nineteen defs and forty-five exported names leave @objectstack/spec/system via
RETIRED_DEFS_BY_MAJOR[18] with three D3 semantic entries; the fourteen deadline-key
tombstones leave with their defs' source and their registry entries stay as history.
ESignatureConfig.expirationDays / reminderDays become retiredKey() tombstones with two
RETIRED_KEYS_BY_MAJOR[18] entries and one D3 entry. Generated artifacts follow in the
next commit (build + check:generated --fix).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M59rPZZFzqhfMUPFqqZTkf
…e compliance-families retirement

authorable-surface/system.json -88 rows and authorable-defaults/system.json -9 (the
deliberate hand-deletions gate (a) asks for on a whole-def retirement), data.json +2
[RETIRED] rows and -2 defaults for the ESignatureConfig pair; api-surface -44,
declaration-map -38, export-origins -44; the three reference pages removed and the
system nav / index regenerated; strictness-ledger counts follow the schema files.
All by the repo tooling (build + check:generated --fix).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M59rPZZFzqhfMUPFqqZTkf
…gs in the compliance-families pin

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M59rPZZFzqhfMUPFqqZTkf
…es (36 -> 33, 207 -> 204)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M59rPZZFzqhfMUPFqqZTkf
…r counts on the merged tree

The merge script's designed collection point: both artifacts were taken from main's side
of the merge and regenerated on the merged tree (gen:docs, gen:strictness-ledger) so the
system rows the retirement removed and the automation rows main added compose.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M59rPZZFzqhfMUPFqqZTkf
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 103 documentable anchor(s). ⚠️ 32 changed file(s) yielded no anchor (packages/spec/PROTOCOL_MAP.md, packages/spec/api-surface/system.json, packages/spec/authorable-defaults/data.json, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

12 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/api/error-handling-client.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema))
  • content/docs/api/error-handling-server.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema))
  • content/docs/api/wire-format.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema))
  • content/docs/concepts/metadata-driven.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema))
  • content/docs/data-modeling/field-types.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema))
  • content/docs/data-modeling/objects.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema))
  • content/docs/getting-started/examples.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema), not_started (literal, a string literal in TrainingCompletionStatusSchema))
  • content/docs/kernel/cluster.mdx (via RETIRED_DEFS_BY_MAJOR (symbol, a top-level const object))
  • content/docs/kernel/contracts/data-engine.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema))
  • content/docs/protocol/kernel/http-protocol.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema), user_123 (literal, a string literal on a changed line))
  • content/docs/protocol/kernel/realtime-protocol.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema), user_123 (literal, a string literal on a changed line))
  • content/docs/protocol/objectui/layout-dsl.mdx (via in_progress (literal, a string literal in TrainingCompletionStatusSchema))
What this run could not see
  • 32 changed file(s) yielded no anchor (packages/spec/PROTOCOL_MAP.md, packages/spec/api-surface/system.json, packages/spec/authorable-defaults/data.json, …) — pages documenting those are invisible to this run
  • 6 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 61 of 219 client-bound route-ledger rows — the other 158 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 158: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 129 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json f7db8f4fd268a86a08c62ae4894cf7417720f8c9packageMentionDocs.

Which tree this was computed on

This run read content/docs from 98bba19479d746740ba173835f7a3b8d7e230eb5 — the merge of head f8ccc47539ae4f189fb2be7bf5e56c53e27c0811 into base f7db8f4fd268a86a08c62ae4894cf7417720f8c9, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 98bba19479d746740ba173835f7a3b8d7e230eb5 && git checkout 98bba19479d746740ba173835f7a3b8d7e230eb5
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f7db8f4fd268a86a08c62ae4894cf7417720f8c9 f8ccc47539ae4f189fb2be7bf5e56c53e27c0811 && git checkout -B drift-repro f7db8f4fd268a86a08c62ae4894cf7417720f8c9 && git merge --no-ff f8ccc47539ae4f189fb2be7bf5e56c53e27c0811

node scripts/docs-audit/affected-docs.mjs --json f7db8f4fd268a86a08c62ae4894cf7417720f8c9

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs f7db8f4fd268a86a08c62ae4894cf7417720f8c9 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

CI note from the dispatching seat. Of the two red checks on 70582583f, Test Core (2/6) and the PM dispatch-gates self-test step of Lint & Repo Gates are this PR's (the examples/** cross-package hint reaching examples/app-crm/test/smoke.test.ts, and the spec suite on the merge with main) — a fix lap is in flight. A THIRD failure will appear on the next push regardless: Lint & Repo GatesMerge-driver wiring gate is red on main itself since ~17:22Z (anchor card #15992, priority:p0: the check-regen-pending.mjs --self-test fixture runs pnpm -s unpinned and Corepack now resolves pnpm latest = 12.3.4, which rejects -s). That one is not this PR's; the fix-forward is dispatched from #15992 and jumps the queue. This PR flips to ready + auto-merge once its own two checks are green and main is green again.


Generated by Claude Code

…les and drop the dead PROTOCOL_MAP row

The dispatch-gates self-test pins that no cross-package hint reaches a test file
outside packages/**; a bare examples/** glob covered the CRM example's smoke test.
The pin now scans only JSON / MD / MDX / YAML under examples/ (every example has its
own tsc typecheck) and the declaration + turbo.json name those five extension globs
with heldBy witnesses. PROTOCOL_MAP.md linked the deleted change-management module;
its row is dropped (the map test's own remedy).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M59rPZZFzqhfMUPFqqZTkf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment