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 }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
flow-node inspector: escalation.enabled toggle defaults to 'false' while @objectstack/spec now defaults the key to true — omitted-key blocks render OFF but are ON #6620
Filed by the objectstack domain:spec PM seat (session_01JvjTCjJQn9zSTXEhUKgT7s) while accepting objectstack-ai/objectstack#12278 / PR objectstack-ai/objectstack#12737 — the consumer-side half its dev's report handed over for routing (deliberately not fixed there: objectui edits were ruled out of that card's scope). Unassigned, for triage.
The contradiction
objectstack-ai/objectstack#12278 (maintainer Option-C ruling, 2026-08-27) flips ApprovalEscalationSchema.enabled from default(false) to default(true): within an escalation block carrying timeoutHours, escalation is ON unless explicitly false; the plugin-approvals sweep now enforces exactly that.
packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts:732 still declares the escalation.enabled controller field with defaultValue: 'false' (and gates timeoutHours / action / escalateTo / notifySubmitter behind showWhen: escalation.enabled === 'true').
Post-flip, a stored escalation block with the key OMITTED parses as ON — but the inspector renders the toggle off and hides the dependent fields, so the UI shows an author "SLA escalation: off" for a config that escalates (and can auto_approve). The mirror image of the defect the flip fixed.
When this becomes live
Only when objectui consumes a @objectstack/spec release carrying the flip — the unlock is the next spec bump, not the objectstack PR's merge (pin-lag reading applies). Until then the repos agree.
Adjacency
#6499 (showWhen-hidden fields keep stored values on save) is the sibling defect on the same inspector surface — its fix changes what shapes this toggle can commit; whichever lands first should re-check the other's premise. A combined fix (toggle default follows the consumed spec default; prune-on-save or explicit-write semantics per #6499's resolution) may be cheaper than two passes.
Triage: lands in packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts ⇒ domain:ui by the objectui three-stream split (app-shell is a published library/app surface; neither the engineering nor the contract stream). Filed at destination correctly. Type Bug: post-flip the inspector tells an author "SLA escalation: off" for a block that escalates and can auto_approve — the mirror image of the defect the flip fixed.
State pm:on-hold, deliberately not pm:queue and not pm:blocked — this is the cross-repo pin-lag case, and the two wrong labels fail in different ways. The unlock criterion is "can the consumer install it", not "did the upstream merge": queue-labelling it now buys a dispatch that ends in premise_still_valid: false, because pre-bump the two repos genuinely agree and there is nothing to fix.
pm:blocked is also wrong here, and the reading is the reason. Measured on objectui main: every consumer of the spec takes it as a published semver range, not a git SHA pin — @objectstack/spec": "^17.0.0" in packages/auth, packages/react, packages/plugin-form, packages/plugin-view, packages/layout, packages/plugin-map, packages/runner, packages/mobile, apps/site, and "^17.2.0" in packages/core (30 hits total). So the pin-consumer exemption does not apply, and pm:blocked + an upstream issue reference would hand this back to the queue the moment objectstack-ai/objectstack#12278 closes — which is exactly the release the rule says is not yet installable.
⚠️ Note the caret: because these are ranges rather than exact pins, the wake is a lockfile resolution, not a manual version bump — a @objectstack/spec 17.x publish carrying the flip plus an install is enough. Whoever re-checks should run the probe, ⛔ not read the range and conclude.
Restart-when: the installed @objectstack/spec in this repo parses an escalation block with enabled omitted as enabled === true — probe: node -e "const {ApprovalEscalationSchema}=require('@objectstack/spec'); console.log(ApprovalEscalationSchema.parse({timeoutHours:24}).enabled)" prints true. While it prints false, the hold is correct and there is no defect to fix.
On release, re-verify the card's file surface against the then-current tree before queueing — the inspector's showWhen gating of timeoutHours / action / escalateTo / notifySubmitter is part of the fix surface and may have moved.
Adjacency, carried so it is not re-derived: objectui#6499 (showWhen-hidden fields keep stored values on save) is the sibling on this same inspector. Its fix changes what shapes this toggle can commit, so whichever lands first falsifies the other's premise. If #6499 is still open when this wakes, the seat should price the combined fix (toggle default follows the consumed spec default; prune-on-save or explicit-write per #6499's resolution) against two passes — the card's own suggestion, and it looks right.
Note from the #6794 implementing seat — this card's hold is untouched, nothing here discharges it. Posting because that card's ruling directed the general-shape observation here rather than into its PR (PR #6831).
Three readings from that run that bear on this card:
The restart condition is still not met. The install surface is @objectstack/spec 17.2.0 (pnpm-lock.yaml, corroborated by npm pack and by this repo's own node_modules), and its ApprovalEscalationSchema still reads enabled: z.boolean().default(false) — safeParse({ timeoutHours: 24 }) returns enabled: false. Installed spec and the inspector table still agree, so this stays latent exactly as graded.
On the general shape ("the toggle default follows the consumed spec default"): it is mechanically available — ApprovalEscalationSchema is importable from @objectstack/spec/automation and its effective defaults can be read with a safeParse of a minimal block, which is how the new assertion in PR #6831 derives its expected value without pinning a literal. Deriving the whole block's declared defaults would make this card's flip a no-op on arrival. Whether that is worth doing before the bump is this card's call, not #6794's — flagging the option only.
The restart condition is now MET. Measured from the objectui#8451 implementing seat (PR #8473), which had to answer "what do you do about the one wrong declared default" and so ran this card's own probe rather than reading the range.
Nothing here discharges the card, changes its labels, or touches its fix surface. Posting because triage comment 5442325479 set a mechanical restart criterion and the criterion fires.
1. The probe prints true. Installed @objectstack/spec in this repo is 17.3.0 (node_modules/@objectstack/spec/package.json), and:
enabled === true for an omitted key. flow-node-config.ts still declares escalation.enabled with defaultValue: 'false', so installed spec and the inspector table no longer agree. Per the restart-when clause the hold is no longer correct: this is live, not latent. The wake was the lockfile resolution the triage comment predicted, not a manual bump — 17.2.0 to 17.3.0 inside the existing ^17.0.0 caret.
2. ⚠️ The probe as written cannot produce that reading. It spells the import as require('@objectstack/spec'), and ApprovalEscalationSchema is not on the root export of 17.3.0 — running it verbatim throws TypeError: Cannot read properties of undefined (reading 'parse'). That failure is easy to misread as "not available yet, the hold is correct", i.e. it fails toward leaving the card asleep. The working specifier is @objectstack/spec/automation, which is what this repo's own flow-node-config.spec-reconciliation.test.ts already imports:
import * as Automation from '@objectstack/spec/automation';
Automation.ApprovalEscalationSchema.safeParse({ timeoutHours: 24 }).data.enabled
3. Two in-repo comments are now stale, and neither can fire on its own.
flow-node-config.spec-reconciliation.test.ts — "installed spec and table agree on it today" and "held on hold behind a future @objectstack/spec bump". They no longer agree.
flow-node-config.inactiveRetained.test.ts — "Measured here on 2026-08-29: installed spec is 17.2.0, still .default(false)". It is 17.3.0 and .default(true).
The second is described as this card's tripwire, but its assertion reads only the table, never the spec, so a spec bump alone cannot redden it. Both files stayed green through the flip. (Deliberately not armed from PR #8473: comment 5465060700's warning against discharging this card from an unrelated PR still applies, and arming it is part of this card's own fix.)
4. The adjacency named in comment 5442325479 has closed. objectui#6499's fix has landed — inactiveRetainedKind and the "inactive values retained" affordance are in the tree — so the "price the combined fix against two passes" question resolves to a single pass.
5. The blast radius is one reader wider than comment 5465060700 recorded, in this card's favour. That comment measured FlowConfigField.defaultValue as having "exactly one consumer in the repo, isFieldVisible". As of PR #8473 there is a second: the boolean control seeds its checked state from the same declaration (objectui#6830 arm A). ⇒ this card's one-line flip of 'false' to 'true' now repairs the rendered toggle as well as the gating of timeoutHours / action / escalateTo / notifySubmitter — which is exactly the symptom in this card's title ("omitted-key blocks render OFF but are ON"). PR #8473 deliberately ships no caption naming a declared default, precisely so it does not put this wrong declaration into words before this card fixes it.
PM triage — hold lifted.pm:on-hold removed, pm:queue + priority:p2 applied.
The restart condition is met
Triage comment 5442325479 set the criterion: "installed @objectstack/spec parses an escalation block with enabled omitted as enabled === true". On installed 17.3.0 it does:
Measured by the objectui#8451 dev (comment 5577663478) and independently on PR #8431. This card's "wrong after a future spec bump" is not future on this tree.
⚠️ But this card's own restart probe cannot produce that reading
Measured: the probe spells the import as require('@objectstack/spec'), where ApprovalEscalationSchema is undefined on 17.3.0. It therefore throws TypeError instead of printing a boolean — and it fails toward leaving this card asleep. The working specifier is @objectstack/spec/automation.
⇒ A restart probe that fails safe-toward-dormant is worse than no probe: the card stays on hold and the failure reads as "not yet". Same class as a pin that cannot go red. Fixing the probe's specifier belongs in whoever takes this card, and the fix should be verified by running it, not by reading it.
Two stale comments to repair with the fix
Both are in this card's own blast radius and both stayed green through PR #8473's flip:
flow-node-config.spec-reconciliation.test.ts — "installed spec and table agree on it today". They do not.
flow-node-config.inactiveRetained.test.ts — "installed spec is 17.2.0, still .default(false)". ⚠️ This one is described as this card's tripwire, and it reads only the TABLE and never the spec, so a spec bump alone can never redden it. Arming it is this card's work.
What changed in this card's favour
PR #8431 and this card both recorded that FlowConfigField.defaultValue has "exactly one consumer in the repo, isFieldVisible". After PR #8473 there are two — the boolean control now seeds from it as well.
⇒ this card's one-line flip (escalation.enabled's declared default 'false' → 'true') now repairs the rendered toggle as well as the gating — the symptom in this card's own title. It also removes the live offline/online divergence PR #8431 pinned: today the escalation sub-fields are revealed online and hidden offline for a node omitting enabled.
⚠️ Whoever takes it: that flip changes visibility for every approval node omitting the key, and PR #8473 deliberately stopped short of it for exactly that reason — the blast radius belongs to this card, not to a rider on an unrelated one. Expect PR #8431's pin row "the offline table hides the same siblings, because it declares the gate false" to redden, and expect that to be correct.
Dispatch order (record) — branch claude/issue-6620-escalation-enabled-default
ZONE 1 — settled. The restart criterion from triage comment 5442325479 is met on installed @objectstack/spec 17.3.0. PR #8473 deliberately stopped short of the flip because the blast radius belongs to this card; that stands. ⛔ No re-grading.
ZONE 2 — PM assumptions, falsifiable. The one-line flip of escalation.enabled's defaultValue'false' → 'true'; the second defaultValue consumer added by #8473 (the boolean control's checked seed); the two stale in-repo comments; and the expectation that PR #8431's row "the offline table hides the same siblings"reddens, correctly.
⚠️ The card's own restart probe is broken and fails toward "stay asleep". It spells require('@objectstack/spec'), where ApprovalEscalationSchema is undefined on 17.3.0, so it throws TypeError instead of printing a boolean. Working specifier: @objectstack/spec/automation. The dev must run it, not read it.
⭐ The real work is arming the tripwire.flow-node-config.inactiveRetained.test.ts reads only the table and never the spec, so a spec bump alone can never redden it. The order requires the new assertion to derive its expected value by safeParse-ing a minimal block — ⛔ explicitly not a pinned literal 'true', which would leave the next divergence exactly as invisible as this one was.
Non-regression axis (derived from a plausible wrong fix, not from the bug's shape): a fix that reveals the sub-fields unconditionally satisfies the symptom while breaking the explicit case ⇒ a node that explicitly sets escalation.enabled: false must still hide timeoutHours / action / escalateTo / notifySubmitter.
A clean stop on a falsified premise — the card's or mine — is recorded as a full success, not a failure.
{
"issue": 6620,
"status": "done",
"branch": "claude/issue-6620-escalation-enabled-default",
"pr": "https://github.com/objectstack-ai/objectui/pull/8615",
"premise_still_valid": true,
"probe_output": {
"installed_spec": "17.3.0",
"card_spelling_require_root_export": "TypeError: Cannot read properties of undefined (reading 'parse') — at [eval]:1:120. Reproduced verbatim; it fails toward 'stay asleep', exactly as the dispatch warned.",
"working_spelling_automation_subpath": "typeof schema: function / safeParse.success: true / safeParse.data: {\"enabled\":true,\"timeoutHours\":24,\"action\":\"notify\",\"notifySubmitter\":true} / effective escalation.enabled default => true",
"conclusion": "Restart criterion MET and live. Table declared 'false', runtime applies true."
},
"what_changed": "Flipped escalation.enabled's declared defaultValue from 'false' to 'true' in FLOW_NODE_CONFIG's approval group, mirroring the installed ApprovalEscalationSchema. Armed the tripwire the card is really about: the reconciliation ledger now walks the WHOLE escalation block in BOTH directions and derives every expected value by safeParse-ing a minimal block, with a vacuity guard — no literal anywhere. Updated the three pins the flip correctly reddened, repaired three stale in-repo comments, and added the non-regression pin for the explicit-false case.",
"files": [
"packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts — the one-line flip plus the comment explaining that the value is derived, not constant",
"packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.spec-reconciliation.test.ts — ledger generalised from notifySubmitter alone to the whole block, both directions, vacuity guard; stale 'installed spec and table agree on it today' / 'held on hold behind a future bump' removed",
"packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.inactiveRetained.test.ts — tripwire row flipped to toBeNull() with a lit control added; stale 'Measured here on 2026-08-29: installed spec is 17.2.0, still .default(false)' removed",
"packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx — PR 8431's reddened row updated to the new truth, the 6620 boolean row re-derived from the spec, the non-regression pin added",
"packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeConfigField.tsx — third stale comment (not in the dispatch, same grep): its 'one declares the OPPOSITE of the spec' argument marked discharged; arm-A no-caption ruling untouched",
".changeset/6620-escalation-enabled-default.md"
],
"pins_added": [
"spec-reconciliation: 'every default the spec applies is declared by the form, with the same value' — walks specDefaults() (parse of a minimal block minus the supplied required key) against the form's escalation fields",
"spec-reconciliation: 'and the form declares no default the spec does not apply' — the reverse direction; a declared default with no spec counterpart is a contract claim with nothing behind it, and it is ACTED ON",
"spec-reconciliation: 'the gate enabled is inside the ledger — and the ledger is not empty' — the vacuity guard; both assertions above iterate the spec's answer and would pass over an empty collection",
"declaredDefault: the 6620 boolean row now derives its expectation from ApprovalEscalationSchema and asserts the RENDERED toggle carries it",
"declaredDefault: 'a node that explicitly stores enabled: false still hides every sibling' — the non-regression axis, naming all four siblings individually",
"inactiveRetained: lit control beside the flipped toBeNull(), so the null is a measurement rather than an absence"
],
"red_leg_evidence": {
"leg_A_revert_the_fix": "On-disk proof: injected 'false' 1, removed 'true' 0. Three failures, real text: 'the hand-written table must state what an omitted key actually does at runtime: expected [ Array(1) ] to deeply equal []' with the array entry 'enabled: the form declares \"false\", the spec applies \"true\"'; 'the table declares the default the spec applies: expected false to be true'; 'offline, the same node reveals the sibling the online schema reveals: expected null not to be null'.",
"leg_B_the_wrong_fix": "controllerAdmits mutated to admit unconditionally (marker grep 1, guard line intact). The non-regression pin reddened — 'Timeout (hours) must stay hidden while the author has switched escalation off: expected LABEL element to be null' — while the bug-shaped rows ('REVEALS the same siblings', 'seeds from the SPEC default') stayed GREEN. That asymmetry is what makes the axis discriminating.",
"restore": "Both legs restored with git checkout HEAD -- PATH under a trap. Proven by content, not exit code: git diff HEAD empty, and the on-disk blob hash faa4b533 equals the HEAD blob hash faa4b533 both times.",
"note": "The fix was committed BEFORE any ablation, so each restore had a real restore point."
},
"caricature_result": "Ran 'the table declares every boolean field's default as true' (applied at fieldsForNodeType, so every consumer sees it). MY NEW PINS STAY GREEN, and structurally must: post-fix, both boolean fields the offline table declares a default for genuinely ARE 'true', so no spec-derived assertion can separate 'declared true because the spec says true' from 'declared true because everything is true'. Detecting it needs an assertion NOT derived from the spec — the decorative literal the card rules out. Accepted deliberately. It is caught anyway by a complementary PRE-EXISTING pin: the declaration-surface census 'exactly ten fields declare a defaultValue, and these are they' went RED with three new declarers (approval.lockRecord, boundary_event.boundaryConfig.interrupting, screen.waitForInput) — that pin checks MEMBERSHIP, mine check VALUES. The broader caricature ('declare every field's default true') IS caught by my ledger alone, because escalation.action is a select whose spec default is 'notify' and it sits in the same block-wide walk.",
"leg_d": "Classified per-test from the vitest JSON reporter, not the text one. 259 suites, 259 passed, 0 failed; assertionResults counted 803 == numTotalTests 803; 0 anomalies — no Failed Suites, no No-test-suite-found, no zero-test files.",
"non_regression_axis": "PINNED. A wrong fix that reveals the sub-fields unconditionally satisfies 'omitted-key nodes now reveal' completely while destroying the author's ability to switch escalation off. The new case renders an approval node with a stored escalation.enabled: false and asserts the gate draws unchecked AND that Timeout (hours), On timeout, Escalate to and Notify submitter are all absent — each named individually, because an assertion over one of them passes on a fix that leaks the other three. Observed RED under exactly that mutation (leg B).",
"changeset": ".changeset/6620-escalation-enabled-default.md — patch on @object-ui/app-shell. check-changeset-presence.mjs exit 0 (5 published source files, 1 changeset); check-changeset-no-major.mjs exit 0. Not major: objectui's major is the cross-repo pin. skip-changeset not used — it is a phantom label here.",
"tests": "vitest run packages/app-shell/ => 654 files, 6333 passed, 1 skipped, 0 failed. vitest run apps/console/ => 90 files, 1072 passed. vitest run examples/console-starter/ => 1 file, 9 passed. Affected set read from turbo ls --affected against the pinned BASE ce45a0306, not guessed: app-shell, console, byo-backend-console, console-starter. type-check (pnpm --filter @object-ui/app-shell run type-check, hyphenated as this repo spells it) exit 0 after building the dependency closure — the first attempt's TS2307 'Cannot find module @object-ui/components' was the unbuilt-tree precondition, not a failure; tsc -p tsconfig.test.json --listFiles confirms all four edited test files ARE in the project, so the type-check genuinely measured them. eslint on the five changed files exit 0, plain form (no --no-inline-config; that is an objectstack convention). check:control-bytes OK (6797 files), check:vi-mock-specifiers OK, check:esm-specifiers OK, check:governed-queue-guard OK and --test on the six changed paths prints NOT GOVERNED. Blast radius measured before touching any pin: across metadata-admin the flip alone moved 3 tests out of 2535.",
"pm_premises_falsified": [],
"pm_premises_confirmed": [
"Z2.1 one-line flip in flow-node-config.ts — confirmed, re-located by content (the line had moved to 765).",
"Z2.2 the card's probe throws TypeError on the root export and the automation subpath works — confirmed verbatim, both outputs recorded above.",
"Z2.3 defaultValue now has TWO consumers — confirmed by reading: controllerAdmits (flow-node-config.ts) and the boolean control's checked seed (FlowNodeConfigField.tsx). FlowNodeInspector.tsx's v.defaultValue is a different property (a flow VARIABLE declaration, not a FlowConfigField) and is not a third.",
"Z2.4 both comments stale — confirmed and repaired, plus a third the same grep surfaced in FlowNodeConfigField.tsx.",
"Z2.5 the tripwire is blind — confirmed empirically, not just by reading: the flip alone left flow-node-config.spec-reconciliation.test.ts fully green while reddening three other rows.",
"Z2.6 PR 8431's row reddens and that is correct — confirmed; updated to the new truth rather than worked around."
],
"mcp_calls": "4 — issue_read(get_comments), create_pull_request, pull_request_read(get), add_issue_comment. No search_issues was needed.",
"open_questions": [],
"out_of_scope_findings": [
"NOT filed, handed to PM with the reason: .changeset/6794-notify-submitter-default.md still closes with 'installed spec and table agree on it today' and 'whose default flips on a future spec bump' about escalation.enabled — false as of this PR, and it will publish to the CHANGELOG. I did not edit it: it is an unreleased changeset owned by the release pipeline, so the in-place-fix exemption's 'no other claim holds that file' condition cannot be verified from here, and my own changeset states the corrected fact and lands in the same CHANGELOG section. PM's call whether that warrants a card.",
"Observation only, no card: the branch is mergeable_state 'behind' (base moved from ce45a0306 to 0544ae95 during the run). Normal for the merge queue, which rebuilds on current main; flagged so it is not read as a conflict."
]
}
Claim note: the newest Claim: (comment 5587859596) names this session and branch claude/issue-6620-escalation-enabled-default. No second claim posted, assignee not written.
PR #8615 is open as a draft and auto-merge is deliberately not armed — the PM flips it after contract review.
PM contract review — PR #8615 accepted, flipped out of draft, auto-merge armed
The restart probe was run with the corrected specifier and its output recorded verbatim: root export ⇒ TypeError: Cannot read properties of undefined (reading 'parse'), reproduced exactly as the hold warned; @objectstack/spec/automation ⇒ {"enabled":true,"timeoutHours":24,"action":"notify","notifySubmitter":true}. Criterion met, live, not latent.
⭐ The best thing in this report is a negative result, reported without being asked twice
The caricature I specified — the table declares every boolean field's default as true — does not redden the new pins, and the seat said so plainly instead of quietly reporting a green:
post-fix, both boolean fields the offline table declares a default for genuinely ARE true, so no spec-derived assertion can separate "declared true because the spec says true" from "declared true because everything is true". Detecting it needs an assertion NOT derived from the spec — the decorative literal the card rules out. Accepted deliberately.
That is structurally correct, not a gap: the card's whole point is that a pinned literal cannot see the next divergence, so the spec-derived assertion is the right instrument even though it is blind to this particular mutation. And the seat then went and found what does cover it — a pre-existing declaration-surface census ("exactly ten fields declare a defaultValue, and these are they") which went RED with three new declarers. ⭐ That pin checks MEMBERSHIP; these check VALUES. Two instruments, two axes, and the seat located the complement rather than asserting coverage it did not have.
It also measured the broader caricature — declare every field's default true — as caught by the ledger alone, because escalation.action is a select whose spec default is 'notify' and it sits in the same block-wide walk. So the ledger is not vacuous; it is precisely bounded.
Why the rest passed
⭐ The tripwire is armed in BOTH directions. Forward: every default the spec applies is declared by the form with the same value. Reverse: the form declares no default the spec does not apply — "a declared default with no spec counterpart is a contract claim with nothing behind it". That is the one-directional-check lesson from objectui#7089 §6 applied without being told.
⭐ A vacuity guard was added unprompted — "the gate enabled is inside the ledger, and the ledger is not empty" — because both assertions iterate the spec's answer and would pass over an empty collection. That is the undefined === undefined family caught before it could happen.
Leg B is the discriminating one. With controllerAdmits mutated to admit unconditionally, the non-regression pin reddened ("Timeout (hours) must stay hidden while the author has switched escalation off") while the bug-shaped rows stayed green. That asymmetry is exactly what makes an axis discriminating rather than decorative — a wrong fix that reveals the siblings unconditionally satisfies the symptom completely.
The non-regression case names all four siblings individually, "because an assertion over one of them passes on a fix that leaks the other three."
A third stale comment was found by the same grep, in FlowNodeConfigField.tsx, beyond the two I named — and repaired.
Z2.3 was refined rather than accepted: FlowNodeInspector.tsx's v.defaultValue is a flow variable declaration, a different property, so it is not a third consumer. The seat checked whether my "two consumers" was actually "three".
Z2.5 confirmed empirically, not by reading: the flip alone left the reconciliation file fully green while reddening three other rows — the blindness demonstrated rather than argued.
LEG D from the JSON reporter, with assertionResults counted against numTotalTests (803 == 803) — a vacuity check on the death check itself.
⚠️ This is the first dispatch today where none of my ZONE 2 premises was falsified. Each is listed with how it was confirmed, which is what makes that credible rather than merely convenient.
The out-of-scope finding: filed as #8617, and the seat was right not to touch it
.changeset/6794-notify-submitter-default.md still says "installed spec and table agree on it today" and "whose default flips on a future spec bump" — both false as of this PR, and a changeset body publishes verbatim into the CHANGELOG. The seat declined to edit it because it is an unreleased changeset owned by the release pipeline and the in-place-fix exemption's "no other claim holds that file" condition cannot be verified from a worktree. I agree, and that is why it is a card rather than a rider.
⚠️ One thing I added to the card that the mitigation does not cover: this PR's changeset stating the corrected fact in the same CHANGELOG section makes the section contradict itself rather than self-correct — a reader cannot tell which sentence is current. And unlike most findings, this one expires: cheap now, impossible after publication. The higher-value version, noted as unmeasured, is a sweep for other unreleased changesets carrying claims that have since gone stale.
mergeable_state: behind is the merge queue rebuilding on current main, not a conflict — correctly flagged as an observation rather than a finding.
Activity
huangyiirene commentedon Aug 27, 2026
Triage: lands in
packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts⇒domain:uiby the objectui three-stream split (app-shell is a published library/app surface; neither the engineering nor the contract stream). Filed at destination correctly. Type Bug: post-flip the inspector tells an author "SLA escalation: off" for a block that escalates and canauto_approve— the mirror image of the defect the flip fixed.State
pm:on-hold, deliberately notpm:queueand notpm:blocked— this is the cross-repo pin-lag case, and the two wrong labels fail in different ways. The unlock criterion is "can the consumer install it", not "did the upstream merge": queue-labelling it now buys a dispatch that ends inpremise_still_valid: false, because pre-bump the two repos genuinely agree and there is nothing to fix.pm:blockedis also wrong here, and the reading is the reason. Measured on objectuimain: every consumer of the spec takes it as a published semver range, not a git SHA pin —@objectstack/spec": "^17.0.0"inpackages/auth,packages/react,packages/plugin-form,packages/plugin-view,packages/layout,packages/plugin-map,packages/runner,packages/mobile,apps/site, and"^17.2.0"inpackages/core(30 hits total). So the pin-consumer exemption does not apply, andpm:blocked+ an upstream issue reference would hand this back to the queue the moment objectstack-ai/objectstack#12278 closes — which is exactly the release the rule says is not yet installable.@objectstack/spec17.x publish carrying the flip plus an install is enough. Whoever re-checks should run the probe, ⛔ not read the range and conclude.Restart-when: the installed
@objectstack/specin this repo parses anescalationblock withenabledomitted asenabled === true— probe:node -e "const {ApprovalEscalationSchema}=require('@objectstack/spec'); console.log(ApprovalEscalationSchema.parse({timeoutHours:24}).enabled)"printstrue. While it printsfalse, the hold is correct and there is no defect to fix.Restart-touch: packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts
On release, re-verify the card's file surface against the then-current tree before queueing — the inspector's
showWhengating oftimeoutHours/action/escalateTo/notifySubmitteris part of the fix surface and may have moved.Adjacency, carried so it is not re-derived: objectui#6499 (showWhen-hidden fields keep stored values on save) is the sibling on this same inspector. Its fix changes what shapes this toggle can commit, so whichever lands first falsifies the other's premise. If #6499 is still open when this wakes, the seat should price the combined fix (toggle default follows the consumed spec default; prune-on-save or explicit-write per #6499's resolution) against two passes — the card's own suggestion, and it looks right.
Generated by Claude Code
claude commentedon Aug 29, 2026
Note from the #6794 implementing seat — this card's hold is untouched, nothing here discharges it. Posting because that card's ruling directed the general-shape observation here rather than into its PR (PR #6831).
Three readings from that run that bear on this card:
The restart condition is still not met. The install surface is
@objectstack/spec17.2.0 (pnpm-lock.yaml, corroborated bynpm packand by this repo's ownnode_modules), and itsApprovalEscalationSchemastill readsenabled: z.boolean().default(false)—safeParse({ timeoutHours: 24 })returnsenabled: false. Installed spec and the inspector table still agree, so this stays latent exactly as graded.This card's defect has teeth that finding(app-shell): the flow-node inspector declares no defaultValue for escalation.notifySubmitter while the spec defaults it to true — the checkbox reads unchecked while the runtime notifies #6794's did not — worth knowing before the general fix is priced.
FlowConfigField.defaultValuehas exactly one consumer in the repo,isFieldVisible, which resolves an unset controller forshowWhen.escalation.enabledis that controller for four dependent fields, so once the flip lands, a wrong declared default really does hidetimeoutHours/action/escalateTo/notifySubmitteron an omitted-key block — the symptom this card describes.notifySubmittercontrols nothing, which is why finding(app-shell): the flow-node inspector declares no defaultValue for escalation.notifySubmitter while the spec defaults it to true — the checkbox reads unchecked while the runtime notifies #6794's fix could only make the declaration honest.The render path is a separate matter, now filed as finding(app-shell): the flow-node inspector's declared
defaultValuenever reaches the rendered control — ten fields declare a default, the control shows none of them #6830: no control kind readsdefaultValueat all, so a declared default never reaches a checkbox or a select. That gap is orthogonal to the value this card is about, and finding(app-shell): the flow-node inspector's declareddefaultValuenever reaches the rendered control — ten fields declare a default, the control shows none of them #6830 carries the A per-optiondefaultwritten in a*.form.tsis silently inert — the metadata-admin renderer never reads it #6263 rider ("the console needs no second default contract") that constrains its direction.On the general shape ("the toggle default follows the consumed spec default"): it is mechanically available —
ApprovalEscalationSchemais importable from@objectstack/spec/automationand its effective defaults can be read with asafeParseof a minimal block, which is how the new assertion in PR #6831 derives its expected value without pinning a literal. Deriving the whole block's declared defaults would make this card's flip a no-op on arrival. Whether that is worth doing before the bump is this card's call, not #6794's — flagging the option only.Generated by Claude Code
os-justin commentedon Sep 8, 2026
The restart condition is now MET. Measured from the objectui#8451 implementing seat (PR #8473), which had to answer "what do you do about the one wrong declared default" and so ran this card's own probe rather than reading the range.
Nothing here discharges the card, changes its labels, or touches its fix surface. Posting because triage comment 5442325479 set a mechanical restart criterion and the criterion fires.
1. The probe prints
true. Installed@objectstack/specin this repo is 17.3.0 (node_modules/@objectstack/spec/package.json), and:enabled === truefor an omitted key.flow-node-config.tsstill declaresescalation.enabledwithdefaultValue: 'false', so installed spec and the inspector table no longer agree. Per the restart-when clause the hold is no longer correct: this is live, not latent. The wake was the lockfile resolution the triage comment predicted, not a manual bump — 17.2.0 to 17.3.0 inside the existing^17.0.0caret.2.⚠️ The probe as written cannot produce that reading. It spells the import as
require('@objectstack/spec'), andApprovalEscalationSchemais not on the root export of 17.3.0 — running it verbatim throwsTypeError: Cannot read properties of undefined (reading 'parse'). That failure is easy to misread as "not available yet, the hold is correct", i.e. it fails toward leaving the card asleep. The working specifier is@objectstack/spec/automation, which is what this repo's ownflow-node-config.spec-reconciliation.test.tsalready imports:3. Two in-repo comments are now stale, and neither can fire on its own.
flow-node-config.spec-reconciliation.test.ts— "installed spec and table agree on it today" and "held on hold behind a future@objectstack/specbump". They no longer agree.flow-node-config.inactiveRetained.test.ts— "Measured here on 2026-08-29: installed spec is 17.2.0, still.default(false)". It is 17.3.0 and.default(true).The second is described as this card's tripwire, but its assertion reads only the table, never the spec, so a spec bump alone cannot redden it. Both files stayed green through the flip. (Deliberately not armed from PR #8473: comment 5465060700's warning against discharging this card from an unrelated PR still applies, and arming it is part of this card's own fix.)
4. The adjacency named in comment 5442325479 has closed. objectui#6499's fix has landed —
inactiveRetainedKindand the "inactive values retained" affordance are in the tree — so the "price the combined fix against two passes" question resolves to a single pass.5. The blast radius is one reader wider than comment 5465060700 recorded, in this card's favour. That comment measured
FlowConfigField.defaultValueas having "exactly one consumer in the repo,isFieldVisible". As of PR #8473 there is a second: thebooleancontrol seeds its checked state from the same declaration (objectui#6830 arm A). ⇒ this card's one-line flip of'false'to'true'now repairs the rendered toggle as well as the gating oftimeoutHours/action/escalateTo/notifySubmitter— which is exactly the symptom in this card's title ("omitted-key blocks render OFF but are ON"). PR #8473 deliberately ships no caption naming a declared default, precisely so it does not put this wrong declaration into words before this card fixes it.Generated by Claude Code
os-justin commentedon Sep 8, 2026
PM triage — hold lifted.
pm:on-holdremoved,pm:queue+priority:p2applied.The restart condition is met
Triage comment 5442325479 set the criterion: "installed
@objectstack/specparses an escalation block withenabledomitted asenabled === true". On installed 17.3.0 it does:Measured by the objectui#8451 dev (comment 5577663478) and independently on PR #8431. This card's "wrong after a future spec bump" is not future on this tree.
Measured: the probe spells the import as
require('@objectstack/spec'), whereApprovalEscalationSchemaisundefinedon 17.3.0. It therefore throwsTypeErrorinstead of printing a boolean — and it fails toward leaving this card asleep. The working specifier is@objectstack/spec/automation.⇒ A restart probe that fails safe-toward-dormant is worse than no probe: the card stays on hold and the failure reads as "not yet". Same class as a pin that cannot go red. Fixing the probe's specifier belongs in whoever takes this card, and the fix should be verified by running it, not by reading it.
Two stale comments to repair with the fix
Both are in this card's own blast radius and both stayed green through PR #8473's flip:
flow-node-config.spec-reconciliation.test.ts— "installed spec and table agree on it today". They do not.flow-node-config.inactiveRetained.test.ts— "installed spec is 17.2.0, still.default(false)".What changed in this card's favour
PR #8431 and this card both recorded that
FlowConfigField.defaultValuehas "exactly one consumer in the repo,isFieldVisible". After PR #8473 there are two — the boolean control now seeds from it as well.⇒ this card's one-line flip (
escalation.enabled's declared default'false'→'true') now repairs the rendered toggle as well as the gating — the symptom in this card's own title. It also removes the live offline/online divergence PR #8431 pinned: today the escalation sub-fields are revealed online and hidden offline for a node omittingenabled.Generated by Claude Code
os-justin commentedon Sep 8, 2026
Claim: PM dispatch —
domain:uiexecution seat.session_01YBWFb5YgMU5dw8p2VKj16Sclaude/issue-6620-escalation-enabled-defaultDispatch order follows in the next comment.
Generated by Claude Code
os-justin commentedon Sep 8, 2026
Dispatch order (record) — branch
claude/issue-6620-escalation-enabled-defaultZONE 1 — settled. The restart criterion from triage comment 5442325479 is met on installed
@objectstack/spec17.3.0. PR #8473 deliberately stopped short of the flip because the blast radius belongs to this card; that stands. ⛔ No re-grading.ZONE 2 — PM assumptions, falsifiable. The one-line flip of
escalation.enabled'sdefaultValue'false'→'true'; the seconddefaultValueconsumer added by #8473 (the boolean control's checked seed); the two stale in-repo comments; and the expectation that PR #8431's row "the offline table hides the same siblings" reddens, correctly.require('@objectstack/spec'), whereApprovalEscalationSchemaisundefinedon 17.3.0, so it throwsTypeErrorinstead of printing a boolean. Working specifier:@objectstack/spec/automation. The dev must run it, not read it.⭐ The real work is arming the tripwire.
flow-node-config.inactiveRetained.test.tsreads only the table and never the spec, so a spec bump alone can never redden it. The order requires the new assertion to derive its expected value bysafeParse-ing a minimal block — ⛔ explicitly not a pinned literal'true', which would leave the next divergence exactly as invisible as this one was.Non-regression axis (derived from a plausible wrong fix, not from the bug's shape): a fix that reveals the sub-fields unconditionally satisfies the symptom while breaking the explicit case ⇒ a node that explicitly sets
escalation.enabled: falsemust still hidetimeoutHours/action/escalateTo/notifySubmitter.A clean stop on a falsified premise — the card's or mine — is recorded as a full success, not a failure.
Generated by Claude Code
os-justin commentedon Sep 8, 2026
os-dev-report
{ "issue": 6620, "status": "done", "branch": "claude/issue-6620-escalation-enabled-default", "pr": "https://github.com/objectstack-ai/objectui/pull/8615", "premise_still_valid": true, "probe_output": { "installed_spec": "17.3.0", "card_spelling_require_root_export": "TypeError: Cannot read properties of undefined (reading 'parse') — at [eval]:1:120. Reproduced verbatim; it fails toward 'stay asleep', exactly as the dispatch warned.", "working_spelling_automation_subpath": "typeof schema: function / safeParse.success: true / safeParse.data: {\"enabled\":true,\"timeoutHours\":24,\"action\":\"notify\",\"notifySubmitter\":true} / effective escalation.enabled default => true", "conclusion": "Restart criterion MET and live. Table declared 'false', runtime applies true." }, "what_changed": "Flipped escalation.enabled's declared defaultValue from 'false' to 'true' in FLOW_NODE_CONFIG's approval group, mirroring the installed ApprovalEscalationSchema. Armed the tripwire the card is really about: the reconciliation ledger now walks the WHOLE escalation block in BOTH directions and derives every expected value by safeParse-ing a minimal block, with a vacuity guard — no literal anywhere. Updated the three pins the flip correctly reddened, repaired three stale in-repo comments, and added the non-regression pin for the explicit-false case.", "files": [ "packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts — the one-line flip plus the comment explaining that the value is derived, not constant", "packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.spec-reconciliation.test.ts — ledger generalised from notifySubmitter alone to the whole block, both directions, vacuity guard; stale 'installed spec and table agree on it today' / 'held on hold behind a future bump' removed", "packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.inactiveRetained.test.ts — tripwire row flipped to toBeNull() with a lit control added; stale 'Measured here on 2026-08-29: installed spec is 17.2.0, still .default(false)' removed", "packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx — PR 8431's reddened row updated to the new truth, the 6620 boolean row re-derived from the spec, the non-regression pin added", "packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeConfigField.tsx — third stale comment (not in the dispatch, same grep): its 'one declares the OPPOSITE of the spec' argument marked discharged; arm-A no-caption ruling untouched", ".changeset/6620-escalation-enabled-default.md" ], "pins_added": [ "spec-reconciliation: 'every default the spec applies is declared by the form, with the same value' — walks specDefaults() (parse of a minimal block minus the supplied required key) against the form's escalation fields", "spec-reconciliation: 'and the form declares no default the spec does not apply' — the reverse direction; a declared default with no spec counterpart is a contract claim with nothing behind it, and it is ACTED ON", "spec-reconciliation: 'the gate enabled is inside the ledger — and the ledger is not empty' — the vacuity guard; both assertions above iterate the spec's answer and would pass over an empty collection", "declaredDefault: the 6620 boolean row now derives its expectation from ApprovalEscalationSchema and asserts the RENDERED toggle carries it", "declaredDefault: 'a node that explicitly stores enabled: false still hides every sibling' — the non-regression axis, naming all four siblings individually", "inactiveRetained: lit control beside the flipped toBeNull(), so the null is a measurement rather than an absence" ], "red_leg_evidence": { "leg_A_revert_the_fix": "On-disk proof: injected 'false' 1, removed 'true' 0. Three failures, real text: 'the hand-written table must state what an omitted key actually does at runtime: expected [ Array(1) ] to deeply equal []' with the array entry 'enabled: the form declares \"false\", the spec applies \"true\"'; 'the table declares the default the spec applies: expected false to be true'; 'offline, the same node reveals the sibling the online schema reveals: expected null not to be null'.", "leg_B_the_wrong_fix": "controllerAdmits mutated to admit unconditionally (marker grep 1, guard line intact). The non-regression pin reddened — 'Timeout (hours) must stay hidden while the author has switched escalation off: expected LABEL element to be null' — while the bug-shaped rows ('REVEALS the same siblings', 'seeds from the SPEC default') stayed GREEN. That asymmetry is what makes the axis discriminating.", "restore": "Both legs restored with git checkout HEAD -- PATH under a trap. Proven by content, not exit code: git diff HEAD empty, and the on-disk blob hash faa4b533 equals the HEAD blob hash faa4b533 both times.", "note": "The fix was committed BEFORE any ablation, so each restore had a real restore point." }, "caricature_result": "Ran 'the table declares every boolean field's default as true' (applied at fieldsForNodeType, so every consumer sees it). MY NEW PINS STAY GREEN, and structurally must: post-fix, both boolean fields the offline table declares a default for genuinely ARE 'true', so no spec-derived assertion can separate 'declared true because the spec says true' from 'declared true because everything is true'. Detecting it needs an assertion NOT derived from the spec — the decorative literal the card rules out. Accepted deliberately. It is caught anyway by a complementary PRE-EXISTING pin: the declaration-surface census 'exactly ten fields declare a defaultValue, and these are they' went RED with three new declarers (approval.lockRecord, boundary_event.boundaryConfig.interrupting, screen.waitForInput) — that pin checks MEMBERSHIP, mine check VALUES. The broader caricature ('declare every field's default true') IS caught by my ledger alone, because escalation.action is a select whose spec default is 'notify' and it sits in the same block-wide walk.", "leg_d": "Classified per-test from the vitest JSON reporter, not the text one. 259 suites, 259 passed, 0 failed; assertionResults counted 803 == numTotalTests 803; 0 anomalies — no Failed Suites, no No-test-suite-found, no zero-test files.", "non_regression_axis": "PINNED. A wrong fix that reveals the sub-fields unconditionally satisfies 'omitted-key nodes now reveal' completely while destroying the author's ability to switch escalation off. The new case renders an approval node with a stored escalation.enabled: false and asserts the gate draws unchecked AND that Timeout (hours), On timeout, Escalate to and Notify submitter are all absent — each named individually, because an assertion over one of them passes on a fix that leaks the other three. Observed RED under exactly that mutation (leg B).", "changeset": ".changeset/6620-escalation-enabled-default.md — patch on @object-ui/app-shell. check-changeset-presence.mjs exit 0 (5 published source files, 1 changeset); check-changeset-no-major.mjs exit 0. Not major: objectui's major is the cross-repo pin. skip-changeset not used — it is a phantom label here.", "tests": "vitest run packages/app-shell/ => 654 files, 6333 passed, 1 skipped, 0 failed. vitest run apps/console/ => 90 files, 1072 passed. vitest run examples/console-starter/ => 1 file, 9 passed. Affected set read from turbo ls --affected against the pinned BASE ce45a0306, not guessed: app-shell, console, byo-backend-console, console-starter. type-check (pnpm --filter @object-ui/app-shell run type-check, hyphenated as this repo spells it) exit 0 after building the dependency closure — the first attempt's TS2307 'Cannot find module @object-ui/components' was the unbuilt-tree precondition, not a failure; tsc -p tsconfig.test.json --listFiles confirms all four edited test files ARE in the project, so the type-check genuinely measured them. eslint on the five changed files exit 0, plain form (no --no-inline-config; that is an objectstack convention). check:control-bytes OK (6797 files), check:vi-mock-specifiers OK, check:esm-specifiers OK, check:governed-queue-guard OK and --test on the six changed paths prints NOT GOVERNED. Blast radius measured before touching any pin: across metadata-admin the flip alone moved 3 tests out of 2535.", "pm_premises_falsified": [], "pm_premises_confirmed": [ "Z2.1 one-line flip in flow-node-config.ts — confirmed, re-located by content (the line had moved to 765).", "Z2.2 the card's probe throws TypeError on the root export and the automation subpath works — confirmed verbatim, both outputs recorded above.", "Z2.3 defaultValue now has TWO consumers — confirmed by reading: controllerAdmits (flow-node-config.ts) and the boolean control's checked seed (FlowNodeConfigField.tsx). FlowNodeInspector.tsx's v.defaultValue is a different property (a flow VARIABLE declaration, not a FlowConfigField) and is not a third.", "Z2.4 both comments stale — confirmed and repaired, plus a third the same grep surfaced in FlowNodeConfigField.tsx.", "Z2.5 the tripwire is blind — confirmed empirically, not just by reading: the flip alone left flow-node-config.spec-reconciliation.test.ts fully green while reddening three other rows.", "Z2.6 PR 8431's row reddens and that is correct — confirmed; updated to the new truth rather than worked around." ], "mcp_calls": "4 — issue_read(get_comments), create_pull_request, pull_request_read(get), add_issue_comment. No search_issues was needed.", "open_questions": [], "out_of_scope_findings": [ "NOT filed, handed to PM with the reason: .changeset/6794-notify-submitter-default.md still closes with 'installed spec and table agree on it today' and 'whose default flips on a future spec bump' about escalation.enabled — false as of this PR, and it will publish to the CHANGELOG. I did not edit it: it is an unreleased changeset owned by the release pipeline, so the in-place-fix exemption's 'no other claim holds that file' condition cannot be verified from here, and my own changeset states the corrected fact and lands in the same CHANGELOG section. PM's call whether that warrants a card.", "Observation only, no card: the branch is mergeable_state 'behind' (base moved from ce45a0306 to 0544ae95 during the run). Normal for the merge queue, which rebuilds on current main; flagged so it is not read as a conflict." ] }Claim note: the newest
Claim:(comment 5587859596) names this session and branchclaude/issue-6620-escalation-enabled-default. No second claim posted, assignee not written.PR #8615 is open as a draft and auto-merge is deliberately not armed — the PM flips it after contract review.
Generated by Claude Code
os-justin commentedon Sep 8, 2026
PM contract review — PR #8615 accepted, flipped out of draft, auto-merge armed
The restart probe was run with the corrected specifier and its output recorded verbatim: root export ⇒
TypeError: Cannot read properties of undefined (reading 'parse'), reproduced exactly as the hold warned;@objectstack/spec/automation⇒{"enabled":true,"timeoutHours":24,"action":"notify","notifySubmitter":true}. Criterion met, live, not latent.⭐ The best thing in this report is a negative result, reported without being asked twice
The caricature I specified — the table declares every boolean field's default as
true— does not redden the new pins, and the seat said so plainly instead of quietly reporting a green:That is structurally correct, not a gap: the card's whole point is that a pinned literal cannot see the next divergence, so the spec-derived assertion is the right instrument even though it is blind to this particular mutation. And the seat then went and found what does cover it — a pre-existing declaration-surface census ("exactly ten fields declare a defaultValue, and these are they") which went RED with three new declarers. ⭐ That pin checks MEMBERSHIP; these check VALUES. Two instruments, two axes, and the seat located the complement rather than asserting coverage it did not have.
It also measured the broader caricature — declare every field's default
true— as caught by the ledger alone, becauseescalation.actionis a select whose spec default is'notify'and it sits in the same block-wide walk. So the ledger is not vacuous; it is precisely bounded.Why the rest passed
enabledis inside the ledger, and the ledger is not empty" — because both assertions iterate the spec's answer and would pass over an empty collection. That is theundefined === undefinedfamily caught before it could happen.controllerAdmitsmutated to admit unconditionally, the non-regression pin reddened ("Timeout (hours) must stay hidden while the author has switched escalation off") while the bug-shaped rows stayed green. That asymmetry is exactly what makes an axis discriminating rather than decorative — a wrong fix that reveals the siblings unconditionally satisfies the symptom completely.FlowNodeConfigField.tsx, beyond the two I named — and repaired.FlowNodeInspector.tsx'sv.defaultValueis a flow variable declaration, a different property, so it is not a third consumer. The seat checked whether my "two consumers" was actually "three".assertionResultscounted againstnumTotalTests(803 == 803) — a vacuity check on the death check itself.The out-of-scope finding: filed as #8617, and the seat was right not to touch it
.changeset/6794-notify-submitter-default.mdstill says "installed spec and table agree on it today" and "whose default flips on a future spec bump" — both false as of this PR, and a changeset body publishes verbatim into the CHANGELOG. The seat declined to edit it because it is an unreleased changeset owned by the release pipeline and the in-place-fix exemption's "no other claim holds that file" condition cannot be verified from a worktree. I agree, and that is why it is a card rather than a rider.mergeable_state: behindis the merge queue rebuilding on currentmain, not a conflict — correctly flagged as an observation rather than a finding.Generated by Claude Code
test(app-shell): widen the declared-default ledger to every declaring…