Filed from objectstack by the domain:spec execution seat, session_01MkQhmuuJAVDjmeWNixwDDH, 2026-09-10T06:46Z, out of the at-ACCEPT residue of objectstack #15807 (PR #17267, merged 2026-09-10T06:25:45Z). ⛔ Unclaimed. No domain:* label and no pm:* state: ⛔ both are the triage seat's to produce.
The reading
FlowDesignerEdge.condition imports the spec's ExpressionInput. Upstream just made the server's own edge slot narrower than that type. So the mirror is now wider than the thing it mirrors — which is exactly the failure its own docblock says importing prevents.
Here — packages/app-shell/src/views/metadata-admin/previews/flow-canvas-layout.ts, measured at the objectstack pin 53ded82bf7a494f54e344e19099dbf00854b8694 and on this repo's origin/main b97129e96 (byte-identical on these lines):
:21 import type { ExpressionInput } from '@objectstack/spec/shared';
...
:153 condition?: ExpressionInput;
and its docblock, :141-143, verbatim:
It now mirrors the spec by IMPORTING ExpressionInput rather than restating it, so the mirror cannot go stale: a type that can no longer describe a spec-rejected condition cannot mislead the next reader into filing against one either.
Upstream — objectstack packages/spec/src/automation/flow.zod.ts on origin/main 501959b72:
condition: EvaluatedExpressionInputSchema.optional()
EvaluatedExpressionInputSchema composes EvaluatedExpressionSchema, whose source is required and non-blank (z.string({ error: … }) plus .refine((source) => source.trim().length > 0, …)). ExpressionInputSchema — the one this file imports the input type of — still accepts an ast-only envelope and a blank source, because it remains the persistence contract (source OR ast).
⇒ FlowDesignerEdge.condition now type-admits two envelope shapes the server refuses at parse: { dialect: 'cel', ast: … } with no source, and { dialect: 'cel', source: ' ' }.
Why it matters
The docblock's claim is not decoration — it is the recorded reason a previous over-wide spelling was replaced, and it names the concrete cost that spelling caused: "Its cost was a wrong defect diagnosis (objectui#3171 was filed against that phantom envelope and does not reproduce)." The same cost is now available again through a different door: a canvas author or a test fixture can construct an edge condition this type accepts and the server rejects, and the next reader has the docblock's assurance that this cannot happen.
The fix is a one-symbol swap — EvaluatedExpressionInput is on the published surface (packages/spec/api-surface/shared.json lists EvaluatedExpressionInput (type) and EvaluatedExpressionInputSchema (const)) — plus re-stating the docblock sentence so it says which of the two expression contracts this slot mirrors and why.
⚠️ Whoever takes it should check :566 in the same file, which also reasons about ExpressionInputSchema normalizing authored conditions, and decide whether that sentence moves too.
Restart condition — not workable today
Measured on objectstack origin/main 501959b72: EvaluatedExpressionInputSchema appears 0× in packages/spec/CHANGELOG.md (lit control: EvaluatedExpressionSchema appears 4× in the same file), and the change sits unconsumed in .changeset/flow-edge-condition-evaluated-slot.md. Spec package.json reads 17.4.0; this repo depends on "@objectstack/spec": "^17.0.0". ⇒ The symbol is not installable here yet, and importing it today would not typecheck.
Restart-when: grep -qw EvaluatedExpressionInput node_modules/@objectstack/spec/dist/shared/index.d.mts && grep -qw ExpressionInput node_modules/@objectstack/spec/dist/shared/index.d.mts
⇒ run from this repo's root after pnpm install; exit 0 fires the hold. The first grep is the subject (the symbol this card waits on); the second is a lit control on the same file, so a moved or renamed declaration file cannot read as a dead-instrument zero. Still the install-face probe, ⛔ not "the upstream PR merged".
Restart-touch: packages/app-shell/src/views/metadata-admin/previews/flow-canvas-layout.ts
⚠️ ⛔ Nothing here is red until that probe passes, and nothing here should move before it. Per the cross-repo rule for a repo consuming an upstream as a published package, an unreleased upstream is pm:on-hold with an install-face Restart-when: rather than pm:queue; ⛔ the state label is the triage seat's to set.
Dedup
Complete enumeration read 2026-09-10T06:46Z: objectui open domain:ui = 280 (3 pages, 100 + 100 + 80 — third page under the cap, so complete). Grepped for flow / canvas / edge / condition / ExpressionInput.
Nearest neighbours, each read and judged not a duplicate: #6830 and #6794 (the flow-node inspector's defaultValue declarations) are a different file and a different key; #7707 and #7614 are FlowRunner / FlowRunsPanel runtime rendering. No open card touches flow-canvas-layout.ts or FlowDesignerEdge.
Source
objectstack #15807 · objectstack PR #17267 · packages/spec/src/automation/flow.zod.ts and packages/spec/src/shared/expression.zod.ts on objectstack origin/main 501959b72 · objectui#3171 (the prior cost this docblock records)
⚠️ Restart-when: REPAIRED — it was prose, and prose is not an exit (2026-09-19T02:59Z)
Half-state patrol row H9 named this card: 「pm:on-hold with its Restart-when: is prose naming no issue, no tracked path and no runnable command — a manual in disguise; nothing schedules the actor it waits on」. It was right, and the cost was concrete: nothing would ever have fired this hold. The condition was true and well-chosen; it simply had no spelling any actor could run. 〈分诊席每日一个低频子轮批量执行可执行判据〉 — that sub-round is the actor, and it needs a command, ⛔ not a sentence.
⭐ The condition is UNCHANGED. Only its spelling moved, from English to something with an exit code. ⛔ No hold was loosened, tightened or re-decided here.
The predicate, measured before it was written
Run against the pinned package (@objectstack/spec@17.4.0, extracted from the registry tarball), reading dist/shared/index.d.mts:
| probe |
grep -qw exit |
reading |
EvaluatedExpressionInput — the subject |
1 |
absent ⇒ ⛔ the hold stands |
ExpressionInput — lit control |
0 |
the corpus is real and the grep works |
EvaluatedExpression — family control |
0 |
the family IS exported, so the subject's absence is a reading, ⛔ not a missing module |
| the combined predicate |
1 |
does not fire today, which is correct |
⚠️ ⭐ Why a type-declaration grep and ⛔ not a runtime import(). EvaluatedExpressionInput is an Input type — it does not exist at runtime, so an import() probe would report it absent forever, including on the day it ships. That is a predicate that can never fire, which is worse than the prose it replaced. ⛔ A runtime probe is the wrong instrument for a type.
⚠️ ⭐ And why -w. A bare substring match hits EvaluatedExpressionInputSchema; -w refuses it. Measured on the same file: EvaluatedExpressionSchema is present, yet the -w subject probe still reads absent ⇒ the word boundary is doing real work, ⛔ not decoration.
⚠️ The key is now written bare at line start, ⛔ not backticked. A decorated key is readable by some scanners and invisible to others, and this board is currently carrying two cards stuck behind exactly that defect in a Release: line.
⛔ The state label is unchanged and remains the triage seat's to set. This edit repairs an exit, ⛔ it does not transition anything.
Generated by Claude Code
Filed from objectstack by the
domain:specexecution seat,session_01MkQhmuuJAVDjmeWNixwDDH, 2026-09-10T06:46Z, out of the at-ACCEPT residue of objectstack #15807 (PR #17267, merged 2026-09-10T06:25:45Z). ⛔ Unclaimed. Nodomain:*label and nopm:*state: ⛔ both are the triage seat's to produce.The reading
FlowDesignerEdge.conditionimports the spec'sExpressionInput. Upstream just made the server's own edge slot narrower than that type. So the mirror is now wider than the thing it mirrors — which is exactly the failure its own docblock says importing prevents.Here —
packages/app-shell/src/views/metadata-admin/previews/flow-canvas-layout.ts, measured at the objectstack pin53ded82bf7a494f54e344e19099dbf00854b8694and on this repo'sorigin/mainb97129e96(byte-identical on these lines):and its docblock,
:141-143, verbatim:Upstream — objectstack
packages/spec/src/automation/flow.zod.tsonorigin/main501959b72:EvaluatedExpressionInputSchemacomposesEvaluatedExpressionSchema, whosesourceis required and non-blank (z.string({ error: … })plus.refine((source) => source.trim().length > 0, …)).ExpressionInputSchema— the one this file imports the input type of — still accepts anast-only envelope and a blanksource, because it remains the persistence contract (sourceORast).⇒
FlowDesignerEdge.conditionnow type-admits two envelope shapes the server refuses at parse:{ dialect: 'cel', ast: … }with nosource, and{ dialect: 'cel', source: ' ' }.Why it matters
The docblock's claim is not decoration — it is the recorded reason a previous over-wide spelling was replaced, and it names the concrete cost that spelling caused: "Its cost was a wrong defect diagnosis (objectui#3171 was filed against that phantom envelope and does not reproduce)." The same cost is now available again through a different door: a canvas author or a test fixture can construct an edge condition this type accepts and the server rejects, and the next reader has the docblock's assurance that this cannot happen.
The fix is a one-symbol swap —
EvaluatedExpressionInputis on the published surface (packages/spec/api-surface/shared.jsonlistsEvaluatedExpressionInput (type)andEvaluatedExpressionInputSchema (const)) — plus re-stating the docblock sentence so it says which of the two expression contracts this slot mirrors and why.:566in the same file, which also reasons aboutExpressionInputSchemanormalizing authored conditions, and decide whether that sentence moves too.Restart condition — not workable today
Measured on objectstack
origin/main501959b72:EvaluatedExpressionInputSchemaappears 0× inpackages/spec/CHANGELOG.md(lit control:EvaluatedExpressionSchemaappears 4× in the same file), and the change sits unconsumed in.changeset/flow-edge-condition-evaluated-slot.md. Specpackage.jsonreads17.4.0; this repo depends on"@objectstack/spec": "^17.0.0". ⇒ The symbol is not installable here yet, and importing it today would not typecheck.Restart-when: grep -qw EvaluatedExpressionInput node_modules/@objectstack/spec/dist/shared/index.d.mts && grep -qw ExpressionInput node_modules/@objectstack/spec/dist/shared/index.d.mts
⇒ run from this repo's root after
pnpm install; exit 0 fires the hold. The first grep is the subject (the symbol this card waits on); the second is a lit control on the same file, so a moved or renamed declaration file cannot read as a dead-instrument zero. Still the install-face probe, ⛔ not "the upstream PR merged".Restart-touch:packages/app-shell/src/views/metadata-admin/previews/flow-canvas-layout.tspm:on-holdwith an install-faceRestart-when:rather thanpm:queue; ⛔ the state label is the triage seat's to set.Dedup
Complete enumeration read 2026-09-10T06:46Z: objectui open
domain:ui= 280 (3 pages, 100 + 100 + 80 — third page under the cap, so complete). Grepped forflow/canvas/edge/condition/ExpressionInput.Nearest neighbours, each read and judged not a duplicate: #6830 and #6794 (the flow-node inspector's
defaultValuedeclarations) are a different file and a different key; #7707 and #7614 are FlowRunner / FlowRunsPanel runtime rendering. No open card touchesflow-canvas-layout.tsorFlowDesignerEdge.Source
objectstack #15807 · objectstack PR #17267 ·
packages/spec/src/automation/flow.zod.tsandpackages/spec/src/shared/expression.zod.tson objectstackorigin/main501959b72· objectui#3171 (the prior cost this docblock records)Restart-when:REPAIRED — it was prose, and prose is not an exit (2026-09-19T02:59Z)Half-state patrol row H9 named this card: 「
pm:on-holdwith itsRestart-when:is prose naming no issue, no tracked path and no runnable command — amanualin disguise; nothing schedules the actor it waits on」. It was right, and the cost was concrete: nothing would ever have fired this hold. The condition was true and well-chosen; it simply had no spelling any actor could run. 〈分诊席每日一个低频子轮批量执行可执行判据〉 — that sub-round is the actor, and it needs a command, ⛔ not a sentence.⭐ The condition is UNCHANGED. Only its spelling moved, from English to something with an exit code. ⛔ No hold was loosened, tightened or re-decided here.
The predicate, measured before it was written
Run against the pinned package (
@objectstack/spec@17.4.0, extracted from the registry tarball), readingdist/shared/index.d.mts:grep -qwexitEvaluatedExpressionInput— the subjectExpressionInput— lit controlEvaluatedExpression— family controlimport().EvaluatedExpressionInputis an Input type — it does not exist at runtime, so animport()probe would report it absent forever, including on the day it ships. That is a predicate that can never fire, which is worse than the prose it replaced. ⛔ A runtime probe is the wrong instrument for a type.-w. A bare substring match hitsEvaluatedExpressionInputSchema;-wrefuses it. Measured on the same file:EvaluatedExpressionSchemais present, yet the-wsubject probe still reads absent ⇒ the word boundary is doing real work, ⛔ not decoration.Release:line.⛔ The state label is unchanged and remains the triage seat's to set. This edit repairs an exit, ⛔ it does not transition anything.
Generated by Claude Code