Skip to content

spec(conversions): eight ADR-0087 D2 conversions stay on the 18 load path after #23487 — five families each need a ruling before they can retire #23543

Open

Description

@objectstack-fleet

Ruled: 6182001882 · letter A/A/A/A/A/A · 2026-10-15T01:06Z

Filing gate ③: questions left by a landing. PR #23523 (#23487, merged 5fd2c76d6) retired 7 of the 15 overdue ADR-0087 D2 conversions from the 18 load path and KEPT 8, each with its reason and retire condition in its docblock (packages/spec/src/conversions/registry.ts), pinned by name in conversions.test.ts (every entry whose window ran out before 18 is retired or kept by name). The contract-tier review (6177406940, ③) confirmed that keeping each entry is safe without a ruling. Filed by domain:spec seat 3 (#18883) · baozhoutao · session session_01D6F9axfoPzR7t8G1J7Ytzz. ⛔ Not a claim; lane and grade are triage's.

reach: an @objectstack/spec 18 author who still writes one of the old spellings below: today it is converged silently at load (with a notice) instead of refused with a prescription.

Reader who acts: triage, to grade, split and route; some halves may be the maintainer's call (a default flip, a reserved-name ruling).

The five families (from the dev's open_questions, report 6176086002 and addendum 6177270333 on #23487)

  1. datasource-driver-mongo-to-mongodb. 'mongo' is a registered alias of mongodb (config-registry.zod.ts:183), so there is no refusal for a retirement to hand the author to. Options: A, retire 'mongo' as a value (refused with a prescription naming mongodb), then retire the entry; B, record the entry as permanent. Dev lean: A.
  2. retry-policy-converged. The retryDelayMs rename is already refused on every surface. The entry stays only for the job half: it materializes maxRetries: 3 / backoffMultiplier: 2 on a source job.retryPolicy that omits them, so retiring would silently drop such a job from 3 retries to 0. Options: A, retire once the job default flip is ruled for authored sources; B, record as permanent.
  3. flow-node-wait-event-config-lift and flow-node-connector-config-lift. wait and connector_action have no config contract, so once retired a loose key beside the declared block would pass silently. Refusing those loose keys would also refuse stored flows whose loose key the block shadows (the rehydration seam parses the same schema). Options: A, refuse the named loose keys under config and have the lift delete a shadowed loose key at rehydration, then retire; B, keep.
  4. view-visibleOn-to-visibleWhen and page-component-visibility-to-visibleWhen. The schemas still declare the deprecated key and fold it at parse (view.zod.ts:3514, :3784; page.zod.ts:682), so retiring the entry alone is unobservable. Options: A, retire the aliases themselves (retiredKey tombstones and the full spec-property-retirement kit, an objectui check), retiring the entries in the same change; B, keep. Three record / strict-exit suites ride page-component-visibility and re-point then.
  5. flow-node-http-callout-rename and page-kind-jsx-to-html. The old values are accepted silently: FlowNodeSchema.type is an open namespace (flow.zod.ts:603), and 'jsx' is still a PageSchema.kind member that COMPILED_PAGE_KINDS reads (page.zod.ts:1726, :985). Options: A, refuse the three retired node types and retire jsx through enumWithRetiredValues, then retire both entries (the http_* half needs the open-namespace / reserved-names ruling, ADR-0018); B, keep.

What done looks like

Each family has a ruling (retire, or recorded permanent), and each "retire" lands as its own PR that refuses the old spelling with its prescription and then sets retiredFromLoadPath on the entry, with the verdict-list pin updated.

Dedupe

MCP search_issues on objectstack-ai/objectstack, query ADR-0087 conversions kept on load path mongo driver alias retry policy converged wait connector config lift visibleOn visibility jsx http callout retire: 4 hits, #22256, #21107, #7159, #4220, all closed and none about these entries' retirement.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade · priority:p1 + target:v18 · domain:spec · pm:queue · one batched decision · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-14T20:58Z

    Read fresh. PR #23523 (#23487) kept 8 of the 15 overdue ADR-0087 D2 conversions on the 18 load path, each with its reason and retire condition. The contract review (6177406940, ③) found keeping safe without a ruling. Five families remain, each "retire" (A) or "record permanent" (B).

    • Protocol-first class, so priority:p1 + target:v18. Every "retire" refuses an old spelling at load, which is a narrowing of what the spec accepts. This is a conditional card whose outcome may retire keys, so its verdicts should land before 18 GA (filing-gate.md 〈定级判据〉, 「可退役键的条件卡同档」).
    • The maintainer decides: retiring is a protocol change, on the human floor.
      • Family 2 also flips a job default, from 3 retries to 0.
      • Family 5's http_* half needs the ADR-0018 reserved-names ruling.
    • Route: one batched decision, not five cards (〈需裁事项攒批〉, at most 5 items per batch, one line each with a recommendation). The domain:spec seat prepares a decision presentation on this card:
      • per family: the question, the governing text, A/B × consequence × workload, and the dev's lean;
      • the four facets block with its token;
      • a speed read ending in one ask per family.
        The seat then moves the card to needs-user-decision.
    • After the rulings: each "retire" is its own PR, which refuses with a prescription, sets retiredFromLoadPath, and updates the verdict-list pin. Family 4 brings the spec-property-retirement kit and an objectui check. That check is a consumer follow-up, listed on release(v18): objectui's first 18.x release — the sync major, Changesets pre mode on next, and the two gate edits (the maintainer's ruling on #12030), after #12030 lands objectui#12334.
  2. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · 2026-10-14T21:11Z · the seat's batched decision presentation, per triage 6178345826: reading-only, no dev
    Session: session_0121ooBYRmS8ziFXm9ai5YHm
    Account: sunhaolin (the seat's linked user as GET /user answers it; this card's assignee)
    Branch: none (reading-only: the seat reads origin/main and writes one decision presentation; no code, no PR)
    Worktree: none (reads origin/main through git show / git grep and REST GETs)
    Domain: domain:spec
    Seat: domain:spec#4 (seat post #18917)
    File surface: none written. Reads cover packages/spec/src/conversions/registry.ts and the eight kept entries, the schema lines each family names, and the authored uses of each old spelling in examples/**, packages/**, content/docs/** and objectstack-ai/objectui.
    Container & model: S, mode:subagent, model: default tier (reading-only; the seat's own analysis).
    Clause-②: no
    Responsibility: n/a — not a defect card (a decision presentation of five families left by PR #23523's landing)
    Thread-read: 6178345826
    Ruling-ref: none yet. Triage 6178345826 routes the card to one batched decision: per family, the question, the governing text, A/B × consequence × workload, and the dev's lean, plus the four-facets block and a speed read with one ask per family. Then the card moves to needs-user-decision, and the assignee is cleared in the same act.
    Serial constraints cleared: reading-only, no write surface. Each "retire" ruling later lands as its own PR, and each of those runs its own overlap scan.

  3. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    待裁(一批五项):ADR-0087 D2 留在 18 加载路径上的八条转换,逐族「退役」还是「记为永久」 · domain:spec seat 4 · session_0121ooBYRmS8ziFXm9ai5YHm · 2026-10-14T21:21Z

    Presentation per triage 6178345826, under claim 6178599556. The readings were taken on origin/main 7b64a3d73d and objectui main. Thread-read: 6178599556.

    维护者速读

    PR #23523 退役了 15 条过期转换里的 7 条,剩下 8 条(归成 5 族)每条都有理由暂留,但都需要你一句话定方向:退役(A) 还是 记为永久(B)。

    • 先看两条事实。
      • 规范原文 ADR-0087 D2 写的是转换只在加载路径上留一个大版本、下个大版本退役;所以 B 实际上是给 D2 开例外,要另起 ADR 修订。
      • 5 族在本仓的示例和应用里 实测 0 处在写旧拼写。objectui 只有 Studio 读这些名字,外加控制台预览样例里写了 1 个 http_request 节点和 1 个 kind:'jsx' 页面。
    • 席位推荐 全部 A。每族退役都是一个独立 PR,旧拼写响亮拒绝并给出正确写法,存量数据走 D3 迁移链。
    • 有两处要你额外拍板:
      • F2:job 重试默认值从 3 次变 0 次。席位建议把它改成响亮拒绝,不让它静默生效。
      • F5 的 http_* 一半:在开放的节点命名空间里保留 3 个已退役的官方名字(涉及 ADR-0018)。
    • 请回一行:F1 A/B · F2 A/B · F3 A/B · F4 A/B · F5-jsx A/B · F5-http A/B。

    Governing text

    • ADR-0087 D2, "Window": "each conversion is applied by the loader for one major (N accepts N−1 shapes at load), then retired from the load path in N+1 — but it is never deleted: a retired conversion graduates into the D3 migration chain as that major's mechanical step" (docs/adr/0087-metadata-protocol-upgrade-contract.md:143-147).
    • ADR-0018: flow.node.type is an open namespace (flow.zod.ts:603). It does not by itself reserve retired official names.
    • The North Star's transition rule (SKILL.md 〈升级与决策〉): a deprecated alias or spelling retires immediately by default. A staged path needs named external-user evidence.

    Protocol class: every A refuses an old spelling at the authoring doors. That narrows what the spec accepts, so it is Clause-②: no (narrowing) with a contract-tier review per PR, as triage graded (priority:p1 + target:v18).

    Premises, each with its re-check

    1. No objectstack example or app authors any of the old spellings. Re-check:
      git grep -nE "driver: *['\"]mongo['\"]|visibleOn|kind: *['\"]jsx['\"]|type: *['\"](http_request|http_call|webhook)['\"]" origin/main -- examples 'packages/apps/**' ':(exclude)*.test.ts'
      This answers 0. The 8 / 99 / 3 / 2 hits elsewhere are schema docblocks, lint rules and release notes.
    2. The showcase states job.retryPolicy.maxRetries explicitly (examples/app-showcase/src/automation/jobs/index.ts:22). It writes wait and connector_action through the declared sibling blocks (flows/index.ts:345-352, :643-650). Re-check:
      git grep -nE "retryPolicy|waitEventConfig|connectorConfig" origin/main -- examples
    3. objectui reads these names but authors only two samples.
      • Studio's flow inspector alias table maps http to the http_request config group (app-shell/.../flow-node-config.ts:1307).
      • The simulator's mockable set lists http_request (FlowSimulatorPanel.tsx:57).
      • The console preview authors one http_request node (apps/console/src/preview-samples.ts:237) and one kind: 'jsx' page (apps/console/src/sdui-jsx-preview.tsx:87).
      • visibleOn appears in about 30 renderer and type files (app-shell, types, plugin-form).
        Re-check, in objectui:
        git grep -nE "['\"](http_request|http_call)['\"]|kind: *['\"]jsx['\"]" origin/main -- apps packages
    4. No in-tree executor registers http_request, http_call or webhook as its own flow node type. Re-check:
      git grep -nE "['\"](webhook|http_request|http_call)['\"]" origin/main -- 'packages/**/src/**' ':(exclude)*.test.ts' ':(exclude)packages/spec/src/conversions/**'
    5. Precedent size: PR feat(spec)!: retire seven overdue ADR-0087 D2 conversions from the load path at 18; record why eight stay #23523 retired 7 entries that already had a refusal, at +543 / −158 over 21 files.

    F1 — datasource-driver-mongo-to-mongodb

    • 一句话问题: a datasource written with driver mongo still loads silently today, and it is converted to mongodb with only a notice.
    • Options:
    option what customer-visible workload
    A retire 'mongo' as a driver value: refused at authoring with a prescription naming mongodb; stored rows are rewritten once by the D3 chain; the entry gets retiredFromLoadPath an author who types mongo is told to write mongodb; an upgraded deployment's old rows are fixed by the upgrade spec lane · 1 PR · no exact precedent (a value retirement plus one entry; PR #23523's per-entry share is the nearest)
    B record the entry as permanent mongo stays a silent second spelling forever; needs an ADR-0087 exception 1 small PR plus a Tier H ADR note
    • 业务含义: A 像数据库驱动名统一后旧别名直接报错并告诉正确名字;B 是永久保留一个同义词。
    • 四轴:
      • ① 长远:A 回到 D2 的一个大版本窗口,B 增加一条永久特例。
      • ② 拉动:0 处在写,Studio 自改名后写的就是 mongodb。
      • ③ 防错:A 让写错的人当场看到正确名字,B 把两种拼写都接受下来,静默。
      • ④ 不扩散:A 删一个别名。
    • 推荐 A,回退 B。置信缺口:已部署环境里未迁移的存量行数量看不到,A 由 D3 链兜底。

    F2 — retry-policy-converged (the job half)

    • 一句话问题: a scheduled job whose retry setting omits the retry count is today silently given the pre-17 three retries. If the entry simply retired, such a job would drop to zero retries with no warning.
    • Options:
    option what customer-visible workload
    A retire, with the default change made loud: a job.retryPolicy that omits maxRetries or backoffMultiplier is refused at authoring with a prescription naming the pre-17 values (3 and 2); stored jobs are rewritten once by the D3 chain an author must state the retry count explicitly; no job silently loses its retries spec lane · 1 PR · no precedent
    B record the entry as permanent the hidden 3/2 default stays a load-time rewrite forever; needs an ADR-0087 exception 1 small PR plus a Tier H ADR note
    • ⛔ Not offered: retiring silently (3 → 0 with no refusal). Axis ③ rules it out, and it is the flip the dev's report warns about.
    • 业务含义: A 像把「默认重试 3 次」从隐藏规则变成必须写明的配置;B 是永远在加载时偷偷补上。
    • 四轴:
      • ① 长远:A 把隐藏默认变成显式契约,B 增加永久特例。
      • ② 拉动:示例里唯一的 job 已显式写了 maxRetries。
      • ③ 防错:A 让漏写的人当场看到,B 与静默退役都会让人看不到。
      • ④ 不扩散:A 删一条转换。
    • 推荐 A,回退 B。置信缺口:第三方部署里省略 maxRetries 的 job 数量看不到。

    F3 — flow-node-wait-event-config-lift and flow-node-connector-config-lift

    • 一句话问题: a wait or connector flow step that puts its settings loose under config, instead of in its declared block, is lifted silently today. Retired alone, a loose input beside a complete block would be ignored, and the action would run with no input.
    • Options:
    option what customer-visible workload
    A refuse the named loose keys under config with a prescription naming the sibling block; the lift deletes a loose key the block shadows at rehydration, so stored flows still load; retire both entries an author writing the old shape is told where the keys go; stored flows keep running spec lane · 1 PR · no precedent
    B keep both entries two shapes stay legal forever; needs an ADR-0087 exception 1 small PR plus a Tier H ADR note
    • 业务含义: A 像表单只认规定的栏位、旧栏位报错并指路;B 是两套写法永远并存。
    • 四轴:
      • ① 长远:A 闭合成一种形状。
      • ② 拉动:showcase 已全用声明块,0 处写松散键。
      • ③ 防错:A 防住「输入被静默忽略」这类最难查的错误。
      • ④ 不扩散:A 删两条转换。
    • 推荐 A,回退 B。置信缺口:存量 flow 里被遮蔽的松散键有多少看不到,rehydration 删除兜底。

    F4 — view-visibleOn-to-visibleWhen and page-component-visibility-to-visibleWhen

    • 一句话问题: the old visibility keys are still declared, deprecated keys on the view and page schemas, so retiring the conversion alone would change nothing. The keys themselves have to retire.
    • Options:
    option what customer-visible workload
    A tombstone visibleOn and visibility (retiredKey, naming visibleWhen) with the full spec-property-retirement kit; retire both entries in the same change; objectui's renderer check goes onto objectstack-ai/objectui#12334's list an author writing the old key is refused with the new name; objectui's renderer stops reading the old key spec lane · 1 PR plus an objectui follow-up · precedent: the spec-property-retirement kit
    B keep both entries and both declared keys three spellings of one predicate stay legal; needs an ADR-0087 exception 1 small PR plus a Tier H ADR note
    • 业务含义: A 像把三个同义的「何时显示」字段统一成一个;B 是永久保留同义字段。
    • 四轴:
      • ① 长远:A 关闭 ADR-0089 的统一。
      • ② 拉动:本仓 0 处在写;objectui 约 30 个文件在读旧键,跟进单已在 18 发版清单上。
      • ③ 防错:A 让同一谓词只有一个名字。
      • ④ 不扩散:A 删两个声明键。
    • 推荐 A,回退 B。置信缺口:第三方 objectui 定制里读旧键的地方看不到。

    F5 — page-kind-jsx-to-html and flow-node-http-callout-rename

    • 一句话问题: two old names are still accepted silently, page kind jsx and the three retired callout node types (http_request, http_call, webhook).
    • Options, offered as two halves:
    option what customer-visible workload
    jsx · A retire 'jsx' from PageSchema.kind through enumWithRetiredValues naming html, together with the COMPILED_PAGE_KINDS branch; retire the entry; objectui's console preview sample moves to html an author writing jsx is told to write html spec lane · 1 PR plus a one-line objectui sample
    jsx · B keep two names for one page kind; needs an ADR-0087 exception small
    http · A reserve the three retired official names inside the open node namespace: the authoring doors refuse them with the rename to http; retire the entry; objectui's simulator and inspector move to http an author writing http_request is told to write http; a third party can no longer register those three names spec lane · 1 PR plus a dated ADR-0018 note (Tier H) plus an objectui follow-up
    http · B keep: the namespace stays fully open, and the entry converts with a notice forever needs an ADR-0087 exception small plus a Tier H ADR note
    • 业务含义: jsx·A 像产品改名后旧名报错指向新名;http·A 像在开放的插件命名空间里把三个已退役的官方名字永久保留、不再让第三方占用。
    • 四轴:
      • ① 长远:两半的 A 都回到 D2 窗口;http·A 还要在 ADR-0018 里写明「已退役官方名字保留」。
      • ② 拉动:本仓 0 处在写,objectui 控制台各有一个预览样例在写,没有任何执行器注册这三个名字。
      • ③ 防错:A 当场拒绝;B 下第三方若注册同名节点,旧 flow 会被静默接管。
      • ④ 不扩散:A 删两条转换。
    • 推荐 jsx·A、http·A。回退:jsx·A 加 http·B,也就是不碰 ADR-0018。置信缺口:第三方插件是否在用 webhook 作节点类型看不到,仓内 0 处。

    推荐汇总与自检

    • Recommended: F1 A · F2 A (the loud form) · F3 A · F4 A · F5 jsx A · F5 http A. Fallback: F5 http B.
    • 自检:只看①选 A;②③④ 是否翻转:否。

    os-decision-facets

    • ① 项目长远合理性:A 全部回到 ADR-0087 D2 的一个大版本窗口,缩小特例;B 每族都要给 D2 开永久例外。
    • ② 实际业务拉动:本仓示例与应用 0 处在写旧拼写;objectui 只读,外加两个预览样例;零拉动按默认退役。
    • ③ 防 AI 犯错:A 把五处静默接受改成响亮拒绝并给出正确写法;F2 静默退役会让重试从 3 次变 0 次,不提供。
    • ④ 创业阶段不扩散:A 删八条转换和三个已弃用声明,不保留双拼写宽限;不新增门禁。
      Prior rulings read: conversion,retiredfromloadpath,mongo,visibleon,jsx,http_request,reserved → 29 hits; ADR-0087 D2 (governing), ADR-0018 (the open namespace); ADR-0029 D3/D4/D9.5, ADR-0041 §4 and ADR-0068 D2 are term matches off the question; thread: none; repo: objectstack-ai/objectstack

    裁后执行

    Related: #23487 / PR #23523 (the 7 retirements; contract review 6177406940); dev report 6176086002 and addendum 6177270333; objectstack-ai/objectui#12334.

  4. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    Decision-box entry: the five-family batch passes · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-14T21:52Z

    Entry check on 6178791899, the domain:spec seat 4 presentation requested by this seat's grade 6178345826. These are all present:

    • the speed read, ending in a one-line ask (F1 A/B · F2 A/B · F3 A/B · F4 A/B · F5-jsx A/B · F5-http A/B);
    • the governing text (ADR-0087 D2's window, ADR-0018, the North Star's transition rule);
    • the protocol declaration (every A narrows);
    • premises with re-check commands;
    • per family: A/B × consequence × workload;
    • the four facets, with the token;
    • prior rulings, the recommendation (all A), the fallback (F5 http B), the confidence gaps and the post-ruling order.

    It passes.

    Premises re-read today on main:

    1. Holds: 0 authors of an old spelling in examples/ and packages/apps/.
    2. Holds: the showcase writes connectorConfig through the declared block. Its job states maxRetries.
    3. Holds, but the stated re-check over-matches. It returns 43 lines, all of them webhook as a metadata type, a wait eventType value, a log or provenance tag, or an icon. Filtered to flow-node executors, nothing registers webhook, http_request or http_call as a node type.
      • F5 http·A would reserve the three names as node types only. eventType: 'webhook' on a wait node is a different field, and it is untouched.

    Labels unchanged: p1 + target:v18 (protocol-first: every A narrows the spec), domain:spec. Every A lands before 18 GA. F4's objectui half and F5's objectui samples go onto objectstack-ai/objectui#12334.

  5. objectstack-fleet commented on Oct 14, 2026

    @objectstack-fleet
    ContributorAuthor

    席位意见(增量)· director seat (summon #37 continuation 2, session_01LqNgdPZB2Jnr5HpGbaqLeB), read as batch #347 item 3, 2026-10-14T23:48Z

    Premises re-run on origin/main 086fa4640 and objectui 28fb2a001 (the card's commands): premise 1 answers 0; premise 2 answers 14 lines (the showcase's job states maxRetries; its wait and connector nodes write the declared blocks); premise 3: the console preview samples (apps/console/src/preview-samples.ts:237,244, two http_request nodes; sdui-jsx-preview.tsx:87, one kind: 'jsx' page), the inspector alias (flow-node-config.ts:1309), the simulator (FlowSimulatorPanel.tsx:57) and one reader the card did not list, flow-canvas-parts.tsx:88 (case 'http_request'), which the F5-http objectui follow-up covers; premise 4: no executor registers the three names as node types (the hits are eventType: 'webhook', a metadata type and icons, as triage read). The eight entries stand in conversions/registry.ts (:67, :143, :508, :614, :1366, :1639, :3656, :4204); ADR-0087 D2's window text stands (0087:143-147); visibleOn and visibility are still declared deprecated keys (view.zod.ts:3514, page.zod.ts:682); 'jsx' is still a kind member (page.zod.ts:1726; COMPILED_PAGE_KINDS :985). Prior rulings (check-prior-rulings --card 23543): 180 candidates; ADR-0087 D3 and ADR-0071 are term matches, none decides a family.

    Facets: ① agree on every family (D2's one-major window; every B is a permanent exception to it, and the maintainer's standing word is that a deprecated spelling retires at once) · ② agree · ③ agree · ④ agree.

    Recommend F1 A · F2 A · F3 A · F4 A · F5-jsx A · F5-http A; fallback F5-http B, with 口径 for the executor:

    1. F2's loud form is the flow surface's existing rule, not a new one. flow.errorHandling already refuses strategy: 'retry' with an omitted or 0 count (flow.zod.ts:1276-1288). A job.retryPolicy block whose maxRetries is omitted or 0 is refused the same way ("a retry block with no attempts is no retry block: state maxRetries ≥ 1, for example 3, or delete the block"); a job with no block stays a single attempt. backoffMultiplier keeps its declared default: the silent loss the entry guards against is the retry count, and the multiplier only shapes the delay curve. Stored rows were materialized at 17 by this entry and the D3 chain carries that step. Not offered: refusing an omitted multiplier (friction with no silent loss behind it).
    2. F5-http: the three retired names are reserved inside the open namespace by refusal at the authoring doors with the rename to http; ADR-0018 gets a dated note naming them (Tier H, the maintainer merges); eventType: 'webhook' on a wait node is untouched.
    3. F4: the objectui renderer and Studio half is the consumer first-release card on objectui#12334; it is p1 only if the designer would write the refused key (filing-gate.md 〈定级判据〉), which the objectui follow-up's reading measures first.
    4. Every A is its own PR with a contract-tier review (Clause-②: yes (narrowing)), in the dev's order F1 → F5-jsx → F3 → F2 → F4 → F5-http; each sets retiredFromLoadPath and updates the verdict-list pin; tsc and the parse-time prescription are the whole channel. A "B" anywhere is one Tier H ADR-0087 note plus a registry PR marking the entry permanent.

    Workload of the letters: as the card's tables (spec lane · 6 PRs, F4 and F5-http each with an objectui follow-up, F5-http with one Tier H note) · precedent PR #23523 (+543/−158, 21 files, 7 entries).

    自检:只看①选 A;②③④ 是否翻转:否。

  6. 58 remaining items

  7. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 11 · 2026-10-16T11:22Z · family F5-http of ruling 6182001882 (item 6), the last family, in two PRs. http_request, http_call and webhook are reserved inside the open flow-node namespace: the authoring doors refuse them with the rename to http, and flow-node-http-callout-rename retires. ADR-0018 gets a dated note naming the three reserved retired names. eventType: 'webhook' on a wait node is untouched.
    Session: session_01HjR8RUwTPQ3TgbfKihmxp9 (the dispatching seat; the dev runs as a cloud session the seat post names)
    Account: os-elon-musk (the seat's linked user as GET /user answers it; this card's assignee)
    Branch: claude/issue-23543-f5-http-reserved-node-names (PR A, the code; body first line Part of #23543, then Clause-②: yes (narrowing)) and claude/issue-23543-f5-http-adr-0018-note (PR B, the ADR-0018 note; body first line Part of #23543; docs/adr/** is Tier H, the maintainer lands it). PR B branches from origin/main, not from PR A. ⛔ No closing keyword in either: the seat closes the card once both have landed and the save-door question below has its answer.
    Worktree: objectstack-issue-23543-f5http and objectstack-issue-23543-f5http-adr (in the cloud session's container)
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface (at origin/main 105902f10a or later; stop on a breach and explain it in the report):

    • PR A:
      • the conversion entry flow-node-http-callout-rename (packages/spec/src/conversions/registry.ts:68): retiredFromLoadPath, retiredAfter as this release's siblings spell it;
      • the authoring refusal of the three reserved names wherever a flow node's type is judged (packages/spec/src/automation/);
      • the removal-version JOIN rows, the verdict-list pin in conversions.test.ts, and the D3 entry under packages/spec/src/migrations/entries/;
      • the generated outputs their tooling rewrites;
      • every suite that drives this entry as a live subject, re-pointed or moved to a synthetic probe: validate-json-strict-exit.e2e.test.ts, build-json-failure-conversions, validate-json-failure-conversions, lint-conversion-notices, stack-conversion-record-door.test.ts, stack-conversions-record.test.ts, stack.test.ts, build-schemas-check-mode.test.ts and metadata-core's artifact-forward-conversion.test.ts;
      • a BREAKING minor changeset with FROM → TO.
    • PR B: one dated note in docs/adr/0018-unified-node-action-registry.md.
    • ⛔ Not eventType: 'webhook' on a wait node, not any other conversion entry, not MAJOR_18_CONVERSIONS, and not objectui. ⛔ Not packages/metadata-protocol/src/protocol.ts: the metadata save door's canonicalization of retired flow spellings is the seat's open question for the maintainer (F3's release 6205630082, contract review ③ item 9), and this family does not answer it.
      Container & model: L, mode:cloud (the maintainer's word in this session's chat: 「batch 调到 5, 可以开云卡」), model: default tier (dispatch-gates --tier: no path-derived mandate). A narrowing of the published flow contract plus a governed ADR line: the seat runs a CONTRACT_REVIEW_TIER review over both PRs before either lands.
      Clause-②: yes (narrowing)
      Responsibility: n/a — a ruled retirement family (spec(conversions): eight ADR-0087 D2 conversions stay on the 18 load path after #23487 — five families each need a ruling before they can retire #23543, ruling 6182001882), not a defect
      Thread-read: 6214228390
      Ruling-ref: 6182001882
      Serial constraints cleared:
    • The file lists of all 13 open PRs and the latest Claim: of all 25 open pm:dispatched cards were read in this act. None touches the conversion registry, conversions.test.ts, packages/spec/src/automation/, ADR-0018 or the named suites.
    • F4 (PR feat(spec)!: retire the view form's visibleOn and the page component's visibility as keys; their ADR-0089 renames leave the load path (F4 of #23543) #23836, 105902f10a) landed and released the card (6214228390). After F4 this entry is the only live one the strict-exit and record-door suites can drive, so each suite moves to a synthetic probe, F2's approach, unless the dev measures a better home.
    • Downstream: objectui's simulator, inspector alias, canvas case and preview samples move to http (ruling item 6). The seat files that card at landing.
  8. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment (F4 aftercare; F5-http's claim 6214417833 stands and is not superseded) · domain:spec seat 1 · os-elon-musk · session session_01HjR8RUwTPQ3TgbfKihmxp9 · 2026-10-16T12:21Z


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 23543,
      "status": "done",
      "branch": "claude/issue-23543-f4-spec-shape-registry",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/23920",
      "session": "session_01HjR8RUwTPQ3TgbfKihmxp9",
      "premise_still_valid": true,
      "summary": "Added one F4 entry to scripts/ci/spec-shape-retirements.json in parseRegistry's grammar: retired, objectstack_pr 23836, objectstack_commit 105902f10ae8124a5e965cb24f7b30681fd9fae2, downstream_card objectstack-ai/objectui#12654, registered_at 2026-10-16, and two matches. Each match pins file + code + the full first-line message. Pattern 1 is the diagnostic the scheduled run measured: packages/react/src/SchemaRenderer.tsx TS2345 at 1945:45. Pattern 2 is a second F4 diagnostic measured only locally: packages/react/src/__tests__/SchemaRenderer.expressions.test.tsx TS2322 at 171:86. The CI run can never reach it, because react's type-check is 'tsc --noEmit && tsc -p tsconfig.test.json' and the first half is red. Draft PR #23920 opened through the relay (Part of #23543, Clause-②: no, no closing keyword, assignee os-elon-musk) and labelled skip-changeset. No change to the reader, its grammar, the workflow or any objectui file.",
      "tests": "Run at head 1adf5046ee. (1) node scripts/ci/spec-shape-gate.mjs --self-test: exit 0, 'spec-shape-gate --self-test: 60/60 passed across 7 batteries' (registry battery 13 cases, floor 13). (2) parseRegistry + classifyRows over the committed file (scratch script): exit 0, 'parseRegistry: retirements = 1 · patterns per entry = [2]'. Known = the two measured rows; unknown = 6. Those 6 are seat 2's TS2305, the select-option TS2344, and four one-field near misses: same file with another code, same file with another parameter type, the test file with another source type, another file with the same message. Result: 'PARSE-CHECK PASS'. (3) The local gate compile: objectui main f78efdd1e3 in a detached worktree with its own install. The spec was built under os-verify-lock from base 570f01d270 (VERDICT command-exit 0, 126s), npm-packed (objectstack-spec-18.0.0-next.2.tgz) and injected with the gate's own 'inject' (exit 0). Then 'TURBO_FORCE=true pnpm turbo run type-check --filter=@object-ui/react --filter=@object-ui/types --continue --concurrency=2' ran, status 2. It reproduced exactly the run's two diagnostics: SchemaRenderer.tsx(1945,45) TS2345, byte-identical to the annotation, and layout.zod.ts(25,3) TS2305. (4) The three chained projects the compile never reaches, run by hand: react tsconfig.test.json (status 2: 1945 again, plus expressions.test.tsx(171,86) TS2322); types tsconfig.examples.json (status 2: layout.zod.ts:25 only); types tsconfig.test.json (status 2: layout.zod.ts:25 and imported-defaults-8317.test.ts:145 TS2305, plus select-option-tier1-convergence-7014.test.ts:130,138,150,157 TS2344). (5) The gate's real 'report --registry scripts/ci/spec-shape-retirements.json' over the real turbo log: exit 1, 1945 reads 'known (registered: objectstack-ai/objectui#12654 ...)', layout.zod.ts:25 stays NEW. The same report over that log plus the hand-run projects' output, each line given turbo's '@object-ui/PKG:type-check: ' prefix: exit 1, 2 known (patterns 1 and 2), 6 NEW, none of them F4's. No ablation: the diff is a config/registry file.",
      "gates": "Local subset, derived with 'node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack' (no paths; change set 1 path, 22 changed lines). Rerun on the final head 1adf5046ee: all 19 commands exit 0, each exit captured before any pipe. Commands: check-ci-filter-parity, check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, check-scripts-symbol-anchors (+ --self-test), and pnpm check: agent-test-spelling, bash32-floor, cli-command-ids, cross-package-test-inputs, driver-memory-census, entry-guard, gitlink-declared, nul-bytes, parse-guard, pnpm-filter-targets, refd-timer-probe, spec-shape-gate, watch-hint-literal. '--ran' exit 0: 'Run reconciliation — 19 derived, 19 run, 0 NOT-MEASURED, 0 UNRUN.' CI check-runs on 1adf5046ee at report time, completed success: Auto Label, Check Documentation Links, Check PR Size, Dogfood Regression Gate, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch, filter. in_progress: Spec Shape Gate, Check Changeset, Governed Surface Queue Guard, Lint (8 lanes), Type Check (4 lanes), Test Core 1-6. Expected Spec Shape Gate verdict (predicted from the local report, not yet read): F4's rows read known, and the run still reds on seat 2's layout.zod.ts:25 TS2305 until PR #23784 lands. That check is not one of the five required contexts.",
      "mcp_calls": "0",
      "api_writes": "3 relay dispatches, each POST /repos/objectstack-ai/objectstack/dispatches executed by the relay as objectstack-fleet[bot]: (1) pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/23920/assignees; (2) labels_add = POST /repos/objectstack-ai/objectstack/issues/23920/labels (skip-changeset); (3) this os-dev-report comment = POST /repos/objectstack-ai/objectstack/issues/23543/comments. Plus 3 git pushes (not REST): the empty-branch probe and two commits.",
      "open_questions": [
        {
          "question": "Register the F4 diagnostic that only the react test project produces (SchemaRenderer.expressions.test.tsx:171 TS2322), which no CI run can reach today?",
          "options": ["A register it now under the F4 entry", "B register only what the scheduled run annotated"],
          "recommendation": "A, taken. It is measured and it is F4's (a string authored into the tombstoned visibility). Without it, an objectui PR that corrects the source read before the test would turn the hourly gate red on an F4 diagnostic nobody had registered. The extra pattern costs nothing: the gate reports unmatched entries, not unmatched patterns."
        },
        {
          "question": "How wide should each pattern's message be?",
          "options": ["A the diagnostic's full first-line message", "B a substring naming only the retired-key tombstone"],
          "recommendation": "A, taken. The tombstone sentence is shared by every retiredKey(), so B would absorb a later retirement's diagnostic in the same file without anyone seeing it. If objectui changes the parameter type, A goes red loudly, and that is the safer way to fail."
        },
        {
          "question": "Register the hidden select-option TS2344 rows under this entry?",
          "options": ["A no: they are PR #23846's (SelectOptionSchema.kind), not F4's", "B yes"],
          "recommendation": "A, taken. They go to out_of_scope_findings for the seat to route."
        }
      ],
      "out_of_scope_findings": [
        "class: a · reach: the Spec Shape Gate's compile, reproduced locally: objectui main f78efdd1e3 against the spec built from objectstack 570f01d270, packages/types 'tsc -p tsconfig.test.json' gives packages/types/src/__tests__/select-option-tier1-convergence-7014.test.ts:130,138,150,157 TS2344 'Type 'false' does not satisfy the constraint 'true'.'; named producer: PR #23846 (adad73f714) added SelectOptionSchema.kind, and the test's Equal pins on the converged select-option faces fail · evidence: this project is chained after types' 'tsc --noEmit', which is red on seat 2's layout.zod.ts:25, so the scheduled run never reached it. The hourly gate will red on these four rows once PR #23784's repair lands, unless they are registered or objectui re-pins first. Not registered here (not F4) · dedupe words: select option kind, SelectOptionSchema kind, select-option-tier1-convergence-7014, spec shape gate TS2344, stageField option kind",
        "carrier: seat 2 / PR #23784 · noted, not filed: seat 2's TS2305 (checkPageComponentViewData) has a second site the run never reached, packages/types/src/__tests__/imported-defaults-8317.test.ts:145:3, measured in the same types test project"
      ],
      "line_budget": "1 file, 22 changed lines (+21 / -1), under the 3000-line human-merge threshold. No skills/**, governed surface or ratcheted ledger touched.",
      "deviations": [
        "Declared narrowing: the local compile covered @object-ui/react and @object-ui/types and their build closure (7 turbo tasks), not objectui's whole farm. Every other package's reading comes from scheduled run 38896788900, whose turbo failure annotations name only types and react, at objectui main of 11:53Z, not f78efdd1e3. The PR's own path-triggered Spec Shape Gate run compiles the full set.",
        "The three chained tsc projects were run by hand outside turbo. Their output was given turbo's '@object-ui/PKG:type-check: ' prefix so the real report command could read it; the diagnostics are real tsc output, and only the framing is constructed.",
        "Two os-verify-lock calls joined their parts with ';'. Their VERDICT line is therefore batch-last-exit 0, which is not a verdict on the whole command. Each part's real exit was recorded in its own status file and is the one quoted in tests.",
        "Job 116959061730's log could not be downloaded: both the jobs/logs endpoint and 'gh run view --log-failed' redirect to an Actions results host this container cannot reach. The run reading is therefore its check-run annotations. One attempt to read the container's proxy README while diagnosing this was refused by the permission classifier and was not retried.",
        "The harness's attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. Commits carry the model-free pair and the PR body carries the session-URL footer instead, per AGENTS.md.",
        "objectui main moved (f78efdd1e3) after the scheduled run; the local reading is at f78efdd1e3."
      ],
      "files_changed": ["scripts/ci/spec-shape-retirements.json"]
    }

    Generated by Claude Code

  10. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat record, 2026-10-16T12:57Z: PR #23920 (the F4 Spec Shape Gate registry entry, Part of #23543) is ACCEPTed at 1adf5046ee (6215952086) and handed to the merge queue. Its one red check is seat 2's layout.zod.ts:25 row. That row is not this PR's, and the check is not a required context (6215945015). The catch-up itself lands on objectstack-ai/objectui#12654. This card stays open for the F5 slice.


    Generated by Claude Code

  11. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · PR #23920 → 11fea6b000 (Part of #23543, F4 aftercare: the Spec Shape Gate registry entry) · domain:spec seat 1 · os-elon-musk · session session_01HjR8RUwTPQ3TgbfKihmxp9 · 2026-10-16T13:18Z

    probe reading
    PR object merged 2026-10-16T13:18Z out of the merge queue (entered 12:59:34Z); merge commit 11fea6b000
    origin/main git merge-base --is-ancestor 11fea6b000 origin/main → exit 0
    merged vs reviewed head the one file's blob (scripts/ci/spec-shape-retirements.json) at 11fea6b000 equals the reviewed head 1adf5046ee (ACCEPT 6215952086)
    queue branch no gh-readonly-queue/main/pr-23920-* ref remains
    mis-close scan the body carries Part of #23543 and no closing keyword; this card is still open, as intended

    No Release: here. This seat's F5-http claim on this card (6214417833) is still in flight, so the card stays with this seat.

    What this does on main: the hourly Spec Shape Gate reads F4's two objectui rows (SchemaRenderer.tsx TS2345 and SchemaRenderer.expressions.test.tsx TS2322) as known against objectstack-ai/objectui#12654. The gate stays red on rows that are not this card's (seat 2's PR #23784 and PR #23846 rows, told on #18549).


    Generated by Claude Code

  12. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23543,
    "status": "done",
    "branch": "claude/issue-23543-f5-http-reserved-node-names (PR A) + claude/issue-23543-f5-http-adr-0018-note (PR B)",
    "pr": "#23954 (PR A, code, draft) · #23955 (PR B, ADR-0018 note, draft, Tier H)",
    "session": "session_01SgC7iCUX8y2TeJAvz8wcaw (this cloud dev session, from the transcript Claude-Session line; dispatched by seat session_01HjR8RUwTPQ3TgbfKihmxp9 under claim 6214417833, whose Branch line names both branches)",
    "premise_still_valid": true,
    "summary": "F5-http of ruling 6182001882 (item 6), the last family. PR A: one table FLOW_RESERVED_NODE_TYPES + reservedFlowNodeTypeRefusal (spec/automation/flow-reserved-node-types.ts, exported) read by three doors. The flow parse refuses http_request / http_call / webhook as a node type naming http and @objectstack/spec 18: a pattern per name on FlowNodeSchema.type (the F1 DriverType shape; the generated JSON Schema carries it) for top-level nodes, and one FlowSchema superRefine arm over collectFlowGraphs for region-body nodes, once per site. AutomationEngine.registerNodeExecutor (and registerNodeAlias through it) throws for an executor or descriptor typed with a reserved name and registers nothing. flow-node-http-callout-rename is retiredFromLoadPath / retiredAfter 17.7.0, reads the same table, and lost its ADR-0078 conflict guard (no live owner can exist). D3 entry flow-node-http-callout-types-reserved (no conversionIds, always listed), JOIN row, verdict-list pin (kept list now empty), BREAKING minor changeset for spec + service-automation marked registered. With no real entry live on the load path any more, the live-window suites now drive test-only probes: vi.mock where in-process, and a node --import preload (cli/test/fixtures/live-conversion-probe.mjs) for the spawned-CLI suites; no entry is added to the published registry. PR B: one dated addendum in ADR-0018 in its own Addendum format. PR bodies carry no closing keyword.",
    "tests": "PR A, merge head d554392 (origin/main abb6df0..b9dbc3d merged via os-regen-merge.sh, no conflict, merge left no extra changes): spec build + check:generated 'All 14 generated artifacts are up to date'; @objectstack/spec test 688 files / 20914 passed (1 todo) exit 0; cli five conversion suites 64/64 (four e2e under OS_TEST_TIERS=nightly 42/42, stack-conversion-record-door 22/22); service-automation flow-load-conversion + nested-region-parity 32/32. Pre-merge head bf004d7: spec typecheck exit 0 and scripts/build-schemas-check-mode.test.ts (repo project) 88/88; service-automation typecheck 0, test 186 files / 2507; metadata-core typecheck 0, test 18 / 737; metadata-protocol save-flow-canonicalization + flow-canonicalizer 34/34; runtime typecheck 0, http-dispatcher.test 248/248; cli typecheck 0 (closure built with declarations), unit tier 302 files / 4500. D3 text tested against the tool on a temp defineStack project carrying all three names: os validate exit 1, os lint exit 1, os build exit 2, each printing the three refusals at flows.0.nodes.{1,2,3}.type; os migrate meta --from 17 exit 0, no edit, the three refusals under 'Migrated stack does not yet pass schema validation — 3 refusals left', D3 entry listed; --write 'the chain made no mechanical change here, so no file was written', source byte-identical (cmp). Ablations via scripts/ablation-replace.mjs, each restored blob == HEAD and git diff HEAD empty: (1) restore the entry's load-path role (delete retiredFromLoadPath + retiredAfter in registry.ts; anchor 1 -> 0, blob c5edb0fc -> 6a8b9dba): red 6 — conversions.test 'every entry whose window ran out before 18 is retired or kept by name', 'a reserved callout node type reaches defineStack as authored and is refused naming http and the release', 'a retired callout name passes the authoring funnel as written, while the stored-row door converts it'; retired-key-removal-version.pin 'every joined entry is a retired conversion', 'the joined rows exercise the derivation in both directions', 'flow-node-http-callout-rename' (spec tests import src, no dist leg). (2) engine registration refusal removed (anchor 1 -> 0, blob 551b5b23 -> 6173ecfb): red 5 in flow-load-conversion.test (three per-name refusals, descriptor case, alias case). (3) cli preload dropped from liveProbeNodeOptions (blob dd726a57 -> 89675a19): red 2, lint-conversion-notices' two anti-vacuity cases. Direction red in all three.",
    "gates": "PR A on d554392: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 118; each run one by one, exit captured before any pipe, recorded 'cmd :: exit N'; --ran: '118 derived famil(ies) accounted for — 117 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. All 117 exited 0 (incl. check-adr-0087-registration --base origin/main, check-changeset-no-major, check:spec-changes, check:upgrade-guide, check:docs, check:api-surface, check:authorable-surface, check:liveness, check:cross-package-test-inputs, check:doc-authoring, check:i18n, check:skill-examples, check:dual-build-cjs-loads, check:i18n-coverage). NOT-MEASURED: check-plugin-teardown-shape --self-test (shallow clone, asks for --unshallow), declared to CI. Local-only: check:dev-prereqs 0, check:skill-frame-freshness 0, check:nul-bytes 0, check-platform-checklist --changed-from origin/main 0 ('15 anchor(s) judged, 0 lost'). PR B on d50a0fd: derived 19; --ran '19 derived — 18 run, 1 NOT-MEASURED': check:doc-formula-expressions (PREREQUISITE NOT MET, @objectstack/formula unbuilt), declared to CI; the other 18 exit 0. PR check-runs at report time: #23954 38 runs, 15 success, 5 skipped, 18 in_progress; #23955 39 runs, 9 success, 10 skipped, 20 in_progress; no failure. Not awaited, per contract.",
    "mcp_calls": "0 — no MCP GitHub tool was called (ToolSearch only loaded schemas). Card and comments were read with unauthenticated REST GETs. No MCP write tool.",
    "api_writes": "4 relay dispatches, each POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write.yml as objectstack-fleet[bot]: (1) pr_create PR A: POST /repos/objectstack-ai/objectstack/pulls + POST /repos//issues/23954/assignees (read-back: 14012 bytes sent, 14012 stored, identical; assignee os-elon-musk; draft true); (2) pr_create PR B: POST /pulls + POST /issues/23955/assignees (2628 / 2628 identical; draft true); (3) label-write labels_add skip-changeset on #23955: POST /repos//issues/23955/labels (read-back matches; PR B touches docs/adr/** only, which publishes nothing); (4) this report: POST /repos//issues/23543/comments. git push (two branches) is not a REST write.",
    "line_budget": "PR A 1431 (+1095 / -336, 33 files, vs merge base 94114c1; the merge of main added nothing to the PR diff) · PR B 12 (+12 / -0, 1 file)",
    "files_changed": {
    "PR A": [
    ".changeset/23543-f5-http-callout-node-types-reserved.md",
    "content/docs/references/api/automation-api.mdx (gen:docs)",
    "content/docs/references/automation/control-flow.mdx (gen:docs)",
    "content/docs/references/automation/flow.mdx (gen:docs)",
    "packages/cli/src/commands/validate-json-strict-exit.e2e.test.ts",
    "packages/cli/test/build-json-failure-conversions.e2e.test.ts",
    "packages/cli/test/fixtures/live-conversion-probe.mjs (new)",
    "packages/cli/test/helpers/live-conversion-probe.ts (new)",
    "packages/cli/test/lint-conversion-notices.e2e.test.ts",
    "packages/cli/test/stack-conversion-record-door.test.ts",
    "packages/cli/test/validate-json-failure-conversions.e2e.test.ts",
    "packages/metadata-core/src/artifact-forward-conversion.test.ts",
    "packages/runtime/src/http-dispatcher.test.ts",
    "packages/services/service-automation/src/engine.ts",
    "packages/services/service-automation/src/flow-load-conversion.test.ts",
    "packages/spec/api-surface/automation.json (gen:api-surface)",
    "packages/spec/export-origins/automation.json (gen:export-origins)",
    "packages/spec/src/automation/flow-reserved-node-types.ts (new)",
    "packages/spec/src/automation/flow-reserved-node-types.test.ts (new)",
    "packages/spec/src/automation/flow.zod.ts",
    "packages/spec/src/automation/index.ts",
    "packages/spec/src/conversions/apply-live-window.test.ts (new)",
    "packages/spec/src/conversions/conversions.test.ts",
    "packages/spec/src/conversions/region-walk.test.ts",
    "packages/spec/src/conversions/registry.ts",
    "packages/spec/src/conversions/stored.test.ts",
    "packages/spec/src/conversions/stored.ts",
    "packages/spec/src/migrations/entries/semantic/18.flow-node-http-callout-types-reserved.ts (new)",
    "packages/spec/src/shared/retired-key-removal-version.pin.test.ts",
    "packages/spec/src/stack-conversion-notices.test.ts (new, moved block)",
    "packages/spec/src/stack-conversions-record.test.ts",
    "packages/spec/src/stack.test.ts",
    "packages/spec/test-typecheck-debt.json (gen:test-typecheck-debt, shrink only)"
    ],
    "PR B": ["docs/adr/0018-unified-node-action-registry.md"]
    },
    "deviations": [
    "File surface widened beyond the claim's list, each measured and named in PR A's body: service-automation engine.ts + flow-load-conversion.test.ts (the registration refusal, hypothesis 1; the engine is the one executor registry); conversions/stored.ts docblock + stored.test.ts (the docblock gave the retired guard as the reason; the stored-row pin of hypothesis 5); region-walk.test.ts (drove the entry on the default path; now includeRetired); new apply-live-window.test.ts and stack-conversion-notices.test.ts (the live-window cases and stack.test.ts's notice-sink block, moved whole with a vi.mock probe) and the test-typecheck-debt.json shrink their two moved type errors caused; runtime http-dispatcher.test.ts (a GET /actions mock listing http_request); cli test helper + preload fixture. Not touched: protocol.ts, any other conversion entry, MAJOR_18_CONVERSIONS, objectui, eventType 'webhook'.",
    "Spawned-CLI suites drive a test-only probe through a node --import preload rather than vi.mock (out of reach in a child) or a published entry (refused by the seat on F4's question 2). The preload appends to ALL_CONVERSIONS in both the ESM and CJS builds of @objectstack/spec (measured as two distinct arrays). It is test-only and outside every files[]; the seat may judge it against its 'test-only entry' refusal.",
    "The generic ADR-0078 conflict channel (ConversionContext.reservedNodeTypes / reportConflict, onConflict, the engine's conflicts, the save door's FLOW_CONVERSION_CONFLICT 409) is left with zero producers: retiring it touches protocol.ts. Only the entry's guard was removed (hypothesis 2).",
    "No closing keyword in either body, per the dispatch and claim, although releases 6189368882 / 6205630082 said 'the last family's PR is Fixes #23543'. The dispatch is newer and names the reasons (PR B and the save-door answer still pending).",
    "No RETIRED_KEYS_BY_MAJOR entry (a value, no key), no STEP18_RATIONALE fragment (protocol 11), no os migrate meta sentence in the prescription (the removal-version pin would demand --from 10, which the CLI refuses): the F5-jsx precedent.",
    "The save-door reading used a canonicalizer built from the real applyConversionsToFlow(includeRetired) + FlowSchema.parse (the engine's canonicalizeFlow sequence), in the protocol.save-flow-canonicalization.test.ts harness, as a throwaway test file deleted after the run; metadata-protocol does not depend on service-automation.",
    "Readings for service-automation, metadata-core, runtime, metadata-protocol, cli typecheck and cli unit tier are on bf004d7, pre-merge; the merge touched none of those PR files. spec test, check:generated, the cli conversion suites, the two engine files and the gate union are on the merge head d554392.",
    "Commit trailers are the model-free pair AGENTS.md prescribes; the first WIP commit 22574a8 carries none. History not rewritten.",
    "PR B labelled skip-changeset (docs/adr/** publishes nothing, the os-dev fast lane); PR A publishes, so no label."
    ],
    "open_questions": [
    {
    "question": "The metadata save door (hypothesis 6, the seat's open question from F3's release 6205630082): measured at PR A's head, a NEW flow saved with type http_request / http_call / webhook is accepted — stored as http when an automation service canonicalizes it, stored as written without one (judged on the converted body). Should the door refuse retired flow spellings?",
    "options": [
    "A: the save door judges an authored flow body without replaying RETIRED conversions (keeps them for its stored-row/migrate paths), so all retired flow spellings, the seven #23487 ones and F2/F3/F5-http's included, are refused at save like at the other doors; a protocol.ts decision with its own PR.",
    "B: keep the recorded verdict (#4542 / #21982): the save door canonicalizes every retired flow spelling."
    ],
    "recommendation": "A, on the axes: ruling item 7's 'no double spelling' and item 6's 'the authoring doors refuse them' (real need: Studio and integrations write through this door); a contract-first loud refusal is harder for an AI to get wrong than a silent lift; it adds no gate. It is a maintainer decision covering every retired flow entry, so not taken here."
    },
    {
    "question": "Retire the ADR-0078 open-namespace conflict channel, which now has no producer (ConversionContext.reservedNodeTypes / reportConflict, ApplyConversionsOptions.onConflict, ConversionConflictNotice, the engine's conflicts array, the save door's FLOW_CONVERSION_CONFLICT 409)?",
    "options": [
    "A: retire it in a follow-up, bundled with the save-door decision since both touch protocol.ts.",
    "B: keep it as a dormant mechanism for a future open-namespace rename."
    ],
    "recommendation": "A: zero-pull published surface reads as a live capability to the next author (startup-stage axis), and the reservation now makes such renames refusals rather than conversions. Not filed (dead code class); the seat decides."
    }
    ],
    "out_of_scope_findings": [
    "carrier: the seat's objectui card at landing (ruling item 6 names objectui#12334, closed; F5-jsx precedent objectui#12464) · noted, not filed. Read sites of the three names at objectui main f78efdd1e3 (same file set at the pin daeb77fc84): preview samples apps/console/src/preview-samples.ts:237,244 (two http_request nodes); inspector alias packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts:1307 (http: 'http_request') and its http_request config group :771; canvas cases previews/flow-canvas-parts.tsx:88-89,261,265,326,330,424; simulator previews/FlowSimulatorPanel.tsx:57 and previews/simulator/flow-simulator.ts:86; also components/src/renderers/basic/metadata-viewer.tsx:271 and i18n.ts key engine.flowNode.http_request.label. FlowNodeSchema.type's TS type is still string, so the pinned console build does not break.",
    "class: none (Acceptance notes) · the ADR-0078 conflict channel is left with no producer (open_questions 2) · dead code, zero pull · carrier: seat (save-door decision) · noted, not filed."
    ]
    }


    Generated by Claude Code

  13. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Patch round → PR #23954 (F5-http, PR A) · domain:spec seat 1 · session session_01HjR8RUwTPQ3TgbfKihmxp9 · 2026-10-16T14:41Z · on the dev report 6217001433 and the contract review FAIL 6217909163 (head d55439273f), same claim 6214417833, the dev session reused. PR B #23955's review PASSed (6217920402); it waits for PR A to land, then for its approver.

    What the patch fixes (the review's three FAIL items, each re-read by the seat on the head):

    1. Lint · ESLint is red at packages/cli/test/fixtures/live-conversion-probe.mjs:33: import * as esm from '@objectstack/spec' is a restricted root namespace import. Use a named import or the subpath the rule allows.
    2. Test Core (1/6) is red in @objectstack/spec's repo project. The review reads it to src/shared/retired-key-migrate-sentence.test.ts, which judges every backticked os migrate meta --from N under packages/spec/src against the house sentence. The new D3 entry's reason (18.flow-node-http-callout-types-reserved.ts:29) carries one. Reword it so no such marker remains, keep the changeset's copy consistent, and run the whole repo project, not one file of it. If the shard log names a different test, fix that one and say so.
    3. The save-door text is false on main. PR feat(metadata-protocol)!: the flow save door refuses a retired spelling on a NEW flow; a stored flow keeps the full chain #23902 (cf071687f1, merged 13:12Z, executing ruling 6212082860 letter B) is not in this head. On main plus this diff a NEW flow saved with a reserved name is refused at the save door. Delete the changeset's "Not refused yet: a flow saved through the metadata API" paragraph and the PR body's "Known gap" table. Merge main with scripts/pm/os-regen-merge.sh (no rebase). engine.ts is on both sides, in disjoint regions. Then re-run flow-load-conversion, nested-region-parity, canonicalize-stored-flow and protocol.save-flow-canonicalization, and re-measure the four save-door rows against the real door.

    The report's open questions, the seat's calls:

    Accepted as reported: the test-only live-conversion probe (a runtime append inside test processes only, every file outside files[]; the review judged it no breach of the seat's refusal of a published test entry); the widened file surface named in the PR body; no closing keyword in either body (the seat closes #23543 when both PRs have landed).

    A new contract review is owed on the patched head before the queue.


    Generated by Claude Code

  14. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23543,
    "status": "done",
    "branch": "claude/issue-23543-f5-http-reserved-node-names",
    "pr": "#23954",
    "session": "session_01SgC7iCUX8y2TeJAvz8wcaw (this cloud dev session, reused for the patch round asked by seat session_01HjR8RUwTPQ3TgbfKihmxp9, record 6217952268; same claim 6214417833)",
    "round": "patch round on contract review FAIL 6217909163 (head d554392). PR B #23955 untouched.",
    "head": "f459d50c",
    "premise_still_valid": true,
    "summary": "The three FAIL items are fixed. (1) Lint · ESLint: live-conversion-probe.mjs:33 now imports { ALL_CONVERSIONS as ESM_CONVERSIONS } from @objectstack/spec, a named import, instead of the restricted root namespace import. ESLint --no-inline-config exits 0 on the file and on every .ts/.mjs in the diff. Control: the old file, linted from git show over stdin, reports the no-restricted-imports error at 33:8. (2) Test Core (1/6): the review's attribution is confirmed. The D3 reason (18.flow-node-http-callout-types-reserved.ts) now spells the tool as objectstack migrate meta, with no --from value, so retired-key-migrate-sentence.test.ts has no house-sentence marker to judge. The changeset's copy matches. The whole spec repo project is green: test:repo 64 files / 1082 passed. Ablation: putting the old marker back turns that test red (2 cases). (3) Save door: origin/main, including PR #23902 cf07168, was merged with os-regen-merge.sh (merge f16ce01, no conflict; the engine.ts regions are disjoint). The changeset's 'Not refused yet' paragraph and the PR body's 'Known gap' table are deleted. Re-measured at the real PUT /api/v1/meta/flow/:name door: a NEW flow typed http_request, http_call or webhook gets 422 INVALID_METADATA at nodes.1.type with this family's prescription and nothing is stored, with a real AutomationEngine and with no automation service alike; http gets 200 and is stored as http. So the changeset's 'what an author sees' and the D3 reason now name the save door among the refusing doors. The PR body is not edited by the dev; the replacement text is in pr_body_replacement.",
    "tests": "On f459d50: spec build + check:generated 'All 14 generated artifacts are up to date'. @objectstack/spec test (local project) 688 files / 20914 passed (1 todo). test:repo (the whole repo project) 64 files / 1082 passed, exit 0. Re-runs: service-automation flow-load-conversion + nested-region-parity + canonicalize-stored-flow 72/72; metadata-protocol protocol.save-flow-canonicalization 34/34; rest meta-flow-save-retired-spelling 6/6; cli conversion suites 64/64 (four e2e under OS_TEST_TIERS=nightly 42, stack-conversion-record-door 22). service-automation typecheck 0. cli typecheck 0, after building the cli dependency closure in this fresh worktree; the first read was TS2307 because the closure was unbuilt. Save-door reading: a throwaway copy of the rest real-stack harness (better-sqlite3 :memory:, real protocol and routes), with services empty or 'automation' set to a real AutomationEngine, 4 names x 2 hosts, deleted after the run. Ablation (scripts/ablation-replace.mjs): the D3 reason given back the backticked os migrate meta --from 17 (anchor 1 -> 0, blob a994918c -> 0d8573ca). Red 2 in retired-key-migrate-sentence.test.ts ('every prescription sentence in every corpus is house-form or MIXED two-clause', and the anti-vacuity floor). Restored to blob == HEAD with git diff HEAD empty.",
    "gates": "On f459d50: dispatch-gates --commands --repo objectstack-ai/objectstack derived 118. Each ran with its exit code captured before any pipe and was recorded as 'cmd :: exit N'. --ran: '118 derived famil(ies) accounted for — 115 run, 3 NOT-MEASURED (3 DERIVED from a recorded exit 3)'. All 115 exited 0, including check-adr-0087-registration --base origin/main, check-changeset-no-major, check:spec-changes, check:upgrade-guide, check:docs, check:api-surface, check:authorable-surface, check:cross-package-test-inputs, check:doc-authoring, check:i18n, check:i18n-coverage and check:i18n-walk-parity. The three i18n gates first refused because the workspace CLI was unbuilt; they were re-run after pnpm --filter @objectstack/cli build and exited 0. The 3 NOT-MEASURED are prerequisite refusals, left to CI: check-plugin-teardown-shape --self-test (shallow clone), check:skill-examples (client-react has no .d.ts) and check:dual-build-cjs-loads (no full build). Local-only checks: check:dev-prereqs 0, check:skill-frame-freshness 0, check:nul-bytes 0. PR check-runs on f459d50: 41 runs, all completed, 36 success and 5 skipped, no failure. Lint · ESLint and Test Core (1/6) are both green.",
    "mcp_calls": "0 this round. Reads were unauthenticated REST GETs of comments 6217952268 and 6217909163 and the check-runs.",
    "api_writes": "1 this round: POST /repos/objectstack-ai/objectstack/dispatches (fleet-write comment: POST /repos//issues/23543/comments, this report). git push of merge f16ce01 and fix commit f459d50 is not a REST write. The PR body was not edited; the replacement is below for the seat to write.",
    "commits_this_round": [
    "f16ce01f Merge origin/main (os-regen-merge.sh; brings PR #23902 cf07168)",
    "f459d50c fix(spec,cli): named spec import in the probe preload; no house-sentence marker in the D3 reason; the save door refuses a new flow, so the changeset says so"
    ],
    "files_changed_this_round": [
    ".changeset/23543-f5-http-callout-node-types-reserved.md",
    "packages/cli/test/fixtures/live-conversion-probe.mjs",
    "packages/spec/src/migrations/entries/semantic/18.flow-node-http-callout-types-reserved.ts"
    ],
    "line_budget": "PR A 1429 (+1093 / -336, 33 files) after the round; the round itself is +9 / -10 in 3 files.",
    "deviations": [
    "The D3 reason and the changeset now name the save door's 422 for a new flow. That goes one step beyond deleting the false paragraph: it is the measured behaviour on main plus this diff, and ruling 6212082860 item 6 lifts the old sentence. If the seat wants deletion only, drop the 'metadata save door' clause from both.",
    "The first cli typecheck in the fresh worktree read TS2307 because the dependency closure was unbuilt. It was re-run after building the closure and exited 0. This is not counted as a failed measurement.",
    "Earlier-head readings carried over from round 1 and not re-run (no file of theirs changed and no main commit touches them): metadata-core test 18/737, runtime http-dispatcher 248, cli unit tier 302/4500, service-automation full test 186/2507, all on bf004d7."
    ],
    "open_questions": [],
    "out_of_scope_findings": [],
    "pr_body_replacement": "Part of #23543\nClause-②: yes (narrowing)\n\nThis PR lands family F5-http of ruling 6182001882 (item 6), the last family, as the code half. The ADR-0018 dated note is its own Tier H PR, claude/issue-23543-f5-http-adr-0018-note, branched from main. #23543 stays open for that note; the seat closes it once both have landed.\n\n## What\n\nRuling F5-http A: "http_request, http_call and webhook are reserved inside the open node namespace: the authoring doors refuse them with the rename to http; … the entry retires; … eventType: 'webhook' on a wait node is untouched."\n\n- One table, three readers. FLOW_RESERVED_NODE_TYPES and reservedFlowNodeTypeRefusal (packages/spec/src/automation/flow-reserved-node-types.ts, exported from @objectstack/spec/automation) are read by the flow parse, the engine's registration refusal and the conversion itself.\n- The parse refuses each name at the node's type, with the prescription naming http and @objectstack/spec 18. A top-level node meets a pattern per name on FlowNodeSchema.type, the DriverType (F1) shape, so the generated JSON Schema carries it too (json-schema/automation/FlowNode.json properties.type.allOf holds the three patterns). A node inside a loop / parallel / try_catch region meets one FlowSchema superRefine arm over collectFlowGraphs, which skips the top-level graph, so each site is reported exactly once. The open namespace is otherwise unchanged: http, a plugin type, a name that merely contains a reserved one (http_request_v2, my_webhook) and a wait node's waitEventConfig.eventType: 'webhook' all parse (pinned).\n- The register side refuses too. AutomationEngine.registerNodeExecutor throws when the executor's type or its descriptor's type is reserved, and registers nothing; registerNodeAlias goes through it. Measured before the change: nothing stopped a plugin registering an executor under one of the names, and the engine is the one executor registry (every builtin and plugin-approvals register through it). No node could ever reach such an executor, because an authored node is refused at parse and a stored one is rewritten to http first, so the reservation is only true with this door closed (dispatch hypothesis 1, axis ③).\n- The conversion flow-node-http-callout-rename is retiredFromLoadPath: true, retiredAfter: '17.7.0' (F1 to F4's stamp, still the newest stable under the 18.0.0-next.2 label). Its docblock's "stays on the load path" verdict is rewritten as a retirement record. Fixture unchanged.\n- The conflict guard is removed (hypothesis 2). Its only purpose was a live third-party executor under a retired name; with registration refused, reservedNodeTypes can never contain one, so the guard had no case left. The rewrite is now unconditional. The generic ADR-0078 conflict channel (ConversionContext.reservedNodeTypes / reportConflict, onConflict, the save door's 409) is left in place; see Acceptance notes.\n- Registration: the D3 entry flow-node-http-callout-types-reserved (no conversionIds: protocol 11 is below MIGRATION_SUPPORT_FLOOR; no relevantWhen, so always listed, the F5-jsx shape), the removal-version JOIN row (three refusals, one per name), the verdict-list pin (the kept list is now empty and the entry is listed among the retired), and a BREAKING minor changeset for @objectstack/spec and @objectstack/service-automation with FROM → TO, marked registered flow-node-http-callout-types-reserved. No RETIRED_KEYS_BY_MAJOR entry (a value retirement, no key) and no STEP18_RATIONALE fragment (no step-18 conversion), both the F5-jsx precedent. No os migrate meta sentence in the prescription: the removal-version pin's rule would demand --from 10, which the CLI refuses.\n\n### The D3 text, tested against the tool\n\nOn a temp project with one flow carrying all three names, at this branch's build:\n\n- os validate, os build and os lint exit 1 / 2 / 1, each printing the three refusals at flows.0.nodes.1.type / .2.type / .3.type (the config calls defineStack).\n- os migrate meta --from 17 exits 0, applies no edit, prints the three refusals under "Migrated stack does not yet pass schema validation — 3 refusals left after the chain", and lists the D3 entry. --write says "the chain made no mechanical change here, so no file was written" and the source is byte-identical afterwards (cmp).\n\nThe entry's reason says exactly that, plus the save door's 422 for a new flow (measured below). It spells the tool objectstack migrate meta without a --from value, so retired-key-migrate-sentence.test.ts (which judges every backticked os migrate meta --from N under packages/spec/src against the house sentence) has nothing to judge there.\n\n## Stored rows (hypothesis 5)\n\nA stored flow with an old node type still loads as http, pinned at three seams: stored.test.ts (applyConversionsToStoredItem('flow', …) rewrites all three, unconditionally, a caller's reservedNodeTypes naming webhook included), flow-load-conversion.test.ts (engine rehydration, registerFlow), and nested-region-parity.test.ts (a webhook node in a loop body still runs as http, unchanged). metadata-core's artifact door still replays the retired rename inside its window (new case).\n\n## The suites that drove this entry as a live subject (hypothesis 4)\n\nAfter this PR no real entry is live on the load path (measured: ALL_CONVERSIONS.filter(c => !c.retiredFromLoadPath) was exactly this one entry on main). Decided per suite; no suite deleted, no assertion weakened.\n\n| suite | what it drove | decision and reason |\n| --- | --- | --- |\n| spec conversions.test.ts | rename cases, the guard, the live-window case, three normalizeStackInput sink cases | Rename cases run the data-at-rest posture (includeRetired), as the CRUD and F3 cases already do. The guard pair now pins the unconditional rewrite. The live-window case and the three sink cases need a live entry, so they moved, assertion for assertion, to the new apply-live-window.test.ts, which appends a test-only probe with vi.mock (F2's approach). In their place: a defineStack refusal pin and an authoring-funnel-vs-stored-door pin for the retired name. |\n| spec region-walk.test.ts | the walker, through webhook | Every pass runs includeRetired: the walker's subject is regions, and the stored seams are where a region-nested old node still has to come out canonical. |\n| spec stack.test.ts | defineStack's conversion-notice sink and warn-once | The block moved whole to stack-conversion-notices.test.ts with a vi.mock probe, so stack.test.ts does not mock the registry for its other 1,400 lines. Its two type errors moved with it (cast at the fixture, not ledgered); the test-typecheck-debt.json row for stack.test.ts shrank by those two. |\n| spec stack-conversions-record.test.ts | the ordering case's second conversion | A second vi.mock probe beside the page probe F4 added. |\n| metadata-core artifact-forward-conversion.test.ts | FIRING CONTROL 1 | The probe is appended for that one case to ALL_CONVERSIONS from @objectstack/spec, the instance the door reads, and removed in finally; a premise line asserts no real entry is live. The door itself is the real one. Plus a new case: the retired rename still fires at this door. |\n| cli stack-conversion-record-door.test.ts, validate-json-strict-exit.e2e.test.ts, build-json-failure-conversions.e2e.test.ts, validate-json-failure-conversions.e2e.test.ts, lint-conversion-notices.e2e.test.ts | the door's conversion record, --strict, failure exits | A spawned CLI is out of vi.mock's reach, so the child loads a test-only preload with --import (test/fixtures/live-conversion-probe.mjs, the unbuilt-spec-dist.hook.mjs precedent). It appends the same kind of probe to ALL_CONVERSIONS in both builds of @objectstack/spec the child can load (measured: the ESM and CJS tables are two arrays, and a defineStack config can load through either). Every real entry stays as published. The record door also gains one case without the probe: os validate --json refuses http_request by name and records no conversion. |\n| spec scripts/build-schemas-check-mode.test.ts | the entry's surface flow.node.type as a leaf collider | No change: retirement does not change the entry's surface or remove it. 88 / 88 green. |\n\nThe seat's call on F4's open question 2 refused "a test-only entry into the published registry". None is added: every probe lives in a test file or a test fixture outside every package's files[].\n\n## The metadata save door (hypothesis 6)\n\nNot touched by this PR (protocol.ts is outside this family). PR #23902 (cf071687f1, ruling 6212082860 letter B) landed on main and is merged into this branch: the save door no longer replays retired conversions on a NEW flow. Measured at f459d50c at the real PUT /api/v1/meta/flow/:name door (the real-stack harness of packages/rest/src/meta-flow-save-retired-spelling.test.ts, run as a throwaway file and deleted), saving a new flow whose one node is typed with each name:\n\n| name | with an automation service (a real AutomationEngine) | without one |\n| --- | --- | --- |\n| http_request | 422 INVALID_METADATA at nodes.1.type, this family's prescription; nothing stored | the same |\n| http_call | the same | the same |\n| webhook | the same | the same |\n| http (control) | 200, stored as http | 200, stored as http |\n\nThe changeset and the D3 entry name the save door among the refusing doors. A stored row that already carries an old name keeps the full chain (ruling 6212082860, pinned by PR #23902).\n\n## Readers and examples (hypothesis 7)\n\nNo example, skill, hand-written doc or published fixture in this repository authors one of the three names as a node type (git grep over content/, skills/, examples/, apps/). The one test fixture that listed one as a registry entry, runtime's http-dispatcher.test.ts GET /actions mock, now lists http. Two docblocks this change made false were corrected: stored.ts (why flows are not converted by the metadata-protocol seams) and engine.ts (registerNodeAlias and the rehydration comment). eventType: 'webhook' is untouched everywhere.\n\n## objectui (hypothesis 8)\n\ncarrier: the seat's objectui card at landing. Read sites of the three names at objectui main f78efdd1e3, identical in file set at the pin daeb77fc84: preview samples apps/console/src/preview-samples.ts:237,244 (two http_request nodes); inspector alias packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts:1307 (http: 'http_request') and its http_request config group :771; canvas cases previews/flow-canvas-parts.tsx:88-89,261,265,326,330,424; simulator previews/FlowSimulatorPanel.tsx:57 and previews/simulator/flow-simulator.ts:86; plus components/src/renderers/basic/metadata-viewer.tsx:271 and the i18n key engine.flowNode.http_request.label. FlowNodeSchema.type's TypeScript type is still string, so the pinned console build does not break on this change.\n\n## Tests\n\nFinal head f459d50c (two merges of origin/main, both through os-regen-merge.sh, no conflict; the second brought PR #23902): spec build + check:generated "All 14 generated artifacts are up to date"; @objectstack/spec test (local project) 688 files / 20914 passed (1 todo); @objectstack/spec test:repo (the whole repo project) 64 files / 1082 passed; service-automation typecheck 0 and flow-load-conversion + nested-region-parity + canonicalize-stored-flow 72 / 72; metadata-protocol protocol.save-flow-canonicalization 34 / 34; rest meta-flow-save-retired-spelling 6 / 6; cli typecheck 0 and the five conversion suites 64 / 64 (four e2e under OS_TEST_TIERS=nightly 42, the record door 22); ESLint (--no-inline-config) over every .ts / .mjs file of the diff exits 0. Earlier on bf004d7a: metadata-core typecheck 0 and test 18 / 737; runtime typecheck 0 and http-dispatcher.test.ts 248; cli unit tier 302 files / 4500; service-automation test 186 files / 2507.\n\nGates on f459d50c: dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 118, each run with its exit captured before any pipe; --ran: "118 derived famil(ies) accounted for — 115 run, 3 NOT-MEASURED (3 DERIVED from a recorded exit 3)". All 115 exited 0, among them check-adr-0087-registration --base origin/main, check-changeset-no-major, check:spec-changes, check:upgrade-guide, check:docs, check:api-surface, check:authorable-surface, check:cross-package-test-inputs, check:doc-authoring and the three check:i18n* gates. The three NOT-MEASURED are prerequisite refusals declared to CI: check-plugin-teardown-shape --self-test (shallow clone), check:skill-examples (client-react unbuilt) and check:dual-build-cjs-loads (a full build absent). Local-only: check:dev-prereqs 0, check:skill-frame-freshness 0, check:nul-bytes 0. PR check-runs on f459d50c: 41, all completed, 36 success and 5 skipped, no failure.\n\nAblation (scripts/ablation-replace.mjs, restored to the HEAD blob each time, git diff HEAD empty):\n\n1. The entry's load-path role restored (retiredFromLoadPath / retiredAfter deleted). Red, 6: the verdict-list pin; the defineStack refusal pin; the authoring-funnel-vs-stored-door pin; and three removal-version pins (the JOIN row, "every joined entry is a retired conversion", "the joined rows exercise the derivation in both directions"). Spec tests import src, so no dist leg.\n2. The engine's registration refusal removed. Red, 5: the three per-name refusals, the descriptor case and the alias case.\n3. The cli preload dropped from NODE_OPTIONS. Red, 2: lint-conversion-notices's two "the fixture REALLY converts" anti-vacuity cases.\n4. The D3 reason given back its first-round marker (os migrate meta --from 17 in backticks). Red, 2: retired-key-migrate-sentence.test.ts ("every prescription sentence in every corpus is house-form or MIXED two-clause" and its anti-vacuity floor), the repo-project test behind the first round's Test Core (1/6) red.\n\n## Acceptance notes\n\n- The ADR-0078 conflict channel has no producer left. ConversionContext.reservedNodeTypes / reportConflict, ApplyConversionsOptions.onConflict, the engine's conflicts array and the save door's FLOW_CONVERSION_CONFLICT 409 stay as a generic mechanism, with zero entries using it. The seat retires it as its own card at landing (it touches protocol.ts and engine.ts), not in this PR.\n- One parse reports every site. Measured: a flow with http_request on a top-level node and webhook inside a loop body answers both issues in one parse, at nodes.1.type and nodes.2.config.body.nodes.0.type.\n\n---\n_Generated by Claude Code_\n"
    }


    Generated by Claude Code

  15. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #23954 comment 6219953741 · domain:spec seat 1 · session session_01HjR8RUwTPQ3TgbfKihmxp9 · 2026-10-16T16:27Z · contract review (CONTRACT_REVIEW_TIER) PASS 6219927228 on the same head f459d50c5b, after FAIL 6217909163 and patch round 6217952268; the head is green and goes to the queue in this act.

    F5-http's code: http_request, http_call and webhook are reserved node types, refused at the flow parse, at the engine's executor registration and (for a new flow, with PR #23902) at the save door; a stored row still loads as http. PR #23955, the ADR-0018 note, is ACCEPTed and handed to its approvers once this PR has landed. The cloud dev session is archived at this ACCEPT.


    Generated by Claude Code

  16. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · PR #23954 → f901746ac8 (Part of #23543, F5-http PR A, the code) · domain:spec seat 1 · os-elon-musk · session session_01HjR8RUwTPQ3TgbfKihmxp9 · 2026-10-16T17:24Z

    probe reading
    PR object merged 2026-10-16T16:56Z out of the merge queue (entered 16:29:06Z); merge commit f901746ac8
    origin/main git merge-base --is-ancestor f901746ac8 origin/main → exit 0
    merged vs reviewed head all 33 files' blobs at f901746ac8 equal the reviewed head f459d50c5b (ACCEPT 6219953741, contract review PASS 6219927228)
    queue branch no gh-readonly-queue/main/pr-23954-* ref remains
    mis-close scan the body carries Part of #23543 and no closing keyword; this card is still open, as intended

    No Release: here. This claim's other PR, #23955 (the ADR-0018 note, Tier H), is ACCEPTed (6220964660) and with its approvers. The seat closes this card when it lands: F5-http is the last family of ruling 6182001882.

    The follow-ups the ACCEPT promised, filed in this act:


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions