You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[finding] spec: MetadataChangedEventPayloadSchema says every metadata persistence layer MUST emit it — zero producers or consumers in-tree, and its bigint version field cannot cross JSON #14180
Found while implementing #13331 (which had to answer where the cluster payload contract lives). Observation, not a defect repro — ADR-0049 enforce-or-remove candidate for the spec lane.
packages/spec/src/kernel/cluster.zod.ts declares MetadataChangedEventPayloadSchema with: "All metadata persistence layers MUST emit this event after any successful write. Readers (registry caches, query engines, REST routers) MUST subscribe to it."
Tree-wide grep for MetadataChangedEventPayload: every hit is the spec package itself (schema, its own tests, api-surface/export-origins baselines, a type-alias pin) plus ONE doc-comment mention in packages/metadata/src/metadata-manager.ts saying its ClusterMetadataChangedPayload "aligns with" it — which it does not: the shipped payload is originNode/type/event, the declared one is type/name/tenantId/version/operation/correlationId. Zero runtime producers, zero subscribers, zero imports outside spec.
Both shipped cluster channels ignore it:
metadata.changed — ClusterMetadataChangedPayload in @objectstack/metadata (originNode + replayed watch event, no version)
authz.invalidated — payload in @objectstack/core's authz-invalidation-channel module (epoch hint)
Structural note: the declared version field is z.bigint(). JSON.stringify throws on bigint, so the payload as declared cannot cross any JSON transport without a custom codec no driver ships — a MUST-emit contract that no conforming emitter could serialize.
What this card asks
The spec seat's enforce-or-remove call: either a consumer materializes (and the shipped channels are migrated onto it — which #13331's ruling argues against for the registry lane, since peers deliberately re-read rather than version-compare), or the declared payload is retired via the ADR-0087 route. Not this lane's file surface (packages/spec single owner).
Dedup: REST open-issues sweep (443 open issues, positive control hit) — zero cards mention MetadataChangedEventPayload.
Ruled route: remove, via the ADR-0087 retirement route (spec-property-retirement playbook, standard removal for a declared surface with zero producers and zero consumers). Rationale, in the order the maintainer's rulings give it: a MUST-emit contract that no conforming emitter could serialize (z.bigint() cannot cross JSON without a codec no driver ships) is declared-but-unenforceable by construction, which is ADR-0049's remove branch; the 2026-08-27 ruling on transitions (「短期不考虑渐进」) removes the staged-window option; and #13331's ruling already settled that peers re-read rather than version-compare, so the one plausible future consumer was decided against. ⛔ Not "make a consumer" — that is contract growth with no pull. The doc-comment in packages/metadata/src/metadata-manager.ts that says its payload "aligns with" this schema is corrected in the same PR (it does not, and after removal there is nothing to align with).
Clause-②: yes at dispatch — the accept set of a published spec entry moves (a schema disappears), so the spec seat runs it at the contract-review tier with the ADR-0087 registry entry as the deliverable's proof.
Size/model suggestion: S–M (registry entry, baseline regeneration, pin updates per the playbook), opus.
Claim: PM loop, domain:spec seat (seat post #6017), R6 of this shift — executing the triage-ruled route (comment 5502971695, 2026-09-02): remove MetadataChangedEventPayloadSchema via the ADR-0087 retirement route (spec-property-retirement playbook; retired-def registry entry as the deliverable's proof), and correct the "aligns with" doc-comment in packages/metadata/src/metadata-manager.ts in the same PR as the triage prescribes. ⛔ Not "make a consumer".
Session: session_0174WZTU6XcFcS7g2kykC53i (GitHub zhuangjianguo)
Branch: claude/issue-14180-retire-metadata-changed-event-payload
Claimed at 2026-09-04T02:32Z; queue read 00:40Z (next by age after #14168; the maintainer's 「14996 插队」 card ran ahead of it). Slot check: 3-cap, 1 dev running (#14168) before this claim.
File surface: packages/spec/src/kernel/cluster.zod.ts (the schema + its type alias), packages/spec/src/kernel/cluster.test.ts (its pins → retirement pins), packages/spec/src/type-alias-convention.pin.test.ts (the Iso394 alias pin), the ADR-0087 registry entry under packages/spec/src/migrations/entries/ (+ generated registry.ts), generated baselines (api-surface, export-origins, declaration-map, docs), the hand-written docs that name the payload (cluster-semantics.mdx §5 per the metadata-manager comment; affected-docs names the rest), packages/metadata/src/metadata-manager.ts:234 (doc-comment only, triage-prescribed), a @objectstack/spec changeset. ⛔ packages/metadata beyond that one comment, packages/core, packages/metadata-protocol, content/docs/releases/**.
Clause ② yes (a published schema disappears) — needs:contract-review hung on this card in this stroke; the dev hangs it on the PR. Contract review at tier by this seat. Pre-dispatch readings (2026-09-04T02:32Z): consumers of MetadataChangedEventPayload on origin/main2cc46103 are the schema, its own test, the alias pin and the one doc-comment — zero runtime producers or subscribers, as the card measured; 0 of 24 open PRs touch cluster.zod.ts; H17 on-hold trigger-file index: no hit.
Dispatch (R6 of this shift, 2026-09-04T02:34Z) — domain:spec seat, session_0174WZTU6XcFcS7g2kykC53i, seat post #6017. mode:subagent, model: fable (CONTRACT_REVIEW_TIER — Clause ② yes overrides the triage's opus suggestion), size M, Clause ② yes (dual carrier: needs:contract-review hung on this card at claim; the dev hangs it on the PR). The dev leaves its own Claim: comment below carrying Clause-②: yes and its file surface before its first edit.
Scope handed to the dev — the triage-ruled route verbatim: remove MetadataChangedEventPayloadSchema via the ADR-0087 retirement route (spec-property-retirement playbook; a retired-def registry entry as the deliverable's proof; liveness ledger discipline; generated baselines; the cluster.test.ts pins turned into retirement pins with a positive control; the Iso394 alias pin; the hand-written cluster-semantics docs), plus the one triage-prescribed doc-comment correction in packages/metadata/src/metadata-manager.ts:234 (the only edit allowed under packages/metadata). ⛔ Not "make a consumer". Premise re-verified first (zero producers/subscribers on origin/main; a real consumer found ⇒ stop and report). Changeset @objectstack/spec minor + **BREAKING** banner under the post-cut lockstep convention with adr-0087: registered <ID> (the entry's prose spelled per #15130 — no call parentheses, no issue ids in the strings). Read-and-report: whether cluster-semantics.mdx still asserts a MUST-emit protocol elsewhere, and whether metadata-protocol's ClusterMetadataMutationPayload docs name the removed schema. ACCEPT path: report → fuse read → contract review at tier → landing at all-green.
Claim: os-dev subagent dispatched by the domain:spec PM seat (PM claim comment 5534838453; triage-ruled route in comment 5502971695 — remove via the ADR-0087 retirement route, spec-property-retirement playbook; ⛔ not "make a consumer").
Session: session_0174WZTU6XcFcS7g2kykC53i
Branch: claude/issue-14180-retire-metadata-changed-event-payload (pushed empty first, as the write-route probe)
Clause-②: yes
File surface (matches the PM claim; two deltas stated below):
packages/spec/src/kernel/cluster.zod.ts — MetadataChangedEventPayloadSchema + MetadataChangedEventPayload removed, with an in-file retirement note
packages/spec/src/kernel/cluster.test.ts — its three pins become retirement pins (the name is absent from the module namespace, with a positive control on a sibling schema that stays)
packages/spec/src/type-alias-convention.pin.test.ts — the Iso394 pin line
packages/spec/src/migrations/entries/retired-defs/18.kernel__MetadataChangedEventPayload.ts + one D3 semantic entry under entries/semantic/ (the id the changeset registers), then gen:migration-registry regenerates registry.ts
generated baselines via check:generated --fix (api-surface, export-origins, declaration-map, docs, json-schema manifest, spec-changes, upgrade guide — whatever it proves stale)
content/docs/kernel/cluster.mdx — the hand-written page that names the payload (the "Target spec (planned)" block and the §6.3 reader contract that goes with it), plus whatever affected-docs names; never content/docs/releases/**
packages/metadata/src/metadata-manager.ts — the one doc-comment only (triage-prescribed)
Delta 1 (playbook §4, orphan value schema): MetadataChangeOperationSchema / MetadataChangeOperation in the same file exist only to type the removed payload's operation field — zero other consumers on origin/main2cc4610 (every hit is the payload itself, its own Iso393 pin line, and generated artifacts). An exported value schema with no consumer reads as a capability, so it leaves with the payload: a second retired-def entry 18.kernel__MetadataChangeOperation.ts (this def IS in json-schema.manifest/kernel.json, so the manifest deletion gate demands the entry; the payload def never was — z.bigint() is skipped by the JSON Schema build) and the Iso393 pin line.
Delta 2: cluster-semantics.mdx does not exist on origin/main — apps/docs/redirects.mjs redirects it to /docs/kernel/cluster; the page that names the payload is content/docs/kernel/cluster.mdx. The metadata-manager comment's stale cluster-semantics.mdx §5 pointer is corrected together with the "aligns with" claim.
⛔ Not touched: packages/metadata beyond that one comment, packages/core, packages/metadata-protocol, content/docs/releases/**. The assignee stays the PM's.
{
"issue": 14180,
"status": "done",
"branch": "claude/issue-14180-retire-metadata-changed-event-payload",
"pr": "https://github.com/objectstack-ai/objectstack/pull/15139",
"premise_still_valid": true,
"summary": "Retired MetadataChangedEventPayloadSchema / MetadataChangedEventPayload and, per playbook §4 (orphan value schema, the kernel/DistributedStateConfig precedent), the MetadataChangeOperationSchema / MetadataChangeOperation enum that existed only to type its operation field, from packages/spec/src/kernel/cluster.zod.ts via ADR-0087 route 3: retired-def entries 18.kernel__MetadataChangedEventPayload + 18.kernel__MetadataChangeOperation and the D3 semantic entry metadata-changed-event-payload-retired (registry.ts regenerated: 148 semantic / 86 retired-key / 94 retired-def), json-schema.manifest/kernel.json loses kernel/MetadataChangeOperation under the manifest deletion gate (the payload def was never in the manifest — the JSON Schema build skips bigint), api-surface / export-origins / declaration-map −4, references page + strictness-ledger counts regenerated, retirement pins (runtime namespace probes on ./cluster.zod and ./index with ClusterCapabilityConfigSchema as positive control) in cluster.test.ts, Iso393 / Iso394 deleted (829 → 827 with a receipt), content/docs/kernel/cluster.mdx rewritten wherever it described the retired version-compare protocol (§6 intro, §6.1, lane-1 'Target spec (planned)' block, §6.3, §7.3), the metadata-manager.ts doc-comment corrected (no 'aligns with', no dead cluster-semantics.mdx pointer), and a @objectstack/spec minor + BREAKING changeset carrying the registered marker; draft PR #15139 at e95a24e52 with needs:contract-review hung and read back. Premise re-verified at origin/main 2cc461030: zero producers / subscribers / imports outside packages/spec, and no hit in objectui at the pinned sha 67dadd60 (positive control hit). Deviations from the PM claim, both declared in my claim comment 5534876299: the orphan enum leaves with the payload, and the hand-written page is kernel/cluster.mdx (cluster-semantics.mdx is a redirect in apps/docs/redirects.mjs). Notes for the PM: the card arrived assigned to the PM and was left so; commit trailers use the model-free pair the dispatch prescribed (Claude-Session + Co-authored-by: Claude) rather than the harness's default attribution line; step-18 D3 semantic entries — mine and every precedent — do not project into spec-changes.json / protocol-upgrade-guide.md while both gates are green, which reads as projection design (unreleased major), so it is reported here and not filed. Read-and-report: metadata-protocol's ClusterMetadataMutationPayload docs do not name the removed schema (zero hits); the cluster.mdx sentences the removal falsified were all on the page already in surface and are fixed there (listed in the PR body).",
"tests": "All at the final head e95a24e52, exits captured before any pipe, verdict lines quoted. spec build (verify lock): exit 0 — 'check-dts-emitted: @objectstack/spec - 34/34 declared declaration file(s) present.' and 'ℹ️ 1 schema(s) left the published set since 2cc4610304c5, each declared (#4725): json-schema/kernel/MetadataChangeOperation.json — RETIRED_DEFS_BY_MAJOR, major 18.' · check:generated: first run named 5 stale (api-surface, export-origins, declaration-map, docs, strictness-ledger), --fix exit 0, second run exit 0 '✓ All 15 generated artifacts are up to date.' (re-run again after the reverse leg + rebuild at HEAD: exit 0, same line) · vitest src/kernel/cluster.test.ts src/type-alias-convention.pin.test.ts (lock): exit 0 'Test Files 2 passed (2)' / 'Tests 23 passed (23)' · pnpm --filter @objectstack/spec typecheck (tsc + check:scripts-typecheck + check:test-typecheck, lock): exit 0 'check:test-typecheck: OK — … 54 file(s) / 261 error(s) / 145 pinned signature(s) held' · check:migration-registry exit 0 '✓ src/migrations/registry.ts is current (148 semantic, 86 retired-key, 94 retired-def)' · check:liveness exit 0 '✓ … state-counts.md is current — the same 35 row(s)' · check:strictness-ledger exit 0 '✓ … counts.md is current — 439 site(s) measured' · eslint --no-inline-config over the 8 edited TS files: exit 0, no findings · pnpm check:doc-authoring exit 0 '✓ … 14710 customer-facing string(s) across 726 spec sources clean' · pnpm check:nul-bytes exit 0 'check-nul-bytes: OK (scanned 8234 text file(s) …)' · node scripts/check-system-context-census.mjs exit 0 'OK — 106 elevation read sites in 20 packages across 45 files, all anchored' (no --fix demanded) · check-changeset-no-major --base 2cc461030 exit 0 '✓ This diff introduces no `major` bump.' · check-adr-0087-registration --base 2cc461030 exit 0 '✓ … 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … [BREAKING] registered metadata-changed-event-payload-retired (new here)' · downstream: closure built in two lock-held layers (types formula metadata-core observability sdui-parser; core lint metadata-fs driver-sql platform-objects driver-sqlite-wasm), each 'VERDICT command-exit 0'; pnpm --filter @objectstack/metadata typecheck exit 0 (tsc --noEmit clean — nothing imports the removed symbols); vitest run --maxWorkers=2 in @objectstack/metadata exit 0 'Test Files 46 passed (46)' / 'Tests 705 passed (705)' · dispatch-gates.mjs --repo objectstack-ai/objectstack --commands exit 0 (derived at e95a24e52, '⚠️ STALE TREE — … at least 2 commit(s) behind origin/main'); derived families touched by this diff all exit 0: check-affected-docs ('# 1 docs name something this change touched' — cluster.mdx), check-drift-comment, doc-frontmatter, doc-route-spelling, docs-section-name, section-landing-index, keyed-text-bounds, undeclared-dep-imports, doc-anchors, docs-redirects, docs-single-h1, corpus-claim-drift, cross-package-test-inputs, spec-parsed-alias ('827 pinned isomorphic'), test-source-alias, quick-reference-counts, type-check-coverage, spec check:variant-docs / exported-any / dual-source-exports / entry-nameability / browser-reachable-entries / empty-state / llms-txt / skill-refs / yaml-examples / api-surface / export-origins / docs / spec-changes / upgrade-guide / authorable-surface. NOT MEASURED by their own words: pnpm check:type-check-debt exit 3 'check-type-check-coverage: PREREQUISITE NOT MET — --re-measure cannot run: 27 workspace dependenc(ies) … have no built type entry point on disk' (whole-repo closure; CI's); check:skill-examples exit 1 'packages/client-react/dist holds no .d.ts declarations — the package is not built' (closure is runtime/rest/objectql-sized; diff touches no skills/ or SDK docs); full pnpm lint sweep not run (CI-owned; eslint above covers every edited TS file); check:react-declaration-parity EXTERNAL_INPUT_REQUIRED. Reverse verification, one leg from the committed state e95a24e52 under the lock with a trap restore: git restore --source=2cc461030 -- packages/spec/src/kernel/cluster.zod.ts; mutation confirmed on disk ('export const MetadataChangedEventPayloadSchema' lines 0 → 1, on-disk blob 37fdc590… = BASE blob); leg A vitest cluster.test.ts exit 1 'Tests 2 failed | 18 passed (20)' (both probes 'expected true to be false'); leg B gen:schema exit 1 '❌ 1 RETIRED_DEFS_BY_MAJOR entr(ies) name a schema this build still publishes: kernel/MetadataChangeOperation (registered at major 18)'; restore proven by the caller: git hash-object = 61538d29… = HEAD: blob, git diff HEAD empty, git status --porcelain empty; spec then rebuilt at HEAD (exit 0, same check-dts line) and check:generated re-run (exit 0). No ablation of a build product beyond that leg; the leg's gen:schema wrote only the gitignored json-schema/ tree, replaced by the HEAD rebuild.",
"mcp_calls": "3 — 2 GitHub MCP search_issues (the dedup search for the finding plus its positive control, taken after the REST search endpoint answered 403; channel switch declared) + 1 Claude_Code_Remote subscribe_pr_activity for PR #15139. Every other GitHub read and write (issue body/comments, claim comment, PR create, label add + read-back, PR body read-back, finding create, this report) went through REST with GITHUB_TOKEN.",
"open_questions": [],
"out_of_scope_findings": [
"filed as #15141: four pointers (two .describe() strings in kernel/events/core.zod.ts and kernel/service-registry.zod.ts that gen:docs copies into the reference pages, two comments in metadata-manager.ts) still cite cluster-semantics.mdx, a page redirected to /docs/kernel/cluster — label finding, no assignee"
]
}
Director audit of the contract — PASS (summon 13, session_01WXyGTWPbbreqXow7Z2pZCk; tier fuse read 2026-09-04T01:26Z, get_session served claude-fable-5-1 = CONTRACT_REVIEW_TIER). Subject: PR #15139 at head e95a24e52. The spec seat's in-seat review owns the release; this reading is recorded so the seat can land on it without a second pass, and the stall clause applies at this seat's next check-in if the head is green and unlanded.
Implemented-by: claude/issue-14180-retire-metadata-changed-event-payload (mode:subagent dev under session_0174WZTU6XcFcS7g2kykC53i)
Reviewed-by: session_01WXyGTWPbbreqXow7Z2pZCk
① Derived judgments
Whole-def removal of MetadataChangedEventPayloadSchema / MetadataChangedEventPayload and the orphan MetadataChangeOperationSchema / MetadataChangeOperation, via ADR-0087 route 3: RETIRED_DEFS_BY_MAJOR[18] entries plus the D3 semantic entry, retirement pins on both the module and the @objectstack/spec/kernel entry, positive control kept. Correct.
Zero producers, zero subscribers, zero importers outside packages/spec (objectui at the pinned sha included, with a lit positive control); the bigintversion field could never have crossed a JSON transport, so the declared MUST-emit / MUST-compare contract was unhonourable as written. Removal, not "make a consumer", matches the 2026-09-02 ruling.
content/docs/kernel/cluster.mdx rewritten to the shipped address-only, re-read lanes; the @objectstack/metadata doc-comment no longer claims alignment with a schema it never matched. Correct and complete for the ruling's second clause.
② Semver: @objectstack/spec minor with the BREAKING banner and the ADR-0087 disposition marker — the repository's registered-retirement convention (check-adr-0087-registration recognises the entry; check-changeset-no-major green). Accepted.
③ Boundary flags: the two deviations from the claim (orphan enum leaves with the payload; the hand-written page is cluster.mdx) are both right. Nothing open.
Landing gate as of 03:15Z: mergeable_state: dirty (merge origin/main, merge commit) and CI on the merged head must be green before the carriers clear.
{
"issue": 14180,
"status": "done",
"branch": "claude/issue-14180-retire-metadata-changed-event-payload",
"pr": "https://github.com/objectstack-ai/objectstack/pull/15139",
"premise_still_valid": true,
"summary": "Sync round for PR #15139 (follow-up to the first report, comment 5535134770): origin/main fcc42e6c1 merged as merge commit 9003435dc via scripts/pm/os-regen-merge.sh in a fresh dedicated worktree on the same branch (no rebase, no amend, no force-push, no stash); the helper kept the branch's bytes for every generated shard only the branch had edited and took main's side of the two os-regen-deferred artifacts moved on both sides (content/docs/references/index.mdx, docs/audits/2026-07-unknown-key-strictness-ledger.counts.md), whose hand-off commit the pre-commit hook refused as stale (the helper's designed collection point); both were regenerated from the merged tree (gen:schema via the spec build, gen:docs, gen:strictness-ledger), staged explicitly, the staged diff inspected (only main's automation increments: 1588→1591 schemas, 439→440 sites), and committed as ceb9887c7 with the hook printing 'os-regen: all deferred artifacts are current — marker cleared.'. Pushed fast-forward e95a24e52..ceb9887c7; GitHub now reads the PR head ceb9887c7, mergeable true / mergeable_state blocked (draft + required checks — no longer dirty). PR body PATCHed with the new final-head line and one sync sentence naming the merge commit and the regenerated artifacts (read back byte-identical; the session-URL footer survived in the body and the platform appended its bare one); needs:contract-review read back on the PR and remains on the card. No behaviour change; the merge commit carries git's default message, the regeneration commit the model-free trailer pair; no model identifiers anywhere. Worktree removed without force after the push (exit 0).",
"tests": "All at the merged head ceb9887c7, each part's exit captured before any pipe, verdict lines quoted. spec build (verify lock) exit 0 — 'check-dts-emitted: @objectstack/spec - 34/34 declared declaration file(s) present.' and 'ℹ️ 1 schema(s) left the published set since fcc42e6c1de9, each declared (#4725): json-schema/kernel/MetadataChangeOperation.json — RETIRED_DEFS_BY_MAJOR, major 18.' · check:generated exit 0 '✓ All 15 generated artifacts are up to date.' (once right after the regeneration commit, again after the head rebuild) · vitest src/kernel/cluster.test.ts src/type-alias-convention.pin.test.ts (lock) exit 0 'Test Files 2 passed (2)' / 'Tests 23 passed (23)' · pnpm --filter @objectstack/spec typecheck (tsc + scripts + test-typecheck, lock) exit 0 'check:test-typecheck: OK — @objectstack/spec's test layer compiles under packages/spec/tsconfig.test.json; 54 file(s) / 261 error(s) / 145 pinned signature(s) held' · check:migration-registry exit 0 '✓ src/migrations/registry.ts is current (148 semantic, 86 retired-key, 94 retired-def)' · check:strictness-ledger exit 0 '✓ docs/audits/2026-07-unknown-key-strictness-ledger.counts.md is current — 440 site(s) measured, 1 authorable strip site(s) left' · check-adr-0087-registration --base origin/main (merge base fcc42e6c1) exit 0 '✓ check-adr-0087-registration: 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition. … [BREAKING] registered metadata-changed-event-payload-retired (new here: metadata-changed-event-payload-retired)' · check-changeset-no-major --base origin/main exit 0 'Diffing HEAD from fcc42e6c1 (merge base …) ✓ This diff introduces no `major` bump.' · node scripts/check-system-context-census.mjs exit 0 'check-system-context-census: OK — 106 elevation read sites in 20 packages across 45 files, all anchored' (no --fix demanded) · metadata closure rebuilt in the fresh worktree (11 packages, lock, 'VERDICT command-exit 0'), then pnpm --filter @objectstack/metadata typecheck (lock) exit 0 (tsc --noEmit clean; nothing imports the removed symbols). The three lock-held checks ran under one hold with per-part exits printed (VITEST_EXIT=0, SPEC_TYPECHECK_EXIT=0, METADATA_TYPECHECK_EXIT=0) — the lock's own 'batch-last-exit' caveat is answered by those per-part readings, not by the batch number. Regenerated-docs sanity: zero occurrences of either retired name in content/docs/references/index.mdx and content/docs/references/kernel/cluster.mdx after regeneration. Not re-run this round (unchanged source; first-round readings at e95a24e52 stand): the metadata vitest suite, eslint, check:liveness, check:nul-bytes, check:doc-authoring, the derived docs/alias gates, and the reverse-verification leg (packages/spec/src/kernel/cluster.zod.ts is byte-identical between e95a24e52 and ceb9887c7).",
"mcp_calls": "0 this round (cumulative 3: 2 GitHub search_issues + 1 Claude_Code_Remote subscribe_pr_activity in the first round); the PR PATCH, both read-backs and this comment went through REST with GITHUB_TOKEN.",
"open_questions": [],
"out_of_scope_findings": [
"none new this round (the first round filed #15141)"
]
}
Contract review (Clause ②) on PR #15139 — PASS · ACCEPT: comment 5535235481 (2026-09-04T03:27Z), by the domain:spec PM seat, session session_0174WZTU6XcFcS7g2kykC53i, seat post #6017; tier fuse read 03:26Z, --pair 15139 exit 0; the director's audit 5535153297 concurs. Both declared deviations (the orphan enum leaves with the payload; the hand-written page is kernel/cluster.mdx) accepted. needs:contract-review cleared on both carriers in this stroke. Landing at all-green on the merged head ceb9887c (18 checks running at 03:26Z); on MERGED this card closes via Fixes, pm:dispatched is stripped, landing note here.
{
"issue": 14180,
"status": "done",
"branch": "claude/issue-14180-retire-metadata-changed-event-payload",
"pr": "https://github.com/objectstack-ai/objectstack/pull/15139",
"premise_still_valid": true,
"summary": "Round 3 for PR #15139 after the merge queue dequeued ceb9887c7 with MERGE_CONFLICT (04:33:40Z): origin/main 25a59bd10 merged as merge commit 63c21fc4b in a fresh dedicated worktree on the same branch (no rebase, amend, force-push or stash). scripts/pm/os-regen-merge.sh stopped on the one text conflict, packages/spec/src/type-alias-convention.pin.test.ts, hand-resolved so both intents stack: #14168's Iso867 kept, Iso393 / Iso394 stay deleted, the machine-checked count 830 → 828 in the header comment, the case title and the toHaveLength assertion, with the two rebalancing notes in sequence ('829 -> 830 is #14168's ValueDomainSchema …' then '830 -> 828 is #14180's ADR-0049 retirement …', the latter restated from the post-merge base). The merge was finished by hand with MERGE_HEAD present, so the pre-commit hook took its deferral path for the one artifact the driver declined to text-merge, content/docs/references/index.mdx; regeneration commit fc66ae833 discharged it (gen:schema via the spec build, gen:docs; check:generated --fix found nothing else stale; the hook printed 'os-regen: deferred regeneration discharged — all artifacts current, marker cleared.'). packages/spec/src/migrations/registry.ts, text-merged by git on both sides, was re-run through gen:migration-registry and came out byte-identical (149 semantic / 86 retired-key / 94 retired-def). Files changed in the merge commit beyond the mechanical merge: exactly one, the pin file (hand-resolved; 25 diff lines against origin/main's side, all of them the 830 → 828 count and the deleted Iso393 / Iso394 lines plus the note); registry.ts auto-merged and generator-identical; index.mdx deferred and regenerated in fc66ae833 (main's shared/value-domain page row, 1591 → 1592 schemas). The delta against ceb9887c7 beyond origin/main's own side is empty by path (every changed path is also on main's side) — i.e. identical to ceb9887c7 apart from the pin file's count/notes and the regenerated index. Pushed fast-forward ceb9887c7..fc66ae833; PR head reads fc66ae833, mergeable true / mergeable_state blocked; PR body got a round-3 paragraph under the final-head heading (read back byte-identical). State observed on the PR that I did not set and left untouched: ready_for_review (zhuangjianguo 03:51:32Z), auto_merge_enabled (03:51:42Z), added_to_merge_queue (03:52:36Z), removed_from_merge_queue (github-merge-queue[bot] 04:33:40Z); needs:contract-review was unlabeled on the PR by claude[bot] at 03:28:03Z — after the size-labeler's 03:25–03:26 writes, so not a whole-set PUT strip — and is absent from the card as well, read as the seat's post-PASS act; PR labels now documentation, size/l, tests, tooling. No behaviour change; no model identifiers anywhere; merge commit carries git's default message, the regeneration commit the model-free trailer pair. Worktree removed without force after the push (exit 0).",
"tests": "Every command at the final head fc66ae833, each exit captured before any pipe, verdict lines quoted. Under one lock hold with per-part exits printed (BUILD_EXIT=0, CLOSURE_EXIT=0, VITEST_EXIT=0, SPEC_TYPECHECK_EXIT=0, METADATA_TYPECHECK_EXIT=0 — the lock's 'batch-last-exit' caveat is answered by those, not by the batch number): pnpm --filter @objectstack/spec build exit 0 — 'check-dts-emitted: @objectstack/spec - 34/34 declared declaration file(s) present.' and 'ℹ️ 1 schema(s) left the published set since 25a59bd109a9, each declared (#4725): json-schema/kernel/MetadataChangeOperation.json — RETIRED_DEFS_BY_MAJOR, major 18.' · metadata closure rebuild (11 packages) exit 0 · vitest src/kernel/cluster.test.ts src/type-alias-convention.pin.test.ts exit 0 'Test Files 2 passed (2)' / 'Tests 23 passed (23)' (the pin case recomputes the count from the source and asserts the header and the title agree with 828) · pnpm --filter @objectstack/spec typecheck exit 0 'check:test-typecheck: OK — @objectstack/spec's test layer compiles under packages/spec/tsconfig.test.json; 54 file(s) / 261 error(s) / 145 pinned signature(s) held' · pnpm --filter @objectstack/metadata typecheck exit 0 (tsc --noEmit clean). Lock-free: check:generated --fix exit 0 and the second run at fc66ae833 exit 0 '✓ All 15 generated artifacts are up to date.' · gen:migration-registry exit 0 '✓ wrote src/migrations/registry.ts (149 semantic, 86 retired-key, 94 retired-def)' with an empty git diff · check:migration-registry exit 0 '✓ src/migrations/registry.ts is current (149 semantic, 86 retired-key, 94 retired-def)' · check:strictness-ledger exit 0 '✓ … counts.md is current — 440 site(s) measured, 1 authorable strip site(s) left' · check-adr-0087-registration --base origin/main (merge base 25a59bd10) exit 0 '✓ check-adr-0087-registration: 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition. … [BREAKING] registered metadata-changed-event-payload-retired (new here: metadata-changed-event-payload-retired)' · check-changeset-no-major --base origin/main exit 0 '✓ This diff introduces no `major` bump.' · node scripts/check-system-context-census.mjs exit 0 'check-system-context-census: OK — 106 elevation read sites in 20 packages across 45 files, all anchored' (no --fix demanded) · pnpm check:spec-parsed-alias exit 0 'ADR-0122 type-alias convention: 1519 bare z.input aliases, 828 pinned isomorphic, 691 paired with an XParsed. OK' · node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --tier <my 11 paths> exit 0 ('Model tier — no path-derived mandate: the surface hits none of the 3 declared glob(s)'; Clause ② SUSPECT surface hint on the seven packages/spec/src/** paths — judged from card content, already yes) · dispatch-gates --commands exit 0, derived at fc66ae833 with no STALE TREE warning, 86 commands, byte-identical family to round 1 · os-regen-merge.sh exit 1 (its designed stop on the non-generated conflict) · git merge commit exit 0 (hook: '1 stale artifact(s) DEFERRED to the next commit … Recorded against ceb9887c7d97 + 25a59bd109a9') · regeneration commit exit 0 · git push exit 0 (ceb9887c7..fc66ae833) · worktree remove exit 0. Not re-run this round (source unchanged; earlier readings stand): the metadata vitest suite, eslint, check:liveness, check:nul-bytes, check:doc-authoring, the derived docs gates, and the reverse-verification leg (cluster.zod.ts byte-identical since e95a24e52).",
"mcp_calls": "0 this round (cumulative 3: 2 GitHub search_issues + 1 Claude_Code_Remote subscribe_pr_activity in round 1); the PR PATCH, the timeline/labels reads, the read-backs and this comment went through REST with GITHUB_TOKEN.",
"open_questions": [
{
"question": "needs:contract-review is absent from both carriers now — the PR timeline shows claude[bot] unlabeled it on the PR at 03:28:03Z (after the size-labeler's writes, so not a PUT strip) and the card no longer carries it either, consistent with the seat's PASS review; the round-2 instruction said it stays hung. I left the state alone under the never-correct-another-actor rule.",
"options": [
"A: leave it off — the review passed and the seat re-queues",
"B: re-add needs:contract-review on the PR and the card"
],
"recommendation": "A, because the unlabel was a deliberate seat act sequenced with ready_for_review / auto-merge / queue, not a bot side effect; re-adding would fight the seat's own state."
}
],
"out_of_scope_findings": [
"none new this round (round 1 filed #15141)"
]
}
Contract review (Clause ②) on the merge-round head fc66ae83 of PR #15139 — PASS · ACCEPT: comment 5535814391 (2026-09-04T04:50Z), by the domain:spec PM seat, session session_0174WZTU6XcFcS7g2kykC53i, seat post #6017; tier fuse read 04:49Z. C3: the merge queue dequeued the PR at 04:33:40Z (MERGE_CONFLICT, one file: the Iso pin count, 830 on main vs 827 on the head → 828), the dev's merge round pushed 63c21fc4 + fc66ae83, --pair read exit 4, needs:contract-review was re-hung on both carriers at 04:49Z and is cleared on both in this stroke (read back). The delta against the mechanical auto-merge is exactly the pin file's resolution and one regenerated artifact; the 03:27Z review stands for the rest. Landing at all-green on fc66ae83: squash auto-merge re-enabled, re-queued.
Landed — PR #15139 merged via the queue at 2026-09-04T05:56:34Z, merge commit 50d6c924 (squash; origin/main tip 50d6c924b at 05:57Z, the merge commit is that tip). Fenced tail of the released domain:spec seat, session session_0174WZTU6XcFcS7g2kykC53i (shift-end brief on #6017: 5536197516; successor os-justin seated, marker 5536179059 — this stroke was left to this session by both fences). Contract review PASS · ACCEPT 5535235481 (03:28Z) on ceb9887c, director audit PASS 5535153297, merge-round delta review PASS · ACCEPT 5535814391 (04:50Z) on fc66ae83; provenance 5535396680 + addendum 5536041814.
Probed on origin/main at 05:57Z: packages/spec/src/kernel/cluster.zod.ts — no MetadataChangedEventPayloadSchema / MetadataChangeOperationSchema declaration left (the two remaining hits are the tombstone comment at :333-337; the file still exports nine schemas, so the zero is a real zero); ADR-0087 retired-def entries entries/retired-defs/18.kernel__MetadataChangedEventPayload.ts and 18.kernel__MetadataChangeOperation.ts, semantic entry entries/semantic/18.metadata-changed-event-payload-retired.ts, registered in the generated migrations/registry.ts (:6992); no json-schema/kernel/MetadataChange* file remains; the Iso pin count reads 828 in the header, the case title and the assertion of type-alias-convention.pin.test.ts; content/docs/kernel/cluster.mdx carries the tombstone; packages/metadata/src/metadata-manager.ts:232-236 comment states the metadata.changed channel's real (address-only) contract.
Card closed by the PR's Fixes; pm:dispatched stripped in this stroke (read back). The kernel/cluster.zod.ts / cluster.test.ts / type-alias-convention.pin.test.ts / migrations/entries/semantic/ + registry.ts / metadata-manager.ts reservation named in seat post #6017 §3 is released — the successor seat owns the serial queue from here. Dev findings from this card: #15141. This session writes nothing further in the lane.
Activity
huangyiirene commentedon Sep 2, 2026
Triage (R+89, triage seat, session
session_019kDRpB7D2XzVzkaLp57T5D): graded →pm:queue·priority:p3·domain:spec· type Task.findingremoved.Ruled route: remove, via the ADR-0087 retirement route (
spec-property-retirementplaybook, standard removal for a declared surface with zero producers and zero consumers). Rationale, in the order the maintainer's rulings give it: a MUST-emit contract that no conforming emitter could serialize (z.bigint()cannot cross JSON without a codec no driver ships) is declared-but-unenforceable by construction, which is ADR-0049's remove branch; the 2026-08-27 ruling on transitions (「短期不考虑渐进」) removes the staged-window option; and #13331's ruling already settled that peers re-read rather than version-compare, so the one plausible future consumer was decided against. ⛔ Not "make a consumer" — that is contract growth with no pull. The doc-comment inpackages/metadata/src/metadata-manager.tsthat says its payload "aligns with" this schema is corrected in the same PR (it does not, and after removal there is nothing to align with).Clause-②: yes at dispatch — the accept set of a published spec entry moves (a schema disappears), so the spec seat runs it at the contract-review tier with the ADR-0087 registry entry as the deliverable's proof.
Size/model suggestion: S–M (registry entry, baseline regeneration, pin updates per the playbook),
opus.Generated by Claude Code
claude commentedon Sep 4, 2026
Claim: PM loop,
domain:specseat (seat post #6017), R6 of this shift — executing the triage-ruled route (comment 5502971695, 2026-09-02): removeMetadataChangedEventPayloadSchemavia the ADR-0087 retirement route (spec-property-retirementplaybook; retired-def registry entry as the deliverable's proof), and correct the "aligns with" doc-comment inpackages/metadata/src/metadata-manager.tsin the same PR as the triage prescribes. ⛔ Not "make a consumer".Session:
session_0174WZTU6XcFcS7g2kykC53i(GitHubzhuangjianguo)Branch:
claude/issue-14180-retire-metadata-changed-event-payloadClaimed at 2026-09-04T02:32Z; queue read 00:40Z (next by age after #14168; the maintainer's 「14996 插队」 card ran ahead of it). Slot check: 3-cap, 1 dev running (#14168) before this claim.
File surface:
packages/spec/src/kernel/cluster.zod.ts(the schema + its type alias),packages/spec/src/kernel/cluster.test.ts(its pins → retirement pins),packages/spec/src/type-alias-convention.pin.test.ts(theIso394alias pin), the ADR-0087 registry entry underpackages/spec/src/migrations/entries/(+ generatedregistry.ts), generated baselines (api-surface, export-origins, declaration-map, docs), the hand-written docs that name the payload (cluster-semantics.mdx§5 per the metadata-manager comment;affected-docsnames the rest),packages/metadata/src/metadata-manager.ts:234(doc-comment only, triage-prescribed), a@objectstack/specchangeset. ⛔packages/metadatabeyond that one comment,packages/core,packages/metadata-protocol,content/docs/releases/**.Clause ② yes (a published schema disappears) —
needs:contract-reviewhung on this card in this stroke; the dev hangs it on the PR. Contract review at tier by this seat. Pre-dispatch readings (2026-09-04T02:32Z): consumers ofMetadataChangedEventPayloadonorigin/main2cc46103are the schema, its own test, the alias pin and the one doc-comment — zero runtime producers or subscribers, as the card measured; 0 of 24 open PRs touchcluster.zod.ts; H17 on-hold trigger-file index: no hit.Generated by Claude Code
claude commentedon Sep 4, 2026
Dispatch (R6 of this shift, 2026-09-04T02:34Z) —
domain:specseat,session_0174WZTU6XcFcS7g2kykC53i, seat post #6017.mode:subagent,model: fable(CONTRACT_REVIEW_TIER— Clause ② yes overrides the triage'sopussuggestion), size M, Clause ② yes (dual carrier:needs:contract-reviewhung on this card at claim; the dev hangs it on the PR). The dev leaves its ownClaim:comment below carryingClause-②: yesand its file surface before its first edit.Scope handed to the dev — the triage-ruled route verbatim: remove
MetadataChangedEventPayloadSchemavia the ADR-0087 retirement route (spec-property-retirementplaybook; a retired-def registry entry as the deliverable's proof; liveness ledger discipline; generated baselines; thecluster.test.tspins turned into retirement pins with a positive control; theIso394alias pin; the hand-written cluster-semantics docs), plus the one triage-prescribed doc-comment correction inpackages/metadata/src/metadata-manager.ts:234(the only edit allowed underpackages/metadata). ⛔ Not "make a consumer". Premise re-verified first (zero producers/subscribers onorigin/main; a real consumer found ⇒ stop and report). Changeset@objectstack/specminor +**BREAKING**banner under the post-cut lockstep convention withadr-0087: registered <ID>(the entry's prose spelled per #15130 — no call parentheses, no issue ids in the strings). Read-and-report: whethercluster-semantics.mdxstill asserts a MUST-emit protocol elsewhere, and whethermetadata-protocol'sClusterMetadataMutationPayloaddocs name the removed schema. ACCEPT path: report → fuse read → contract review at tier → landing at all-green.Generated by Claude Code
claude commentedon Sep 4, 2026
Claim: os-dev subagent dispatched by the
domain:specPM seat (PM claim comment 5534838453; triage-ruled route in comment 5502971695 — remove via the ADR-0087 retirement route,spec-property-retirementplaybook; ⛔ not "make a consumer").Session:
session_0174WZTU6XcFcS7g2kykC53iBranch:
claude/issue-14180-retire-metadata-changed-event-payload(pushed empty first, as the write-route probe)Clause-②: yes
File surface (matches the PM claim; two deltas stated below):
packages/spec/src/kernel/cluster.zod.ts—MetadataChangedEventPayloadSchema+MetadataChangedEventPayloadremoved, with an in-file retirement notepackages/spec/src/kernel/cluster.test.ts— its three pins become retirement pins (the name is absent from the module namespace, with a positive control on a sibling schema that stays)packages/spec/src/type-alias-convention.pin.test.ts— theIso394pin linepackages/spec/src/migrations/entries/retired-defs/18.kernel__MetadataChangedEventPayload.ts+ one D3 semantic entry underentries/semantic/(the id the changeset registers), thengen:migration-registryregeneratesregistry.tscheck:generated --fix(api-surface, export-origins, declaration-map, docs, json-schema manifest, spec-changes, upgrade guide — whatever it proves stale)content/docs/kernel/cluster.mdx— the hand-written page that names the payload (the "Target spec (planned)" block and the §6.3 reader contract that goes with it), plus whateveraffected-docsnames; nevercontent/docs/releases/**packages/metadata/src/metadata-manager.ts— the one doc-comment only (triage-prescribed).changeset/*.mdfor@objectstack/spec(minor+ BREAKING banner, launch-window convention,adr-0087: registeredmarker)Delta 1 (playbook §4, orphan value schema):
MetadataChangeOperationSchema/MetadataChangeOperationin the same file exist only to type the removed payload'soperationfield — zero other consumers onorigin/main2cc4610 (every hit is the payload itself, its ownIso393pin line, and generated artifacts). An exported value schema with no consumer reads as a capability, so it leaves with the payload: a second retired-def entry18.kernel__MetadataChangeOperation.ts(this def IS injson-schema.manifest/kernel.json, so the manifest deletion gate demands the entry; the payload def never was —z.bigint()is skipped by the JSON Schema build) and theIso393pin line.Delta 2:
cluster-semantics.mdxdoes not exist onorigin/main—apps/docs/redirects.mjsredirects it to/docs/kernel/cluster; the page that names the payload iscontent/docs/kernel/cluster.mdx. The metadata-manager comment's stalecluster-semantics.mdx §5pointer is corrected together with the "aligns with" claim.⛔ Not touched:
packages/metadatabeyond that one comment,packages/core,packages/metadata-protocol,content/docs/releases/**. The assignee stays the PM's.Generated by Claude Code
claude commentedon Sep 4, 2026
os-dev-report
{ "issue": 14180, "status": "done", "branch": "claude/issue-14180-retire-metadata-changed-event-payload", "pr": "https://github.com/objectstack-ai/objectstack/pull/15139", "premise_still_valid": true, "summary": "Retired MetadataChangedEventPayloadSchema / MetadataChangedEventPayload and, per playbook §4 (orphan value schema, the kernel/DistributedStateConfig precedent), the MetadataChangeOperationSchema / MetadataChangeOperation enum that existed only to type its operation field, from packages/spec/src/kernel/cluster.zod.ts via ADR-0087 route 3: retired-def entries 18.kernel__MetadataChangedEventPayload + 18.kernel__MetadataChangeOperation and the D3 semantic entry metadata-changed-event-payload-retired (registry.ts regenerated: 148 semantic / 86 retired-key / 94 retired-def), json-schema.manifest/kernel.json loses kernel/MetadataChangeOperation under the manifest deletion gate (the payload def was never in the manifest — the JSON Schema build skips bigint), api-surface / export-origins / declaration-map −4, references page + strictness-ledger counts regenerated, retirement pins (runtime namespace probes on ./cluster.zod and ./index with ClusterCapabilityConfigSchema as positive control) in cluster.test.ts, Iso393 / Iso394 deleted (829 → 827 with a receipt), content/docs/kernel/cluster.mdx rewritten wherever it described the retired version-compare protocol (§6 intro, §6.1, lane-1 'Target spec (planned)' block, §6.3, §7.3), the metadata-manager.ts doc-comment corrected (no 'aligns with', no dead cluster-semantics.mdx pointer), and a @objectstack/spec minor + BREAKING changeset carrying the registered marker; draft PR #15139 at e95a24e52 with needs:contract-review hung and read back. Premise re-verified at origin/main 2cc461030: zero producers / subscribers / imports outside packages/spec, and no hit in objectui at the pinned sha 67dadd60 (positive control hit). Deviations from the PM claim, both declared in my claim comment 5534876299: the orphan enum leaves with the payload, and the hand-written page is kernel/cluster.mdx (cluster-semantics.mdx is a redirect in apps/docs/redirects.mjs). Notes for the PM: the card arrived assigned to the PM and was left so; commit trailers use the model-free pair the dispatch prescribed (Claude-Session + Co-authored-by: Claude) rather than the harness's default attribution line; step-18 D3 semantic entries — mine and every precedent — do not project into spec-changes.json / protocol-upgrade-guide.md while both gates are green, which reads as projection design (unreleased major), so it is reported here and not filed. Read-and-report: metadata-protocol's ClusterMetadataMutationPayload docs do not name the removed schema (zero hits); the cluster.mdx sentences the removal falsified were all on the page already in surface and are fixed there (listed in the PR body).", "tests": "All at the final head e95a24e52, exits captured before any pipe, verdict lines quoted. spec build (verify lock): exit 0 — 'check-dts-emitted: @objectstack/spec - 34/34 declared declaration file(s) present.' and 'ℹ️ 1 schema(s) left the published set since 2cc4610304c5, each declared (#4725): json-schema/kernel/MetadataChangeOperation.json — RETIRED_DEFS_BY_MAJOR, major 18.' · check:generated: first run named 5 stale (api-surface, export-origins, declaration-map, docs, strictness-ledger), --fix exit 0, second run exit 0 '✓ All 15 generated artifacts are up to date.' (re-run again after the reverse leg + rebuild at HEAD: exit 0, same line) · vitest src/kernel/cluster.test.ts src/type-alias-convention.pin.test.ts (lock): exit 0 'Test Files 2 passed (2)' / 'Tests 23 passed (23)' · pnpm --filter @objectstack/spec typecheck (tsc + check:scripts-typecheck + check:test-typecheck, lock): exit 0 'check:test-typecheck: OK — … 54 file(s) / 261 error(s) / 145 pinned signature(s) held' · check:migration-registry exit 0 '✓ src/migrations/registry.ts is current (148 semantic, 86 retired-key, 94 retired-def)' · check:liveness exit 0 '✓ … state-counts.md is current — the same 35 row(s)' · check:strictness-ledger exit 0 '✓ … counts.md is current — 439 site(s) measured' · eslint --no-inline-config over the 8 edited TS files: exit 0, no findings · pnpm check:doc-authoring exit 0 '✓ … 14710 customer-facing string(s) across 726 spec sources clean' · pnpm check:nul-bytes exit 0 'check-nul-bytes: OK (scanned 8234 text file(s) …)' · node scripts/check-system-context-census.mjs exit 0 'OK — 106 elevation read sites in 20 packages across 45 files, all anchored' (no --fix demanded) · check-changeset-no-major --base 2cc461030 exit 0 '✓ This diff introduces no `major` bump.' · check-adr-0087-registration --base 2cc461030 exit 0 '✓ … 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … [BREAKING] registered metadata-changed-event-payload-retired (new here)' · downstream: closure built in two lock-held layers (types formula metadata-core observability sdui-parser; core lint metadata-fs driver-sql platform-objects driver-sqlite-wasm), each 'VERDICT command-exit 0'; pnpm --filter @objectstack/metadata typecheck exit 0 (tsc --noEmit clean — nothing imports the removed symbols); vitest run --maxWorkers=2 in @objectstack/metadata exit 0 'Test Files 46 passed (46)' / 'Tests 705 passed (705)' · dispatch-gates.mjs --repo objectstack-ai/objectstack --commands exit 0 (derived at e95a24e52, '⚠️ STALE TREE — … at least 2 commit(s) behind origin/main'); derived families touched by this diff all exit 0: check-affected-docs ('# 1 docs name something this change touched' — cluster.mdx), check-drift-comment, doc-frontmatter, doc-route-spelling, docs-section-name, section-landing-index, keyed-text-bounds, undeclared-dep-imports, doc-anchors, docs-redirects, docs-single-h1, corpus-claim-drift, cross-package-test-inputs, spec-parsed-alias ('827 pinned isomorphic'), test-source-alias, quick-reference-counts, type-check-coverage, spec check:variant-docs / exported-any / dual-source-exports / entry-nameability / browser-reachable-entries / empty-state / llms-txt / skill-refs / yaml-examples / api-surface / export-origins / docs / spec-changes / upgrade-guide / authorable-surface. NOT MEASURED by their own words: pnpm check:type-check-debt exit 3 'check-type-check-coverage: PREREQUISITE NOT MET — --re-measure cannot run: 27 workspace dependenc(ies) … have no built type entry point on disk' (whole-repo closure; CI's); check:skill-examples exit 1 'packages/client-react/dist holds no .d.ts declarations — the package is not built' (closure is runtime/rest/objectql-sized; diff touches no skills/ or SDK docs); full pnpm lint sweep not run (CI-owned; eslint above covers every edited TS file); check:react-declaration-parity EXTERNAL_INPUT_REQUIRED. Reverse verification, one leg from the committed state e95a24e52 under the lock with a trap restore: git restore --source=2cc461030 -- packages/spec/src/kernel/cluster.zod.ts; mutation confirmed on disk ('export const MetadataChangedEventPayloadSchema' lines 0 → 1, on-disk blob 37fdc590… = BASE blob); leg A vitest cluster.test.ts exit 1 'Tests 2 failed | 18 passed (20)' (both probes 'expected true to be false'); leg B gen:schema exit 1 '❌ 1 RETIRED_DEFS_BY_MAJOR entr(ies) name a schema this build still publishes: kernel/MetadataChangeOperation (registered at major 18)'; restore proven by the caller: git hash-object = 61538d29… = HEAD: blob, git diff HEAD empty, git status --porcelain empty; spec then rebuilt at HEAD (exit 0, same check-dts line) and check:generated re-run (exit 0). No ablation of a build product beyond that leg; the leg's gen:schema wrote only the gitignored json-schema/ tree, replaced by the HEAD rebuild.", "mcp_calls": "3 — 2 GitHub MCP search_issues (the dedup search for the finding plus its positive control, taken after the REST search endpoint answered 403; channel switch declared) + 1 Claude_Code_Remote subscribe_pr_activity for PR #15139. Every other GitHub read and write (issue body/comments, claim comment, PR create, label add + read-back, PR body read-back, finding create, this report) went through REST with GITHUB_TOKEN.", "open_questions": [], "out_of_scope_findings": [ "filed as #15141: four pointers (two .describe() strings in kernel/events/core.zod.ts and kernel/service-registry.zod.ts that gen:docs copies into the reference pages, two comments in metadata-manager.ts) still cite cluster-semantics.mdx, a page redirected to /docs/kernel/cluster — label finding, no assignee" ] }Generated by Claude Code
hotlong commentedon Sep 4, 2026
Director audit of the contract — PASS (summon 13, session_01WXyGTWPbbreqXow7Z2pZCk; tier fuse read 2026-09-04T01:26Z,
get_sessionservedclaude-fable-5-1=CONTRACT_REVIEW_TIER). Subject: PR #15139 at heade95a24e52. The spec seat's in-seat review owns the release; this reading is recorded so the seat can land on it without a second pass, and the stall clause applies at this seat's next check-in if the head is green and unlanded.Implemented-by: claude/issue-14180-retire-metadata-changed-event-payload (mode:subagent dev under session_0174WZTU6XcFcS7g2kykC53i)
Reviewed-by: session_01WXyGTWPbbreqXow7Z2pZCk
① Derived judgments
MetadataChangedEventPayloadSchema/MetadataChangedEventPayloadand the orphanMetadataChangeOperationSchema/MetadataChangeOperation, via ADR-0087 route 3:RETIRED_DEFS_BY_MAJOR[18]entries plus the D3 semantic entry, retirement pins on both the module and the@objectstack/spec/kernelentry, positive control kept. Correct.packages/spec(objectui at the pinned sha included, with a lit positive control); thebigintversionfield could never have crossed a JSON transport, so the declared MUST-emit / MUST-compare contract was unhonourable as written. Removal, not "make a consumer", matches the 2026-09-02 ruling.content/docs/kernel/cluster.mdxrewritten to the shipped address-only, re-read lanes; the@objectstack/metadatadoc-comment no longer claims alignment with a schema it never matched. Correct and complete for the ruling's second clause.② Semver:
@objectstack/specminor with the BREAKING banner and the ADR-0087 disposition marker — the repository's registered-retirement convention (check-adr-0087-registrationrecognises the entry;check-changeset-no-majorgreen). Accepted.③ Boundary flags: the two deviations from the claim (orphan enum leaves with the payload; the hand-written page is
cluster.mdx) are both right. Nothing open.Landing gate as of 03:15Z:
mergeable_state: dirty(mergeorigin/main, merge commit) and CI on the merged head must be green before the carriers clear.Generated by Claude Code
claude commentedon Sep 4, 2026
os-dev-report
{ "issue": 14180, "status": "done", "branch": "claude/issue-14180-retire-metadata-changed-event-payload", "pr": "https://github.com/objectstack-ai/objectstack/pull/15139", "premise_still_valid": true, "summary": "Sync round for PR #15139 (follow-up to the first report, comment 5535134770): origin/main fcc42e6c1 merged as merge commit 9003435dc via scripts/pm/os-regen-merge.sh in a fresh dedicated worktree on the same branch (no rebase, no amend, no force-push, no stash); the helper kept the branch's bytes for every generated shard only the branch had edited and took main's side of the two os-regen-deferred artifacts moved on both sides (content/docs/references/index.mdx, docs/audits/2026-07-unknown-key-strictness-ledger.counts.md), whose hand-off commit the pre-commit hook refused as stale (the helper's designed collection point); both were regenerated from the merged tree (gen:schema via the spec build, gen:docs, gen:strictness-ledger), staged explicitly, the staged diff inspected (only main's automation increments: 1588→1591 schemas, 439→440 sites), and committed as ceb9887c7 with the hook printing 'os-regen: all deferred artifacts are current — marker cleared.'. Pushed fast-forward e95a24e52..ceb9887c7; GitHub now reads the PR head ceb9887c7, mergeable true / mergeable_state blocked (draft + required checks — no longer dirty). PR body PATCHed with the new final-head line and one sync sentence naming the merge commit and the regenerated artifacts (read back byte-identical; the session-URL footer survived in the body and the platform appended its bare one); needs:contract-review read back on the PR and remains on the card. No behaviour change; the merge commit carries git's default message, the regeneration commit the model-free trailer pair; no model identifiers anywhere. Worktree removed without force after the push (exit 0).", "tests": "All at the merged head ceb9887c7, each part's exit captured before any pipe, verdict lines quoted. spec build (verify lock) exit 0 — 'check-dts-emitted: @objectstack/spec - 34/34 declared declaration file(s) present.' and 'ℹ️ 1 schema(s) left the published set since fcc42e6c1de9, each declared (#4725): json-schema/kernel/MetadataChangeOperation.json — RETIRED_DEFS_BY_MAJOR, major 18.' · check:generated exit 0 '✓ All 15 generated artifacts are up to date.' (once right after the regeneration commit, again after the head rebuild) · vitest src/kernel/cluster.test.ts src/type-alias-convention.pin.test.ts (lock) exit 0 'Test Files 2 passed (2)' / 'Tests 23 passed (23)' · pnpm --filter @objectstack/spec typecheck (tsc + scripts + test-typecheck, lock) exit 0 'check:test-typecheck: OK — @objectstack/spec's test layer compiles under packages/spec/tsconfig.test.json; 54 file(s) / 261 error(s) / 145 pinned signature(s) held' · check:migration-registry exit 0 '✓ src/migrations/registry.ts is current (148 semantic, 86 retired-key, 94 retired-def)' · check:strictness-ledger exit 0 '✓ docs/audits/2026-07-unknown-key-strictness-ledger.counts.md is current — 440 site(s) measured, 1 authorable strip site(s) left' · check-adr-0087-registration --base origin/main (merge base fcc42e6c1) exit 0 '✓ check-adr-0087-registration: 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition. … [BREAKING] registered metadata-changed-event-payload-retired (new here: metadata-changed-event-payload-retired)' · check-changeset-no-major --base origin/main exit 0 'Diffing HEAD from fcc42e6c1 (merge base …) ✓ This diff introduces no `major` bump.' · node scripts/check-system-context-census.mjs exit 0 'check-system-context-census: OK — 106 elevation read sites in 20 packages across 45 files, all anchored' (no --fix demanded) · metadata closure rebuilt in the fresh worktree (11 packages, lock, 'VERDICT command-exit 0'), then pnpm --filter @objectstack/metadata typecheck (lock) exit 0 (tsc --noEmit clean; nothing imports the removed symbols). The three lock-held checks ran under one hold with per-part exits printed (VITEST_EXIT=0, SPEC_TYPECHECK_EXIT=0, METADATA_TYPECHECK_EXIT=0) — the lock's own 'batch-last-exit' caveat is answered by those per-part readings, not by the batch number. Regenerated-docs sanity: zero occurrences of either retired name in content/docs/references/index.mdx and content/docs/references/kernel/cluster.mdx after regeneration. Not re-run this round (unchanged source; first-round readings at e95a24e52 stand): the metadata vitest suite, eslint, check:liveness, check:nul-bytes, check:doc-authoring, the derived docs/alias gates, and the reverse-verification leg (packages/spec/src/kernel/cluster.zod.ts is byte-identical between e95a24e52 and ceb9887c7).", "mcp_calls": "0 this round (cumulative 3: 2 GitHub search_issues + 1 Claude_Code_Remote subscribe_pr_activity in the first round); the PR PATCH, both read-backs and this comment went through REST with GITHUB_TOKEN.", "open_questions": [], "out_of_scope_findings": [ "none new this round (the first round filed #15141)" ] }Generated by Claude Code
claude commentedon Sep 4, 2026
Contract review (Clause ②) on PR #15139 — PASS · ACCEPT: comment 5535235481 (2026-09-04T03:27Z), by the
domain:specPM seat, sessionsession_0174WZTU6XcFcS7g2kykC53i, seat post #6017; tier fuse read 03:26Z,--pair 15139exit 0; the director's audit 5535153297 concurs. Both declared deviations (the orphan enum leaves with the payload; the hand-written page iskernel/cluster.mdx) accepted.needs:contract-reviewcleared on both carriers in this stroke. Landing at all-green on the merged headceb9887c(18 checks running at 03:26Z); on MERGED this card closes viaFixes,pm:dispatchedis stripped, landing note here.Generated by Claude Code
claude commentedon Sep 4, 2026
os-dev-report
{ "issue": 14180, "status": "done", "branch": "claude/issue-14180-retire-metadata-changed-event-payload", "pr": "https://github.com/objectstack-ai/objectstack/pull/15139", "premise_still_valid": true, "summary": "Round 3 for PR #15139 after the merge queue dequeued ceb9887c7 with MERGE_CONFLICT (04:33:40Z): origin/main 25a59bd10 merged as merge commit 63c21fc4b in a fresh dedicated worktree on the same branch (no rebase, amend, force-push or stash). scripts/pm/os-regen-merge.sh stopped on the one text conflict, packages/spec/src/type-alias-convention.pin.test.ts, hand-resolved so both intents stack: #14168's Iso867 kept, Iso393 / Iso394 stay deleted, the machine-checked count 830 → 828 in the header comment, the case title and the toHaveLength assertion, with the two rebalancing notes in sequence ('829 -> 830 is #14168's ValueDomainSchema …' then '830 -> 828 is #14180's ADR-0049 retirement …', the latter restated from the post-merge base). The merge was finished by hand with MERGE_HEAD present, so the pre-commit hook took its deferral path for the one artifact the driver declined to text-merge, content/docs/references/index.mdx; regeneration commit fc66ae833 discharged it (gen:schema via the spec build, gen:docs; check:generated --fix found nothing else stale; the hook printed 'os-regen: deferred regeneration discharged — all artifacts current, marker cleared.'). packages/spec/src/migrations/registry.ts, text-merged by git on both sides, was re-run through gen:migration-registry and came out byte-identical (149 semantic / 86 retired-key / 94 retired-def). Files changed in the merge commit beyond the mechanical merge: exactly one, the pin file (hand-resolved; 25 diff lines against origin/main's side, all of them the 830 → 828 count and the deleted Iso393 / Iso394 lines plus the note); registry.ts auto-merged and generator-identical; index.mdx deferred and regenerated in fc66ae833 (main's shared/value-domain page row, 1591 → 1592 schemas). The delta against ceb9887c7 beyond origin/main's own side is empty by path (every changed path is also on main's side) — i.e. identical to ceb9887c7 apart from the pin file's count/notes and the regenerated index. Pushed fast-forward ceb9887c7..fc66ae833; PR head reads fc66ae833, mergeable true / mergeable_state blocked; PR body got a round-3 paragraph under the final-head heading (read back byte-identical). State observed on the PR that I did not set and left untouched: ready_for_review (zhuangjianguo 03:51:32Z), auto_merge_enabled (03:51:42Z), added_to_merge_queue (03:52:36Z), removed_from_merge_queue (github-merge-queue[bot] 04:33:40Z); needs:contract-review was unlabeled on the PR by claude[bot] at 03:28:03Z — after the size-labeler's 03:25–03:26 writes, so not a whole-set PUT strip — and is absent from the card as well, read as the seat's post-PASS act; PR labels now documentation, size/l, tests, tooling. No behaviour change; no model identifiers anywhere; merge commit carries git's default message, the regeneration commit the model-free trailer pair. Worktree removed without force after the push (exit 0).", "tests": "Every command at the final head fc66ae833, each exit captured before any pipe, verdict lines quoted. Under one lock hold with per-part exits printed (BUILD_EXIT=0, CLOSURE_EXIT=0, VITEST_EXIT=0, SPEC_TYPECHECK_EXIT=0, METADATA_TYPECHECK_EXIT=0 — the lock's 'batch-last-exit' caveat is answered by those, not by the batch number): pnpm --filter @objectstack/spec build exit 0 — 'check-dts-emitted: @objectstack/spec - 34/34 declared declaration file(s) present.' and 'ℹ️ 1 schema(s) left the published set since 25a59bd109a9, each declared (#4725): json-schema/kernel/MetadataChangeOperation.json — RETIRED_DEFS_BY_MAJOR, major 18.' · metadata closure rebuild (11 packages) exit 0 · vitest src/kernel/cluster.test.ts src/type-alias-convention.pin.test.ts exit 0 'Test Files 2 passed (2)' / 'Tests 23 passed (23)' (the pin case recomputes the count from the source and asserts the header and the title agree with 828) · pnpm --filter @objectstack/spec typecheck exit 0 'check:test-typecheck: OK — @objectstack/spec's test layer compiles under packages/spec/tsconfig.test.json; 54 file(s) / 261 error(s) / 145 pinned signature(s) held' · pnpm --filter @objectstack/metadata typecheck exit 0 (tsc --noEmit clean). Lock-free: check:generated --fix exit 0 and the second run at fc66ae833 exit 0 '✓ All 15 generated artifacts are up to date.' · gen:migration-registry exit 0 '✓ wrote src/migrations/registry.ts (149 semantic, 86 retired-key, 94 retired-def)' with an empty git diff · check:migration-registry exit 0 '✓ src/migrations/registry.ts is current (149 semantic, 86 retired-key, 94 retired-def)' · check:strictness-ledger exit 0 '✓ … counts.md is current — 440 site(s) measured, 1 authorable strip site(s) left' · check-adr-0087-registration --base origin/main (merge base 25a59bd10) exit 0 '✓ check-adr-0087-registration: 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition. … [BREAKING] registered metadata-changed-event-payload-retired (new here: metadata-changed-event-payload-retired)' · check-changeset-no-major --base origin/main exit 0 '✓ This diff introduces no `major` bump.' · node scripts/check-system-context-census.mjs exit 0 'check-system-context-census: OK — 106 elevation read sites in 20 packages across 45 files, all anchored' (no --fix demanded) · pnpm check:spec-parsed-alias exit 0 'ADR-0122 type-alias convention: 1519 bare z.input aliases, 828 pinned isomorphic, 691 paired with an XParsed. OK' · node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --tier <my 11 paths> exit 0 ('Model tier — no path-derived mandate: the surface hits none of the 3 declared glob(s)'; Clause ② SUSPECT surface hint on the seven packages/spec/src/** paths — judged from card content, already yes) · dispatch-gates --commands exit 0, derived at fc66ae833 with no STALE TREE warning, 86 commands, byte-identical family to round 1 · os-regen-merge.sh exit 1 (its designed stop on the non-generated conflict) · git merge commit exit 0 (hook: '1 stale artifact(s) DEFERRED to the next commit … Recorded against ceb9887c7d97 + 25a59bd109a9') · regeneration commit exit 0 · git push exit 0 (ceb9887c7..fc66ae833) · worktree remove exit 0. Not re-run this round (source unchanged; earlier readings stand): the metadata vitest suite, eslint, check:liveness, check:nul-bytes, check:doc-authoring, the derived docs gates, and the reverse-verification leg (cluster.zod.ts byte-identical since e95a24e52).", "mcp_calls": "0 this round (cumulative 3: 2 GitHub search_issues + 1 Claude_Code_Remote subscribe_pr_activity in round 1); the PR PATCH, the timeline/labels reads, the read-backs and this comment went through REST with GITHUB_TOKEN.", "open_questions": [ { "question": "needs:contract-review is absent from both carriers now — the PR timeline shows claude[bot] unlabeled it on the PR at 03:28:03Z (after the size-labeler's writes, so not a PUT strip) and the card no longer carries it either, consistent with the seat's PASS review; the round-2 instruction said it stays hung. I left the state alone under the never-correct-another-actor rule.", "options": [ "A: leave it off — the review passed and the seat re-queues", "B: re-add needs:contract-review on the PR and the card" ], "recommendation": "A, because the unlabel was a deliberate seat act sequenced with ready_for_review / auto-merge / queue, not a bot side effect; re-adding would fight the seat's own state." } ], "out_of_scope_findings": [ "none new this round (round 1 filed #15141)" ] }Generated by Claude Code
claude commentedon Sep 4, 2026
Contract review (Clause ②) on the merge-round head
fc66ae83of PR #15139 — PASS · ACCEPT: comment 5535814391 (2026-09-04T04:50Z), by thedomain:specPM seat, sessionsession_0174WZTU6XcFcS7g2kykC53i, seat post #6017; tier fuse read 04:49Z. C3: the merge queue dequeued the PR at 04:33:40Z (MERGE_CONFLICT, one file: the Iso pin count, 830 on main vs 827 on the head → 828), the dev's merge round pushed63c21fc4+fc66ae83,--pairread exit 4,needs:contract-reviewwas re-hung on both carriers at 04:49Z and is cleared on both in this stroke (read back). The delta against the mechanical auto-merge is exactly the pin file's resolution and one regenerated artifact; the 03:27Z review stands for the rest. Landing at all-green onfc66ae83: squash auto-merge re-enabled, re-queued.Generated by Claude Code
claude commentedon Sep 4, 2026
Landed — PR #15139 merged via the queue at 2026-09-04T05:56:34Z, merge commit
50d6c924(squash;origin/maintip50d6c924bat 05:57Z, the merge commit is that tip). Fenced tail of the releaseddomain:specseat, sessionsession_0174WZTU6XcFcS7g2kykC53i(shift-end brief on #6017: 5536197516; successoros-justinseated, marker 5536179059 — this stroke was left to this session by both fences). Contract review PASS · ACCEPT 5535235481 (03:28Z) onceb9887c, director audit PASS 5535153297, merge-round delta review PASS · ACCEPT 5535814391 (04:50Z) onfc66ae83; provenance 5535396680 + addendum 5536041814.Probed on
origin/mainat 05:57Z:packages/spec/src/kernel/cluster.zod.ts— noMetadataChangedEventPayloadSchema/MetadataChangeOperationSchemadeclaration left (the two remaining hits are the tombstone comment at:333-337; the file still exports nine schemas, so the zero is a real zero); ADR-0087 retired-def entriesentries/retired-defs/18.kernel__MetadataChangedEventPayload.tsand18.kernel__MetadataChangeOperation.ts, semantic entryentries/semantic/18.metadata-changed-event-payload-retired.ts, registered in the generatedmigrations/registry.ts(:6992); nojson-schema/kernel/MetadataChange*file remains; the Iso pin count reads 828 in the header, the case title and the assertion oftype-alias-convention.pin.test.ts;content/docs/kernel/cluster.mdxcarries the tombstone;packages/metadata/src/metadata-manager.ts:232-236comment states themetadata.changedchannel's real (address-only) contract.Card closed by the PR's
Fixes;pm:dispatchedstripped in this stroke (read back). Thekernel/cluster.zod.ts/cluster.test.ts/type-alias-convention.pin.test.ts/migrations/entries/semantic/+registry.ts/metadata-manager.tsreservation named in seat post #6017 §3 is released — the successor seat owns the serial queue from here. Dev findings from this card: #15141. This session writes nothing further in the lane.Generated by Claude Code