Skip to content

docs(changeset): correct pending v18 changesets that later train landings made false, in place (deliberate correction) - #23126

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-22586-pending-changeset-corrections
Oct 13, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-22586-pending-changeset-corrections

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #22586
Clause-②: no (pending release text only; no accept set or public surface changes)

What this does

Edits 21 pending .changeset/*.md files in place so that each sentence states what main does now. Every one of them is unconsumed (.changeset/pre.json is mode: pre, tag: next, 0 consumed changesets, read on origin/main bcebd8409), so whatever they say when the Version Packages PR #21988 (18.0.0-next.0) merges is frozen into every package's CHANGELOG. Today that release would print both the false sentence and the later entry's correction of it.

No new changeset, no CHANGELOG.md, no content/docs/releases/, no .changeset/pre.json, no code. Measured on every edited file against base c9b5b24b0: the frontmatter bump block, the Clause-② line and the ADR-0087 marker are byte-identical (md5 of the extracted lines), and no control byte is present.

check-empty-changeset is red on purpose: DELIBERATE CORRECTION

scripts/check-empty-changeset.mjs (ruling D on #17712) refuses a diff that modifies a changeset present on the merge base. It names two classes with opposite remedies: COLLISION (restore theirs, rename yours) and DELIBERATE CORRECTION ("do NOT restore it -- say so on the PR and get it confirmed; restoring it from the base would put the false sentence back"). This PR is the second class by design, for all 21 files: each file is a pending note whose sentence a later landing on the same next train made false. Nothing here is restored to make the gate green. The gate stays red until the correction is confirmed; the claim on #22586 names that confirmation as an at-tier contract review on the same head.

Corrections, per file

BEFORE is the base text, AFTER is this PR's text, and the last column is the landing that made BEFORE false (sha, PR). "This PR" means the sentence quoted text that another row corrects in place, so it would have become false here. … elides text left unchanged. {$User.PATH} is this body's spelling of the files' own placeholder (the body sanitizer eats angle-bracket fragments); the files keep theirs.

# file:line (base) BEFORE AFTER made false by
1 22443-storage-scope-public-retired.md:30 Files already stored with scope public are not touched. They download exactly as they did: … Files already stored with scope public download exactly as they did: … Their stored file records are rewritten to scope user by the one-time operator sweep @objectstack/service-storage exports, which changes no access: the storage key and the bytes stay as they are. 96e4be482 (#22552), the sys_file scope sweep
2 19939-flow-value-slot-template-dialect-refused.md:21-26 What is still accepted, unchanged. A CEL value envelope, every literal (…), and two spellings CEL cannot write yet …: the date macros … CEL has no string form for one; the run user, {$User.PATH}. The flow CEL scope binds no user. A string whose tokens include one of these is not refused. Text slots (notify title / message, a screen description, …) and filter values keep the template dialect. What is still accepted, unchanged. A CEL value envelope and every literal (…). A filter value keeps the template dialect; a text slot (notify title / message, a screen description, …) reads {{ }} holes and refuses a single-brace token. run user 6a06e3b00 (#22563); date macros d85615ddd (#22635); text slots 2b61f2d9d (#22315)
3 same :32 (FROM → TO row 1) … guard one that may be absent: has(record.owner) ? record.owner : null, has(vars.x) ? vars.x : null (writes null) … guard one that may be absent a step at a time from vars: has(vars.record) && has(vars.record.owner) ? vars.record.owner : null, has(vars.x) ? vars.x : null (writes null) d85615ddd (#22635), the step-by-step guard (guardOf)
4 same :41 (census) … 20 refused (…) and 1 kept ({$User.Id}, examples/app-todo); … 71 refused (…) and 20 kept (15 date macros, 5 {$User.Id}). … 20 refused by this change (…) and 1 {$User.Id} (examples/app-todo), which the run-user refusal on this line refuses and migrates; … 71 refused by this change (…) and 20 that the date-macro and run-user refusals on this line refuse (15 date macros, 5 {$User.Id}). 6a06e3b00 (#22563), d85615ddd (#22635)
5 19939-flow-value-slot-run-user-refused.md:22 Still accepted, unchanged. A CEL value envelope, every literal, and the date macros {NOW()} / {TODAY() ± N} (CEL has no string form for a Timestamp yet). A string that mixes a date macro with any other token, a $User path included, is still kept whole. {$User.*} keeps resolving where the single-brace dialect still lives — a filter value, a notify recipients entry. The value-slot retirement's entry earlier on this line lists {$User.PATH} among the spellings still accepted, and the text-slot entries compute the run user through it; this entry supersedes those lines. Still accepted, unchanged. A CEL value envelope and every literal. {$User.*} keeps resolving where the single-brace dialect still lives, a CRUD filter value. date macros, mixed string d85615ddd (#22635); recipients 111ffff55 (#22926); supersede clause: this PR (rows 2, 20-22)
6 same :32 (row 5, "what changes") the text-slot remedy published earlier on this line computed the run user through the value-slot spelling this change refuses nothing when the run has a user; where the flow can run without one, compute current_user != null ? current_user.id : null, which renders nothing where the template did this PR (rows 20-22); the AFTER is the text-slot judge's run-user remedy on main
7 same :36 examples/app-showcase's {$User.Id} is a notify recipients entry, which is not a value slot, and is unchanged. examples/app-showcase's {$User.Id}, a notify recipients entry, is migrated to current_user with the notify value slots on this line. 111ffff55 (#22926)
8 same :44 A text slot's hint keeps the {{ }} hole, and every other position keeps the single brace. A text slot's hint keeps the {{ }} hole, the hint at a node's literal names the value itself, and every other position keeps the single brace. 111ffff55 (#22926), 968acc895 (#23062)
9 same :45 Its Expressions section states the value-slot envelope, current_user, and the date macros still read until CEL can write them. Its Expressions section states the value-slot envelope and current_user. d85615ddd (#22635)
10 19939-flow-value-slot-date-macros-refused.md:27 … carries the same guard. The value-slot retirement's earlier entry on this line prints the last-key guard; this entry supersedes it. … carries the same guard. this PR (row 3)
11 same :41 (row 9, "what changes") the text-slot remedy published earlier on this line computed the date through the value-slot spelling this change refuses nothing for a whole number of days this PR (row 20)
12 same :47 … keeps resolving where it still lives — a filter value, a notify recipients entry, an http body, a subflow input. The value-slot retirement's earlier entries on this line list the date macros as still accepted, and the text-slot entry computes a date through them; this entry supersedes those lines. … keeps resolving where it still lives, a CRUD filter value. subflow input f66fdc797 (#22715); recipients 111ffff55 (#22926); http body 968acc895 (#23062); supersede: this PR (rows 2, 5, 20)
13 19939-flow-callee-input-value-slots.md:32 … where it still lives: a map or loop collection, a filter value, a notify recipients entry, an http body, a screen's defaults. The value-slot retirement's earlier changesets on this line list subflow.input among those positions; this one supersedes that line. … where it still lives, a CRUD filter value. defaults 12b9daf74 (#22832); collection 9fdb12752 (#22883); recipients 111ffff55 (#22926); http body 968acc895 (#23062); supersede: this PR (rows 12, 19)
14 19939-flow-screen-value-slots.md:41 … where it still lives: a map or loop collection, a filter value, a notify recipients entry, an http body. The value-slot retirement's earlier changesets on this line list a screen's defaults among those positions; this one supersedes that line. … where it still lives, a CRUD filter value. collection 9fdb12752 (#22883); recipients 111ffff55 (#22926); http body 968acc895 (#23062); supersede: this PR (rows 13, 19)
15 19939-flow-collection-value-slots.md:38 … where it still lives: a filter value, a notify recipients entry, an http body. The value-slot retirement's earlier changesets on this line list a map or loop collection among those positions; this one supersedes that line. … where it still lives, a CRUD filter value. recipients 111ffff55 (#22926); http body 968acc895 (#23062); supersede: this PR (rows 13, 14, 19)
16 19939-flow-notify-value-slots.md:44 … where it still lives: a filter value, an http body. The value-slot retirement's earlier changesets on this line, and the text-slot changeset, list recipients, actionUrl, sourceId, payload and templateData among those positions; this one supersedes that line. … where it still lives, a CRUD filter value. http body 968acc895 (#23062); supersede: this PR (rows 5, 12-15, 19)
17 19939-flow-http-slots.md:44 … where it still lives, a CRUD filter value. The notify changeset on this line lists an http body among those positions; this one supersedes that line. … where it still lives, a CRUD filter value. this PR (row 16)
18 22110-flow-text-slot-double-brace.md:20 The five text slots render through one renderer … The text slots render through one renderer … actionUrl 111ffff55 (#22926); http url and headers 968acc895 (#23062): FLOW_NODE_TEXT_SLOTS holds eight
19 same :24 Unchanged: every other flow string keeps the single-brace dialect — recipients, actionUrl, sourceId, payload, templateData values, a screen's recordId / defaults / field defaultValue, subflow.input, script.inputs, map.input, http, loop / map collection, filter — and the value slots are CEL's. Unchanged: a CRUD filter value keeps the single-brace dialect, and the value slots are CEL's. f66fdc797 (#22715), 12b9daf74 (#22832), 9fdb12752 (#22883), 111ffff55 (#22926), 968acc895 (#23062)
20 same :35 (FROM → TO row 4) compute it first with an assignment node, whose value slot still reads that spelling — assignments: { due: '{TODAY() + 7}' } — then 'Due {{ due }}' compute it first with an assignment node's CEL value envelope — assignments: { due: { dialect: 'cel', source: 'isoDate(daysFromNow(7))' }, by: { dialect: 'cel', source: 'current_user.id' } } — then 'Due {{ due }}', 'By {{ by }}' 6a06e3b00 (#22563), d85615ddd (#22635); the AFTER is textSlotTemplateRefusal's remedy on main
21 22477-flow-text-slot-dollar-root-refused.md:22 The remedy for {{ $User.PATH }} is the sentence {$User.PATH} gets: compute the value into a variable with an assignment node, whose value slot still reads that spelling, then write the variable as a hole. The remedy for {{ $User.PATH }} is the sentence {$User.PATH} gets: for $User.Id, compute the run user's id into a variable with an assignment node's CEL value envelope (current_user.id), then write the variable as a hole; any other $User path never resolved, and the refusal says how to read the user record by that id. 6a06e3b00 (#22563)
22 same :33 an assignment node first, assignments: { by: '{$User.Id}' }, then message: 'By {{ by }}' an assignment node first, assignments: { by: { dialect: 'cel', source: 'current_user.id' } }, then message: 'By {{ by }}' 6a06e3b00 (#22563)
23 22507-screen-copy-engine-pick-spec.md:15 A translated screen title is not judged by the text-slot rule yet, so a single-brace token in it is drawn as literal text, as it was before. (bullet deleted) d973c34cd (#22673)
24 22627-flow-screen-title-translation-text-slot.md:13 … An earlier entry in this release says a translated screen title is not judged by the text-slot rule yet; that describes the face before this change. (sentence deleted) this PR (row 23)
25 15213-unmanaged-import-verb.md:10 This release adds the import; no door calls it yet, and no manifest key declares the mode yet. This release adds the import; the install door calls it for an unmanaged install, and the manifest key installModes declares the modes a package permits. c7d60378f (#22916)
26 same :14 Seed data and translations are left to the install door, which applies them after the copy as it does for a managed install; … The package's translations are copied too, each locale of each bundle as one translation item, and an unmanaged install loads no seed data; … c7d60378f (#22916)
27 15213-install-modes.md:12 One exception is carried: an item the package ships with an authored protection lock (_lock) keeps that lock on the copy as written today, and a follow-up on #15213 strips it per #22971's ruling A. (sentence deleted) 2d21b9c89 (#23075)
28 same :14 This entry supersedes parts of that earlier entry, 15213-unmanaged-import-verb, in this same release. … (the whole paragraph) (paragraph deleted) this PR (rows 25, 26); its lock clause, "except an item shipped with an authored _lock, which keeps that lock", 2d21b9c89 (#23075)
29 15213-unmanaged-lock-strip.md:14 This entry supersedes two sentences of the entry 15213-install-modes, in this same release. … (the whole paragraph) (paragraph deleted) this PR (rows 27, 28)
30 21898-flow-builtin-node-config-values-refused.md:19 That is not a promise it runs: only http interpolates its config before it parses, so only an http slot sees the token's resolved value. Every other builtin parses its config as authored, so a token in one of its number or boolean slots (…) still fails at its first run, exactly as before — write a literal there; That is not a promise it runs: every builtin parses its config as authored, so a token in one of its number or boolean slots (…) still fails at its first run, exactly as before — write a literal there (an http node's timeoutMs and durable refuse the token itself at the build doors); 968acc895 (#23062)
31 same :20 on http, any value with a token inside it, and signingSecret (the credential channel may supply it); on http, signingSecret (the credential channel may supply it); 968acc895 (#23062): RUN_RESOLVED_KEYS is http: ['signingSecret'], and the http token carve-out went with the interpolation
32 same :32 timeoutMs: 5000, durable: true — or, on http alone, a sole-token template such as timeoutMs: '{timeout}': http interpolates before it parses, so the token resolves to its value's type first timeoutMs: 5000, durable: true — a literal only: http parses its config as authored, and a {token} there is refused at the build doors 968acc895 (#23062)
33 21982-flow-script-subflow-config-undeclared-keys-refused.md:30 inside the input map: config: { function: 'f', inputs: { taskId: '{record.id}' } } inside the input map: config: { function: 'f', inputs: { taskId: { dialect: 'cel', source: 'record.id' } } } f66fdc797 (#22715): a {…} token in script.inputs is refused
34 22054-notify-title-template-input.md:24 These two slots read the flow's single-brace {token} ({record.name}). A {{var}} is not a placeholder here: the inner {var} resolves and the outer braces stay in the text, for a bare string and an envelope alike. These two slots render {{ }} holes ({{ record.name }}), for a bare string and an envelope alike, and a single-brace {token} in them is refused. 2b61f2d9d (#22315)
35 same :25 … descriptions state the {token} interpolation in place of "sent verbatim". … descriptions state the {{ }} holes in place of "sent verbatim". 2b61f2d9d (#22315)
36 22081-notify-refusal-single-brace.md:5 A notify flow node's title / message refusal now prescribes '{record.name}', the single-brace spelling the notify executor reads. It used to prescribe the shared template sentence's '{{record.name}}', which the build's flow-double-brace-interpolation rule then flagged on the same node and the notify renderer sent inside a stray pair of braces. A notify flow node's title / message refusal now names the key and prescribes '{{ record.name }}', the {{ }} hole the notify executor renders. It used to answer with the shared template sentence, which names no key. 2b61f2d9d (#22315): NOTIFY_TEMPLATE_PLACEHOLDER = '{{ record.name }}' lands there (git log -S)
37 same :10 … prescribes '{record.name}' or { dialect: 'template', source: '{record.name}' }, and says why: the notify executor interpolates single-brace {token} placeholders, and a doubled brace keeps its outer braces in the sent text. The branch issue … carries the same sentence, so no {{…}} prescription reaches the author on these two keys. … prescribes '{{ record.name }}' or { dialect: 'template', source: '{{ record.name }}' }, and says why: the notify executor renders {{ }} template holes, and a single-brace token is not one. The branch issue … carries the same sentence. 2b61f2d9d (#22315)
38 same :12 {{record.x}} for the formula template engine and the messaging, email and i18n renderers, {record.x} for a notify node's title / message, and either for titleFormat. {{record.x}} for the formula template engine, the messaging, email and i18n renderers and a notify node's title / message, and either for titleFormat. 2b61f2d9d (#22315): the tmpl docblock on main
39 22290-value-slot-remedy-cel-claimed-head.md:11 … and a claimed head is guarded as has(vars.list.tags) ? vars.list.tags : null. … and a claimed head is guarded a step at a time from vars, like any other head: has(vars.list) && has(vars.list.tags) ? vars.list.tags : null. d85615ddd (#22635): guardOf in flow-value-slot-template.ts

What main does, measured at c9b5b24b0 (the facts behind the AFTER column): interpolateFilter in service-automation/src/builtin/template.ts is the only single-brace interpolator still called ("Only filter blocks use this"), from the CRUD filter hand-off in crud-nodes.ts; the two interpolate() calls left run on token-free text. FLOW_NODE_TEXT_SLOTS lists eight slots. textSlotTemplateRefusal prescribes current_user.id and isoDate(daysFromNow(7)) through an assignment CEL envelope. examples/ carries no $User token; the showcase recipient reads current_user.

Cross-references between pending entries

Every clause that quoted another pending entry, found by phrase (supersede, earlier entry, earlier changeset, published earlier, this same release, companion entry, …) across all 486 pending files:

  • Dropped or reworded because the quoted text is corrected here: run-user :22 and :32 (rows 5, 6); date-macros :27, :41 and :47 (rows 10-12); S1 to S5's "still lives" clauses (rows 13-17); 22627:13 (row 24); 15213-install-modes.md:14 (row 28); 15213-unmanaged-lock-strip.md:14 (row 29).
  • Kept: they quote code, not a pending entry, and are true as written. 22443-sys-file-public-scope-rewrite.md:55 quotes the D3 entry's earlier reason ("said that files already stored with scope public are not touched"), a change to 18.storage-scope-public-retired.ts this release makes. date-macros :40 maps "the guard an earlier refusal named", and :17 says a mixed string "used to be kept whole". 15213-unmanaged-lock-strip.md:12 begins "Until now an item locked with _lock was copied with that lock". All four describe the code before that change.
  • Outside these trains, untouched: the supersede clauses in 15953-verify-parent-write-reach-family, 22402-option-gate-fails-closed, 22428-field-existence-every-spelling, 22445-update-preview-stored-row, 22481-attached-block-served-rows, 22579-migrate-telemetry-sibling and 22581-migrate-reads-env-files quote none of the files above. Each already flags the earlier sentence in order.

Sweep: what was read, and what stays as written

  • Population. The 22 train files: eight 19939-* files, 22110, 22477, the two 22443-* files, the five 22507-* files, 22627, and the four 15213-* files. Then a grep of all 486 pending files for the brace dialects and slot names (63 hits, plus 25 more on slot names), reading every flow entry among them. That sweep added 21898, 21982-…-script-subflow…, 22054, 22081 and 22290, each falsified by a train landing above. I bounded the sweep to sentences those landings falsified, as triage's direction scopes it. Other pending text is not judged here.
  • Read and true as written: 22443-sys-file-public-scope-rewrite; 22507-screen-copy-engine-pick-{automation,cli,lint} and 22507-flow-options-toasts-translation; 15213-readonly-package-remedy; 21982-flow-builtin-node-config-undeclared-keys-refused (keys inside a free-form map are still never judged); 22301-verify-evaluate-condition-door:12 (evaluateCondition still reads a template string); 22344, 22502, 22572 ({read.id} and "a single-brace token in a value position" still exist in a CRUD filter); the 22161 lint slices.
  • Judgement calls, left as written; please check them. (a) 22110:8 and 22477:6 list the five text slots that change created. They are not framed as exhaustive, and the notify and http entries state the three added since; only the count "the five" (row 18) contradicted them. (b) S4 :17 and S5 :19 print a last-key guard on a field of the trigger record, which is bound there, so pass 3's absent-variable reasoning does not reach them. (c) 15213-unmanaged-import-verb.md:6 and :10 ("editable from then on", "is fully editable") are true again on main since the lock strip (2d21b9c89). (d) 15213-unmanaged-import-verb.md:14 refuses "a body carrying … code (functions, …)". S2 stopped refusing an empty container, which carries no code, so I read it as true.
  • NOT MEASURED: 22081:12's clause "the generated expression reference page says a template slot's fix is written in the spelling its renderer reads". It is left as written.

Verification

Gates were derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on HEAD 88fa8fe1b (this branch merged with origin/main bcebd8409; the delta vs origin/main is exactly these 21 files, +36 / -46). That gave 20 commands, and all 20 ran on 88fa8fe1b. --ran reconciliation: "20 derived, 20 run, 0 NOT-MEASURED, 0 UNRUN", with exit codes recorded.

  • Red, as designed: node scripts/check-empty-changeset.mjs --base origin/main, exit 1. It prints 21 ::error lines, one per edited file, and each one says "exists on the merge base and was not added by this PR … DELIBERATE CORRECTION -- your change may have made this PENDING release note false, and you rewrote it in the same stroke. Remedy: do NOT restore it -- say so on the PR and get it confirmed".
  • Green, exit 0: check-adr-0087-registration --base origin/main ("this PR adds no declared-breaking changeset (21 non-breaking changeset(s) seen)") and its --self-test (548 assertions); check-changeset-no-major --base origin/main ("This diff introduces no major bump") and its --self-test (401); check-closing-keyword-parity and --self-test; check-comment-mask-corpus (8926 files, 0 disagree); check-empty-changeset --self-test (170); release-rehearsal-clone --self-test; release-pending-publish --self-test (92 cases); check:changeset-gate-self-tests; check:driver-memory-census; check:gitlink-declared; check:nul-bytes (11157 files, no raw control bytes); check:objectui-changeset; check:pm-changeset-deadline-census; check:published-files; check:refd-timer-probe; check:watch-hint-literal.
  • Also run, outside the derivation: node scripts/check-changeset-fixed.mjs, the one roster family whose roster lives under .changeset/. Exit 0.
  • check:doc-authoring is not in the derivation for .changeset/** and its script names no changeset path, so it does not read these files.
  • No package build or test is owed: the diff touches no package source.

Generated by Claude Code

…ace to what main does

The #19939 value-slot entries listed the date macros, the run user and
positions S1 to S5 later made value slots as still read by the single
brace; on main only a CRUD filter value reads it. Each list now names
that one position, and each supersede clause that quoted the old lists
is dropped. The storage-scope entry stops saying stored public files are
not touched: the operator sweep rewrites their scope to user.

Claude-Session: https://claude.ai/code/session_012uFegdfR6K6uqvLzt7XsdZ
Co-authored-by: Claude <noreply@anthropic.com>
…pending entries in place

The text-slot entries prescribed computing a date or the run user through
a value-slot spelling the value slots now refuse, and listed positions as
single-brace that are value slots, text slots or literals on main. The
notify entries said its title and message read the single brace; they
render double-brace holes. The node-config entry said http interpolates
before it parses; it parses as authored. The unmanaged-install entries
said no door calls the import and that the copy keeps an authored lock.
Each sentence now states main, and every supersede clause that quoted
the corrected text is dropped.

Claude-Session: https://claude.ai/code/session_012uFegdfR6K6uqvLzt7XsdZ
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Check Changeset is red on 88fa8fe1b by design · domain:spec seat 3 · os-support-ai · session session_012uFegdfR6K6uqvLzt7XsdZ · 2026-10-13T02:01Z


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 88fa8fe1b0052891518c6cef610a9c0636ba100d
Local-runs: none

Read: card #22586 (body and all 12 comments; the dispatching seat's ACCEPT 6136455585 was not used as evidence), PR #23126 (body, file list, net diff against main), the 34 check-runs on the head, and origin/main at bcebd8409 read-only (git show, git grep, git merge-base). The post-PR text of each note was derived in scratch as origin/main plus the diff, to sweep cross-references; nothing was built, run or re-run. This record is the written confirmation of the DELIBERATE CORRECTION that check-empty-changeset asks for: it names all 21 edited notes and judges every rewritten sentence against origin/main.

① Derived judgments

Accept-set and public-surface changes implied by the diff: none. The file list is 21 rows, every one modified on an existing .changeset/*.md, zero added, zero deleted (+36 / -46). No path under packages/, examples/, content/, no .changeset/pre.json, no CHANGELOG.md. All 21 notes are still unconsumed on origin/main (.changeset/pre.json: mode: pre, tag: next, changesets: []; 490 pending files). The diff changes the release text changeset version will compile into the 18.0.0-next.0 CHANGELOGs; it moves no schema, export, option or refusal.

Invariants measured on base vs post for all 21 files. Frontmatter bump block md5-identical 21/21. Clause-② line md5-identical 21/21. ADR-0087 marker comment count identical per file, present and unchanged in the 8 notes that carry one (callee-input, collection, http-slots, notify-value-slots, screen-value-slots, template-dialect, 21982-script-subflow, 22110). No raw control byte in any post file. Every hunk sits below the frontmatter and the Clause line (hunk headers at base lines 9, 7, 11, 29, 35, 41, 41, 38, 24/38, 19/29/41, 18/38, 16/29, 27, 21, 2, 17/32, 8, 27, 19/30, 12, 10).

The twelve landings the PR cites are all ancestors of origin/main (git merge-base --is-ancestor): 96e4be482 #22552, 6a06e3b00 #22563, d85615ddd #22635, 2b61f2d9d #22315, 111ffff55 #22926, 968acc895 #23062, f66fdc797 #22715, 12b9daf74 #22832, 9fdb12752 #22883, d973c34cd #22673, c7d60378f #22916, 2d21b9c89 #23075.

Every edited note, every rewritten sentence. Row numbers follow the PR body's table. TRUE: the AFTER text states what origin/main does, with the evidence. DROP-OK: the removed text is false on origin/main or restated elsewhere, and nothing true and load-bearing for an upgrading author went with it. Line numbers are base lines; {$User.PATH} stands for the files' own angle-bracket placeholder. Paths are under packages/ unless they start with .changeset/, examples/ or content/; service-automation is packages/services/service-automation.

Note 1 — .changeset/22443-storage-scope-public-retired.md

  • Row 1, :30 — "Files already stored with scope public download exactly as they did … Their stored file records are rewritten to scope user by the one-time operator sweep @objectstack/service-storage exports, which changes no access: the storage key and the bytes stay as they are." TRUE. services/service-storage/src/index.ts:95-105 exports planSysFilePublicScopeBackfill / applySysFilePublicScopeBackfill / runSysFilePublicScopeBackfill, the comment reading "the one-time operator sweep that rewrites stored sys_file rows whose scope is the retired public to user". Landed note .changeset/22443-sys-file-public-scope-rewrite.md:16-17 (96e4be482): "No access behaviour changes … the storage key keeps its public/ prefix, the acl and ownership columns are untouched, and no byte moves in the storage backend." Dropped "are not touched": false since 96e4be482. DROP-OK.

Note 2 — .changeset/19939-flow-value-slot-template-dialect-refused.md

  • Row 2, :21-26 — "A filter value keeps the template dialect; a text slot (notify title / message, a screen description, …) reads {{ }} holes and refuses a single-brace token." TRUE. service-automation/src/builtin/template.ts:41-42 ("The {$User.*} and date branches below still answer the position that keeps this dialect, a filter") and :524-527 ("Only filter blocks use this. No other position reads the single-brace dialect any more"); spec/src/automation/flow-text-slot-template.ts:196-205 (FLOW_NODE_TEXT_SLOTS, notify title/message among them); service-automation/README.md:192 (text slots: "a single-brace token is refused"). Dropped: the date macros as "a spelling CEL cannot write yet" (false: formula/src/stdlib.ts:106 isoDate, landed note .changeset/19939-flow-value-slot-date-macros-refused.md:15), the run user as kept because "the flow CEL scope binds no user" (false: spec/src/automation/flow-value-slot-template.ts:66-72, current_user is bound), "a string whose tokens include one of these is not refused" (false: date-macros note :17, a mixed string "is refused now"). DROP-OK.
  • Row 3, :32 — guard "a step at a time from vars: has(vars.record) && has(vars.record.owner) ? vars.record.owner : null, has(vars.x) ? vars.x : null". TRUE. spec/src/automation/flow-value-slot-template.ts:260-265 (guardOf joins has(vars.a) && has(vars.a.b) … ? vars.a.b : null), :270-271 (ABSENT_SENTENCE: "a step at a time from vars"), :353-356 (the path remedy prints that guard).
  • Row 4, :41 — census reworded: the 1 {$User.Id} in examples/app-todo is one "the run-user refusal on this line refuses and migrates"; hotcrm's 20 are ones "the date-macro and run-user refusals on this line refuse (15 date macros, 5 {$User.Id})". TRUE. Run-user note on origin/main (6a06e3b00), its unchanged :36: "This repository's two authored value-slot sites are migrated in this change: the examples/app-todo quick-add screen flow …"; date-macros note :30: "15 date-macro value-slot sites in hotcrm … they migrate there"; flow-value-slot-template.ts:66-70 ({$User.Id} is refused) and :82-88 (the date macros are refused). The counts (20 / 1; 71 / 20) are unchanged.

Note 3 — .changeset/19939-flow-value-slot-run-user-refused.md

  • Row 5, :22 — "Still accepted, unchanged. A CEL value envelope and every literal. {$User.*} keeps resolving where the single-brace dialect still lives, a CRUD filter value." TRUE. template.ts:270-272 (the $User.* branch), :529-547 (interpolateFilter is the one caller left, reached from crud-nodes.ts:104), :524-527. Dropped: date macros "still accepted" and a mixed string "kept whole" (false: date-macros note :16-17, d85615ddd); "a notify recipients entry" (false: landed S4 note .changeset/19939-flow-notify-value-slots.md:9, a token is refused at recipients); the supersede clause (its quoted text is corrected by rows 2, 20-22). DROP-OK.
  • Row 6, :32 — what-changes column: "nothing when the run has a user; where the flow can run without one, compute current_user != null ? current_user.id : null, which renders nothing where the template did". TRUE. spec/src/automation/flow-template-token.ts:201 (CEL_RUN_USER_ID), :208 (CEL_RUN_USER_ID_GUARDED is exactly that source); flow-text-slot-template.test.ts:114-115 pins the text-slot judge's remedy as the assignment CEL envelope with current_user.id and that guard; a null hole renders nothing (.changeset/22110-flow-text-slot-double-brace.md:20, unchanged: "null and an absent path render nothing"). Dropped: "computed the run user through the value-slot spelling this change refuses" — false once row 20 rewrites the text-slot remedy. DROP-OK.
  • Row 7, :36 — "examples/app-showcase's {$User.Id}, a notify recipients entry, is migrated to current_user with the notify value slots on this line." TRUE. git grep '\$User' origin/main -- examples/: 0 hits; examples/app-showcase/src/automation/flows/index.ts:1955-1963 (recipients carries { dialect: 'cel', source: 'current_user != null ? current_user.id : null' }); S4 note :38 (the showcase's 16 recipient strings migrated in 111ffff55).
  • Row 8, :44 — lint hint: "A text slot's hint keeps the {{ }} hole, the hint at a node's literal names the value itself, and every other position keeps the single brace." TRUE. lint/src/lint-flow-patterns.ts:730 (text-slot hint: "A text slot renders only {{ }} holes"), :833-856 (LITERAL_KEYS hints end "Write the value itself."), :670-675 (every other config string keeps the single-brace dialect, except a node's literals).
  • Row 9, :45 — "Its Expressions section states the value-slot envelope and current_user." TRUE. service-automation/README.md:181-192 (the section, the envelope row at :191) and :233-241 (current_user, inside the section that runs to :255). Dropped "and the date macros still read until CEL can write them": false, the README at :194-199 now says a value slot refuses every token and a date macro is its CEL string form. DROP-OK.

Note 4 — .changeset/19939-flow-value-slot-date-macros-refused.md

  • Row 10, :27 — supersede clause dropped ("The value-slot retirement's earlier entry on this line prints the last-key guard; this entry supersedes it"). DROP-OK. Row 3 rewrites the quoted text; the guard paragraph that remains states origin/main (flow-value-slot-template.ts:249-258).
  • Row 11, :41 — what-changes: "nothing for a whole number of days". TRUE. flow-value-slot-template.ts:84-88 ({TODAY() + N} is isoDate(daysFromNow(N))), the note's own unchanged :19 ("for no offset or a whole number of days the CEL form writes the template's text byte for byte"); flow-text-slot-template.test.ts:91 pins {TODAY() + 7} → isoDate(daysFromNow(7)).
  • Row 12, :47 — "The single-brace dialect, date macros included, keeps resolving where it still lives, a CRUD filter value." TRUE. template.ts:235-237 (the date branch), :41-42, :524-527. Dropped positions: a notify recipients entry (S4 :9), an http body (landed S5 note .changeset/19939-flow-http-slots.md:9, a token refused in "any string of a literal body"), a subflow input (landed S1 note .changeset/19939-flow-callee-input-value-slots.md:5); the supersede clause's quoted texts are corrected in rows 2, 5, 20. DROP-OK.

Note 5 — .changeset/19939-flow-callee-input-value-slots.md — Row 13, :32: "The single-brace dialect keeps resolving where it still lives, a CRUD filter value." TRUE (same evidence as row 12; README.md:191 lists map/loop collection, screen defaults, notify recipients, the http body among the value slots). Dropped positions: collection (S3, 9fdb12752, .changeset/19939-flow-collection-value-slots.md Clause line "a string is refused at loop.collection and map.collection"), recipients (S4 :9), http body (S5 :9), a screen's defaults (landed S2 note .changeset/19939-flow-screen-value-slots.md:8); the supersede clause quoted subflow.input text now corrected in rows 12 and 19. DROP-OK.

Note 6 — .changeset/19939-flow-screen-value-slots.md — Row 14, :41: same sentence. TRUE (as row 13). Dropped: collection (S3), recipients (S4 :9), http body (S5 :9); supersede clause quoted the defaults text corrected in rows 13 and 19. DROP-OK.

Note 7 — .changeset/19939-flow-collection-value-slots.md — Row 15, :38: same sentence. TRUE. Dropped: recipients (S4 :9), http body (S5 :9); supersede clause quoted the collection text corrected in rows 13, 14, 19. DROP-OK.

Note 8 — .changeset/19939-flow-notify-value-slots.md — Row 16, :44: same sentence. TRUE. Dropped: http body (S5 :9); supersede clause quoted the recipients / actionUrl / sourceId / payload / templateData texts corrected in rows 5, 12-15, 19. DROP-OK.

Note 9 — .changeset/19939-flow-http-slots.md — Row 17, :44: the supersede clause alone is dropped; the sentence before it ("… a CRUD filter value") is unchanged and TRUE. DROP-OK (the quoted http body text is corrected in row 16).

Note 10 — .changeset/22110-flow-text-slot-double-brace.md

  • Row 18, :20 — "The text slots render through one renderer …" (was "The five text slots"). TRUE. flow-text-slot-template.ts:196-205: eight slots (notify title/message/actionUrl, http url/headers, screen title/description, end message); template.ts:467 (renderTextSlot, the one renderer, used by notify-node.ts:355-356, 374).
  • Row 19, :24 — "Unchanged: a CRUD filter value keeps the single-brace dialect, and the value slots are CEL's." TRUE (template.ts:524-527, README.md:191-192). Dropped list, each now a value or text slot on origin/main: recipients, actionUrl, sourceId, payload, templateData (S4 :9, 111ffff55); a screen's recordId / defaults / field defaultValue (S2 :8, 12b9daf74); subflow.input, script.inputs, map.input (S1 :5, f66fdc797); http (S5 :9, 968acc895); loop / map collection (S3, 9fdb12752). DROP-OK.
  • Row 20, :35 — remedy: "compute it first with an assignment node's CEL value envelope — assignments: { due: { dialect: 'cel', source: 'isoDate(daysFromNow(7))' }, by: { dialect: 'cel', source: 'current_user.id' } } — then 'Due {{ due }}', 'By {{ by }}'". TRUE. flow-text-slot-template.ts:86 (the judge's run-user remedy: "current_user.id with an assignment node's CEL envelope, then write" the hole); flow-text-slot-template.test.ts:91, 114 pin isoDate(daysFromNow(7)) and assignments: { v: { dialect: 'cel', source: 'current_user.id' } }. The variable names due / by are the author's. Dropped "whose value slot still reads that spelling": false since 6a06e3b00 / d85615ddd. DROP-OK.

Note 11 — .changeset/22477-flow-text-slot-dollar-root-refused.md

  • Row 21, :22 — "for $User.Id, compute the run user's id into a variable with an assignment node's CEL value envelope (current_user.id), then write the variable as a hole; any other $User path never resolved, and the refusal says how to read the user record by that id." TRUE. flow-text-slot-template.ts:68-69, 86; flow-template-token.ts:228-237 (runUserPathNeverResolved: "never resolved in any shipped run … read the user record by current_user.id" through a get_record on sys_user); flow-text-slot-template.test.ts:121-125.
  • Row 22, :33 — FROM → TO: assignments: { by: { dialect: 'cel', source: 'current_user.id' } }, then message: 'By {{ by }}'. TRUE (same evidence). Dropped assignments: { by: '{$User.Id}' }: refused since 6a06e3b00 (flow-value-slot-template.ts:66-70). DROP-OK.

Note 12 — .changeset/22507-screen-copy-engine-pick-spec.md — Row 23, :15: bullet "A translated screen title is not judged by the text-slot rule yet …" deleted. DROP-OK. False since d973c34cd (#22673): spec/src/system/translation.zod.ts:14, 80, 1303 (textSlotTemplateRefusal judges the translated screen keys) and the landed note .changeset/22627-flow-screen-title-translation-text-slot.md:5 ("A translated flow screen heading … is judged by the same text-slot rule … A single-brace {token} in it is refused"). Nothing true was dropped.

Note 13 — .changeset/22627-flow-screen-title-translation-text-slot.md — Row 24, :13: the clause "An earlier entry in this release says a translated screen title is not judged by the text-slot rule yet; that describes the face before this change." deleted. DROP-OK. Its quoted bullet no longer exists after row 23; the rest of the "Why" paragraph still states the before-face ("The heading accepted it and drew it as literal text").

Note 14 — .changeset/15213-unmanaged-import-verb.md

  • Row 25, :10 — "This release adds the import; the install door calls it for an unmanaged install, and the manifest key installModes declares the modes a package permits." TRUE. spec/src/kernel/manifest.zod.ts:635 (installModes on ManifestSchema), :449-454 (resolveInstallModes); cloud-connection/src/marketplace-install-local-plugin.ts:305-310 ("The one verb the unmanaged install mode calls"), :1391-1399 (the installMode === 'unmanaged' branch), :48-65.
  • Row 26, :14 — "The package's translations are copied too, each locale of each bundle as one translation item, and an unmanaged install loads no seed data". TRUE. metadata-protocol/src/package-unmanaged-install.ts:45-53 ("translations … are COPIED, converted: each locale of each bundle becomes one translation item"), :410; marketplace-install-local-plugin.ts:65 (unmanaged: "its sample data is not loaded"); spec/src/kernel/unmanaged-install.ts:109 (seed datasets are data, never metadata items). Dropped "left to the install door, which applies them after the copy as it does for a managed install": false since c7d60378f. DROP-OK.

Note 15 — .changeset/15213-install-modes.md

Note 16 — .changeset/15213-unmanaged-lock-strip.md — Row 29, :14: the supersede paragraph ("This entry supersedes two sentences of the entry 15213-install-modes …") deleted. DROP-OK. Both quoted sentences are gone after rows 27-28, so the clause would quote nothing; its "what holds now" (no lock in either spelling, the next save edits it, the answer lists each lock dropped) is the unchanged :12 and :16 of the same note.

Note 17 — .changeset/21898-flow-builtin-node-config-values-refused.md

  • Row 30, :19 — "every builtin parses its config as authored, so a token in one of its number or boolean slots … still fails at its first run … (an http node's timeoutMs and durable refuse the token itself at the build doors)". TRUE. service-automation/src/builtin/parse-config.ts:18-24 ("every executor parses the raw stored config as stored … http too since [v18] retire the {var} template dialect in flow assignment slots: refuse at registration with per-spelling remedies (the C half of #11182 ruling D, on the v18 train) #19939 … a {…} token is refused at every position now"); http-nodes.ts:62-65; S5 note :9 (a token is refused at durable, timeoutMs) and :34. Dropped "only http interpolates its config before it parses": false since 968acc895. DROP-OK.
  • Row 31, :20 — "on http, signingSecret (the credential channel may supply it)". TRUE. spec/src/automation/flow-node-config-refusals.ts:298 (RUN_RESOLVED_KEYS = { http: ['signingSecret'] }), :414. Dropped "any value with a token inside it": false, S5 :9. DROP-OK.
  • Row 32, :32 — "timeoutMs: 5000, durable: true — a literal only: http parses its config as authored, and a {token} there is refused at the build doors". TRUE (parse-config.ts:18-24; S5 :34: "the key is a literal now; nothing computes it").

Note 18 — .changeset/21982-flow-script-subflow-config-undeclared-keys-refused.md — Row 33, :30: TO row now inputs: { taskId: { dialect: 'cel', source: 'record.id' } }. TRUE. S1 note :5 on origin/main (f66fdc797): a script node's inputs are value slots, "A {…} template token there is refused"; README.md:191. The old TO row prescribed a refused token. DROP-OK.

Note 19 — .changeset/22054-notify-title-template-input.md

  • Row 34, :24 — "These two slots render {{ }} holes ({{ record.name }}), for a bare string and an envelope alike, and a single-brace {token} in them is refused. The .describe() on both keys now says so, and no longer says the text is "sent verbatim"." TRUE. spec/src/automation/io-node-config.zod.ts:553, 556 (both describes: "rendered per run with {{ }} holes"), :142, 156-157; git grep 'sent verbatim' in that file: 0 hits; notify-node.ts:355-356 (renderTextSlot on title.source / message.source). Dropped single-brace description: false since 2b61f2d9d. DROP-OK.
  • Row 35, :25 — "the descriptor's title / message descriptions state the {{ }} holes in place of "sent verbatim"". TRUE. service-automation/src/builtin/notify-node.ts:248, 252 ("rendered per run with {{ }} placeholders").

Note 20 — .changeset/22081-notify-refusal-single-brace.md

  • Row 36, :5 — "A notify flow node's title / message refusal now names the key and prescribes '{{ record.name }}', the {{ }} hole the notify executor renders. It used to answer with the shared template sentence, which names no key." TRUE. io-node-config.zod.ts:149 (NOTIFY_TEMPLATE_PLACEHOLDER = '{{ record.name }}'), :163-167 (the key-naming refusal); notify-node.ts:355-356; spec/src/shared/expression.zod.ts:292-299 (the shared sentence is TemplateExpressionInputSchema's; "A template slot that must name itself in the refusal does not answer with it … The notify node's title / message do, so their refusals can name the key … since protocol 18 they prescribe the same {{ }} hole, {{ record.name }}") and :325-328 (the shared sentence names no key). Dropped history of the 17.x stray braces: obsolete once the prescription is {{ }}; the new before-sentence is the one the compiled entry needs. DROP-OK.
  • Row 37, :10 — "prescribes '{{ record.name }}' or { dialect: 'template', source: '{{ record.name }}' }, and says why: the notify executor renders {{ }} template holes, and a single-brace token is not one. The branch issue … carries the same sentence." TRUE. io-node-config.zod.ts:167 (both spellings), :156-157 (the why, verbatim). Dropped "so no {{…}} prescription reaches the author on these two keys": false. DROP-OK.
  • Row 38, :12 — "{{record.x}} for the formula template engine, the messaging, email and i18n renderers and a notify node's title / message, and either for titleFormat." TRUE. expression.zod.ts:505-516 (the tmpl docblock bullets: double braces for the formula engine and the messaging, email and i18n renderers, "Since protocol 18 a notify flow node's title / message read {{record.x}} too"; "either — titleFormat"), :395-403 (the TemplateExpressionInputSchema docblock lists the notify slots the same way). The unchanged tail the dev marked NOT MEASURED is measured here: content/docs/references/shared/expression.mdx:36-41 says "a template slot's fix is written in the placeholder spelling its renderer reads". TRUE.

Note 21 — .changeset/22290-value-slot-remedy-cel-claimed-head.md — Row 39, :11: "a claimed head is guarded a step at a time from vars, like any other head: has(vars.list) && has(vars.list.tags) ? vars.list.tags : null". TRUE. flow-value-slot-template.ts:256-265 (guardOf emits the chain; the docblock names has(vars.list) && has(vars.list.tags)); flow-template-token.ts:106 (CEL_KEYWORDS is true/false/null/in, so list takes the guard), :137, 174 (a claimed head is selected off vars).

Cross-references, swept on the post-PR text of all 490 pending files. A phrase sweep (supersede, earlier entry, earlier changeset, published earlier, this same release, companion entry, earlier on this line, said that, …) and a sweep for each removed phrase ("are not touched", "binds no user", "still reads that spelling", "no door calls it", "left to the install door", "keeps that lock", "not judged by the text-slot rule", "interpolates … before it parses", "sent verbatim", "the five text slots", "kept whole", "supersedes") and for the 21 file names:

  • Every clause that quoted text this PR corrects is dropped or reworded (rows 5, 6, 10, 11, 12, 13-17, 24, 28, 29). No remaining clause quotes removed text.
  • Kept clauses that quote code, not a pending note, and are true as written: 22443-sys-file-public-scope-rewrite.md:55 quotes the D3 ledger entry storage-scope-public-retired's earlier reason; 19939-flow-value-slot-date-macros-refused.md:17, :40 ("used to be kept whole", "the guard an earlier refusal named") describe the code before d85615ddd; 15213-unmanaged-lock-strip.md:12 ("Until now … was copied with that lock") describes the code before 2d21b9c89. 15213-install-modes.md:12 still names 15213-unmanaged-import-verb as its companion entry; that file exists.
  • The remaining supersede-by-quotation clauses (15953-verify-parent-write-reach-family:40, 22402-option-gate-fails-closed:27, 22428-field-existence-every-spelling:19, 22445-update-preview-stored-row:21, 22481-attached-block-served-rows:10, :17, 22579-migrate-telemetry-sibling:13, 22581-migrate-reads-env-files:11) quote none of the 21 files (the by-name sweep's only cross-file hit is install-modes → import-verb); their targets are untouched by this diff.
  • The dev's judgement call (b), checked: S4 :17 and S5 :19 print has(record.assignee) ? record.assignee : null as author guidance on the trigger record, which the run binds; the last-key guard fails only where the head variable was never bound (date-macros note :27), so neither sentence is false and neither claims to quote the refusal. Left as written, rightly. (c) and (d) hold for the reasons under rows 28 and 26.

Check-runs on 88fa8fe1b0052891518c6cef610a9c0636ba100d: 34, all completed; 25 success, 8 skipped, 1 failure. Success includes Lint & Repo Gates, TypeScript Type Check, Test Core, Dogfood Regression Gate, Governed Surface Queue Guard, The card this PR closes must claim this branch, No other open PR may claim the same single-writer path, Check PR Size, Check Documentation Links and every Lint · / Type Check · slice. Skipped (path filter, no package source): Build Core, the sharded Test Core / Dogfood Regression Gate matrices, Console Pin Gate, Build Docs, Temporal Conformance, Dogfood Verify CLI, Packed-tarball smoke. The one failure is Check Changeset (pr-automation.yml, on: pull_request only, :41-43): its route 0 names exactly this class — every .changeset row M, none A — and says "do NOT apply 'skip-changeset' … LEAVE THIS CHECK RED", adding that the check "is not one of the required contexts" (.github/workflows/pr-automation.yml:716-731, :934-945). The file list confirms the class: 21 modified, 0 added. The red is the designed signal that this record answers. mergeable_state: unstable follows from that one red.

② Semver level

③ Boundary flags

Dev report 6136369091, every flag answered:

  1. Merged origin/main bcebd8409 into the branch (dispatch-gates staleness) — fine: the net diff against main is exactly the 21 files, +36 / -46, and the merge touches none of them.
  2. Scope beyond the card and the six pointers by five files (21898, 21982-flow-script-subflow-…, 22054, 22081, 22290) — inside the claim 6135924684's surface ("any further pending file the claim-time sweep … finds false on main"); each rewritten sentence judged TRUE above (rows 30-39).
  3. Attribution form — not a contract matter; the body carries the session URL footer.
  4. No label written — correct, see ②.
  5. open_questions 1 — extend the five-item text-slot lists at 22110:8 and 22477:6 to the eight on main? Answer: A, leave them. Each sentence names the slots its own change created (notify title/message, screen title/description, end message), in its own entry's scope; the three later slots are declared by their own entries in the same release (19939-flow-notify-value-slots for actionUrl, 19939-flow-http-slots for url and each headers value), and FLOW_NODE_TEXT_SLOTS on origin/main holds exactly those eight (flow-text-slot-template.ts:196-205). The one exhaustive wording, "the five text slots" at 22110:20, is corrected (row 18). Extending the two lists would attribute to [v18] flow text slots: read ADR-0032 §3's {{ }} delimiter instead of single-brace {token} (notify title/message and the other flow string slots), converting only what renders the same #22110 and spec(automation): a {{ $User.Id }} hole in a flow text slot passes objectstack validate and renders blank with ok: true — the door refuses {$User.Id} loudly but admits its {{ }} spelling silently #22477 slots those changes did not create. Not a FAIL item; no escalation.
  6. NOT MEASURED, 22081:12's reference-page clause — measured here, TRUE (content/docs/references/shared/expression.mdx:36-41); closed.
  7. Judgement calls (a)-(d) — (a) is item 5; (b), (c), (d) checked and held (①, cross-references).
  8. Out-of-scope observation (other trains' supersede clauses read correctly in order) — confirmed by the sweep; acceptance note, nothing to file.

No escalation to the maintainer is owed by this record beyond what the landing rules already reserve: this PR is not governed (Governed Surface Queue Guard success; no docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md or docs/NORTH-STAR.md path), and Check Changeset stays red by design.

Implemented-by: claude/issue-22586-pending-changeset-corrections
Reviewed-by: session_012uFegdfR6K6uqvLzt7XsdZ

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 13, 2026 02:16
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 13, 2026 02:16
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 13, 2026
Merged via the queue into main with commit 287fd6e Oct 13, 2026
34 of 35 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-22586-pending-changeset-corrections branch October 13, 2026 02:38
This was referenced Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

2 participants