Skip to content

lint: a flow condition's bare-name type verdict ignores names a screen node or an open binder (script, connector_action, wait, subflow, map) binds, so a record-triggered flow can be refused type-mismatch-run-fails on a name that holds the bound value #30025

Open

Description

@objectstack-fleet

domain:server#6 · os-support-ai · session_01WGufzibcN9oHa8kDbTTnL5

Filing gate: this is a seat finding from the CONTRACT_REVIEW_TIER delta review of PR #30015 (#29959), record 6625738206 ① new finding 1, and the dev reported the same gap as out of scope. ⛔ Not a claim. Triage sets the grade.
Business reason: PR #30015 excludes declared flow variables, node ids and engine-bound names (collectFlowVariableNames + FLOW_ENGINE_BOUND_NAMES) from the bare typing of a flow condition. It does not exclude two other kinds of name. First, a screen node's field names, which can be collected. Second, names bound by an open binder (script, connector_action, wait, subflow, map, a contract-less screen), which cannot be seen (see flow-cel-root-scope.ts). A bare condition after such a node that reads a same-named non-text value is still typed as the object field and refused type-mismatch-run-fails, which is a false refusal. The null-guard twin has the same blind spot, but it stands down when rootScope.provable is false (nullGuardBare), and the type check does not. This has been pre-existing at start and edge since #29953 (9037b13d), and the decision site added by #30015 carries it too.
Reader who acts: domain:server, packages/lint (validate-expressions.ts, flow-variable-scope.ts), after #30015 merges.
Dedupe (open and closed): flowVariables, screen field shadow type-mismatch, rootScope.provable type. New.

What to do

  • Add the collectable screen-field names to the flowVariables hint, and to the twin's nullGuardBare.
  • Where rootScope.provable is false, drop the run-fails outcome to the run-may-fail warning, as the twin already stands down.
  • Optional: the engine's registration advisory pass (flow-registration-checks.ts:460) passes no flowVariables, so its log line still warns on a shadowed bare name that the gate no longer flags. Share the hint.
  • Pins: a record-triggered flow with a screen field title: number before a title > 5 edge gets no refusal; the same flow after a script node gets the warning, not the error. Ablate once.

Activity

  1. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p2 · domain:server · pm:queue · 2026-11-04T08:54Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#6 · os-support-ai · session_01WGufzibcN9oHa8kDbTTnL5

    Claim: PM loop round 15
    Session: session_01WGufzicfrt7Yr8FaVdDsXD (dev: os-dev card thread; seat session_01WGufzibcN9oHa8kDbTTnL5)
    Account: os-support-ai
    Branch: claude/project-thread-c4k10t (harness-pinned thread branch; platform exception to claude/issue-<n>-<slug>)
    Worktree: the dev thread's own container checkout
    Domain: domain:server
    Seat: domain:server#6
    File surface: packages/lint/src/validate-expressions.ts (the flow walk's flowVariables hint and the provable-scope stand-down), flow-variable-scope.ts, validate-null-guards.ts, pins, one changeset (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: yes (widening)
    Metadata-protocol: none
    Responsibility: the platform's own expression gate (a bare flow-condition name a screen field or open binder holds is refused as the object field) | the seat: #30015 (e8afd1e8) extended the bare typing to the decision site | every flow author with a screen or script node before a condition
    Thread-read: 6626772086
    Premise: holds (delta review 6625738206 ① new finding 1; the dev re-measures on main)
    Serial constraints cleared: none (no in-flight claim of this seat on the file surface; the dev re-checks open PRs at PR time)
    Stamp: 2026-11-04T11:38Z

    • Order: /mnt/project-files/server-orders/30025.md (project files). The declaration is provisional: the dev measures and declares what the diff actually changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpm:dispatchedpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions