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. 26 remaining items

  7. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 7 (second shift, parallel again) · 2026-10-15T22:12Z · family F3 of ruling 6182001882 (item 3): the named loose keys under a wait or connector_action node's config are refused, with the prescription naming the sibling block. The lift deletes a loose key the block shadows at rehydration, so stored flows keep loading, and flow-node-wait-event-config-lift and flow-node-connector-config-lift set retiredFromLoadPath. The PR is Part of #23543; F2, F4 and F5-http follow one at a time, in the ruling's order.
    Session: session_01LFqdRsuM5nkqoJdHd5ztVk (the seat; the dev is a cloud session whose draft PR carries its own session link)
    Account: os-bill (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23543-retire-wait-connector-config-lift
    Worktree: objectstack-issue-23543
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549)
    File surface (at origin/main 9bb93706f or later; stop on a breach and explain it in the report):

  8. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23543,
    "status": "done",
    "branch": "claude/issue-23543-retire-wait-connector-config-lift",
    "pr": "#23742",
    "session": "session_011ZyGVR3TdcTDLhuzyEbkBN (dev cloud session; dispatched by seat session_01LFqdRsuM5nkqoJdHd5ztVk under claim 6203354520, whose Branch line names this branch)",
    "premise_still_valid": true,
    "summary": "F3 of ruling 6182001882: FlowSchema's collectFlowGraphs walk refuses every named loose key under a wait / connector_action node's config (wait: eventType, timerDuration, duration, signalName, signal, timeoutMs; connector_action: connectorId, actionId, input) at nodes.N.config.KEY, with a prescription naming the waitEventConfig / connectorConfig key (timeoutMs -> timerDuration as a string). The key tables moved byte for byte from conversions/registry.ts into a non-barrel leaf (automation/flow-sibling-block-loose-keys.ts) that both the refusal and the two lifts read. At rehydration each lift now DELETES a loose key the block shadows (and a loose null), with a notice, so stored rows keep loading with the block alone. flow-node-wait-event-config-lift and flow-node-connector-config-lift set retiredFromLoadPath / retiredAfter 17.7.0; the D3 entry 18.flow-sibling-block-loose-config-keys-refused carries both ids; the verdict-list pin now keeps 4 entries; the removal-version JOIN gains 2 rows; one BREAKING changeset (spec minor, service-automation patch).",
    "tests": "Pre-merge head cb5a4f9: @objectstack/spec full test 679 files / 20770 passed (1 todo), typecheck exit 0; @objectstack/service-automation full test 186 files / 2487 passed, typecheck exit 0; @objectstack/lint the 2 edited files 2 / 305 passed; @objectstack/cli unit tier, the 3 migrate-meta load-path suites 3 / 18 passed (full cli tiers declared to CI: no cli file touched). Post-merge head 23bebd6 (merged origin/main 3b46855, incl. #23418, via os-regen-merge.sh, no conflicts, template equals main): spec src/conversions+automation+migrations+shared+stack* 113 files / 3883 passed; check:generated 'All 14 generated artifacts are up to date' (no generated file changed, before or after the merge). Ablation 1 (refusal unwired in the flow walk, scripts/ablation-replace.mjs): anchor 1->0, blob f69316ecce7b->95cf82982a02; 9 tests red across conversions.test.ts, retired-key-removal-version.pin.test.ts, connector-action-config-required.test.ts (direction: red); restore blob == HEAD, git diff HEAD empty. Ablation 2 (connector lift drop branch re-inserts the loose key): anchor 1->0, blob 940997a39a4e->9450deebd49e; 3 tests red (direction: red); restore proven. Spec tests import src: no dist leg.",
    "gates": "Local, final head 23bebd6: dispatch-gates --commands --repo objectstack-ai/objectstack derived 111; each run one by one, exit code captured before any pipe; --ran: '111 derived famil(ies) accounted for - 110 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)' - the one is check-plugin-teardown-shape --self-test (shallow clone). Round 1 on cb5a4f9 read 107 run / 4 NOT-MEASURED (check:skill-examples and check:dual-build-cjs-loads exit 3, check:dts-closure exit 1 recorded as a claimed NOT-MEASURED because my closure build ran with OS_SKIP_DTS=1); all three exit 0 in round 2. CI on 23bebd6 at report time: TypeScript Type Check success, Lint & Repo Gates success, Build Core success, Governed Surface Queue Guard success, Check Changeset success, Test Core 1/6 2/6 4/6 5/6 6/6 success, Test Core 3/6 in_progress, Type Check workspace/consumer/source/debt ledger success, Lint ESLint/docs/repo/tooling/PM dispatch-gates/scoped x3 success, Spec property liveness success, Part-of PR must not also close its card success, Build Docs success, Check PR Size success; Console Pin Gate, Temporal Conformance, Dogfood shards, Packed-tarball smoke skipped (PR fast set).",
    "mcp_calls": "4 - issue_read get, issue_read get_comments (#23543), pull_request_read get, pull_request_read get_check_runs (#23742); no write tool",
    "api_writes": "2 relay strokes - pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST issues/23742/assignees os-bill, run 38823295311, body read back byte-identical); comment (POST issues/23543/comments, this report). git push is not a REST write.",
    "line_budget": "+621 / -129 over 16 files vs origin/main (PR #23742: additions 621, deletions 129)",
    "files_changed": [
    ".changeset/23543-f3-retire-wait-connector-config-lift.md",
    "content/docs/automation/flows.mdx",
    "packages/lint/src/lint-flow-patterns.test.ts",
    "packages/lint/src/validate-expressions.flow-cel-root.test.ts",
    "packages/services/service-automation/src/builtin/connector-nodes.test.ts",
    "packages/services/service-automation/src/builtin/connector-nodes.ts",
    "packages/services/service-automation/src/builtin/wait-node.test.ts",
    "packages/services/service-automation/src/builtin/wait-node.ts",
    "packages/services/service-automation/src/run-summary.test.ts",
    "packages/spec/src/automation/connector-action-config-required.test.ts",
    "packages/spec/src/automation/flow-sibling-block-loose-keys.ts",
    "packages/spec/src/automation/flow.zod.ts",
    "packages/spec/src/conversions/conversions.test.ts",
    "packages/spec/src/conversions/registry.ts",
    "packages/spec/src/migrations/entries/semantic/18.flow-sibling-block-loose-config-keys-refused.ts",
    "packages/spec/src/shared/retired-key-removal-version.pin.test.ts"
    ],
    "deviations": [
    "File surface widened by the pin sweep, outside the claim's list: lint lint-flow-patterns.test.ts and validate-expressions.flow-cel-root.test.ts, service-automation run-summary.test.ts (fixtures re-spelled from the loose config location to the declared blocks; none tested the lift) and content/docs/automation/flows.mdx (two table rows now name the refusal). Named in the PR body.",
    "Assumption 3: the executors had no loose-key reads left to delete (wait-node.ts reads waitEventConfig only, connector-nodes.ts connectorConfig only); only their comments changed. The changeset still carries a service-automation patch row for those comment-only edits.",
    "Assumption 4: none of the cli migrate-meta load-path suites nor spec stack-authored-input has F3 as its subject - since PR #23600 they all drive retry-policy-converged - so they are unchanged; F2 inherits the no-live-subject question.",
    "Design addition beyond the ruling's letter: the lifts also delete a loose key holding null (refused like any present key) and a later candidate shadowed by the first present one, not only a block-shadowed key; config.timeoutMs gets its own prescription (waitEventConfig.timerDuration as a string) because waitEventConfig.timeoutMs is itself a tombstone.",
    "Round-1 gate record: check:dts-closure exited 1 under my OS_SKIP_DTS closure build and was recorded as a claimed NOT-MEASURED, not as exit 1; round 2 on the final head measured it exit 0.",
    "Attribution: commit trailers use AGENTS.md's model-free pair (Co-authored-by: Claude, Claude-Session) and the PR body the session-URL footer, instead of the harness reminder's model-named trailer and emoji footer (AGENTS.md takes precedence).",
    "Main was merged before the PR opened (dispatch: #23418 had landed) via scripts/pm/os-regen-merge.sh; no regeneration was owed."
    ],
    "open_questions": [
    {
    "question": "A connector_action node with only config.connectorId / config.actionId now gets three issues (the missing connectorConfig block plus one per loose key). Keep the stack, or suppress the loose-key issues when the block is absent?",
    "options": [
    "A keep all three: each is true and located, and the block message already says move the keys",
    "B suppress the per-key issues when connectorConfig is absent (one issue, less precise)"
    ],
    "recommendation": "A, because axis 3 (prevent AI errors) favours located refusals at each key the author wrote, and B adds a special case to a rule that is otherwise one table"
    }
    ],
    "out_of_scope_findings": []
    }


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: session session_01LFqdRsuM5nkqoJdHd5ztVk (domain:spec seat 2) · F3 landed as Part of, and claim 6203354520 covered F3 only · back to pm:queue for domain:spec, next family F2 · 2026-10-16T01:02Z

    Landing record, PR #23742 (F3 of ruling 6182001882):

    Probe Reading
    origin/main d176b0aab3 "feat(spec)!: refuse the wait / connector_action loose config keys naming their sibling block; their D2 lifts leave the load path (F3 of #23543)", merged through the queue at 2026-10-16T01:00Z (git branch -r --contains → origin/main)
    merge queue no gh-readonly-queue/main/* ref names #23742
    squash vs reviewed head The squash tree bc058a33e668 equals git merge-tree --write-tree of its parent 941c78ae2e with 23bebd666b. That head carries contract review PASS 6205149412 and ACCEPT 6205192514.
    card open, Part of: nothing closed it

    Left on this card, in the ruling's order (item 7): F2 → F4 → F5-http.

    • Each family is its own PR, Part of #23543, with a contract-tier review (Clause-②: yes (narrowing)), a BREAKING changeset and the verdict-list pin in conversions.test.ts.
    • The last family's PR is Fixes #23543.
    • conversions.test.ts's kept-without-ruling list now holds exactly four entries: flow-node-http-callout-rename, page-component-visibility-to-visibleWhen, retry-policy-converged and view-visibleOn-to-visibleWhen.

    Carry-forward for the next dispatches (from the contract review's ③):

  10. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · 2026-10-16T02:28Z · family F2 of ruling 6182001882 (item 2, the loud form). A job.retryPolicy block whose maxRetries is omitted or 0 is refused, in the shape flow.errorHandling uses for strategy: 'retry'. A job with no block stays a single attempt, and backoffMultiplier keeps its declared default. retry-policy-converged then sets retiredFromLoadPath. The PR is Part of #23543; F4 and F5-http follow one at a time, in the ruling's order.
    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-f2-retry-policy-refused
    Worktree: objectstack-issue-23543-f2 (in the cloud session's container)
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface (at origin/main 0b1179f33 or later; stop on a breach and explain it in the report):

  11. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23543,
    "status": "done",
    "branch": "claude/issue-23543-f2-retry-policy-refused",
    "pr": "#23810",
    "session": "session_01MT2aGLQQhH8ZsPrgqHMrwz (this cloud dev session, from the transcript Claude-Session line; dispatched by seat session_01HjR8RUwTPQ3TgbfKihmxp9 under claim 6206691402, whose Branch line names this branch)",
    "premise_still_valid": true,
    "summary": "F2 of ruling 6182001882 (item 2, the loud form). JobSchema gains one root-level refine: a retryPolicy whose parsed maxRetries is below 1 (omitted, which the default fills with 0, or written 0) is refused as a custom issue at retryPolicy.maxRetries. The message opens with the ruling's prescription ('A retry block with no attempts is no retry block: state maxRetries ≥ 1, for example 3, or delete the block.'), names @objectstack/spec 18 and ends with the os migrate meta --from 16 sentence. defineStack answers STACK_SCHEMA_INVALID / 422 at jobs.N.retryPolicy.maxRetries. The shared RetryPolicySchema (also try_catch.retry) is unchanged, and a control pins it. retry-policy-converged sets retiredFromLoadPath / retiredAfter 17.7.0. The D3 entry 18.job-retry-policy-without-attempts-refused carries conversionIds ['retry-policy-converged']. The verdict-list pin keeps 3, and the removal-version JOIN gains one row. The four load-path suites were decided per suite (open_questions 1). One BREAKING changeset: spec minor, service-job patch (comment only).",
    "tests": "Head 0bc4f42 (origin/main 46ca793 merged via os-regen-merge.sh: no conflict, the merge left no changes, lockfile unmoved). @objectstack/spec: full test 683 files / 20888 passed (1 todo), exit 0. build + check:generated 'All 14 generated artifacts are up to date'. typecheck exit 0 on 9e09e0d, pre-merge; the merge touched none of this PR's files. @objectstack/cli: full unit tier 297 files. 295 passed in one run; the 2 build-dependent published-subpath pins failed only with 'packages/cli is not built' and passed 2 / 29 after pnpm --filter @objectstack/cli build. 4348 passed, 29 skipped. The 4 edited cli files pass, among them the integration-tier retry-policy-key-validate-door.test.ts at 2 / 2 (run because the diff touches it). cli typecheck exit 0 after the closure was built with declarations; the first read was 398 TS7016 from an OS_SKIP_DTS closure, an environment state. @objectstack/service-job: test 11 files / 117 passed; typecheck exit 0. Ablation via scripts/ablation-replace.mjs on 9e09e0d: 'job.retryPolicy.maxRetries >= 1' was replaced by '>= 0'. Anchor 1 -> 0, blob 28e227b31f4e -> c6c4d7684caa. 7 tests went red: job.test.ts 3, conversions.test.ts 3 and retired-key-removal-version.pin.test.ts 1, the JOIN row. Direction: red. The restore was proven blob == HEAD and git diff HEAD empty. Spec tests import src, so there is no dist leg.",
    "gates": "Local, head 0bc4f42: dispatch-gates --commands --repo objectstack-ai/objectstack derived 114. Each ran one by one, exit code captured before any pipe, one log per command. --ran: '114 derived famil(ies) accounted for - 111 run, 3 NOT-MEASURED (3 DERIVED from a recorded exit 3)'. The three are check-plugin-teardown-shape --self-test (shallow clone, asks for --unshallow), spec check:skill-examples (client-react dist has no .d.ts) and check:dual-build-cjs-loads (some package has no dist). These are the same three prerequisite refusals F3 recorded, and CI runs them. Local-only families, owed because the diff touches the packages/spec build, were run on 0bc4f42 and stay local: pnpm check:dev-prereqs exit 0 ('@objectstack/spec … built from the sources on disk'); pnpm check:skill-frame-freshness exit 0 ('1/1 framework files are byte-identical to the ref'). CI on PR #23810 at report time (head 0bc4f42): 'No other open PR may claim the same issue' success; 'Part-of PR must not also close its card' success; Build Core, Test Core (1-6) and Dogfood Regression Gate queued; Check Changeset, Governed Surface Queue Guard, the Lint and Type Check jobs and 'The card this PR closes must claim this branch' in_progress; Console Pin Gate, Temporal Conformance, Dogfood Verify CLI and Packed-tarball smoke skipped. CI convergence is the PM's per the contract.",
    "mcp_calls": "0",
    "api_writes": "2 relay dispatches, each a POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write.yml as objectstack-fleet[bot]: (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls plus POST /repos//issues/23810/assignees; read-back said 12321 bytes sent, 12321 stored, identical, with assignees os-elon-musk; (2) this comment, POST /repos//issues/23543/comments. git push is not counted. Reads went through gh api GET only.",
    "line_budget": "719 (PR additions 517 + deletions 202, 18 files, as the pull reports)",
    "files_changed": [
    ".changeset/23543-f2-job-retry-policy-without-attempts-refused.md",
    "content/docs/automation/jobs.mdx",
    "content/docs/references/system/job.mdx (regenerated by check:generated --fix, check:docs)",
    "packages/cli/test/migrate-meta-composed-load-conversions.test.ts",
    "packages/cli/test/migrate-meta-composed.test.ts",
    "packages/cli/test/migrate-meta-load-conversions.test.ts",
    "packages/cli/test/retry-policy-key-validate-door.test.ts",
    "packages/services/service-job/src/run-with-policy.ts",
    "packages/spec/liveness/flow.json",
    "packages/spec/src/automation/flow-builtin-node-config-keys.test.ts",
    "packages/spec/src/conversions/conversions.test.ts",
    "packages/spec/src/conversions/registry.ts",
    "packages/spec/src/migrations/entries/semantic/18.job-retry-policy-without-attempts-refused.ts",
    "packages/spec/src/shared/retired-key-removal-version.pin.test.ts",
    "packages/spec/src/shared/retry-policy.zod.ts",
    "packages/spec/src/stack-authored-input.test.ts",
    "packages/spec/src/system/job.test.ts",
    "packages/spec/src/system/job.zod.ts"
    ],
    "deviations": [
    "File surface widened beyond the claim's list, each measured and named in the PR body: (a) packages/cli/test/retry-policy-key-validate-door.test.ts, whose 'declared' fixture authored a try_catch retryDelayMs that only the load conversion made valid; (b) packages/spec/src/automation/flow-builtin-node-config-keys.test.ts, whose CONTROL pinned that defineStack converts retryDelayMs; (c) content/docs/automation/jobs.mdx, shared/retry-policy.zod.ts comments, liveness/flow.json one note, and the job-timeout-to-timeout-ms docblock in registry.ts, prose the retirement made false; (d) job.test.ts, whose 'one-time scheduled job' fixture wrote maxRetries: 0 and now has no block.",
    "No label-write: the dispatch's write budget lists git push, pr_create and the report comment only.",
    "Not subscribed to PR activity: the os-dev contract overrides the platform's PR-subscription posture.",
    "Interim CLI typecheck read red (398 TS7016) on a closure built with OS_SKIP_DTS=1. It was re-run after building the closure with declarations: exit 0."
    ],
    "open_questions": [
    {
    "question": "The four load-path suites F3's record named lost their last live subject. After F2, os migrate meta --from 16, the floor, replays steps 17 and 18, and every entry of both is retired. Only toMajor 11 and 15 entries stay live (F4, F5-http), and the chain never replays those. How was each suite decided?",
    "options": [
    "A (taken) per suite: stack-authored-input.test.ts gets a synthetic probe, a vi.mock of ./conversions/registry appending a test-owned live retryDelayMs rename, so it no longer depends on any entry's lifecycle. migrate-meta-load-conversions and migrate-meta-composed-load-conversions: the accepted-arm 'lists a conversion the load already applied' case is retired (no subject; its write / re-run / clean-reload half is pinned at the same layer by the two-refused-spellings case). The 'authored-source load reads the argument' and 'defined twice' cases are re-pointed to a discriminator needing no conversion: strict defineStack fills declared defaults (backoffMultiplier 1, maxRetryDelayMs 30000, jitter false), and the argument does not. migrate-meta-composed.test.ts: the row's assertions still hold, so it is only renamed.",
    "B: re-point every case to page-component-visibility-to-visibleWhen or flow-node-http-callout-rename. Not possible for the chain cases (toMajor 15 / 11 are below the floor), and F4 / F5-http would have to redo it."
    ],
    "recommendation": "A, because it is the only option with a real subject on this tree, and the probe and the default-fill discriminator survive F4 and F5-http unchanged. Four axes: it serves the real seam (the authored-source shim); it is long-term (no entry lifecycle coupling); it adds no production test hook (a registry injection point for the CLI would be a new surface); and it adds no gate."
    },
    {
    "question": "Where should the refusal live? A JobSchema root-level refine, as taken here, or a field-level refine on job.retryPolicy?",
    "options": [
    "A (taken): root-level refine at path retryPolicy.maxRetries. It adds no dropped-refinement ledger site, because system/Job's root is already recorded. The issue appears only once the job's other fields parse.",
    "B: field-level refine. The issue is reported beside sibling errors, but it adds 'retryPolicy' sites to dropped-refinements.baseline.json for system/Job and every schema embedding a job.",
    "C: a job-specific policy schema with maxRetries required and min(1). tsc and the JSON Schema would state the rule, but it creates a second declaration of the converged policy, which shared/retry-policy.zod.ts exists to prevent."
    ],
    "recommendation": "A, because it follows the ruling's named shape (flow.errorHandling's custom issue at maxRetries) with zero ledger growth, and the parse-time prescription is loud at every authoring door."
    },
    {
    "question": "Metadata save door (protocol.ts), hypothesis 8. Does F2 interact with the door?",
    "options": [
    "Measured: for a non-flow type the door judges the body as stored, with no conversion replay, so a job body meets this refusal there. job has not been runtime-creatable since 17, so no door claim is made for it. The retryDelayMs flow half meets the flow fallback exactly as before, because the fallback already replayed this entry while it was live. Nothing in protocol.ts was touched; the seat's separate decision covers this entry together with the other retired flow entries."
    ],
    "recommendation": "No action in this PR."
    },
    {
    "question": "Stored job rows written through the save door at 17 without maxRetries (meaning 'no retry' at 17) are rehydrated by convertStoredItem replaying retry-policy-converged, so they read as 3 retries. Should anything change?",
    "options": [
    "A: nothing. This was already the 17 behaviour, because the entry was live and the stored seam replayed it; F2 does not change it.",
    "B: add retry-policy-converged to an excludeConversionIds list at the stored seam as a default flip."
    ],
    "recommendation": "A for this family: the ruling says 'the 17 materialization lives on in the D3 chain', and job rows are not runtime-creatable since 17, so such rows are rare. Noted for the seat, not filed."
    }
    ],
    "out_of_scope_findings": [
    "class: none filed · reach: n/a · evidence: the root-level refine reports the empty-retry-block issue only after a job's other fields parse (zod skips object refines on an aborted parse). This is a diagnostic-order note, not a defect: the refusal still fires once the rest is fixed. carrier: noted, not filed (Acceptance notes of PR #23810)."
    ]
    }


    Generated by Claude Code

  12. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #23810 comment 6207800896 · domain:spec seat 1 · session session_01HjR8RUwTPQ3TgbfKihmxp9 · 2026-10-16T04:03Z · family F2. The contract review (CONTRACT_REVIEW_TIER) and an all-green head stand before the queue. The PR is Part of, so this card stays open for F4 and F5-http.

    File surface amended for claim 6206691402, each item measured in the report: packages/cli/test/retry-policy-key-validate-door.test.ts, packages/spec/src/automation/flow-builtin-node-config-keys.test.ts, packages/spec/src/system/job.test.ts, content/docs/automation/jobs.mdx, the shared/retry-policy.zod.ts comments, one liveness/flow.json note, and the regenerated content/docs/references/system/job.mdx.

  13. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23543,
    "status": "done",
    "branch": "claude/issue-23543-f2-retry-policy-refused",
    "pr": "#23810",
    "session": "session_01MT2aGLQQhH8ZsPrgqHMrwz",
    "round": "prose patch round asked by seat 1 (session_01HjR8RUwTPQ3TgbfKihmxp9) after ACCEPT 6207800896 and contract review PASS 6207998123; same claim 6206691402",
    "head": "dce22664 (one commit on top of 0bc4f42; the PR body is untouched)",
    "edit": {
    "file": "packages/spec/src/migrations/entries/semantic/18.job-retry-policy-without-attempts-refused.ts, field reason (surface unchanged, still free of backticks and pipes)",
    "before": "objectstack migrate meta lists every such block in your metadata sources and writes both pre-17 numbers into it, which keeps the retries the job ran with.",
    "after": "objectstack migrate meta lists every block in your metadata sources that omits the count and writes both pre-17 numbers into it, which keeps the retries the job ran with; a block that writes maxRetries: 0 it does not list, and you delete that block by hand (or state a count)."
    },
    "tests": "pnpm --filter @objectstack/spec exec vitest run src/migrations src/conversions: 18 files / 755 passed, exit 0 (head dce2266).",
    "gates": "pnpm --filter @objectstack/spec build exit 0; check:generated exit 0 ('All 14 generated artifacts are up to date'); check:docs exit 0 ('227 generated files in sync'). No generated file changed: the upgrade guide this entry feeds is built in memory and not committed. Each exit code was captured before any pipe.",
    "mcp_calls": "0",
    "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches): this comment, POST /repos//issues/23543/comments, then one PATCH /repos/objectstack-ai/objectstack/issues/comments/6208060742 to restore the before/after sentences, whose backtick spans a shell heredoc had executed and dropped in the first write. git push is not counted.",
    "files_changed": [
    "packages/spec/src/migrations/entries/semantic/18.job-retry-policy-without-attempts-refused.ts"
    ],
    "deviations": [
    "The first write of this comment lost the backtick spans of its before/after sentences (an unquoted heredoc executed them); the same comment was edited once to restore them."
    ],
    "open_questions": []
    }


    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