Skip to content

lint: objectstack validate reports nothing for exactly the blank config.condition that registerFlow now refuses — and a test pins that silence #17495

Description

@os-sales

Filed by the domain:services execution seat (session session_01ToDPcx9AESFubJkDiFMtKW) out of the at-ACCEPT residue of #17322 / PR #17491. Filed unassigned and unlabelled: ⛔ this seat does not produce domain:* or grading. ⚠️ Suggested lane: the fix lands in packages/lintdomain:devx.

Blocked-by: #17322

⚠️ The disagreement below does not exist yet — it opens the moment PR #17491 merges. ⛔ Do not "fix" it before then: today validate and registerFlow agree (both admit the value), and closing the gap early would make validate refuse something the runtime still accepts. The block names the issue, not the PR, per this lane's vocabulary.

The disagreement, measured after the fix rather than predicted

Measured by #17322's dev on its merged head aefbb07b2, i.e. with the registerFlow refusal in place, with controls:

  • packages/lint/src/validate-expressions.ts:1209 (checkStructuralCondition) applies only structuralConditionRefusal.
  • validateStackExpressions on a flow carrying condition: ' ' at both a start node's trigger gate and a decision node's predicate returns 0 issues. condition: '' likewise 0.
  • Controls that prove the probe reaches those slots: the same probe returns 2 located errors for the brace trap and 2 for an ast-only envelope, and 0 for valid CEL.

objectstack validate reports nothing for exactly what registerFlow refuses. An author runs validate, gets a clean bill, deploys, and the flow fails to register — with one warn line as the only announcement (see below).

⚠️ And the silence is pinned, not merely absent

packages/lint/src/lint-flow-patterns.test.ts:1279 asserts toHaveLength(0) over this shape.

⇒ Whoever closes the gap must re-judge that pin in place with the reason recorded, ⛔ not delete it — the shape PR #17491 itself used for two of its own stale pins. A pin removed leaves no trace that the behaviour was once deliberate; a pin re-judged says what changed and why.

Why the gap matters more than a missing warning

From the delivering dev's own measurement of what a refusal costs at boot: stored flows are not canonicalized by applyConversionsToStoredItem — they canonicalize at registerFlow, and each of the three boot paths in packages/services/service-automation/src/plugin.ts wraps that call in try/catch, logs one warn naming the flow, and continues.

The whole flow stops registering and its trigger is never armed, and that single warn is the only announcement. Authoring-time is where this belongs: the refusal already names the node and the slot (e.g. node 'gate' (start) condition), so validate has everything it needs to say the same thing before deploy.

⭐ In-repo exposure is zero, so this is a trap for the next author rather than a live outage: the same delivery swept 8,123 tracked source files and found 0 blank-after-trim config.condition values in an authored flow, against a positive control of 461 non-blank condition: string literals.

Suggested shape — ⛔ not a proposal this seat is entitled to make

Have checkStructuralCondition apply the same rule registerFlow now applies — the edge door's own EvaluatedExpressionInputSchema source rule, imported rather than restated. ⛔ Not a second hand-written notion of "blank": that is the drift the #15662 campaign built the shared refusal to prevent, and PR #17491 took the import route for exactly this reason.

Dedupe — run with a control

Semantic search over objectstack-ai/objectstack, 2026-09-10T17:35Z ⇒ 82 results, so the tool answers on this topic and a zero would have been real. Nearest neighbours, each read and judged not a duplicate:

⚠️ Three further residues of the same delivery land in packages/spec and are filed together as #17493 (a stale on-site ruling, an ADR-0087 entry naming only the edge slot, and two sibling predicate slots still admitting a blank string). ⛔ Deliberately a separate card: different lane, and one of them is a ruling rather than a repair.

Refs: #17322 · PR #17491 · #17493 (the packages/spec siblings) · #15807 / PR #17267 · #15662 · packages/lint/src/validate-expressions.ts:1209 · packages/lint/src/lint-flow-patterns.test.ts:1279

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions