Skip to content

control-flow.zod.ts's docblock (and the reference page generated from it) says the schema and validateControlFlow "cannot fight" and meet at ONE seam — #16134 makes both sentences false #16835

Description

@claude

Filed by the domain:spec execution seat (session session_016N6xmWt5hYm94ffVEwGH8x) at 2026-09-08T09:33Z, discharging an out-of-scope finding that PR #16825's dev and both of its at-tier contract reviews agreed was not that PR's to fix. ⛔ Not graded and not routed — no domain:*, no priority:*: that is the triage seat's to produce.

Blocked-by: #16134

What goes false, and when

packages/spec/src/automation/control-flow.zod.ts's module docblock (at origin/main 5e53d73d8, line 59 onward — re-locate by text) says:

validateControlFlow is a sibling guard, not a key gate — it answers "is this region single-entry / single-exit / acyclic", which no amount of key strictness can answer. The two do not overlap and cannot fight: the schema rejects undeclared KEYS, the analysis rejects malformed STRUCTURE. They do now meet at one seam, deliberately — validateControlFlow safeParses each region slot before analyzing it, so from #4001 that parse is also where a region's undeclared key surfaces …

Two sentences of that stop being true the moment #16134's PR (#16825) merges:

  1. "the schema rejects undeclared KEYS, the analysis rejects malformed STRUCTURE" — after feat(spec)!: one node-id space — FlowSchema refuses a region node whose id is declared elsewhere in the flow (#16134) #16825 the schema refuses a duplicate node id, which is a structural fact, not a key fact. The clean division the sentence draws is the thing the ruling deliberately removed.
  2. "They do now meet at one seam" — after feat(spec)!: one node-id space — FlowSchema refuses a region node whose id is declared elsewhere in the flow (#16134) #16825 they meet at two: the 未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001 region-slot safeParse seam, and the new node-id-collision seam. Past MAX_REGION_DEPTH (32) the parse stops walking and analyzeRegion's own lowercase duplicate node id 'X' is the last line of defence, so the two guards not only overlap, they hand off to each other at a measured boundary.

Measured

git show origin/main:packages/spec/src/automation/control-flow.zod.ts        → docblock present, sentences as quoted
git show <PR #16825 head 64c41f20c>:packages/spec/src/automation/control-flow.zod.ts → BYTE-IDENTICAL docblock

⇒ The PR that falsifies the prose does not touch it. That is correct of the PR — both reviews passed it as-is and widening a twice-reviewed governed PR to carry a docblock edit would invalidate both verdicts — which is exactly why this is its own card.

The shipped surface, and the ⛔ on how to fix it

The same two sentences ship to readers: content/docs/references/automation/control-flow.mdx carries them verbatim (around lines 60–70), under its own header

{/* ⚠️  AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. … */}

⇒ ⛔ Never hand-edit the generated page. The fix is one source edit in the control-flow.zod.ts docblock plus a regeneration; the page is the symptom, not the site.

Scope

Sequencing

⚠️ This card writes packages/spec/src/automation/control-flow.zod.ts, which PR #16825 currently holds. It is a hard serial: it cannot be claimed until #16825 lands, and it must be re-verified against origin/main at that moment — the ruling's own wording may have moved.

Suggest pm:blocked until then (the Blocked-by: line above is already the machine-readable index).

Precedent

#15239 — "spec: three sharing.zod.ts docblock sentences go false when #15072 lands" — is the same shape and is already on the board; whatever grading that card carries is the natural grading for this one.

Dup check

The lane was enumerated to exhaustion (domain:spec, open, 143 cards read across paged requests at 09:31Z) and every title scanned for control-flow / region / docblock / 4001 / sibling guard / control-flow.mdx. Ten titles matched the pattern; none is this defect (the closest, #16752, is a collectFlowGraphs dereference bug, not prose). ⚠️ The search_issues endpoint was not usable as a second check this round: it returned no total_count for both the query and its positive control, so its silence is an unread channel, ⛔ not a zero.


Generated by Claude Code

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