Repository navigation
spec(changelog): the published 17.4.0 notes still say the burn-rate window and the OTel exporter timeout are outside the duration-unit gate — #17783 and #17785 renamed both #18076
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentationand removed
on Sep 13, 2026 claude commented
on Sep 13, 2026 claudeboton Sep 13, 2026 – with ClaudeContributorAuthorMore actionsClaim: PM loop round 9 — epic PM for the #15939 subtree, carrying residue E after the epic closed
Session:session_015c5G6TmpMKgnusmTpD7Ntt
Branch:claude/issue-18076-changelog-duration-keys-erratum
Worktree:objectstack-issue-18076
Domain:domain:spec
File surface:packages/spec/CHANGELOG.md(stop on breach; explain in the report)
Container & model:S — one prose correction plus one gate run,mode:subagent,model: sonnet— quoting this dispatch's ownnode scripts/pm/dispatch-gates.mjs --tier packages/spec/CHANGELOG.md, 2026-09-13T19:00Z: "Model tier — no path-derived mandate … The tier stays the PM's per-card judgment call (floor sonnet · default opus · ceiling fable)". Floor is honest here: the correct text is already measured and quoted on the card, the remedy shape is a precedent to copy rather than a design, and the one judgment call — whether this instance differs materially from #17026 — is written into the order as a stop-and-report rather than left to the round.
Clause-②: no
Thread-read: none — this card carries no comments at the moment this claim is written
Serial constraints cleared: measured, not recalled (2026-09-13T19:00Z). Every open PR's file list was read. Exactly one touchespackages/spec/CHANGELOG.md: #17076, thechore: version packagesrelease PR, which rewrites 78 CHANGELOG files including this one. Instrument check: that 78 is the lit control for the single hit, and a fabricated package path reads 0. ⛔ #17076 is not to be touched, merged or worked around — a PM never merges a Version Packages PR — but it is the reason the survival gate below is mandatory rather than inherited. No other open PR touches this file. The #15939 epic closed at 18:45Z and all seven of its cards are merged, so no sibling is in flight.Why the answer on clause ② is
noThe landing surface is markdown prose inside an already-compiled
packages/spec/CHANGELOG.mdsection. No schema key, no accepted-set change, no new exported symbol, no new key on a published payload, and no path underpackages/**/src/**moves. This matches the precedent PRef47459474(#17896), whose own declaration reads "Clause-②: no — the landing surface is prose inside two already-compiledpackages/*/CHANGELOG.mdentries plus erratum lines."⚠️ If the round finds it cannot correct the text without changing what the released version is described as having done — as opposed to correcting a claim about what is true now — that is a different kind of change: stop and report. ⛔ Do not edit this line.epic PM for #15939 ·
session_015c5G6TmpMKgnusmTpD7Ntt· 2026-09-13T19:02Z
Generated by Claude Code
claude commented
on Sep 13, 2026 claudeboton Sep 13, 2026 – with ClaudeContributorAuthorMore actionsDispatch order — residue E, the 17.4.0 erratum
Epic PM for the #15939 subtree,
session_015c5G6TmpMKgnusmTpD7Ntt, 2026-09-13T19:03Z. Claim:5655399040. Base:origin/main@484484041a.
Zone 1 — Adjudicated. ⛔ Not re-litigable, quoted rather than paraphrased.
Director seat, decision batch #119 item 1, 2026-09-12T04:15Z; maintainer's own word to the batch presented as
1A·2A·3A·4D·5A: 「同意」. Implemented byef47459474(#17896,Fixes #17026) — the precedent this card copies:A: correct the two published CHANGELOG entries in the repository, with a post-release erratum note. … the … sentences … are corrected to the post-#17013 truth, each followed by one erratum line naming PR #17013 and the correction date.
Before editing, run the release tooling's dry-run (
changeset versionon a scratch branch) and record that a manual edit inside an already-compiled section survives — the triage seat's open confidence gap; if it does not survive, stop and report.skip-changeset: no package publishes anything from this change.And the boundary that makes it legitimate, also verbatim:
Immutability belongs to the shipped npm tarball, which this ruling does not and cannot touch; it does not belong to the repository's markdown.
⛔ Two standing prohibitions this card sits next to: a code PR never edits
packages/*/CHANGELOG.md(which is exactly why this is its own PR and was kept out of #17635), and a PM or dev never runs a release or merges the Version Packages PR.
Zone 2 — PM mechanism assumptions. Every line is a premise to falsify first.
Readings taken by this seat from
origin/main@484484041a, 2026-09-13T19:00Z.②‑1 · The text.
packages/spec/CHANGELOG.md:2865-2869, inside the already-released## 17.4.0section, under "Keys deliberately left alone":ServiceLevelObjective.errorBudget's burn-ratewindowand the OpenTelemetry exportertimeoutname no unit anywhere in their prose, so both are outside the gate's population entirely. Pin tests assert each of these, so a later sweep cannot read this card as "every duration-shaped number on these files".Re-locate it by content, not by line number — #17076 or any other merge can move it.
②‑2 · Half 1 is falsified by #17783.
packages/spec/src/system/metrics.zod.ts:368-375carries the retirement string stating the burn-ratewindow"was renamed todurationSecondsin @objectstack/spec 17", and explaining why notwindowSeconds. The pin that held the bare spelling is nowit('REFUSES the burn-rate \window` with a rename naming `durationSeconds`', …)`.②‑3 · Half 2 is falsified by #17785.
packages/spec/src/system/tracing.zod.ts:546istimeoutMs: z.number().int().positive().optional().default(10000)withtimeout: retiredKey(at:550; the sibling went the same way (exportTimeoutMs:586,exportTimeout: retiredKey(:601).⇒ All three of the sentence's claims are false: "name no unit anywhere in their prose", "outside the gate's population entirely", and the pin-test assertion.
⚠️ Verify each yourself — a correction built on my reading rather than yours is how a second erratum gets written later.②‑4 ·
⚠️ The survival gate is MANDATORY and ⛔ must NOT be inherited. The precedent PR measured that a manual edit inside an already-compiled section surviveschangeset version(marker present before and after, pushed down but intact, with a lit control proving the tool really rewrote the files). Re-run it here on a scratch branch off the same base, with your own marker and your own lit control, then discard the branch. If the edit does not survive: stop and report. ⛔ Do not proceed on #17896's result — that is exactly the "relayed rather than measured" failure this epic has already paid for once.②‑5 · One open PR collides, and it is the release PR. #17076 (
chore: version packages) rewrites 78 CHANGELOG files including this one — measured, with that 78 as the lit control for the single hit and a fabricated package path reading 0. No other open PR touches this file. ⛔ Do not touch, merge, rebase or work around #17076. If it merges first, your branch conflicts on this file and the resolution is to re-locate the sentence by content in the new layout and re-apply — ⛔ never to accept either side wholesale.②‑6 ·
skip-changeset. No package publishes anything from this change. Follow the precedent; if the changeset gate disagrees on this diff, report what it said rather than adding a changeset to quiet it.
Zone 3 — Suggested route. ⛔ Not adjudicated; measurement beats it.
- Worktree
objectstack-issue-18076, branchclaude/issue-18076-changelog-duration-keys-erratumoff484484041a. - Survival gate first (②‑4), before any edit. Record the readings.
- Correct the sentence to the post-spec: 5 duration key(s) in
system/metrics.zod.tsname their unit only in JSDoc — #15939 Ruling A remediation (5 of the 21-row delta) #17783 / post-spec: 4 duration key(s) insystem/tracing.zod.tsname their unit only in JSDoc — #15939 Ruling A remediation (4 of the 21-row delta) #17785 truth, and append one erratum line naming this PR and the correction date, matchingef47459474's shape. Keep the surrounding paragraph's other claims (FailoverConfig.dns.ttl,CacheAvalanchePrevention.lockout.lockTimeoutMs,MetricExportConfig.batch.size,QueueConfig.rateLimit.max) —⚠️ but check each one is still true while you are in there, and report any that is not rather than silently correcting beyond scope. - Derive and run the gate family (
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack), reconcile with--ran. Exit 3 isPREREQUISITE NOT MET— ⛔ neither pass nor finding. - Push, open a draft PR, report. ⛔ Do not turn it ready, ⛔ do not enqueue, ⛔ do not touch labels.
⚠️ The one stop-and-report that matters: if correcting the text would change what the released 17.4.0 is described as having done, rather than correcting a claim about what is true now, that is outside batch #119's shape — stop and report, and it goes to the decision box instead.epic PM for #15939 ·
session_015c5G6TmpMKgnusmTpD7Ntt· 2026-09-13T19:03Z
Generated by Claude Code
- Worktree
- added a commit that references this issue
on Sep 13, 2026 zhuangjianguo commented
on Sep 13, 2026 CollaboratorMore actionsos-dev-report
{ "issue": 18076, "status": "done", "branch": "claude/issue-18076-changelog-duration-keys-erratum", "pr": "https://github.com/objectstack-ai/objectstack/pull/18077", "premise_still_valid": true, "summary": "Corrected packages/spec/CHANGELOG.md's already-released 17.4.0 'Keys deliberately left alone' paragraph: verified independently that #17783 renamed ServiceLevelObjective.errorBudget.burnRateWindows[].window to durationSeconds and #17785 renamed OpenTelemetryCompatibility.exporter.timeout to timeoutMs (plus its exportTimeout->exportTimeoutMs sibling), both tombstoned with retiredKey() and both pins now rename-refusal tests, falsifying all three of the paragraph's original claims. Corrected the sentence to the post-#17783/#17785 truth and appended one erratum line naming this PR (#18077) and the correction date, matching precedent ef47459474 (#17896). Ran the mandatory survival gate on a discarded scratch branch before editing (marker survived changeset version with a lit control proving the tool actually rewrote files); pushed a draft PR, left it draft, touched no labels.", "tests": "SURVIVAL GATE (mandatory, run before any edit, on scratch branch scratch/issue-18076-survival-gate off 484484041a, discarded after): marker SURVIVALGATEMARKER18076XQ7 inserted into the target paragraph, count 1 before `pnpm changeset version`; dark control ZZQV18076NOPE count 0 before (grep exit 1, confirming a real zero). `pnpm changeset version` exit 0 ('All files have been updated'). AFTER: marker count still 1 (line 2869->7316, pushed down, content intact) = SURVIVES; dark control still 0. LIT CONTROL confirming the tool actually rewrote the tree: new `## 17.5.0` section prepended, packages/spec/package.json moved 17.4.0->17.5.0, 452 of 453 pending .changeset/*.md files consumed. Restored via `git checkout -f` back to the real branch; a diff between `git show origin/main:packages/spec/CHANGELOG.md` and the working file was empty (byte-identical); scratch branch deleted. PREMISE VERIFICATION (independent of the card): metrics.zod.ts:368-375 SLO_BURN_RATE_WINDOW_RETIRED confirms the window->durationSeconds rename and reason; metrics.test.ts:612 pin is exactly \"REFUSES the burn-rate `window` with a rename naming `durationSeconds`\". tracing.zod.ts:546-550 confirms timeoutMs with `timeout: retiredKey(` tombstone; :586/:601 confirms exportTimeoutMs/exportTimeout sibling; tracing.test.ts:594-611 it.each pin \"REFUSES the retired `%s` with the rename in the message\" covers both. All four 'still true' claims re-verified on tree: FailoverConfig.dns.ttl still bare (disaster-recovery.zod.ts:148, externalVocabulary exemption comment intact); CacheAvalanchePrevention.lockout.lockTimeoutMs still ms (cache.zod.ts:162); MetricExportConfig.batch.size still a bare record count (metrics.zod.ts:702); QueueConfig.rateLimit.max still a bare task count (worker.zod.ts:~276) -- none falsified, none touched. GATE DERIVATION: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 54 local gate families (all matched via broad packages/** or packages/spec globs, none specific to CHANGELOG.md). Ran full sweep TWICE under the shared verify-lock (OS_VERIFY_LOCK_SLOT=issue-18076-gates) -- once on commit bfc744c98c, again on final commit ac68eff364 after a placeholder fix -- identical result both times: 50/54 exit 0 (pass), 4/54 exit 3 declared PREREQUISITE NOT MET (check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content -- each explicitly refuses on a missing dist/ in this fresh worktree per its own printed message, e.g. 'Run `pnpm build` first ... this is NOT a pass: nothing was measured'; a full ~80-package build was judged disproportionate to a one-line CHANGELOG fix and was not run -- CI builds fresh and will cover these). Reconciled both runs with `--ran` (a file of \"command :: exit N\" lines): 'Run reconciliation - 54 derived, 50 run, 4 NOT-MEASURED, 0 UNRUN' both times, 0 UNRUN. check:slot-lookup needed >90s (my first artificial per-command timeout killed it at exit 124, a self-inflicted cap, not a platform cap-kill); re-run with a 280s budget it passed cleanly (exit 0) both sweeps, corrected in the record. Byte hygiene: `pnpm check:nul-bytes` exit 0 and a direct `grep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]'` on the diff both clean. `node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD` clean on both commits (no card-relation trailer, model-free trailer pair) -- caught and fixed one violation pre-push (an initial `Fixes #18076` body line was reworded before pushing). PLACEHOLDER INCIDENT AND FIX (caught by PM review): first pushed commit bfc744c98c shipped the erratum line with a literal `#PRPLACEHOLDER18076` token (PR number unknowable before the PR existed); a local fixup commit (ac68eff364) substituting the real `#18077` was made but NOT pushed before the PM's status snapshot, so the PM correctly flagged a shipped placeholder. Pushed the fixup immediately; verified directly against the remote via `git show` of the pushed branch's CHANGELOG.md piped to `grep -c PRPLACEHOLDER` = 0 and `grep -n 'Corrected after publication, #18077'` present at line 7331. PLACEHOLDER SWEEP with controls (requested by PM) over the full diff (`git diff origin/main..HEAD -- packages/spec/CHANGELOG.md`, 35 lines): pattern class (case-insensitive): PLACEHOLDER, word-bounded TODO/TBD/XXX/FIXME, a bracket-wrapped all-caps token, or a double-curly interpolation = 0 matches; LIT CONTROL drawn a different way (appended a synthetic PRPLACEHOLDER99999 line to the same scanned text, re-ran identical pattern) = 1 match, confirming the regex class fires and the 0 is real; positive control `18077` appears exactly once in the diff. Re-ran full 54-gate sweep + trailer check on the final pushed commit ac68eff364, same clean result. No `pnpm --filter @objectstack/spec test`/`typecheck` run: diff touches no code, export or public-surface byte, so nothing in scope for them to newly exercise. CI on ac68eff364 as of 2026-09-13T19:37Z (in flight, not read by me since -- declared per operating constraints rather than awaited): 39 check runs, several completed success (Check Documentation Links, Spec property liveness, Governed Surface Queue Guard, PR-claim/single-writer-path guards, filter), 'Check Changeset' completed SKIPPED on both workflow runs (skip-changeset label already applied by automation, not by this session), 0 failures observed, remainder (Build Core, Test Core 1-6, Lint & Repo Gates, Type Check x4, Temporal Conformance, Dogfood Regression Gate x3, Dogfood Verify CLI) in_progress.", "mcp_calls": 10, "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
- added a commit that references this issue
on Sep 17, 2026
The published
packages/spec/CHANGELOG.mdtells a reader that two duration keys are outsidecheck:duration-unit-keys's population and will keep their bare names. Both were renamed under #15939 ruling A, in@objectstack/spec 17. The sentence now actively misdirects anyone reading the 17.4.0 notes to find out whether a key moved.The falsified text
packages/spec/CHANGELOG.md:2865-2869onorigin/main@484484041a, inside the already-released## 17.4.0section, under the heading "Keys deliberately left alone":Three claims, all now false: "name no unit anywhere in their prose", "outside the gate's population entirely", and the pin-test assertion that was supposed to hold them bare.
The measurements that falsify it
Read from
origin/main@484484041a, 2026-09-13T19:00Z. The tree states the contradiction in its own words:Half 1 — the burn-rate
window, renamed by #17783.packages/spec/src/system/metrics.zod.ts:368-375carries the retirement string:It also records why not
windowSeconds("the array this object sits in is already calledburnRateWindows, so the key would stutter"). The pin that asserted the bare spelling was itself rewritten by #17783 intoit('REFUSES the burn-rate \window` with a rename naming `durationSeconds`', …)`.Half 2 — the OpenTelemetry exporter
timeout, renamed by #17785.packages/spec/src/system/tracing.zod.ts:546is nowtimeoutMs: z.number().int().positive().optional().default(10000), withtimeout: retiredKey(tombstoned at:550. The sibling moved the same way:exportTimeoutMsat:586,exportTimeout: retiredKey(at:601.⇒ Not merely "no longer accurate": the CHANGELOG says these keys are outside the very gate whose ruling renamed them.
Why this is its own PR and was deliberately kept out of #17635
⛔ A code PR never edits
packages/*/CHANGELOG.md. #17635 (the gate, merged484484041a) carried the two in-tree prose repairs and stopped there; this one is release-owned text and takes the documented erratum route instead.The prescribed remedy shape — precedent, not improvisation
ef47459474— "docs(changelog): correct the two publishedSeed.localeclaims PR #17013 falsified, with erratum lines" (#17896,Fixes #17026) — is the on-point precedent. It implements director-seat decision batch #119 item 1, 2026-09-12T04:15Z, maintainer 「同意」:and the boundary that makes it legitimate, also verbatim from that ruling:
That PR's own reading recorded the survival gate as passing (marker present before and after
pnpm changeset version, with a lit control proving the tool really did rewrite the files). ⛔ Re-run it anyway rather than inheriting the result — it is cheap, and it is the one step the ruling says to stop on.Shape to match: markdown only,
Clause-②: no,skip-changeset, one erratum line naming the correcting PR and the date.ef47459474was 2 files, +14/−2; this one touchespackages/spec/CHANGELOG.mdalone.Scope note for whoever picks this up
This card applies batch #119's remedy shape to a new instance; it does not re-decide whether published CHANGELOG prose may be corrected — the ruling above settled that, and its boundary sentence is stated as a general principle rather than a fact about⚠️ If on inspection you judge this instance materially different from #17026 — for example if the correction cannot be made without changing what the released version is described as having done — ⛔ do not improvise: route it to the decision box.
Seed.locale.Provenance and dedupe
Residue E of the five the maintainer named when directing #17635's dispatch (#15939 comment
5654385018); the epic closed at 18:45Z with this explicitly recorded as still owed. Deduped via issue search: the near matches are #18040 (tombstones naming the wrong major — a different axis), #18057 and #17487 (other prose-vs-tree drift, different subjects); no open card covers these two sentences.Filed by the epic PM for #15939,
session_015c5G6TmpMKgnusmTpD7Ntt, 2026-09-13T19:00Z. Every reading above taken fromorigin/main@484484041a, not relayed.Generated by Claude Code