Skip to content

Commit f459d50

Browse files
committed
fix(spec,cli): F5-http patch round — named spec import in the CLI probe preload; no house-sentence marker in the D3 reason; the save door refuses a new flow (main's #23902), so the changeset says so
Claude-Session: https://claude.ai/code/session_01SgC7iCUX8y2TeJAvz8wcaw Co-authored-by: Claude <noreply@anthropic.com>
1 parent f16ce01 commit f459d50

3 files changed

Lines changed: 8 additions & 10 deletions

File tree

‎.changeset/23543-f5-http-callout-node-types-reserved.md‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,18 @@ Clause-②: yes (narrowing)
2020

2121
**The one-line fix:** change the node's `type` to `'http'`; the node's `id`, `label` and `config` stay as they are (the conversion never touched `config`, so the `http` contract judges it as written).
2222

23-
**What an author who still writes it sees.** The parse refuses the node at its own `type` path — a top-level node and a node inside a `loop`, `parallel` or `try_catch` region alike. `defineStack` throws `STACK_SCHEMA_INVALID` (422), and `os validate`, `os build` and `os lint` (whose config calls `defineStack`) print the issue:
23+
**What an author who still writes it sees.** The parse refuses the node at its own `type` path — a top-level node and a node inside a `loop`, `parallel` or `try_catch` region alike. `defineStack` throws `STACK_SCHEMA_INVALID` (422), `os validate`, `os build` and `os lint` (whose config calls `defineStack`) print the issue, and the metadata save door answers a NEW flow with `422 INVALID_METADATA` at the node's `type`, with or without an automation service, and stores nothing:
2424

2525
> Flow node `type: 'http_request'` was removed in @objectstack/spec 18 (ADR-0087 D2) — it is one of the three callout node types ADR-0018 unified into `http`, the loader rewrote it to `http` until this release, and the name stays reserved inside the open node namespace so no plugin can claim it (ADR-0018). Use `type: 'http'`. Change the value; the conversion never touched the node's `config`, so the `http` contract judges it as written.
2626
2727
The refusal is a `pattern` on `FlowNodeSchema.type`, so the published JSON Schema carries it too.
2828

2929
**`@objectstack/service-automation`:** `AutomationEngine.registerNodeExecutor` (and `registerNodeAlias`, which calls it) throws when the executor's `type` or its descriptor's `type` is one of the three names, and registers nothing. No node could ever reach such an executor: an authored node with the name is refused at parse, and a stored one is rewritten to `http` before it parses. A plugin that registered its own executor under one of these names fails at that call and needs a type of its own.
3030

31-
**No tool makes the rename.** The conversion belongs to protocol 11, below the migration floor, so `os migrate meta --from 17` applies no edit for it and `--write` writes none: it prints each such node among the refusals the migrated stack still has, at `flows.N.nodes.M.type`, and lists the D3 entry `flow-node-http-callout-types-reserved` as the hand edit.
31+
**No tool makes the rename.** The conversion belongs to protocol 11, below the migration floor, so `objectstack migrate meta` applies no edit for it and `--write` writes none: it prints each such node among the refusals the migrated stack still has, at `flows.N.nodes.M.type`, and lists the D3 entry `flow-node-http-callout-types-reserved` as the hand edit.
3232

3333
**Stored metadata needs no edit.** Stored-row rehydration, the automation engine's flow rehydration and the artifact-ingestion door inside its window still replay the conversion, so a `sys_metadata` flow row written with an old name keeps loading as an `http` node. The rewrite there is now unconditional: until 18 it skipped a node whose old name a live executor owned and reported a conflict, and the engine no longer lets such an executor exist.
3434

35-
**Not refused yet: a flow saved through the metadata API.** The save door replays every retired flow conversion before it judges a flow body, so a flow saved there with an old name is accepted — stored as `http` when an automation service canonicalizes it, stored as written otherwise and converted on every read. Whether that door should refuse retired flow spellings instead is an open decision covering every retired flow conversion, not this one alone.
36-
3735
## The retirement kit
3836

3937
- **The reserved-name table** `FLOW_RESERVED_NODE_TYPES` and its refusal `reservedFlowNodeTypeRefusal` (`@objectstack/spec/automation`), read by the flow parse, the engine's registration refusal and the conversion itself.

‎packages/cli/test/fixtures/live-conversion-probe.mjs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
*/
3131
import { createRequire } from 'node:module';
3232

33-
import * as esm from '@objectstack/spec';
33+
import { ALL_CONVERSIONS as ESM_CONVERSIONS } from '@objectstack/spec';
3434

3535
export const PROBE_CONVERSION_ID = 'cli-live-conversion-probe';
3636
export const PROBE_OLD_TYPE = 'probe_old_callout';
@@ -62,6 +62,6 @@ const probe = {
6262
};
6363

6464
const cjs = createRequire(import.meta.url)('@objectstack/spec');
65-
for (const table of new Set([esm.ALL_CONVERSIONS, cjs.ALL_CONVERSIONS])) {
65+
for (const table of new Set([ESM_CONVERSIONS, cjs.ALL_CONVERSIONS])) {
6666
if (!table.some((c) => c.id === PROBE_CONVERSION_ID)) table.push(probe);
6767
}

‎packages/spec/src/migrations/entries/semantic/18.flow-node-http-callout-types-reserved.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ export const entry: SemanticMigration = {
2121
+ '18. ADR-0018 unified `http_request`, `http_call` and `webhook` into the one `http` node, and through 17 '
2222
+ 'the loader rewrote an authored node typed with one of them to `http` with a notice. At 18 the flow parse '
2323
+ "refuses each as a node's `type`, with the prescription naming `http`: at `objectstack validate`, "
24-
+ '`objectstack build`, `objectstack lint` and `defineStack`, for a node in a loop, parallel or try_catch '
25-
+ 'region too. The automation engine also refuses to register a node executor under one of the three '
26-
+ 'names, so a plugin that registered its own executor under one fails at registration and needs a type of '
24+
+ '`objectstack build`, `objectstack lint`, `defineStack` and the metadata save door (a 422 for a new '
25+
+ 'flow), for a node in a loop, parallel or try_catch region too. The automation engine also refuses to '
26+
+ 'register a node executor under one of the three names, so a plugin that registered its own executor under one fails at registration and needs a type of '
2727
+ 'its own. No tool makes the rename for an authored source: the D2 conversion '
2828
+ '`flow-node-http-callout-rename` belongs to protocol 11, below the migration floor, so '
29-
+ '`os migrate meta --from 17` applies no edit for it and prints each such node among the refusals left '
29+
+ '`objectstack migrate meta` applies no edit for it and prints each such node among the refusals left '
3030
+ 'after the chain, at `flows.N.nodes.M.type`; change the value by hand. Stored flows need no edit: the '
3131
+ "automation engine's flow rehydration and every stored-row rehydration seam replay the retired "
3232
+ 'conversion, so a `sys_metadata` flow row written with an old name keeps loading as an `http` node. A '

0 commit comments

Comments
 (0)