Repository navigation
fix(app-shell): declare the spec default for escalation.notifySubmitter in the flow-node inspector - #6831
Merged
Conversation
…w-node table The metadata-admin flow-node config table declared no `defaultValue` for `escalation.notifySubmitter` while the installed `@objectstack/spec` (17.2.0) defaults the key to `true` — so the hand-written table stated the opposite of what an omitted key does at runtime, and disagreed with the online half of the same form (a published `configSchema` carries `default: true`, which `json-schema-to-fields` turns into `defaultValue: 'true'`). Adds the missing declaration and a reconciliation assertion that reads the expected value out of the installed spec rather than pinning a literal, so objectui never becomes a second source of truth for a published contract. Scoped to `notifySubmitter`: the sibling `escalation.enabled` controller is a separate, deliberately on-hold card whose default flips on a future spec bump. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CRJge11jso9TpXRWFt1Z49
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CRJge11jso9TpXRWFt1Z49
This was referenced Aug 29, 2026
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #6794
The metadata-admin flow-node table declared no
defaultValueforescalation.notifySubmitterwhile the installed@objectstack/specdefaults the key totrue. One line of table data, plus the reconciliation assertion that keeps the two sides pinned.Premise, re-derived against the install surface
Triage asked the implementing seat to re-derive rather than trust the pin, because the pin moves. Two independent readings of the artefact a consumer actually installs, plus the runtime's own answer:
pnpm-lock.yamlresolution@objectstack/spec: 17.2.0npm pack @objectstack/spec@17.2.0—package/dist/automation/index.js:3497notifySubmitter: zod.z.boolean().default(true).describe(...)node_modules/.pnpm/@objectstack+spec@17.2.0_ai@7.0.65_zod@4.4.3_/.../dist/automation/index.js:3497ApprovalEscalationSchema.safeParse({ timeoutHours: 24 }){ enabled: false, timeoutHours: 24, action: 'notify', notifySubmitter: true }The premise holds: live today, not latent. The card's collapse-into-a-duplicate branch stays closed, and the split was correct.
The same reading also re-confirms the sibling card's latency in the other direction:
enabledis stilldefault(false)in 17.2.0, so installed spec and table still agree on it.What changed
flow-node-config.ts—escalation.notifySubmittergainsdefaultValue: 'true', with a comment naming the spec and the online half.flow-node-config.spec-reconciliation.test.ts— a new describe block. The file is already the objectui half of the form-versus-spec ledger; it carried the KEY axis, this adds the DEFAULT axis for this one field.The expected value is read out of the installed spec, never spelled out as a literal: objectui consumes that contract and must not become a second source of truth for it. A vacuity guard beside it asserts the key still materialises from an omitted input, so the comparison can never quietly become a comparison against
undefined.A corroboration worth recording: the online half of this same form already carried the default. A backend that publishes the approval
configSchemasendsdefault: truefor the key, andjson-schema-to-fieldsturns a JSON-SchemadefaultintodefaultValue: 'true'— the fixture injson-schema-to-fields.test.ts:68is that exact payload. Offline and online were rendering the same key from two different claims about the spec.Ablation — red without the fix, green with it
Mutation and restore both proven on disk, both legs under one trap, restore pinned to the HEAD blob rather than to a bare checkout.
Test Files 1 passed (1)·Tests 12 passed, 1 skipped (13)defaultValue: 'true'removedTest Files 1 failed (1)·Tests 1 failed, 11 passed, 1 skipped (13)The red leg's named failure is the new assertion and nothing else:
The mutation was confirmed on disk before the red leg ran — anchor replaced exactly once (a zero-hit replace exits non-zero), declared-default marker count 1 to 0, bare marker count 0 to 1, blob hash
df04b55to93555d5. The restore reproduced the HEAD blobdf04b55byte-for-byte withgit diff HEADempty. The first attempt at this ablation failed loudly on a bad grep anchor rather than reporting a no-op as a measurement, which is the check working.No existing test moved. Not one assertion was edited or deleted; the whole
metadata-adminsuite is green unchanged (216 files, 2264 tests). Stating it plainly because it is a real answer: this field had no default-side coverage at all, so there was nothing to update.Read before grading this as the p1 remedy
The card's severity narrative is that the checkbox reads unchecked while the runtime notifies. This fix does not change what the checkbox renders, and no fix confined to the table could:
FlowConfigField.defaultValuehas exactly one consumer in the repo —isFieldVisible(flow-node-config.ts), which resolves an unset controller forshowWhen. The render path never reads it:FlowNodeConfigFielddraws a boolean aschecked={value === true}off the stored value alone, and no field currently gates onnotifySubmitter. So what lands here is the declaration made honest — the table now states what the runtime does, the offline half agrees with the online half, and any futureshowWhennaming this controller resolves correctly.The remaining half — ten fields in this table declare a default and the rendered control reads none of them — is filed as #6830 and deliberately not ridden in here. It also is not obviously a bug in the direction one would guess: an adjacent maintainer ruling on #6263 says the console needs no second default contract, so the question there is how an effective default is shown, not whether the designer should start writing defaults into stored metadata. That is a triage call, not this card's.
Not absorbed
#6620 is the same class and its stated shape would have covered this field too, but it is
pm:on-holddeliberately, behind a future spec bump that flips its own key's default. Adopting the general shape here would discharge it without its restart condition being met, so this PR does not: the new assertion is scoped tonotifySubmitteralone, with the reason written in the test, and the sibling card is untouched and stays open. A note about the general shape belongs on that card, for its own grading.Verification
Union re-run after the final commit, at
7bf9a6313:pnpm exec vitest run(3 inspector files, from the repo root)Test Files 3 passed (3)·Tests 84 passed, 1 skipped (85)pnpm --filter @object-ui/app-shell run type-checktsc --noEmit && tsc -p tsconfig.test.json, exit 0pnpm --filter @object-ui/app-shell run lint2789 problems (0 errors, 2789 warnings)— the package baseline; neither changed file emits a diagnosticnode scripts/check-changeset-presence.mjs2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)node scripts/check-changeset-no-major.mjsNo changeset declares a major bumppnpm check:control-bytesOK (scanned 5648 tracked text file(s); skipped 85 binary)pnpm check:designer-field-key-parity·check:spec-symbols·check:i18n-keys·check:i18n-drift·check:vi-mock-specifiersTests were run from the repo root, the way the repo's own scripts do —
pnpm --filter PKG exec vitest run FILEre-roots at the package and is a false green here. The executed file names are in the verbose run: every one of the 13 cases is prefixedpackages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.spec-reconciliation.test.ts.The type-check was proven to actually cover both edited files rather than assumed to:
tsc --listFilesnamesflow-node-config.tsin both projects and the new test file intsconfig.test.json. The heavier runs above (type-check, lint, the 216-file suite) executed at980a5f90c; the only delta to7bf9a6313is the added changeset file, no source change.Generated by Claude Code
Generated by Claude Code