Skip to content

Commit 7f368f5

Browse files
feat(lint)!: os lint refuses a flow region the engine refuses to register (flow-region-shape-invalid) (#29495)
<!-- claude-projects-attribution: {"github_login":"os-steve"} --> _Requested by **Steve** · [project thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi94SgyoaFCXpCbitt9ZQSDDL)_ Fixes #29049 Clause-②: no (narrowing) Metadata-protocol: none ## 维护者速读 - 改了什么:流程区域形状检查(ADR-0031,loop / parallel / try_catch 区域须单入口单出口、无环,parallel 至少两个分支)从 CLI 专用关卡搬进 `@objectstack/lint` 的作者期规则表,新规则 `flow-region-shape-invalid`,直接调用 spec 的 `validateControlFlow`;`os lint` 从此也拒收这类流程。 - 为什么改:此前只有 `os validate` / `os build` 拒收,`os lint` 照样放行;作者跑 lint 看到绿灯,部署后引擎注册时拒收该流程,触发器永不触发。 - 风险与回滚:`os lint` 收窄(BREAKING 横幅);validate / build 的通过与拒收结论不变,只是错误改由规则表报出、`--json` 行的形状随之变化(该形状尚未发布)。回滚即还原本 PR。 - 先看:`packages/lint/src/validate-flow-region-shape.ts`(规则本体)、`packages/lint/src/authoring-rules.ts` 新条目、`packages/cli/test/validate-flow-region-shape.test.ts`(三命令同一夹具)。 - 两分钟验证:`pnpm --filter @objectstack/cli exec vitest run --project unit test/validate-flow-region-shape.test.ts`,预期 5/5 通过,其中三条用例对 validate、build、lint 同一夹具均退出 1 并给出同一规则 id。 - 需要你做的:无,席位落地(新规则 id 由席位在 ACCEPT 中裁定;两条待发 changeset 的句子被本 PR 改正,Check Changeset 按设计变红,由席位复核确认)。 ## What changes - **New authoring rule** `flow-region-shape-invalid` (`packages/lint/src/validate-flow-region-shape.ts`; `validateFlowRegionShape` and `FLOW_REGION_SHAPE_INVALID` exported from the root barrel). Each `flows[]` record goes through the two calls the engine's `registerFlow` makes: `FlowSchema`, then `validateControlFlow` from `@objectstack/spec/automation`. No copy of the region logic. Message: `Flow 'NAME' would be refused at registration: ` plus the engine's sentence, verbatim. Gating, `input: 'parsed'`, all three commands. - **Fail-closed kept (#29243).** A flow record `FlowSchema` refuses is a finding ("could not be judged", with the schema's issues), never a skip. A non-record entry (null, a string) is skipped like every registry reader skips it (`non-record-object-entry.test.ts` reds otherwise); the flows after it keep their own index. - **Runtime publish gate: not wired** (`surfaces: CLI_ONLY`, with a `surfaceReason`). Whether a metadata publish refuses a malformed region is sibling card #29233 (domain:server); this PR does not decide it. - **CLI-only gate retired.** `packages/cli/src/utils/flow-region-shape.ts` and its unit test are deleted; `validate.ts` step 3a-vi and `compile.ts` step 3b-iii-ter are reduced to a pointer comment. validate and build now get the check from the registry, so the defect is reported once (measured below). - **`os explain flow-region-shape-invalid`**: new entry in `rule-explanations.ts`. - **Docs**: the four CLI transcripts now print `Running author-time rules (61)` (recounted from the merged registry: validate 61, build 61). - **Changesets**: new `.changeset/29049-flow-region-shape-lint-rule.md` (`@objectstack/lint` + `@objectstack/cli` patch, BREAKING banner, `adr-0087: not-required (no-migration-prescription)`). ### Forced test edits - `packages/cli/test/authoring-rule-command-parity.test.ts`: the `flow region shape (#28893)` row left `OUTSIDE_THE_TABLE` and is now a `CASES` row (`rule: 'flow-region-shape-invalid'`, `blindTo: ['lint']`), as that table's docblock prescribed. `OUTSIDE_THE_TABLE` held only that row, so the table, its docblock and its `it.each` are removed (an empty `it.each` would register no test). - `packages/cli/test/validate-build-gate-parity.test.ts`: the `findFlowRegionRefusals` row is removed from `SHARED_NON_REGISTRY_GATES`; neither command calls it now, and the ledger's own stale-row check requires that. - `packages/cli/test/validate-flow-region-shape.test.ts`: still green, with three edits. (1) A refusal is now a rule finding (`rule`, `where`, `path`, `message`, `hint`), under `errors` for `os validate --json` and under `issues` for `os build --json` (the rule table's envelope), not the old gate's `VALIDATION_ERROR` row with `flow`. (2) The #29059 assembled-artifact case located the row at `packages[1].manifest.flows[0]`; the rule table judges the artifact's folded union first (as it does every collection), so the finding is at `flows[1]` with `where: flow 'rgn_ops_lead_time'`. Still exactly one row, from the second package. (3) Each case now also runs `os lint` in process on the same fixture. - `packages/cli/src/utils/flow-region-shape.test.ts` (deleted with its subject): its three #29059 refused-parse cases moved to `packages/lint/src/validate-flow-region-shape.test.ts`. The `packages[]` location case has no rule-level counterpart (the rule reads the stack it is handed); its door-level half is the assembled case above. ## Tests One test per command on the same fixture: `packages/cli/test/validate-flow-region-shape.test.ts` runs `os validate --json`, `os build --json` and `os lint --json` in process on each of `duly`, `nested`, `singleBranch` and `assembled`; all three exit 1 with `rule: flow-region-shape-invalid` and the engine's sentence, build writes no `dist/`, and the joined control passes validate and build with no finding of the rule under lint. The validate leg also asserts the refusal appears exactly once (no echo from a second gate). Readings on head `52b05b8e` (after merging `origin/main` at `7b1ae338`, closure rebuilt): <details><summary>Consumer suites</summary> - `pnpm --filter @objectstack/lint test`: Test Files 190 passed (190), Tests 7843 passed (7843); `typecheck` clean. - `pnpm --filter @objectstack/cli exec vitest run --project unit`: Test Files 373 passed (373), Tests 5263 passed (5263) (includes `validate-flow-region-shape`, `validate-build-gate-parity`, `explain-rule-id`, the `published-subpath-*` pins after `pnpm --filter @objectstack/cli build`); `typecheck` clean. - `pnpm --filter @objectstack/cli exec vitest run --project integration test/authoring-rule-command-parity.test.ts`: Tests 12 passed (12), including `flow-region-shape-invalid gates on all three commands`. - `pnpm --filter @objectstack/spec exec vitest run src/automation`: Test Files 45 passed (45), Tests 1745 passed (1745). - Rule count recounted from the merged registry's dist: validate 61, build 61 (lint 59), matching the four transcripts. </details> <details><summary>Ablation (one, on the line the tests pin)</summary> Mutation: `validateControlFlow(result.data);` in `packages/lint/src/validate-flow-region-shape.ts` guarded behind an always-false `globalThis.ABLATION_29049_MARKER` read, via `scripts/ablation-replace.mjs` (anchor 1 -> 0, blob `46bdaf4b` -> changed), lint rebuilt, `ablation-dist-preflight` found the marker in 4 dist files. - lint `validate-flow-region-shape.test.ts`: 4 failed, 3 passed (red as expected; the 3 green are the refused-parse and control cases, which do not reach the call). - cli `validate-flow-region-shape.test.ts`: 4 failed, 1 passed: validate, build and lint all PASS the malformed flow with the rule disabled, which also proves no second gate refuses it any more (the retired walk is gone). - cli `authoring-rule-command-parity.test.ts`: `flow-region-shape-invalid gates on all three commands` failed, 11 passed. - Restore: blob back to `46bdaf4b` == HEAD, `git diff HEAD` empty, lint rebuilt, preflight `--absent` clean on 20 files and a clean tree; both CLI files green again (5/5, 12/12). A first attempt replaced the call with a bare expression; that build failed, so the marker never reached `dist/` and its readings are discarded (not counted). </details> <details><summary>Measured out of scope</summary> A flow whose top-level graph cycles (start -> a -> b -> a, b -> end) draws no finding; the same cycle inside a `loop` body draws `loop 'L' body: ... region contains a cycle`. So this rule does not cover #29051. </details> ## Acceptance notes - `os lint` now also reports a flow record the flow schema refuses (the fail-closed finding). `os validate` and `os build` already refuse such a flow at their schema step, so no command accepts what it refused before beyond the region case; `os lint` reaches it because it never parses. - Top-level graph cycles stay out of scope (#29051): the engine's `detectCycles` is not exported, and `validateControlFlow` checks cycles inside regions only. Measured: this rule does not cover the top-level cycle. - The lane line in `lanes/server.md` reported in triage 6579387723 is not touched. ## Verification Gates on head `52b05b8e`: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 92 commands; all 92 run and reconciled with `--ran` (`92 derived famil(ies) accounted for — 88 run, 4 NOT-MEASURED`). <details><summary>Non-zero exits</summary> - `node scripts/check-empty-changeset.mjs --base origin/main` exit 1, by design: this PR corrects two PENDING changesets whose sentences it makes false (DELIBERATE CORRECTION class). `.changeset/28893-flow-region-shape-at-validate-build.md` no longer says the doors call `findFlowRegionRefusals` and print a `VALIDATION_ERROR` row; it now names the rule `flow-region-shape-invalid` and that `os lint` reports it too. `.changeset/29059-flow-region-gate-hardening.md` now says the unjudgeable flow is refused with a `flow-region-shape-invalid` finding instead of a `VALIDATION_ERROR` row. Restoring them would republish false sentences; this needs confirming on the PR. `Check Changeset` is not a required context. - NOT MEASURED (exit 3, prerequisite): `check:dual-build-cjs-loads` and `check:skill-examples` (packages outside this closure have no `dist/`, e.g. `client-react`), `check:i18n-coverage` (the showcase example needs an unbuilt connector `dist/`), `check-plugin-teardown-shape --self-test` (shallow clone cannot reach its pinned fixture commit). None reads a file this PR changes for its verdict; CI runs them on a full build. - Offline: `check-changeset-no-major --event` exit 0 (LEVEL AXIS: `no (narrowing)` + `none`, patch); `check-adr-0087-registration` exit 0 (`not-required (no-migration-prescription)`). </details> Dogfood (required by the `(narrowing)` arm) on head `52b05b8e`, `pnpm --filter @objectstack/dogfood test` under the lock after building `@objectstack/dogfood^...`: `VERDICT command-exit 1` · Test Files 2 failed | 393 passed | 3 skipped (398) · Tests 4 failed | 3255 passed | 28 skipped (3287). <details><summary>The 4 failures are not this PR's (control measured)</summary> - `test/flow-runas.dogfood.test.ts`: `runAs:'system' ELEVATES` (trigger answers 404 `RECORD_NOT_FOUND` on `runas_note`), `runAs:'user' DE-ELEVATES`, `runAs:'system' READS`. - `test/declarative-endpoint-anonymous-guest.dogfood.test.ts`: `carries the guest position …` (`flowContexts` length 0, expected 1). - Re-run alone on this head: same 4 failed, 8 passed. Control: `packages/lint/src`, `packages/cli/src` and `packages/cli/test` restored to `origin/main` `7b1ae338` (this PR's diff removed from both packages), lint and cli rebuilt, the same two files: the same 4 failed, 8 passed. So they fail on `main`'s code without this diff; reported to the seat as a main-red candidate. Tree restored to HEAD and rebuilt (clean `git status`). </details> --- _Generated by [Claude Code](https://claude.ai/code/session_01ADHkmQjqkXDjc5jhjFfHt3)_ <!-- signed: domain:spec#4 · os-steve · session_01ADHkmQNap7ryQcyQXocWct --> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 728c73e commit 7f368f5

19 files changed

Lines changed: 371 additions & 270 deletions

‎.changeset/28893-flow-region-shape-at-validate-build.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ Metadata-protocol: none
99

1010
**BREAKING** accept-set narrowing at `os validate` and `os build` (`@objectstack/cli`): a stack carrying a flow whose `loop` body, `parallel` branches or `try_catch` region is not single-entry/single-exit or is cyclic, at any depth, or whose `parallel` has fewer than two branches, now fails validation and the build instead of passing and emitting an artifact.
1111

12-
Both commands now call `findFlowRegionRefusals`, which hands each flow (each `packages[]` entry's flows, or the stack's own) to the automation engine's own registration verdict: `FlowSchema`, then the spec's `validateControlFlow`. A refused flow prints `Flow '<name>' would be refused at registration: <where>: <the engine's message>` (`VALIDATION_ERROR`, exit 1), and the build writes nothing to `dist/`. Before, both passed it, and the engine refused it at boot with an `[Automation] failed to register flow` warning while the server ran without the flow. What the engine registers is unchanged. The fix is the engine's own sentence, e.g. add one node every exit of the region leads to.
12+
Both commands now hand each flow to the automation engine's own registration verdict: `FlowSchema`, then the spec's `validateControlFlow`. A refused flow is reported by the author-time rule `flow-region-shape-invalid` as `Flow '<name>' would be refused at registration: <where>: <the engine's message>` (exit 1), and the build writes nothing to `dist/`; `os lint` reports it too. Before, both passed it, and the engine refused it at boot with an `[Automation] failed to register flow` warning while the server ran without the flow. What the engine registers is unchanged. The fix is the engine's own sentence, e.g. add one node every exit of the region leads to.
1313

1414
<!-- adr-0087: not-required (no-migration-prescription) No key of any schema is added, removed, renamed or re-shaped, and no export or type changes: `os validate` and `os build` now run the check `registerFlow` already runs, with the same function (`validateControlFlow` from `@objectstack/spec/automation`) and its message. Every flow they now refuse was already refused at registration and never ran, so there is nothing for `objectstack migrate meta` to rewrite and no tombstone; the remedy is the engine's own sentence (close the region with one exit node, or give the parallel a second branch). -->
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
'@objectstack/lint': patch
3+
'@objectstack/cli': patch
4+
---
5+
6+
feat(lint): `os lint` refuses a flow whose structured region the automation engine refuses to register (`flow-region-shape-invalid`, ADR-0031)
7+
8+
Clause-②: no (narrowing)
9+
Metadata-protocol: none
10+
11+
**BREAKING** accept-set narrowing at `os lint` (`@objectstack/cli`, through the `@objectstack/lint` rule table): a stack carrying a flow whose `loop` body, `parallel` branches or `try_catch` region is not single-entry/single-exit or is cyclic, at any depth, or whose `parallel` has fewer than two branches, now fails `os lint` (exit 1) instead of passing. `os validate` and `os build` already refused it; their verdicts are unchanged.
12+
13+
- **One rule for all three commands.** The check is now the author-time rule `flow-region-shape-invalid` (`validateFlowRegionShape` and `FLOW_REGION_SHAPE_INVALID`, exported from `@objectstack/lint`). It calls the automation engine's own registration verdict, `FlowSchema` then the spec's `validateControlFlow`, and its message is the engine's refusal behind the flow's name. `os explain flow-region-shape-invalid` prints the full reasoning.
14+
- **What changes at `os validate` and `os build`.** They refuse the same flows as before, now from the rule table, so the refusal prints under `Author-time rules failed` and appears once. Under `--json` it is a rule finding (`rule`, `where`, `path`, `message`, `hint`), in `errors` for `os validate` and in `issues` for `os build`. A flow in a multi-package artifact is located at its place in the artifact's flows (`flows[N]`), with the flow's name in `where`.
15+
- **A flow the flow schema refuses** is reported by the same rule as one that could not be judged, with the schema's issues, never passed. `os validate` and `os build` refuse such a flow at the schema step already; `os lint`, which does not parse, now reports it here.
16+
- **Not judged:** a cycle in a flow's top-level graph, outside any region.
17+
18+
**The remedy.** Fix the flow the way the engine's sentence says: add one node every exit of the region leads to, remove the edge that loops back inside the region, or give the `parallel` a second branch.
19+
20+
<!-- adr-0087: not-required (no-migration-prescription) No key of any schema is added, removed, renamed or re-shaped: `os lint` now runs the check `registerFlow`, `os validate` and `os build` already run, with the same function (`validateControlFlow` from `@objectstack/spec/automation`) and its message. Every flow it now refuses was already refused by `os validate`, `os build` and at registration, and never ran, so there is nothing for `objectstack migrate meta` to rewrite and no tombstone. -->

‎.changeset/29059-flow-region-gate-hardening.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ fix(cli): the os validate / os build flow-region check never passes a flow it co
77
Clause-②: no
88
Metadata-protocol: none
99

10-
- **No silent pass.** The flow-region check `os validate` and `os build` run (the automation engine's registration verdict, ADR-0031) parses each flow with `FlowSchema` before it judges the regions. When that parse failed it used to skip the flow with no row, so the flow passed unjudged. It now refuses it with a `VALIDATION_ERROR` row at the flow's `path`, naming the flow and the schema's issues. No authored stack reaches this branch today: the stack schema has already parsed every flow the check reads, and `FlowSchema` accepts its own output. Nothing refused or accepted today changes.
10+
- **No silent pass.** The flow-region check `os validate` and `os build` run (the automation engine's registration verdict, ADR-0031) parses each flow with `FlowSchema` before it judges the regions. When that parse failed it used to skip the flow with no row, so the flow passed unjudged. It now refuses it with a `flow-region-shape-invalid` finding at the flow's `path`, naming the flow and the schema's issues. No authored stack reaches this branch today: the stack schema has already parsed every flow the check reads, and `FlowSchema` accepts its own output. Nothing refused or accepted today changes.
1111
- **Refused flows in the boot banner.** When the automation engine refuses a declared flow at registration, boot still continues and the per-flow reason is still under Boot diagnostics. The `os serve` / `os dev` banner now also prints one line beside the declared count, for example `⚠ Flows: 2 flow(s) declared, 1 refused at registration`, read from the engine's own record (`getFlowRegistration`). It prints even when every declared flow was refused and nothing registered. A boot with nothing refused prints no such line.

‎content/docs/deployment/cli.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ os compile --json # JSON output for CI pipelines
771771
→ Normalizing stack definition...
772772
→ Lowering inline handlers...
773773
→ Validating protocol compliance...
774-
→ Running author-time rules (61)...
774+
→ Running author-time rules (62)...
775775
→ Checking that every required capability has a provider installable in this edition...
776776
→ Collecting package docs (ADR-0046)... 0 collected
777777
→ Writing artifact...

‎content/docs/deployment/validating-metadata.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ A clean run walks the registry and reports timing:
760760
Config: /path/to/support-desk/objectstack.config.ts
761761
Load time: 21ms
762762
→ Validating against ObjectStack Protocol...
763-
→ Running author-time rules (61)...
763+
→ Running author-time rules (62)...
764764
→ Checking that every required capability has a provider installable in this edition...
765765
→ Checking package docs (ADR-0046)...
766766

‎content/docs/getting-started/build-with-claude-code.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ visible: 'status != "resolved"'
310310
◆ Validate
311311
────────────────────────────────────────
312312
→ Validating against ObjectStack Protocol...
313-
→ Running author-time rules (61)...
313+
→ Running author-time rules (62)...
314314
315315
✗ Author-time rules failed (1 issue)
316316
• stack · action 'resolve_ticket' visible: bare reference `status` — a

‎content/docs/ui/react-pages.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ objectstack validate
404404
────────────────────────────────────────
405405
→ Loading configuration...
406406
→ Validating against ObjectStack Protocol...
407-
→ Running author-time rules (61)...
407+
→ Running author-time rules (62)...
408408
→ Checking that every required capability has a provider installable in this edition...
409409
→ Checking package docs (ADR-0046)...
410410

‎packages/cli/src/commands/compile.ts‎

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@ import { findOverrideDeclarationRefusals } from '../utils/override-declarations.
8383
// `os validate` step 3a-iv runs, over the save and install doors' own judge
8484
// (`judgeExtensionFieldSuffix`).
8585
import { findExtensionFieldSuffixRefusals } from '../utils/extension-field-suffix.js';
86-
// [#28893] The ADR-0031 region-shape check — the walk `os validate` step 3a-vi
87-
// runs, over the automation engine's own registration verdict.
88-
import { findFlowRegionRefusals } from '../utils/flow-region-shape.js';
8986

9087
export default class Compile extends Command {
9188
static override description = 'Compile ObjectStack configuration to JSON artifact';
@@ -840,28 +837,9 @@ export default class Compile extends Command {
840837
this.exit(1);
841838
}
842839

843-
// 3b-iii-ter. [#28893] Flow region shape (ADR-0031), at build time — the
844-
// SAME call `os validate` makes at its step 3a-vi: the engine's
845-
// registration verdict (`FlowSchema`, then the spec's
846-
// `validateControlFlow`). Before this the build emitted a flow the
847-
// engine then refused at boot, logging a warning and running without
848-
// it; now the door that ships refuses it and writes no artifact. Same
849-
// two faces as the gates above.
850-
const regionRefusals = findFlowRegionRefusals(result.data as Record<string, unknown>);
851-
if (regionRefusals.length > 0) {
852-
if (flags.json) {
853-
await emitJson({ success: false, errors: regionRefusals, warnings: warningsSoFar(), conversions: conversionNotices }, 0, { compact: true });
854-
this.exit(1);
855-
}
856-
const n = regionRefusals.length;
857-
console.log('');
858-
printError(`The automation engine would refuse to register ${n} flow${n > 1 ? 's' : ''} for a malformed region (ADR-0031)`);
859-
printBulletList(
860-
regionRefusals.map((r) => `${r.path} [${r.code}] ${r.message}`),
861-
{ noun: 'flow region refusal(s)', remedy: JSON_FULL_LIST_REMEDY },
862-
);
863-
this.exit(1);
864-
}
840+
// 3b-iii-ter. [#28893] Flow region shape (ADR-0031) is judged by the
841+
// rule table at step 3b since #29049 (`flow-region-shape-invalid`),
842+
// the same verdict `os validate` and `os lint` give.
865843

866844
// 3b-quater. ADR-0141 D2, author side — every `manifest.dependencies`
867845
// range of the packages one install act would deliver, judged by the

‎packages/cli/src/commands/validate.ts‎

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,6 @@ import { findExtensionFieldSuffixRefusals } from '../utils/extension-field-suffi
8181
// [ADR-0146 D10, second rule] The field-patch target check's walk; the verdict
8282
// is the marketplace install door's own judge.
8383
import { findFieldPatchTargetRefusals } from '../utils/field-patch-targets.js';
84-
// [#28893] The ADR-0031 region-shape check: the automation engine's own
85-
// registration verdict (`FlowSchema` then the spec's `validateControlFlow`).
86-
import { findFlowRegionRefusals } from '../utils/flow-region-shape.js';
8784
// A field `picklist` that names no picklist the stack declares — refused, or
8885
// reported when the declaring package depends on packages outside the stack.
8986
// Walked the way the load path registers, like the refusal above.
@@ -754,35 +751,10 @@ export default class Validate extends Command {
754751
this.exit(1);
755752
}
756753

757-
// 3a-vi. [#28893] Flow region shape (ADR-0031): every `loop` body,
758-
// `parallel` branch and `try_catch` region, at every depth, must be
759-
// single-entry/single-exit and acyclic, and a `parallel` needs two
760-
// branches. The verdict is the engine's registration call
761-
// (`FlowSchema`, then the spec's `validateControlFlow`), so a flow
762-
// green here is one boot registers instead of logging
763-
// `[Automation] failed to register flow` and running without it; see
764-
// `utils/flow-region-shape.ts`.
765-
const regionRefusals = findFlowRegionRefusals(result.data as Record<string, unknown>);
766-
if (regionRefusals.length > 0) {
767-
if (flags.json) {
768-
await emitJson({
769-
valid: false,
770-
errors: regionRefusals,
771-
warnings: warningsSoFar(),
772-
conversions: conversionNotices,
773-
duration: timer.elapsed(),
774-
});
775-
this.exit(1);
776-
}
777-
const n = regionRefusals.length;
778-
console.log('');
779-
printError(`The automation engine would refuse to register ${n} flow${n > 1 ? 's' : ''} for a malformed region (ADR-0031)`);
780-
printBulletList(
781-
regionRefusals.map((r) => `${r.path} [${r.code}] ${r.message}`),
782-
{ noun: 'flow region refusal(s)', remedy: JSON_FULL_LIST_REMEDY },
783-
);
784-
this.exit(1);
785-
}
754+
// 3a-vi. [#28893] Flow region shape (ADR-0031) is judged by the rule
755+
// table above since #29049 (`flow-region-shape-invalid`,
756+
// `@objectstack/lint`'s `validate-flow-region-shape.ts`), so all
757+
// three authoring commands give the engine's registration verdict.
786758

787759
// 3b. [#3366] Installable-provider preflight — the shift-left of the
788760
// `serve`-time capability check. `os validate` previously only checked

‎packages/cli/src/utils/flow-region-shape.test.ts‎

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)