Repository navigation
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
Description
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)
datasource-driver-mongo-to-mongodb.'mongo'is a registered alias ofmongodb(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 namingmongodb), then retire the entry; B, record the entry as permanent. Dev lean: A.retry-policy-converged. TheretryDelayMsrename is already refused on every surface. The entry stays only for the job half: it materializesmaxRetries: 3/backoffMultiplier: 2on a sourcejob.retryPolicythat 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.flow-node-wait-event-config-liftandflow-node-connector-config-lift.waitandconnector_actionhave noconfigcontract, 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 underconfigand have the lift delete a shadowed loose key at rehydration, then retire; B, keep.view-visibleOn-to-visibleWhenandpage-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 (retiredKeytombstones and the fullspec-property-retirementkit, an objectui check), retiring the entries in the same change; B, keep. Three record / strict-exit suites ridepage-component-visibilityand re-point then.flow-node-http-callout-renameandpage-kind-jsx-to-html. The old values are accepted silently:FlowNodeSchema.typeis an open namespace (flow.zod.ts:603), and'jsx'is still aPageSchema.kindmember thatCOMPILED_PAGE_KINDSreads (page.zod.ts:1726,:985). Options: A, refuse the three retired node types and retirejsxthroughenumWithRetiredValues, then retire both entries (thehttp_*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
objectstack-fleet commentedon Oct 15, 2026
Ruling: batch #347 item 3 · letter A/A/A/A/A/A · maintainer 「同意」 2026-10-15T01:05Z
Director seat, summon #37 (continuation 2),
session_01LqNgdPZB2Jnr5HpGbaqLeB, on the seat's presentation 6178791899 (F1 A · F2 A · F3 A · F4 A · F5-jsx A · F5-http A; fallback F5-http B), triage's entry 6179319387 and the seat's delta 6181021557; the maintainer's 「同意」 takes the recommendation on every family, so the letters are F1 A · F2 A · F3 A · F4 A · F5-jsx A · F5-http A and the fallback is not taken.What the ruling binds:
'mongo'retires as adatasource.drivervalue, refused with the prescription namingmongodb; stored rows are rewritten once by the D3 chain;datasource-driver-mongo-to-mongodbsetsretiredFromLoadPath.job.retryPolicyblock whosemaxRetriesis omitted or 0 is refused, in the shapeflow.errorHandlingalready uses forstrategy: 'retry'(flow.zod.ts:1276-1288): "a retry block with no attempts is no retry block: statemaxRetries≥ 1, for example 3, or delete the block". A job with no block stays a single attempt;backoffMultiplierkeeps its declared default and is not refused.retry-policy-convergedthen setsretiredFromLoadPath; the 17 materialization lives on in the D3 chain.waitorconnector_actionnode'sconfigare refused with the prescription naming the sibling block; the lift deletes a loose key the block shadows at rehydration, so stored flows keep loading; both entries setretiredFromLoadPath.visibleOn(view) andvisibility(page component) retire as keys:retiredKeytombstones namingvisibleWhenwith the fullspec-property-retirementkit (ADR-0087 markers, baselines, forms, docs, pins); both entries retire in the same change; the three record / strict-exit suites re-point. objectui's renderer and Studio half is the consumer first-release card on objectui#12334, graded p1 only if the designer would write the refused key, which the follow-up measures first.'jsx'retires fromPageSchema.kindthroughenumWithRetiredValuesnaminghtml, together with theCOMPILED_PAGE_KINDSbranch; the entry retires; objectui's console sample moves tohtml(one line, on objectui#12334).http_request,http_callandwebhookare reserved inside the open node namespace: the authoring doors refuse them with the rename tohttp; ADR-0018 gets a dated note naming the three reserved retired names (Tier H, the maintainer's merge); the entry retires; objectui's simulator, inspector alias, canvas case and preview samples move tohttp(on objectui#12334).eventType: 'webhook'on a wait node is untouched.Part of #23543, with a contract-tier review (Clause-②: yes (narrowing)), a BREAKING changeset and the verdict-list pin inconversions.test.tsupdated; order F1 → F5-jsx → F3 → F2 → F4 → F5-http;tscand the parse-time prescription are the whole channel, no staged window and no double spelling.Workload of the letters (the card's tables): spec lane · 6 PRs (F4 and F5-http each with an objectui follow-up; F5-http with one Tier H ADR-0018 note) · precedent PR #23523 (+543/−158, 21 files, 7 entries).
Execution: this card is the execution card:
needs-user-decisionremoved andpm:queueadded in this act fordomain:spec(priority:p1+target:v18stand); the body's first line carriesRuled:. The card closes when all six have landed and the verdict-list pin reads no kept-without-ruling entry.objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 1 (second shift) · 2026-10-15T01:22Z · family F1 of ruling
6182001882:'mongo'retires as adatasource.drivervalue. The PR isPart of #23543; F5-jsx, F3, F2, F4 and F5-http follow on this card one at a time, in the ruling's order.Session:
session_01LFqdRsuM5nkqoJdHd5ztVkAccount:
os-bill(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23543-retire-mongo-driver-aliasWorktree:
objectstack-issue-23543Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface (at
origin/maincdc42eb49or later; stop on a breach and explain it in the report):packages/spec/src/data/driver/config-registry.zod.ts: themongodbrow's'mongo'alias (:183) and the docblock that names it.'mongo', with the prescription namingmongodb, whereverpackages/spec/src/data/**parsesdatasource.driver.packages/spec/src/conversions/registry.ts: thedatasource-driver-mongo-to-mongodbentry only, which getsretiredFromLoadPath.packages/spec/src/conversions/conversions.test.ts: the verdict-list pin and that entry'sdescribeblock.packages/spec/src/migrations/entries/for the stored-row rewrite, plus the outputs the generators write.'mongo'alias outsidepackages/specthat the pin sweep finds, measured..changeset/23543-f1-*.md.MAJOR_18_CONVERSIONS: that is [finding] AdminScope.manageBindings and authorEnvironmentSets are honoured by no write path after C3; the ADR-0090 D9/D12 junction gates are unmeasured; permissions docs describe removed gates #23488's.Container & model:
M,mode:subagent,model: default tier(dispatch-gates --tier --repo objectstack-ai/objectstack: "no path-derived mandate"); review ceilingCONTRACT_REVIEW_TIER, reason:Clause-②: yes (narrowing)per the ruling, a retired published spec value.Clause-②: yes
Responsibility: n/a — not a defect card
Thread-read: 6182001882
Ruling-ref: 6182001882
Serial constraints cleared:
config-registry.zod.ts,registry.tsorconversions.test.ts.os validaterefuses: cross it to the runtime door, and on what evidence #23388) adds other semantic entries as new files: disjoint.MAJOR_18_CONVERSIONSentry and its own D3 file: another region, so ordinary concurrency. The later lander mergesmainand regenerates throughscripts/pm/os-regen-merge.sh.pm:queuewith aRelease:line naming F1 done and the five families left.objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 23543,
"status": "done",
"branch": "claude/issue-23543-retire-mongo-driver-alias",
"pr": "#23600",
"session": "session_01LFqdRsuM5nkqoJdHd5ztVk (subagent = parent's; transcript Claude-Session line)",
"premise_still_valid": true,
"summary": "F1 only. An authored datasource.driver 'mongo' is now refused at parse by DriverType with the prescription naming mongodb. The refusal is spelled as a JSON-Schema-projectable pattern derived from a new retiredAliases column on the driver vocabulary row (exported RETIRED_DRIVER_ID_GUIDANCE). 'mongo' left the boot selection face, so both hosts refuse OS_DATABASE_DRIVER=mongo with their Supported-drivers list naming mongodb. datasource-driver-mongo-to-mongodb now sets retiredFromLoadPath with retiredAfter 17.7.0, and D3 entry 18.datasource-driver-mongo-alias-retired joins it. The verdict-list pin moves the entry to the retired side. Mechanism assumption 1 is partly falsified: deleting the alias outright (measured on fa6a608) made a raw stored legacy 'mongo' row serve all ten mongodb passthrough secrets in cleartext through redactStoredMetadataBody, and turned 4 stored-row/contract pins red. So the spelling stays on the CONTRACT face only (resolveDriverId('mongo') = mongodb), the memory engine's posture. With it there, no D2 reorder was needed. F5-jsx, F3, F2, F4 and F5-http stay on the card.",
"tests": "Readings on head acf0e6c (origin/main 32e03d2 merged via os-regen-merge.sh). spec: pnpm --filter @objectstack/spec test = 678 files / 20738 passed; typecheck (tsc + scripts + test layer) exit 0; test:repo 61 / 1033 passed (run before the PM's 03:40Z lock note); build + check:generated = 'All 14 generated artifacts are up to date' (api-surface/data.json and export-origins/data.json regenerated for the one new export). cli: vitest --project unit full tier = 290 files pass (288 in the first run + the 2 build-dependent published-subpath pins, which failed only with 'packages/cli is not built' and passed 2/29 after pnpm --filter @objectstack/cli build); typecheck exit 0 (check:test-typecheck OK). The six touched or pinning cli files: 6 / 113 passed. runtime: typecheck exit 0; vitest --project local 382 files / 5717 passed, 19 skipped. service-datasource: typecheck exit 0; vitest 45 files / 838 passed. drivers: no packages/drivers/driver-* src reads a datasource.driver value (zero hits for resolveDriverId / resolveDatabaseDriverId / DRIVER_ID_ALIASES / DatasourceSchema / DriverType in src), so no driver suite is owed. Ablation (one behaviour, through scripts/ablation-replace.mjs, with on-disk proof: anchor 1->0, blob 3ae04c6f21b1->2a33e628bb45, injected text grep -c 1): with DriverType's retired-spelling patterns emptied, 6 tests went red across conversions.test.ts, config-registry.test.ts and retired-key-removal-version.pin.test.ts (direction: red). The restore was proven blob == HEAD and git diff HEAD empty. Spec tests resolve src, so no dist rebuild leg applies. Premise measurement: an in-memory retirement probe on dist showed driver 'mongo' passing defineStack silently, with no refusal, before this change.",
"gates": "dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 117 commands at acf0e6c (identical to the 81eb862 derivation). Each was run one by one with its exit code captured before any pipe, one log per command. dispatch-gates --ran: '117 derived famil(ies) accounted for — 112 run, 5 NOT-MEASURED (5 DERIVED from a recorded exit 3)', exit 0. 111 of the 112 run families exit 0, including check-adr-0087-registration --base origin/main ('BREAKING+bang+clause-②-narrowing, registered datasource-driver-mongo-alias-retired (new here)'), check:api-surface, check:generated, check:docs, check:liveness, check:doc-authoring and check:nul-bytes. The 112th, pnpm check:platform-checklist, exits 1 on anchors outside this diff (attachments-storage / search areas: protocol.ts#countable is absent on origin/main itself; zero overlap with the diff); it is kept out of per-PR CI by decision (checklist-status.yml:18). NOT MEASURED, each a PREREQUISITE NOT MET exit 3: check-plugin-teardown-shape --self-test (shallow clone), spec check:skill-examples (client SDK not built), check:dual-build-cjs-loads (full build absent), check:i18n-coverage (examples' connector-slack dist absent; check:i18n and check:i18n-walk-parity went green on a rerun after the cli build), check:type-check-debt (its inner lock call timed out). PR check-runs read once on acf0e6c: 41 total, 36 success and 5 skipped, 0 failing or pending. This includes Lint & Repo Gates, TypeScript Type Check, Test Core (1-6/6), Build Core, Governed Surface Queue Guard, Check Changeset, Dogfood Regression Gate, Console Pin Gate, Spec property liveness and Temporal Conformance, all success.",
"mcp_calls": "0",
"api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, objectstack-fleet[bot]): (1) pr_create, which executed POST /repos/objectstack-ai/objectstack/pulls (draft #23600; 9086 bytes sent, 9086 stored, identical) and POST /repos//issues/23600/assignees (os-bill, confirmed); (2) this os-dev-report comment, POST /repos//issues/23543/comments. label-write: zero writes (none named; skip-changeset not applicable). git push is not counted. REST reads only otherwise: the issue, its comments, and the commit check-runs.",
"open_questions": [
{
"question": "The claim's line
Clause-②: yesis copied verbatim to the PR body's head, as instructed. Ruling item 7 spells itClause-②: yes (narrowing), and the diff does both: it widens the public surface (export RETIRED_DRIVER_ID_GUIDANCE) and narrows the accept set. The changeset carries the ruling'syes (narrowing). Should the PR body line gain the arm?","options": [
"A: the seat amends the PR body line to
Clause-②: yes (narrowing)(dev wrote the body once and does not PATCH it)","B: leave it; Check Changeset reads
yes(minor) and the ADR-0087 gate reads the changeset's arm"],
"recommendation": "A, because the ruling names the arm and the body is the carrier
check-changeset-no-majorreads; both gates are green either way today"}
],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed — check:platform-checklist is red on origin/main 32e03d2's tree. docs/qa/platform-checklist areas/search.json cites packages/metadata-protocol/src/protocol.ts#countable, which
git grepfinds absent on origin/main, and areas/attachments-storage.json reports SYMBOL ANCHORS LOST, 27 against a floor of 28. The family is kept out of per-PR CI; its daily watchdog is the patrol that owns it. Zero overlap with this diff. Dedupe words: platform-checklist anchor countable attachment-access-hooks canEdit floor","carrier: the F3 and F2 PRs on #23543 · noted, not filed — after this PR, the load-path conversions that
os migrate meta --from 16replays are retry-policy-converged and F3's two lifts. The re-pointed suites (cli migrate-meta-load-conversions, migrate-meta-composed-load-conversions, the load-path case of migrate-meta-composed, spec stack-authored-input) lose their last real subject when F3 and F2 land, and need a synthetic probe or retirement there. Dedupe words: load-path conversion authored-source shim retryDelayMs stack-authored-input"],
"deviations": [
"Mechanism assumption 1 changed route: the alias left the selection face and authoring, and kept the contract face (retiredAliases column), instead of being deleted. Evidence is above. The refusal is a regex
pattern, not enumWithRetiredValues, because driver is an open z.string(). A first superRefine spelling was refused by the build's dropped-refinement gate.","A new public export, RETIRED_DRIVER_ID_GUIDANCE (api-surface +1). DriverType reads it cross-module.",
"Files outside the claim's literal list, each a pin-sweep or false-text hit: packages/spec stack-authored-input.test.ts, retired-key-removal-version.pin.test.ts, datasource.test.ts, driver/mongo.zod.ts and mongo.test.ts (comments), liveness/datasource.json (note); cli driver-vocabulary-parity.test.ts, src/utils/config.ts (docblocks), test/migrate-meta-load-conversions.test.ts, test/migrate-meta-composed-load-conversions.test.ts, test/migrate-meta-composed.test.ts; service-datasource src/driver-catalog.ts (comment); drivers/driver-mongodb/README.md (published, hence a patch row in the changeset); content/docs/data-modeling/drivers.mdx. MAJOR_18_CONVERSIONS and every other conversion entry are untouched.",
"Declared narrowing: per the PM's 03:40Z note, no package test:repo after that point, so runtime test:repo is left to CI (Test Core green). The spec test:repo run (61 files) happened before the note.",
"One locked closure build was wrapped in
timeout 590and the wrapper killed turbo mid-run (runtime and service-automation build tasks force-killed). It was re-run clean under the lock: 60/60, 47 cached.","The harness reminder's model-named Co-Authored-By trailer was not used. Commits carry the model-free pair the pre-push hook checks, and check:commit-card-trailers was green on every push."
],
"line_budget": "n/a — no skills/** file and no line-ratcheted ledger in the diff",
"files_changed": "23 files, +557/-162 vs merge-base: .changeset/23543-f1-retire-mongo-driver-alias.md; content/docs/data-modeling/drivers.mdx; packages/cli/src/utils/config.ts; packages/cli/src/utils/driver-vocabulary-parity.test.ts; 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/drivers/driver-mongodb/README.md; packages/services/service-datasource/src/driver-catalog.ts; packages/spec/api-surface/data.json; packages/spec/export-origins/data.json; packages/spec/liveness/datasource.json; packages/spec/src/conversions/conversions.test.ts; packages/spec/src/conversions/registry.ts; packages/spec/src/data/datasource.test.ts; packages/spec/src/data/datasource.zod.ts; packages/spec/src/data/driver/config-registry.test.ts; packages/spec/src/data/driver/config-registry.zod.ts; packages/spec/src/data/driver/mongo.test.ts; packages/spec/src/data/driver/mongo.zod.ts; packages/spec/src/migrations/entries/semantic/18.datasource-driver-mongo-alias-retired.ts; packages/spec/src/shared/retired-key-removal-version.pin.test.ts; packages/spec/src/stack-authored-input.test.ts"
}
Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
ACCEPT → PR #23600 comment 6184470731 ·
domain:specseat 2 · sessionsession_01LFqdRsuM5nkqoJdHd5ztVk· 2026-10-15T04:32Z · family F1; the contract review atCONTRACT_REVIEW_TIERis owed before the queue.objectstack-fleet commentedon Oct 15, 2026
Release: session
session_01LFqdRsuM5nkqoJdHd5ztVk(domain:specseat 2) · F1 landed asPart of; claim6182201116covered F1 only · back topm:queuefordomain:spec, next family F5-jsx · 2026-10-15T05:33ZLanding record, PR #23600 (F1 of ruling
6182001882):origin/mainbc0538a429"feat(spec)!: retire the datasource driver spelling mongo …" (git branch -r --contains→origin/main)gh-readonly-queue/main/*ref names #23600git patch-id --stableequal:1bb5ac36786ffor bothacf0e6c1f(ACCEPT6184470731, contract review PASS on that head) and the squashPart of: nothing closed it (closed_bynone)Left on this card, in the ruling's order (item 7): F5-jsx → F3 → 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 inconversions.test.ts. The last family's PR isFixes #23543.Carry-forward for the next dispatch:
packages/specplus the conversion's readers, which makes it a build-heavy closure. Until [Decision] Three spec contract dev agents in one container queued ~70 min each on the shared verify lock: leave packagetest:repoto CI, and send build-heavy cards to cloud sessions? #23607 is ruled, this seat sends such families as cloud sessions.objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 2 (second shift) · 2026-10-15T05:36Z · family F5-jsx of ruling
6182001882(item 5):'jsx'retires fromPageSchema.kindnaminghtml, together with theCOMPILED_PAGE_KINDSbranch; thepage-kind-jsx-to-htmlentry retires. The PR isPart of #23543; F3, 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 asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23543-retire-jsx-page-kindWorktree:
objectstack-issue-23543Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface (at
origin/mainbc0538a42or later; stop on a breach and explain it in the report):packages/spec/src/ui/page.zod.ts:PageSchema.kind's'jsx'member throughenumWithRetiredValuesnaminghtml,COMPILED_PAGE_KINDS, and the source-kind list beside it.packages/spec/src/conversions/registry.ts: thepage-kind-jsx-to-htmlentry only, which getsretiredFromLoadPath.packages/spec/src/conversions/conversions.test.ts: the verdict-list pin and that entry'sdescribeblock. Any D3 entry the stored-row rewrite needs underpackages/spec/src/migrations/entries/, as F1 (PR feat(spec)!: retire the datasource driver spelling mongo — refused naming mongodb, its D2 conversion leaves the load path (F1 of #23543) #23600) did.'jsx'readers outsidepackages/specthat the pin sweep finds, measured:metadata-protocol/src/runtime-authoring-gate.ts(COMPILED_PAGE_KINDS),cli/src/utils/sdui-manifest.tsandi18n-extract.ts, andlint/src/page-walk.ts,validate-jsx-pages.ts,validate-page-source-styling.tsandauthoring-rules.ts..changeset/23543-f5-jsx-*.md.htmlis on release(v18): objectui's first 18.x release — the syncmajor, Changesets pre mode onnext, and the two gate edits (the maintainer's ruling on #12030), after #12030 lands objectui#12334. ⛔ Not any other conversion entry.Container & model:
M,mode:cloud,model: default tier(dispatch-gates --tier --repo objectstack-ai/objectstack: "no path-derived mandate"). Cloud by the seat's interim rule ([Decision] Three spec contract dev agents in one container queued ~70 min each on the shared verify lock: leave packagetest:repoto CI, and send build-heavy cards to cloud sessions? #23607):packages/specplusmetadata-protocol,cliandlintis a build-heavy closure. Review ceilingCONTRACT_REVIEW_TIER, reason:Clause-②: yes (narrowing)per the ruling (a retired published spec value).Clause-②: yes
Responsibility: n/a — not a defect card
Thread-read: 6185220492
Ruling-ref: 6182001882
Serial constraints cleared:
bc0538a42, record6185220492).MAJOR_18_CONVERSIONSentry inregistry.ts. That is another region: the later lander mergesmainand regenerates throughscripts/pm/os-regen-merge.sh. Draft PR feat(lint)!: the two page component rules run on the runtime publish door (ruling B) #23418 ([Decision] Pages saved through Studio, REST or MCP skip the component-props rule thatos validaterefuses: cross it to the runtime door, and on what evidence #23388) editsprotocol.runtime-authoring-gate.test.ts, and so may this PR: same rule.page.zod.tsor the ui generated shards, so the shard queue (landing-operations D) is free. spec:PageTypeSchemasayshomeis "the platform-level landing page" andutilitya "floating utility panel", but the landing is the first navigation item and both types render as ordinary inline pages #23610's execution PR, which will editpage.zod.ts, waits on its ruling, and this seat dispatches it after this family lands or mergesmainbehind it.6185014283) is onprotocol.ts,packaged-base-regime.tsandapi/protocol.zod.ts: disjoint.objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 23543,
"status": "done",
"branch": "claude/issue-23543-retire-jsx-page-kind",
"pr": "#23638",
"session": "session_01DdfPiKZUYAduc1ERcEvDso (cloud dev; dispatched by seat session_01LFqdRsuM5nkqoJdHd5ztVk)",
"premise_still_valid": true,
"summary": "F5-jsx only. PageSchema.kind is now enumWithRetiredValues(['full','slotted','html','react'], PAGE_KIND_RETIRED_GUIDANCE): an authored kind 'jsx' fails tsc and is refused at parse with the prescription naming html (defineStack: STACK_SCHEMA_INVALID / 422 at pages.0.kind). COMPILED_PAGE_KINDS is ['html']; page-kind-jsx-to-html sets retiredFromLoadPath with retiredAfter 17.7.0; D3 entry 18.page-kind-jsx-retired (no conversionIds: protocol 11 is below the migration floor, so no step replays it, and the prescription carries no os migrate meta sentence). Every non-test 'jsx' reader in metadata-protocol, cli and lint dropped its branch. Mechanism assumption 1, first branch, holds: the stored-row seams replay the retired entry (applyConversionsToStoredItem, includeRetired), so a stored jsx page loads as html, which is pinned; the save door does not convert pages and refuses jsx with a 422. Assumption 5 holds too: jsx was the live-conversion subject of 3 cli e2e suites, stack-conversions-record, conversions.test cases and a metadata-core firing control, all re-pointed (flow-node-http-callout-rename / page-component-visibility-to-visibleWhen).",
"tests": "Final head 831a9fa (origin/main f7cd580 merged via os-regen-merge.sh, no conflict, check:generated 'All 14 generated artifacts are up to date'). Post-merge: spec src/conversions+migrations+ui+shared+stack-conversions-record 195 files / 6977 passed; metadata-core 18 / 719 passed; metadata-protocol 236 files / 20550 passed, 19 skipped. Pre-merge (5bf2584): spec full suite 740 files, 21785 passed with 4 failures in one file (page-requires-compiled-kinds.test.ts), which was fixed and re-run at 8 files / 567 passed; spec typecheck exit 0; lint 139 / 6771 passed plus typecheck; metadata-protocol 237 / 28429 passed plus typecheck; metadata-core 18 / 701 passed plus typecheck; cli unit tier 290 files / 4323 passed plus typecheck; the 3 edited nightly-tier cli e2e suites (OS_TEST_TIERS=nightly) 3 / 35 passed; pnpm check:i18n OK. Ablation via scripts/ablation-replace.mjs: kind back to a bare z.enum of the four kinds, so the prescription is dropped; anchor 1->0, blob 4ceaa5dffafc->35fbaad1835c; 2 tests went red (conversions.test defineStack refusal; retired-key-removal-version pin row), direction red; restore blob == HEAD and git diff HEAD empty; spec tests resolve src, so no dist leg.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack derived 118 commands on 5bf2584; each was run with its exit code captured before any pipe, one log per command. --ran (the record carries exit codes): '118 derived famil(ies) accounted for - 116 run, 2 NOT-MEASURED (2 DERIVED from a recorded exit 3)', exit 0. 115 exit 0, including check-adr-0087-registration, check:spec-changes, check:upgrade-guide, check:docs, check:liveness, check:doc-authoring, check:nul-bytes, check:i18n-stale-fill, check:api-surface, check:generated and check:i18n-coverage; the last three first exited 3 on a stale spec dist or a missing example build and were re-run green after a rebuild. 1 exit 1: check:platform-checklist, ABSENT SYMBOL anchors in metadata-protocol/src/protocol.ts and service-storage attachment-access-hooks.ts, neither touched by this diff (the same main-tree red F1 reported). NOT MEASURED: check-plugin-teardown-shape --self-test (shallow clone) and check:dual-build-cjs-loads (full build absent). PR check-runs read once on 831a9fa: 24 total, 22 in_progress, 1 success, 1 skipped, 0 failing (in_progress is the honest value; not waited on).",
"mcp_calls": "0",
"api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches as objectstack-fleet[bot]): (1) pr_create, which executed POST /repos/objectstack-ai/objectstack/pulls (draft #23638; 11432 bytes sent, 11432 stored, identical) and POST /repos//issues/23638/assignees (os-bill, confirmed); (2) this os-dev-report comment, POST /repos//issues/23543/comments. label-write: zero (none named). git push not counted. Reads were unauthenticated REST only.",
"line_budget": "n/a - no skills/** file and no line-ratcheted ledger in the diff",
"files_changed": "44 files vs merge-base (+~400/-~200): .changeset/23543-f5-jsx-retire-page-kind-jsx.md; content/docs/ui/pages.mdx; content/docs/ui/react-pages.mdx; content/docs/references/ui/page.mdx (generated); packages/spec: src/ui/page.zod.ts, src/ui/page.form.ts, src/conversions/registry.ts, src/conversions/walk.ts, src/conversions/conversions.test.ts, src/migrations/entries/semantic/18.page-kind-jsx-retired.ts (new), 18.page-requires-non-compiled-kind-refused.ts, 18.ui-html-page-div-refused.ts, src/migrations/registry.ts.template, src/shared/retired-key-removal-version.pin.test.ts, src/stack-conversions-record.test.ts, src/ui/object-refinement-check-exports.test.ts, src/ui/page-print.test.ts, src/ui/page-requires-compiled-kinds.test.ts, liveness/page.json; packages/metadata-protocol: src/runtime-authoring-gate.ts, src/protocol.batch-verb-driver-text.test.ts (comment); packages/metadata-core: src/artifact-forward-conversion.test.ts; packages/cli: src/utils/sdui-manifest.ts, src/utils/sdui-manifest.test.ts, src/utils/i18n-extract.ts, test/lint-conversion-notices.e2e.test.ts, test/build-json-failure-conversions.e2e.test.ts, test/validate-json-failure-conversions.e2e.test.ts; packages/lint: src/page-walk.ts, src/page-walk.test.ts, src/page-walk-conversion-parity.test.ts, src/validate-jsx-pages.ts, src/validate-jsx-pages.test.ts, src/validate-page-source-styling.ts, src/validate-page-source-styling.test.ts, src/validate-action-name-refs.test.ts, src/authoring-rules.ts, src/rule-explanations.ts, src/validate-translation-references.ts; packages/platform-objects: src/apps/translations/{en (generated),zh-CN,ja-JP,es-ES}.metadata-forms.generated.ts",
"deviations": [
"Files beyond the claim's surface, each a pin-sweep or false-text hit: metadata-core artifact-forward-conversion.test.ts; spec stack-conversions-record, object-refinement-check-exports, page-print and page-requires-compiled-kinds tests; walk.ts and liveness/page.json; two D3 entries and one step-18 rationale paragraph whose text named jsx as live; cli e2e suites; content/docs/ui/pages.mdx and react-pages.mdx; and three hand-written translated help-text values (zh-CN, ja-JP, es-ES), where editing a value is allowed and the key set is unchanged. MAJOR_18_CONVERSIONS and every other conversion entry are untouched.",
"Changeset bumps metadata-protocol, cli and lint at patch, beside spec minor, because their runtime readers changed.",
"The worktree was created from origin/main 9a6f790 (newer than the dispatch's bc0538a) after detaching the primary checkout, which had the branch checked out.",
"The harness reminder's model-named Co-Authored-By trailer was not used; commits carry the model-free pair the pre-push hook checks (check:commit-card-trailers green on every push)."
],
"open_questions": [
{
"question": "skills/objectstack-ui/rules/pages.md:138 still says kind 'jsx' is a deprecated alias for 'html', which is false after this PR. The file is a governed Tier H surface, so editing it here would make this whole PR Tier H. Left untouched.",
"options": [
"A: the seat files or sends a one-line skills-only PR (Tier H, maintainer merge) that drops the sentence",
"B: fold it into this PR and accept Tier H landing"
],
"recommendation": "A, because it keeps this contract-tier PR landable by the seat; the one sentence is a doc fix, not a contract change"
}
],
"out_of_scope_findings": [
"carrier: objectstack-ai/objectui#12334 (the ruling's objectui half) - noted, not filed. At the pinned .objectui-sha b9814b3, objectui reads the retired value in more places than the one console sample: packages/types/src/layout.ts:1795 overrides PageNodeSchema.kind with a union including 'jsx' on an interface that extends the spec Page minus PAGE_SPEC_EXCLUDED (kind is not excluded). Once objectui's own spec dependency moves to this release, by reading, that is an interface-incorrectly-extends tsc error (not compiled here). Also packages/components/src/renderers/layout/page.tsx:611 has a kind === 'jsx' branch, and the types zod mirror (SpecPageFields) will refuse jsx at runtime. The Console Pin Gate is unaffected today: build-console.sh injects this tree's spec only at the vite bundle step. Dedupe words: PageNodeSchema kind jsx union layout.ts sdui-jsx-preview objectui types",
"carrier: the F5-http PR on #23543 - noted, not filed. The suites re-pointed here ride flow-node-http-callout-rename, which retires last; when it does, those suites and F1's re-pointed migrate-meta load-path suites have no live conversion left. Dedupe words: live conversion subject e2e conversions field load-path suites http_request",
"carrier: 承接者:无 - noted, not filed. check:platform-checklist is red on main's tree (absent symbol anchors in protocol.ts and attachment-access-hooks.ts), as F1 recorded; its daily watchdog owns it. Dedupe words: platform-checklist anchor countable canEdit anonymousFormIntake envWideRawViewRows"
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
ACCEPT → PR #23638 comment 6187645640 ·
domain:specseat 2 · sessionsession_01LFqdRsuM5nkqoJdHd5ztVk· 2026-10-15T08:16Z · F5-jsx on831a9fa8ea; the skillspages.mdjsx sentence rides #23610's Tier H PR on the same file; contract review atCONTRACT_REVIEW_TIERbefore ready.objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 23543,
"status": "done",
"branch": "claude/issue-23543-retire-jsx-page-kind",
"pr": "#23638",
"session": "session_01DdfPiKZUYAduc1ERcEvDso",
"round": "patch round on contract review 6187937404 (FAIL on its second part), as the seat's message asked",
"head": "2e1b65d0 (one commit on top of 831a9fa; the PR body is untouched)",
"edits": [
"1 (the FAIL) .changeset/23543-f5-jsx-retire-page-kind-jsx.md: the frontmatter gains '@objectstack/platform-objects': patch, and the body gains the row: the package publishes the Studio page form's source help text in four locales (en, zh-CN, ja-JP, es-ES), and that text no longer names jsx.",
"2 (residual 8) packages/spec/liveness/page.json, the requires row's note: before 'the key exists only on kind 'html' / 'jsx' pages, the kinds compiled at save'; after 'the key exists only on kind 'html' pages, the kind compiled at save'.",
"3 (residual 9) packages/spec/src/ui/page.form.ts:51 (a comment): before 'only the three source-compiled kinds ever read it'; after 'only the two source kinds (html / react) ever read it'. It is a comment, so no generated output changes; check:generated stays up to date.",
"4 (residual 10) The changeset and D3 entry 18.page-kind-jsx-retired.ts: before 'every door that parses a page (defineStack, os validate, os build, os lint, the metadata save door)'; after 'at os validate, os build, the metadata save door and defineStack, so under os lint too when the config calls it' (the D3 text spells the CLI 'objectstack')."
],
"gates": "Each run on 2e1b65d with its exit code captured before any pipe. check-adr-0087-registration --base origin/main: exit 0 ('[BREAKING+bang+clause-②-narrowing] registered page-kind-jsx-retired'). check-changeset-no-major --base origin/main: exit 0. check-empty-changeset --base origin/main: exit 0. pnpm changeset status --since=origin/main: exit 0, and @objectstack/platform-objects is now listed. After a spec build (exit 0): spec check:liveness exit 0; spec check:generated exit 0 ('All 14 generated artifacts are up to date'). Spec tests: src/ui, src/migrations, src/conversions and the src tests that read the liveness ledger, 182 files / 6880 passed, exit 0.",
"mcp_calls": "0",
"api_writes": "1 relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches): this comment, POST /repos//issues/23543/comments. Plus one send_message to the seat session (not a GitHub write). git push is not counted.",
"deviations": [],
"open_questions": []
}
Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
Release: session
session_01LFqdRsuM5nkqoJdHd5ztVk(domain:specseat 2) · F5-jsx landed asPart of, and claim6185261661covered F5-jsx only · back topm:queuefordomain:spec, next family F3 · 2026-10-15T09:54ZLanding record, PR #23638 (F5-jsx of ruling
6182001882):origin/mainc5dd7fce30"feat(spec)!: retire the page kind jsx …", merged 2026-10-15T09:48Z (git branch -r --contains→origin/main)gh-readonly-queue/main/*ref names #23638f9861d1dd97dequalsgit merge-tree --write-treeof its parenta647783d46with2e1b65d066. That head carries the contract review PASS6188246285, which follows FAIL6187937404on the missing@objectstack/platform-objectsrow.Part of: nothing closed itLeft on this card, in the ruling's order (item 7): F3 → F2 → F4 → F5-http.
Part of #23543, with a contract-tier review (Clause-②: yes (narrowing)), a BREAKING changeset and the verdict-list pin inconversions.test.ts.Fixes #23543.conversions.test.ts's kept-without-ruling list now holds exactly those four families' six entries.Carry-forward for the next dispatches (from the contract review's item 8):
artifact-forward-conversion.test.tsFIRING CONTROL 1 now drivespage-component-visibility-to-visibleWhen, F4's entry. F4's dispatch order names it, so the dev re-points it.flow-node-http-callout-rename: the three cli e2e suites (build-json-failure-conversions,validate-json-failure-conversionsandlint-conversion-notices, all nightly tier),stack-conversions-record.test.ts, and twoconversions.test.tscases. F5-http's dispatch order names them, because that family retires that entry last.os migrate metaload-path suites, as F1's record said.packages/specplus the readers). Until [Decision] Three spec contract dev agents in one container queued ~70 min each on the shared verify lock: leave packagetest:repoto CI, and send build-heavy cards to cloud sessions? #23607 is ruled, this seat sends them as cloud sessions.The objectui half: the ruling put the console sample's move on objectstack-ai/objectui#12334, which closed at 01:40Z without it. Under cross-repo rule 3, this seat filed objectstack-ai/objectui#12464, with
Blocked-by:this PR. It names four sites on objectuimaincf430cd10:apps/console/src/sdui-jsx-preview.tsx:87;PageNodeSchema.kind,packages/types/src/layout.ts:1795;packages/components/src/renderers/layout/page.tsx:682;The ACCEPT's "types zod mirror" does not exist:
packages/types/src/zod/carries no'jsx'page kind.Rides elsewhere:
skills/objectstack-ui/rules/pages.md:138still callsjsxan alias ofhtml. That file is governed, so the sentence rides #23610's Tier H PR on the same file (ACCEPT item 6).objectstack-fleet commentedon Oct 15, 2026
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 awaitorconnector_actionnode'sconfigare refused, with the prescription naming the sibling block. The lift deletes a loose key the block shadows at rehydration, so stored flows keep loading, andflow-node-wait-event-config-liftandflow-node-connector-config-liftsetretiredFromLoadPath. The PR isPart 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 asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23543-retire-wait-connector-config-liftWorktree:
objectstack-issue-23543Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface (at
origin/main9bb93706for later; stop on a breach and explain it in the report):packages/spec/src/automation/(flow.zod.tsandbuiltin-node-config.zod.ts): the refusal of the loose keys underwaitandconnector_actionconfig, namingwaitEventConfigandconnectorConfig.packages/spec/src/conversions/registry.ts: the two entries only (retiredFromLoadPath, and the rehydration-time delete of a shadowed loose key).conversions.test.ts: the verdict-list pin and the two entries'describeblocks. The D3 entries underpackages/spec/src/migrations/entries/.packages/services/service-automation/src/builtin/wait-node.tsandconnector-nodes.tswith their tests, andpackages/spec/src/automation/connector-action-config-required.test.ts.os migrate metaload-path suites that F1's record (6185220492) names for F3 and F2: the CLI'smigrate-meta-load-conversions,migrate-meta-composed-load-conversionsand the load-path case ofmigrate-meta-composed, plus the spec'sstack-authored-input. They are re-pointed or retired, with the reason in the report..changeset/23543-f3-*.md.MAJOR_18_CONVERSIONS. ⛔ Not objectui.Container & model:
M,mode:cloud,model: default tier(dispatch-gates --tier --repo objectstack-ai/objectstack: "no path-derived mandate"). Cloud by the seat's interim rule ([Decision] Three spec contract dev agents in one container queued ~70 min each on the shared verify lock: leave packagetest:repoto CI, and send build-heavy cards to cloud sessions? #23607):packages/specplusservice-automationand the CLI suites is a build-heavy closure. Review ceilingCONTRACT_REVIEW_TIER, reason:Clause-②: yes (narrowing)per the ruling.Clause-②: yes
Responsibility: n/a — not a defect card
Thread-read: 6189368882
Ruling-ref: 6182001882
Serial constraints cleared:
c5dd7fce30, record6189368882). The ruling's order puts F3 next.packages/spec/src/automation/,conversions/registry.ts,conversions.test.tsorservice-automation's wait and connector nodes. PR feat(spec)!: a page declares nothing the console does not honour — isDefault only on a bound record page, a closed template set, regions its template places #23708 holds the ui generated shards only. Draft PR feat(lint)!: the two page component rules run on the runtime publish door (ruling B) #23418 editsregistry.ts.template: the later lander mergesmainand regenerates throughscripts/pm/os-regen-merge.sh.datasourcesaccepts a datasource nameddefault, which every boot refuses as host-reserved —defineStack/os validate/ publish pass a config that boots in no posture #23634, dispatched in the same act, is onstack.zod.ts: disjoint.objectstack-fleet commentedon Oct 15, 2026
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
objectstack-fleet commentedon Oct 16, 2026
Release: session
session_01LFqdRsuM5nkqoJdHd5ztVk(domain:specseat 2) · F3 landed asPart of, and claim6203354520covered F3 only · back topm:queuefordomain:spec, next family F2 · 2026-10-16T01:02ZLanding record, PR #23742 (F3 of ruling
6182001882):origin/maind176b0aab3"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)gh-readonly-queue/main/*ref names #23742bc058a33e668equalsgit merge-tree --write-treeof its parent941c78ae2ewith23bebd666b. That head carries contract review PASS6205149412and ACCEPT6205192514.Part of: nothing closed itLeft on this card, in the ruling's order (item 7): F2 → F4 → F5-http.
Part of #23543, with a contract-tier review (Clause-②: yes (narrowing)), a BREAKING changeset and the verdict-list pin inconversions.test.ts.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-convergedandview-visibleOn-to-visibleWhen.Carry-forward for the next dispatches (from the contract review's ③):
os migrate metaload-path suites (packages/cli/test/migrate-meta-load-conversions.test.ts,migrate-meta-composed-load-conversions.test.ts,migrate-meta-composed.test.ts) andpackages/spec/src/stack-authored-input.test.tsall driveretry-policy-converged, F2's entry. F2 retires their last live subject, so its PR gives them a synthetic probe or retires them, with a reason for each. F2's dispatch order names them.6189368882still stand.protocol.ts) canonicalizes every retired flow entry, as a recorded verdict ([P2] A Studio edit heals every legacy row except a flow's —saveMetaItemre-persists the pre-protocol dialect an author was served #4542, build: ascriptnode's undeclared config key passesobjectstack validate,compileandregisterFlow, then fails every run — the key half of #21898's class (subflowby reading) #21982); F3's PR left it untouched.protocol.tsdecision for every retired flow entry, the seven spec(conversions): 15 ADR-0087 D2 conversions are still on the load path at 18 though their window closed (10toMajor: 17, 5 older): retire each or record why it stays, one verdict per entry (family closing card after #23421) #23487 retirements included, so it is not a family rider.retryDelayMs→backoffMsand F5-http's node-type rename meet the same door, so one answer serves all three. The seat presents it as its own decision. A family PR does not wait on it, because none of them touchesprotocol.tseither way.packages/specplus the readers). Until [Decision] Three spec contract dev agents in one container queued ~70 min each on the shared verify lock: leave packagetest:repoto CI, and send build-heavy cards to cloud sessions? #23607 is ruled, this seat sends them as cloud sessions.objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 3 · 2026-10-16T02:28Z · family F2 of ruling
6182001882(item 2, the loud form). Ajob.retryPolicyblock whosemaxRetriesis omitted or 0 is refused, in the shapeflow.errorHandlinguses forstrategy: 'retry'. A job with no block stays a single attempt, andbackoffMultiplierkeeps its declared default.retry-policy-convergedthen setsretiredFromLoadPath. The PR isPart 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 asGET /useranswers it; this card's assignee)Branch:
claude/issue-23543-f2-retry-policy-refusedWorktree:
objectstack-issue-23543-f2(in the cloud session's container)Domain:
domain:specSeat:
domain:spec#1(seat post #6017)File surface (at
origin/main0b1179f33or later; stop on a breach and explain it in the report):packages/spec/src/system/job.zod.ts(andpackages/spec/src/shared/retry-policy.zod.tsonly if the refusal must live there): the refusal of aretryPolicyblock withmaxRetriesomitted or 0, with the ruling's prescription.packages/spec/src/conversions/registry.ts: theretry-policy-convergedentry only (retiredFromLoadPath,retiredAfter).conversions.test.ts: the verdict-list pin and that entry'sdescribeblocks. The D3 entry underpackages/spec/src/migrations/entries/, and the removal-version JOIN row if one is owed.6205630082) names, which all driveretry-policy-convergedas their last live subject: the CLI'smigrate-meta-load-conversions,migrate-meta-composed-load-conversionsandmigrate-meta-composed(its load-path case), and the spec'sstack-authored-input. Each gets a synthetic probe or is retired, with a reason per suite in the report.packages/services/service-job/src/run-with-policy.tsnames the entry), and any example that authors ajob.retryPolicywithoutmaxRetries..changeset/23543-f2-*.md.MAJOR_18_CONVERSIONS, and not the metadata save door (protocol.ts), which the seat presents as its own decision. ⛔ Not objectui.Container & model:
M,mode:cloud(the maintainer's word in this session's chat: 「batch 调到 5, 可以开云卡」; a build-heavy closure, as seat 2 noted for every family),model: default tier(dispatch-gates --tier --repo objectstack-ai/objectstack: no path-derived mandate). The review owed before the queue is atCONTRACT_REVIEW_TIER: facepackages/spec/src/**,Clause-②: yes (narrowing)per ruling item 7.Clause-②: yes
Responsibility: n/a — not a defect card
Thread-read: 6205630082
Ruling-ref: 6182001882
Serial constraints cleared:
d176b0aab3, record6205630082). The ruling's order puts F2 next.Claim:of all 21 openpm:dispatchedcards was read in this act, and none names this surface.page:headershowStaris declared but no longer reaches a user in the reference console: since objectui#12427 the star draws only where a host wires a favorites toggle, and no host does #23650) adds an entry toconversions/registry.tsand a row toretired-key-removal-version.pin.test.ts; PR feat(spec)!: delete checkPageComponentViewData; the component-props rule is the one judge of a page component's retired api data binding #23784 (page: deletecheckPageComponentViewDataonce PR #23418 moves the component-props rule onto the save door — ruling6161173492item 6, the follow-up for #23357 #23447, seat 2) editsconversions/refused-shapes.ts. Different entries; the later lander mergesmainthroughscripts/pm/os-regen-merge.sh.wip(spec): refuse a job retryPolicy with no attempts; retire retry-po…
objectstack-fleet commentedon Oct 16, 2026
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
objectstack-fleet commentedon Oct 16, 2026
ACCEPT → PR #23810 comment 6207800896 ·
domain:specseat 1 · sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T04:03Z · family F2. The contract review (CONTRACT_REVIEW_TIER) and an all-green head stand before the queue. The PR isPart 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, theshared/retry-policy.zod.tscomments, oneliveness/flow.jsonnote, and the regeneratedcontent/docs/references/system/job.mdx.objectstack-fleet commentedon Oct 16, 2026
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 metalists 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 metalists 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 writesmaxRetries: 0it 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
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 23543,
"status": "done",
"branch": "claude/issue-23543-f2-retry-policy-refused",
"pr": "#23810",
"session": "session_01MT2aGLQQhH8ZsPrgqHMrwz",
"round": "sync round asked by seat 1 (session_01HjR8RUwTPQ3TgbfKihmxp9) after PR #23781 landed on main; same claim 6206691402",
"head": "27418495",
"merge_commit": "27418495, parents dce2266 (branch) and f846cc2 (origin/main, which carries ae0ca66 from PR #23781), made by scripts/pm/os-regen-merge.sh: no conflict; step 2 kept the branch's bytes of content/docs/references/system/job.mdx (the branch changed it and main did not)",
"tests": "On 2741849: pnpm --filter @objectstack/spec exec vitest run src/conversions src/migrations src/shared src/system, 109 files / 3602 passed, exit 0 (the verdict-list pin and the removal-version JOIN pin hold with #23781's entry and row; no fix needed). CLI unit tier: migrate-meta-load-conversions, migrate-meta-composed-load-conversions and migrate-meta-composed, 3 files / 18 passed, exit 0. CLI integration tier: retry-policy-key-validate-door, 1 file / 2 passed, exit 0 (after the cli dependency closure was rebuilt, exit 0).",
"gates": "pnpm install --frozen-lockfile exit 0; pnpm --filter @objectstack/spec build && check:generated exit 0 ('All 14 generated artifacts are up to date'); check:docs exit 0 ('227 generated files in sync'). Each exit code was captured before any pipe.",
"files_changed_beyond_main": "none. The merge and the regeneration changed nothing beyond main's side: the tree after build + check:generated was clean, and git diff origin/main..2741849 is exactly this PR's 18 files (+519 -202).",
"mcp_calls": "0",
"api_writes": "1 relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches): this comment, POST /repos//issues/23543/comments. git push is not counted. The PR body was not edited.",
"deviations": [],
"open_questions": []
}
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Landed · PR #23810 →
f606ba2e25(Part of, family F2 of ruling6182001882) ·domain:specseat 1 ·os-elon-musk· sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T05:59Zf606ba2e25origin/maingit merge-base --is-ancestor f606ba2e25 origin/main→ exit 0f606ba2e25equal the PR head2741849586. That head is the contract-reviewed0bc4f4286a(ACCEPT6207800896, contract review PASS6207998123) plus two moves, both on the PR body'sRegen-provenance:line: the prose-only D3reasonpatchdce22664d4, and a merge ofmainatf846cc2020throughos-regen-merge.sh. Against the reviewed head, every file's change is identical except the one prose file.gh-readonly-queue/main/pr-23810-*ref remainsPart of #23543and no closing keyword; this card is still open, as intendedRelease: session
session_01HjR8RUwTPQ3TgbfKihmxp9· because PR #23810 landed family F2 (ajob.retryPolicyblock withmaxRetriesomitted or 0 is refused, andretry-policy-convergedisretiredFromLoadPath) and the card stays open for F4 and F5-http · topm:queuefor the next claimant, assignee cleared in this act.What remains on this card, in the ruling's order: F4, then F5-http, one PR each, each on its own claim. Neither was attempted here.
Carried forward from this landing:
migrate-meta-load-conversions,migrate-meta-composed-load-conversions,migrate-meta-composed's load-path case,stack-authored-input) now drive a synthetic probe rather thanretry-policy-converged. They survive F4 and F5-http, so neither family needs to re-home them.protocol.ts) was not touched. A stored job body meets the new refusal at the door because it is judged as stored. Any change to the door is the seat's separate decision, not an F4 or F5 rider.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 6 · 2026-10-16T06:05Z · family F4 of ruling
6182001882(item 4).visibleOn(view:FormFieldSchema,FormSectionSchemaand every other view position that declares it) andvisibility(page component) retire as keys. Each becomes aretiredKey()tombstone namingvisibleWhen, with the fullspec-property-retirementkit (ADR-0087 markers, baselines, forms, docs, pins). Both entries,view-visibleOn-to-visibleWhenandpage-component-visibility-to-visibleWhen, retire in the same change, and the record / strict-exit suites re-point. The PR isPart of #23543; F5-http follows, and its PR isFixes #23543.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 asGET /useranswers it; this card's assignee)Branch:
claude/issue-23543-f4-visibility-keys-retiredWorktree:
objectstack-issue-23543-f4(in the cloud session's container)Domain:
domain:specSeat:
domain:spec#1(seat post #6017)File surface (at
origin/mainf606ba2e25or later; stop on a breach and explain it in the report):packages/spec/src/ui/view.zod.tsandpackages/spec/src/ui/page.zod.ts: the declaredvisibleOn/visibilitykeys, their docblocks, and the field-groupderivedKeyslist.RETIRED_KEYS_BY_MAJOR[18]and the removal-version JOIN rows.packages/spec/src/conversions/registry.ts: the two entries only (retiredFromLoadPath,retiredAfter).conversions.test.ts: the verdict-list pin and those entries' cases.view-spelling-walk.test.ts. The D3 entry underpackages/spec/src/migrations/entries/.packages/cli/src/commands/validate-json-strict-exit.e2e.test.ts,packages/cli/test/stack-conversion-record-door.test.tsandpackages/metadata-core/src/artifact-forward-conversion.test.ts(FIRING CONTROL 1, per F5-jsx's record6189368882). Each gets a synthetic probe or another live subject, with a reason per suite in the report.packages/lint(validate-visibility-predicates.ts,validate-predicate-path-refs.ts,authoring-rules.ts,rule-explanations.ts),packages/metadata-core/src/form-predicate-root-policy.ts,packages/sdui-parser/src/validate.ts, and theprotocol.tsread sites of the retired key, but only where a reader must move tovisibleWhen. Also any example or fixture that authors either key..changeset/23543-f4-*.md.MAJOR_18_CONVERSIONS, and not the save door's canonicalization policy for retired spellings (the seat's separate decision, carried on this card). ⛔ Not objectui.Container & model:
L,mode:cloud(the maintainer's word in this session's chat: 「batch 调到 5, 可以开云卡」; a build-heavy closure across spec, lint, metadata-core, metadata-protocol, sdui-parser and cli),model: default tier(dispatch-gates --tier: no path-derived mandate). The review owed before the queue is atCONTRACT_REVIEW_TIER: facepackages/spec/src/**,Clause-②: yes (narrowing)per ruling item 7.Clause-②: yes
Responsibility: n/a — not a defect card
Thread-read: 6209157268
Ruling-ref: 6182001882
Serial constraints cleared:
f606ba2e25, record6209157268). The ruling's order puts F4 next.Claim:of all openpm:dispatchedcards and the file lists of all 12 open PRs were read in this act. Only PR feat(spec)!: delete checkPageComponentViewData; the component-props rule is the one judge of a page component's retired api data binding #23784 (page: deletecheckPageComponentViewDataonce PR #23418 moves the component-props rule onto the save door — ruling6161173492item 6, the follow-up for #23357 #23447, seat 2) touches a neighbour: it editspage.zod.ts(checkPageComponentViewDataand itsPageSchema.superRefine), aview.zod.tscomment near:190, and the generatedapi-surface/ui.jsonandexport-origins/ui.json. Those are different hunks from F4's keys. The later lander mergesmainthroughscripts/pm/os-regen-merge.sh.major, Changesets pre mode onnext, and the two gate edits (the maintainer's ruling on #12030), after #12030 lands objectui#12334 is closed, so this seat files F4's objectui follow-up card at landing (the F5-jsx precedent, types, components, console: spec 18 refuses the page kindjsx(objectstack#23543 F5-jsx) — move the console sample tohtml, then drop the'jsx'member ofPageNodeSchema.kindand the page renderer's'jsx'branch objectui#12464), graded as the ruling says: p1 only if the designer would write the refused key.wip(spec): tombstone view form visibleOn and page component visibilit…
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 23543,
"status": "done",
"branch": "claude/issue-23543-f4-visibility-keys-retired",
"pr": "#23836",
"session": "session_014ruwnS8CSGGVA5UWfJA8xZ (this cloud dev session, from the transcript Claude-Session line; dispatched by seat session_01HjR8RUwTPQ3TgbfKihmxp9)",
"premise_still_valid": true,
"summary": "F4 of ruling 6182001882 only: the view form's visibleOn (FormFieldSchema, FormSectionSchema) and the page component's visibility (PageComponentSchema), the only three declared positions on main f606ba2, are retiredKey() tombstones naming visibleWhen. The three normalizeVisibleWhen pipes are removed. view-visibleOn-to-visibleWhen and page-component-visibility-to-visibleWhen are retiredFromLoadPath / retiredAfter 17.7.0. The registration is three RETIRED_KEYS_BY_MAJOR[18] entries plus the D3 entry ui-visibility-alias-keys-retired (no conversionIds, below the floor), and the changeset is a BREAKING minor marked registered. The live-subject suites were re-homed: stack-conversions-record got a synthetic probe; FIRING CONTROL 1, validate-json-strict-exit and stack-conversion-record-door were re-pointed to flow-node-http-callout-rename. The lint and metadata-core readers read visibleWhen only, after measuring that every door hands them a parse-accepted body. PR is Part of #23543; F5-http follows.",
"tests": "On 24622be (merge of origin/main 43567a8 via os-regen-merge.sh): spec build exit 0; check:generated 'All 14 generated artifacts are up to date'; spec test 684 files / 20896 passed (1 todo) exit 0. On 6e24206 (pre-merge; the merge touched only view.test.ts other hunks of these files): spec typecheck exit 0, test:repo 64 files / 1082 passed; lint typecheck 0, test 140 files / 6779 passed; metadata-core typecheck 0, test 18 / 734; metadata-protocol typecheck 0, test 245 files 20594 passed 19 skipped after re-spelling one graft fixture (that file 46/46); cli closure built (--filter '@objectstack/cli^...'), typecheck 0, unit tier 297 / 4432, stack-conversion-record-door.test.ts 21/21, validate-json-strict-exit.e2e.test.ts (OS_TEST_TIERS=nightly) 7/7; dogfood expression-conformance.test.ts 7/7. Live tool check of the D3 text, on a temp project carrying all three old keys: os migrate meta --from 17 exits 0, applies no edit, prints the 3 tombstone refusals under 'Migrated stack does not yet pass schema validation', and lists ui-visibility-alias-keys-retired; --write leaves the source unchanged. Ablation (scripts/ablation-replace.mjs on 6e24206): 'visibility: retiredKey(' became 'visibility: EvaluatedExpressionInputSchema.optional(), __ablationRetired: retiredKey(' in page.zod.ts, restoring the key as live. Anchor 1 -> 0, blob b8bce09a -> e5d1edef. Red: page.test.ts x2 (refusal; beside visibleWhen), retired-key-removal-version.pin JOIN row page-component-visibility-to-visibleWhen, visibility-alias-keys-retirement.test.ts x2 (@ts-expect-error type leg; defineStack page refusal). Direction red. Restore: blob == HEAD b8bce09a, git diff HEAD empty; spec tests import src, so no dist leg.",
"gates": "dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on 24622be: 123 derived, each run with its exit captured before any pipe and recorded as 'cmd :: exit N'. --ran: '123 derived famil(ies) accounted for — 119 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3)'. All 119 exited 0, including check-adr-0087-registration --base origin/main (registered ui-visibility-alias-keys-retired), check-changeset-no-major, check:spec-changes, check:upgrade-guide, check:liveness, check:docs, check:authorable-surface, check:api-surface, check:react-blocks, check:cross-package-test-inputs, check:i18n and check:doc-authoring. The 4 NOT-MEASURED are prerequisite refusals, declared to CI: check-plugin-teardown-shape --self-test (shallow clone), check:skill-examples (client dist absent), check:dual-build-cjs-loads (full build absent), check:i18n-coverage (@objectstack/connector-slack unbuilt). Local-only: check:dev-prereqs 0, check:skill-frame-freshness 0, check:nul-bytes 0. PR check-runs: in_progress at report time (not awaited, per contract).",
"mcp_calls": "2 — mcp__github__issue_read (get, get_comments on #23543). No MCP write tool.",
"api_writes": "2 relay strokes — POST /repos/objectstack-ai/objectstack/dispatches (fleet-write pr_create: POST /repos/objectstack-ai/objectstack/pulls + POST /repos//issues/23836/assignees) and POST /repos/objectstack-ai/objectstack/dispatches (fleet-write comment: POST /repos//issues/23543/comments, this report). git push is not a REST write. No label write: the PR publishes, so skip-changeset does not apply.",
"line_budget": 1849,
"files_changed": 52,
"deviations": [
"File surface widened at measured readers/subjects outside the claim list, each with its reason in the PR body. packages/spec/src/stack-conversions-record.test.ts drove page-component-visibility as its live subject (found by the full spec run); it got a synthetic probe. packages/lint/src/page-envelope-audit.ts (comments) and its test: the negative control's exemplar was the retired key. packages/metadata-protocol/src/protocol.ts (comments only) and protocol.graft-folded-form-sections.test.ts (one fixture re-spelled). packages/spec/dropped-refinements.baseline.json: 13 entries named sites through the removed pipe's .in, and the build printed the corrected entries; one site was reached one level shallower, so the header total is 763 -> 764. Five tests read the old pipe's .in.shape and moved to .shape. component.zod.ts buildObjectFormSectionFieldEntry read the pipe at runtime. evaluated-slot-population (34 -> 31) and the dogfood ADR-0058 ledger (3 covers deleted). shared/visibility.ts and visibility-strict-options.ts prose and prescription (it claimed both aliases 'still accepted'). content/docs/protocol/objectui/layout-dsl.mdx.",
"Governed path in the diff: skills/objectstack-ui/references/react-blocks.md, regenerated by gen:react-blocks. object-form sections is object[] instead of any[], because the pipe had hidden the element type; 115 -> 115 lines, published SKILL.md set unchanged. So the PR is Tier H.",
"FIRING CONTROL 1 (metadata-core) and the two cli suites were re-pointed to flow-node-http-callout-rename, not given a probe. A probe cannot reach the spec registry behind metadata-core's dist import without mocking the callee under test, or a spawned CLI loading the built spec. F5-http inherits them.",
"normalizeVisibleWhen / VISIBILITY_ALIAS_KEYS kept exported (docblock made true); see open_questions.",
"No STEP18_RATIONALE fragment: both conversions are protocol 15; F5-jsx precedent.",
"Prescriptions carry no 'os migrate meta' sentence: below the floor, and the removal-version pin's --from rule would require --from 14, which the CLI refuses.",
"lint / metadata-core / metadata-protocol / cli / dogfood readings are on 6e24206, pre-merge; the merge brought no change to their files. spec readings are on the final head 24622be.",
"Commit trailers use the model-free pair AGENTS.md prescribes (Claude-Session + Co-authored-by: Claude), not the harness-suggested model-named trailer."
],
"open_questions": [
{
"question": "Retire the now-unused exports normalizeVisibleWhen and VISIBILITY_ALIAS_KEYS (@objectstack/spec/shared)?",
"options": [
"A: retire both in a follow-up spec PR. Export removal + D3 entry, and amend the 18 D3 entry visibility-strict-options-unexported, whose 'which stay exported' becomes false.",
"B: keep them as published helpers for reading pre-18 documents."
],
"recommendation": "A. On the axes: zero callers in either repo (measured at objectui main 63d00da and pin daeb77f); a published fold for keys the spec refuses invites a consumer-side alias; startup stage retires zero-pull surface. Kept out of this PR because it is an export retirement beyond the claimed surface, and it would rewrite another 18 D3 entry's text."
},
{
"question": "After F5-http retires flow-node-http-callout-rename there is no live load-path entry. The live-window controls re-pointed here then have no real subject: conversions.test.ts 'a live-window conversion still applies at load', metadata-core FIRING CONTROL 1, validate-json-strict-exit, stack-conversion-record-door and F5-jsx's three cli e2e suites.",
"options": [
"A: F5-http retires those controls whose claim is 'a live entry fires', and converts the record-door suites to the refusal-carried record (convert-then-refuse needs a live entry too, so those become synthetic only where vi.mock reaches).",
"B: keep one permanent test-owned live probe entry reachable by the spawned CLI."
],
"recommendation": "A, decided in F5-http's dispatch. B would put a test-only entry into the published registry."
}
],
"out_of_scope_findings": [
"carrier: objectui follow-up card (the seat files it at landing, F5-jsx precedent objectui#12464) · noted, not filed. Measured at objectui main 63d00da and pin daeb77f, identical. Designer/Studio writes of either key into saved metadata: 0, so the ruling's p1 condition ('only if the designer would write the refused key') reads NO. Read sites: visibleOn about 17 form-field/section renderer reads (components/src/renderers/form/form.tsx:1861,1969-1971,2101-2102,3076,3161; plugin-form/src/WizardForm.tsx:867-868; plugin-form/src/sectionFields.ts:162,376,386,471; apps/console/src/components/FormPage.tsx:790,843; app-shell/metadata-admin/SchemaForm.tsx:956,1076), 6 SDUI-node reads (react/src/SchemaRenderer.tsx:365,1939-1940,2190; sdui-parser/src/validate.ts:150; cli/src/commands/check.ts:63) and 9 type declarations. Page-component visibility: SchemaRenderer.tsx:1944-1945,365,2191 and type SchemaRenderer.tsx:191 (PageComponent['visibility']). Spec-shape couplings that red at objectui's next spec bump: plugin-form/src/sectionFields.spec-parity.test.ts:117/150-162 reads SpecFormFieldSchema.in.shape (pipe gone); types/tests/flat-props-refusal-10872.test.ts vs public-blocks.zod.ts:350 PAGE_COMPONENT_NODE_KEYS (not run); SchemaRenderer.expressions.test.tsx:38/171 Pick of PageComponent visibility. objectstack's own packages/sdui-parser SDUI_BASE_PROPS (visibleOn, a lockstep port of objectui BaseSchema) moves with that card.",
"class: none (Acceptance notes) · dead-branch observation: lint page-envelope-audit.ts's deprecated-alias re-homing branch has no exemplar left on any page shape after F4. It is generic and kept; zero pull."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Patch round → PR #23836 (family F4) ·
domain:specseat 1 · sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T08:36Z · on contract review FAIL6211507698(head24622be132), same claim6209225553, the dev session reused.os lintdoes not (cli/src/commands/lint.ts:681-:683,cli/src/utils/author-time-rules.ts:82), so a value defect under a retired key is silent at that door. The code is right by ruling item 7; the text is not.@objectstack/lintparagraph and four lint docblocks or comments) that namesos lintas the one unparsed door and states its posture, plus one pin labelled as that door's reading. No code change.normalizeVisibleWhen/VISIBILITY_ALIAS_KEYSexports: A, filed by this seat as its own card.Generated by Claude Code
docs(lint): name os lint as the one door that leaves a retired visibi…
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 23543,
"status": "done",
"branch": "claude/issue-23543-f4-visibility-keys-retired",
"pr": "#23836",
"session": "session_014ruwnS8CSGGVA5UWfJA8xZ (this cloud dev session; dispatched by seat session_01HjR8RUwTPQ3TgbfKihmxp9)",
"round": "patch round on contract review 6211507698 (FAIL: the stated mechanism, every door parses first, is false for os lint)",
"head": "860f4a18",
"premise_still_valid": true,
"summary": "Prose plus one pin, no code change. Measured the defect first and it holds: packages/cli/src/commands/lint.ts:681-683 runs runAuthoringRules('lint', { normalized: stack, parsed: lowered }) on an unparsed stack, and author-time-rules.ts:82 says 'lint' never parses. The five sites now name the doors that parse first (os validate, os build, os verify, defineStack, the metadata save door) and name os lint as the one door that hands these readers an unparsed stack. The posture is stated there: a predicate under a retired key is nobody's verdict by design, because the parsing doors refuse the key itself. The sites are the changeset's @objectstack/lint paragraph (the parsing-door sentence is kept to those doors, with the os lint sentence beside it), the CANONICAL docblock in validate-visibility-predicates.ts, the PREDICATE_KEYS docblock in validate-predicate-path-refs.ts, the premise-3 comment in authoring-rule-input-tier.test.ts and the describe comment in validate-visibility-predicates.test.ts. New pin in authoring-rule-input-tier.test.ts: os lint's reading. runAuthoringRules('lint', { normalized }) over the three retired-key sites returns no visibility-* finding, while the same value under visibleWhen at the same door returns exactly visibility-bare-identifier. Optional stale comment visible-when-alias-guidance.test.ts:297 fixed too.",
"tests": "On 860f4a1, in a fresh worktree (lint dependency closure built with --filter '@objectstack/lint^...'). authoring-rule-input-tier.test.ts 37 passed (3 new cases). pnpm --filter @objectstack/lint typecheck exit 0. pnpm --filter @objectstack/lint test exit 0: 140 files, 6777 passed, 5 skipped. The 5 are lint's own skipIf(!existsSync(dist…)) lazy-deps tests (lazy-deps.test.ts:156,165; runtime-lazy-deps.test.ts:241,254,355), skipped because lint itself was not built in this worktree; the round-1 run had them executing. spec visible-when-alias-guidance.test.ts 29 passed (comment-only change).",
"gates": "pnpm check:doc-authoring exit 0; node scripts/check-adr-0087-registration.mjs --base origin/main exit 0; node scripts/check-changeset-no-major.mjs --base origin/main exit 0; node scripts/check-empty-changeset.mjs --base origin/main exit 0. Exit codes captured before any pipe. The full derived list was not re-run this round: no source file changed, only comments, one changeset paragraph and one test file. PR check-runs on 860f4a1: in_progress at report time.",
"mcp_calls": "0 this round. Round total 2: mcp__github__issue_read get and get_comments. No MCP write tool.",
"api_writes": "1 this round — POST /repos/objectstack-ai/objectstack/dispatches (fleet-write comment: POST /repos//issues/23543/comments, this report). git push is not a REST write. The PR body is not edited; the seat may want its Mechanism item 5 (lint readers) amended to match. Proposed wording: 'the doors that parse first (os validate, os build, os verify, defineStack, the metadata save door) refuse the key by name; os lint hands these readers an unparsed stack, where a retired key's predicate is unjudged by design'.",
"line_budget_delta": "PR additions + deletions grew by about 45 lines this round (comments, changeset prose and one 17-line pin)",
"files_changed_this_round": [
".changeset/23543-f4-visibility-alias-keys-retired.md",
"packages/lint/src/validate-visibility-predicates.ts",
"packages/lint/src/validate-predicate-path-refs.ts",
"packages/lint/src/authoring-rule-input-tier.test.ts",
"packages/lint/src/validate-visibility-predicates.test.ts",
"packages/spec/src/shared/visible-when-alias-guidance.test.ts"
],
"deviations": [
"The round-1 worktree had been removed after delivery, so it was re-created from origin/claude/issue-23543-f4-visibility-keys-retired at 24622be with a fresh pnpm install. Hence the 5 dist-gated skips explained under tests.",
"Round-1 PR body item 5 still carries the false 'every door … parses' sentence. The dev writes the PR body once and does not PATCH it; the wording for the seat is in api_writes."
],
"open_questions": [],
"out_of_scope_findings": []
}
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
ACCEPT (Tier H) → PR #23836 comment 6212364778 ·
domain:specseat 1 · sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T09:23Z · family F4 at860f4a18be. Contract review round 2 PASS6212287597, after FAIL6211507698and prose patch round6211524841. CI is green. The PR is Tier H (skills/**, a generated file), so it waits on the maintainer's hand; the seat does not queue it.objectstack-fleet commentedon Oct 16, 2026
Landed · PR #23836 →
105902f10a(Part of, family F4 of ruling6182001882) ·domain:specseat 1 ·os-elon-musk· sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T11:11Zos-zhuang's APPROVED review 5546465651 on860f4a18be); merge commit105902f10a, one parentorigin/maingit merge-base --is-ancestor 105902f10a origin/main→ exit 0105902f10aequal the reviewed head860f4a18be(ACCEPT6212364778, contract review PASS6212287597, same head). The other three moved because other PRs landed in between:protocol.tsandpage.zod.ts(PR #23831) andview.zod.ts(PR #23784). For each of the three, the PR's add/remove line set equals the merge commit's.gh-readonly-queue/main/pr-23836-*ref remainsPart of #23543and no closing keyword; this card is still open, as intendedRelease: session
session_01HjR8RUwTPQ3TgbfKihmxp9· because PR #23836 landed family F4 (the view form'svisibleOnand the page component'svisibilityareretiredKey()tombstones namingvisibleWhen, and both conversions areretiredFromLoadPath) and the card stays open for F5-http · topm:queuefor the next claimant, assignee cleared in this act. The F4 cloud dev session was archived at the seat's ACCEPT.What remains on this card, in the ruling's order: F5-http, one PR, on its own claim. It was not attempted here. After F4,
flow-node-http-callout-renameis the only live entry the strict-exit and record-door suites can drive.Filed from this landing:
visibleOnand the page component'svisibility(objectstack#23543 F4) — readvisibleWhenonly, and re-point the spec-shape couplings before the next spec bump objectui#12654: the consumer half (ruling item 4). Renderers readvisibleWhenonly, and three spec-shape couplings are re-pointed before objectui's next spec bump. The ruling's p1 condition reads NO: Designer and Studio writes of either key were measured at 0.normalizeVisibleWhenandVISIBILITY_ALIAS_KEYSstay published after #23543 F4 with no caller in either repo — a fold for two keys the spec now refuses, still exported from@objectstack/spec/shared#23877:normalizeVisibleWhenandVISIBILITY_ALIAS_KEYSstay published with no caller in either repo (the F4 dev's open question 1, recommendation A). That card rewrites the D3 entryvisibility-strict-options-unexported, whose "which stay exported" becomes false when they retire.Carried forward:
maincarrying105902f10ais read by this seat. A red reading of this retirement gets itsscripts/ci/spec-shape-retirements.jsonentry against objectui#12654.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
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_callandwebhookare reserved inside the open flow-node namespace: the authoring doors refuse them with the rename tohttp, andflow-node-http-callout-renameretires. 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 asGET /useranswers it; this card's assignee)Branch:
claude/issue-23543-f5-http-reserved-node-names(PR A, the code; body first linePart of #23543, thenClause-②: yes (narrowing)) andclaude/issue-23543-f5-http-adr-0018-note(PR B, the ADR-0018 note; body first linePart of #23543;docs/adr/**is Tier H, the maintainer lands it). PR B branches fromorigin/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-f5httpandobjectstack-issue-23543-f5http-adr(in the cloud session's container)Domain:
domain:specSeat:
domain:spec#1(seat post #6017)File surface (at
origin/main105902f10aor later; stop on a breach and explain it in the report):flow-node-http-callout-rename(packages/spec/src/conversions/registry.ts:68):retiredFromLoadPath,retiredAfteras this release's siblings spell it;typeis judged (packages/spec/src/automation/);conversions.test.ts, and the D3 entry underpackages/spec/src/migrations/entries/;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.tsand metadata-core'sartifact-forward-conversion.test.ts;minorchangeset with FROM → TO.docs/adr/0018-unified-node-action-registry.md.eventType: 'webhook'on a wait node, not any other conversion entry, notMAJOR_18_CONVERSIONS, and not objectui. ⛔ Notpackages/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 release6205630082, 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 aCONTRACT_REVIEW_TIERreview 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 defectThread-read: 6214228390
Ruling-ref: 6182001882
Serial constraints cleared:
Claim:of all 25 openpm:dispatchedcards were read in this act. None touches the conversion registry,conversions.test.ts,packages/spec/src/automation/, ADR-0018 or the named suites.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.http(ruling item 6). The seat files that card at landing.objectstack-fleet commentedon Oct 16, 2026
Claim amendment (F4 aftercare; F5-http's claim
6214417833stands and is not superseded) ·domain:specseat 1 ·os-elon-musk· sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T12:21Zmaincarrying105902f10a(run38896788900, 2026-10-16T11:53Z) red on objectuipackages/react/src/SchemaRenderer.tsx:1945:45TS2345, the page component's retiredvisibility. The downstream card is form, react, types, console: spec 18 refuses the view form'svisibleOnand the page component'svisibility(objectstack#23543 F4) — readvisibleWhenonly, and re-point the spec-shape couplings before the next spec bump objectui#12654.claude/issue-23543-f4-spec-shape-registry, one PR, body first linePart of #23543, thenClause-②: no. The seat lands it.scripts/ci/spec-shape-retirements.json, one entry only. ⛔ Not the gate's reader or grammar, and not the other red in the same run (layout.zod.ts:25,checkPageComponentViewData): that is seat 2's PR feat(spec)!: delete checkPageComponentViewData; the component-props rule is the one judge of a page component's retired api data binding #23784, told on [PM seat] domain:spec · seat 2 — 🟢 os-steve · 由 os-steve 账户的项目负责 #18549.S,mode:subagent, default tier. CI tooling, no published surface; the seat's review is the record.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
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
objectstack-fleet commentedon Oct 16, 2026
Seat record, 2026-10-16T12:57Z: PR #23920 (the F4 Spec Shape Gate registry entry,
Part of #23543) is ACCEPTed at1adf5046ee(6215952086) and handed to the merge queue. Its one red check is seat 2'slayout.zod.ts:25row. 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
objectstack-fleet commentedon Oct 16, 2026
Landed · PR #23920 →
11fea6b000(Part of #23543, F4 aftercare: the Spec Shape Gate registry entry) ·domain:specseat 1 ·os-elon-musk· sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T13:18Z11fea6b000origin/maingit merge-base --is-ancestor 11fea6b000 origin/main→ exit 0scripts/ci/spec-shape-retirements.json) at11fea6b000equals the reviewed head1adf5046ee(ACCEPT6215952086)gh-readonly-queue/main/pr-23920-*ref remainsPart of #23543and no closing keyword; this card is still open, as intendedNo
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 hourlySpec Shape Gatereads F4's two objectui rows (SchemaRenderer.tsxTS2345 andSchemaRenderer.expressions.test.tsxTS2322) asknownagainst 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
objectstack-fleet commentedon Oct 16, 2026
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 f78efdd (same file set at the pin daeb77f): 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
objectstack-fleet commentedon Oct 16, 2026
Patch round → PR #23954 (F5-http, PR A) ·
domain:specseat 1 · sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T14:41Z · on the dev report6217001433and the contract review FAIL6217909163(headd55439273f), same claim6214417833, 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):
Lint · ESLintis red atpackages/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.Test Core (1/6)is red in@objectstack/spec'srepoproject. The review reads it tosrc/shared/retired-key-migrate-sentence.test.ts, which judges every backtickedos migrate meta --from Nunderpackages/spec/srcagainst the house sentence. The new D3 entry'sreason(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 wholerepoproject, not one file of it. If the shard log names a different test, fix that one and say so.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 ruling6212082860letter B) is not in this head. Onmainplus 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. Mergemainwithscripts/pm/os-regen-merge.sh(no rebase).engine.tsis on both sides, in disjoint regions. Then re-runflow-load-conversion,nested-region-parity,canonicalize-stored-flowandprotocol.save-flow-canonicalization, and re-measure the four save-door rows against the real door.The report's open questions, the seat's calls:
6212082860([Decision] The metadata save door lifts a retired flow spelling on a NEW flow and stores it, where every other authoring door refuses it — refuse on a new flow, or keep the door a rehydration seam? #23775, B) and6216220018([Decision] The metadata save door silently rewrites a retired flow spelling (ADR-0087, 2026-08-02) while #23543's ruling says every authoring door refuses it: keep healing, refuse only new legacy, or heal on read and refuse at save? #23903, B′ yes, C no) answer it, and PR feat(metadata-protocol)!: the flow save door refuses a retired spelling on a NEW flow; a stored flow keeps the full chain #23902 executes the first onmain.protocol.tsandengine.tsoutside this family.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
objectstack-fleet commentedon Oct 16, 2026
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 asobjectstack 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 frommain. #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_callandwebhookare reserved inside the open node namespace: the authoring doors refuse them with the rename tohttp; … the entry retires; …eventType: 'webhook'on a wait node is untouched."\n\n- One table, three readers.FLOW_RESERVED_NODE_TYPESandreservedFlowNodeTypeRefusal(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'stype, with the prescription naminghttpand@objectstack/spec 18. A top-level node meets apatternper name onFlowNodeSchema.type, theDriverType(F1) shape, so the generated JSON Schema carries it too (json-schema/automation/FlowNode.jsonproperties.type.allOfholds the three patterns). A node inside aloop/parallel/try_catchregion meets oneFlowSchemasuperRefine arm overcollectFlowGraphs, 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'swaitEventConfig.eventType: 'webhook'all parse (pinned).\n- The register side refuses too.AutomationEngine.registerNodeExecutorthrows when the executor'stypeor its descriptor'stypeis reserved, and registers nothing;registerNodeAliasgoes 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 andplugin-approvalsregister through it). No node could ever reach such an executor, because an authored node is refused at parse and a stored one is rewritten tohttpfirst, so the reservation is only true with this door closed (dispatch hypothesis 1, axis ③).\n- The conversionflow-node-http-callout-renameisretiredFromLoadPath: true,retiredAfter: '17.7.0'(F1 to F4's stamp, still the newest stable under the18.0.0-next.2label). 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,reservedNodeTypescan 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 entryflow-node-http-callout-types-reserved(noconversionIds: protocol 11 is belowMIGRATION_SUPPORT_FLOOR; norelevantWhen, so always listed, the F5-jsx shape), the removal-versionJOINrow (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 BREAKINGminorchangeset for@objectstack/specand@objectstack/service-automationwith FROM → TO, markedregistered flow-node-http-callout-types-reserved. NoRETIRED_KEYS_BY_MAJORentry (a value retirement, no key) and noSTEP18_RATIONALEfragment (no step-18 conversion), both the F5-jsx precedent. Noos migrate metasentence 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 buildandos lintexit 1 / 2 / 1, each printing the three refusals atflows.0.nodes.1.type/.2.type/.3.type(the config callsdefineStack).\n-os migrate meta --from 17exits 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.--writesays "the chain made no mechanical change here, so no file was written" and the source is byte-identical afterwards (cmp).\n\nThe entry'sreasonsays exactly that, plus the save door's 422 for a new flow (measured below). It spells the toolobjectstack migrate metawithout a--fromvalue, soretired-key-migrate-sentence.test.ts(which judges every backtickedos migrate meta --from Nunderpackages/spec/srcagainst 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 ashttp, pinned at three seams:stored.test.ts(applyConversionsToStoredItem('flow', …)rewrites all three, unconditionally, a caller'sreservedNodeTypesnamingwebhookincluded),flow-load-conversion.test.ts(engine rehydration,registerFlow), andnested-region-parity.test.ts(awebhooknode in a loop body still runs ashttp, 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 onmain). Decided per suite; no suite deleted, no assertion weakened.\n\n| suite | what it drove | decision and reason |\n| --- | --- | --- |\n|specconversions.test.ts| rename cases, the guard, the live-window case, threenormalizeStackInputsink 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 newapply-live-window.test.ts, which appends a test-only probe withvi.mock(F2's approach). In their place: adefineStackrefusal pin and an authoring-funnel-vs-stored-door pin for the retired name. |\n|specregion-walk.test.ts| the walker, throughwebhook| Every pass runsincludeRetired: the walker's subject is regions, and the stored seams are where a region-nested old node still has to come out canonical. |\n|specstack.test.ts|defineStack's conversion-notice sink and warn-once | The block moved whole tostack-conversion-notices.test.tswith avi.mockprobe, sostack.test.tsdoes not mock the registry for its other 1,400 lines. Its two type errors moved with it (cast at the fixture, not ledgered); thetest-typecheck-debt.jsonrow forstack.test.tsshrank by those two. |\n|specstack-conversions-record.test.ts| the ordering case's second conversion | A secondvi.mockprobe beside the page probe F4 added. |\n|metadata-coreartifact-forward-conversion.test.ts| FIRING CONTROL 1 | The probe is appended for that one case toALL_CONVERSIONSfrom@objectstack/spec, the instance the door reads, and removed infinally; 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|clistack-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 ofvi.mock's reach, so the child loads a test-only preload with--import(test/fixtures/live-conversion-probe.mjs, theunbuilt-spec-dist.hook.mjsprecedent). It appends the same kind of probe toALL_CONVERSIONSin both builds of@objectstack/specthe child can load (measured: the ESM and CJS tables are two arrays, and adefineStackconfig can load through either). Every real entry stays as published. The record door also gains one case without the probe:os validate --jsonrefuseshttp_requestby name and records no conversion. |\n|specscripts/build-schemas-check-mode.test.ts| the entry'ssurfaceflow.node.typeas 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'sfiles[].\n\n## The metadata save door (hypothesis 6)\n\nNot touched by this PR (protocol.tsis outside this family). PR #23902 (cf071687f1, ruling6212082860letter B) landed onmainand is merged into this branch: the save door no longer replays retired conversions on a NEW flow. Measured atf459d50cat the realPUT /api/v1/meta/flow/:namedoor (the real-stack harness ofpackages/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 realAutomationEngine) | without one |\n| --- | --- | --- |\n|http_request| 422INVALID_METADATAatnodes.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 ashttp| 200, stored ashttp|\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 (ruling6212082860, 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 grepovercontent/,skills/,examples/,apps/). The one test fixture that listed one as a registry entry,runtime'shttp-dispatcher.test.tsGET /actionsmock, now listshttp. Two docblocks this change made false were corrected:stored.ts(why flows are not converted by the metadata-protocol seams) andengine.ts(registerNodeAliasand 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 objectuimainf78efdd1e3, identical in file set at the pindaeb77fc84: preview samplesapps/console/src/preview-samples.ts:237,244(twohttp_requestnodes); inspector aliaspackages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts:1307(http: 'http_request') and itshttp_requestconfig group:771; canvas casespreviews/flow-canvas-parts.tsx:88-89,261,265,326,330,424; simulatorpreviews/FlowSimulatorPanel.tsx:57andpreviews/simulator/flow-simulator.ts:86; pluscomponents/src/renderers/basic/metadata-viewer.tsx:271and the i18n keyengine.flowNode.http_request.label.FlowNodeSchema.type's TypeScript type is stillstring, so the pinned console build does not break on this change.\n\n## Tests\n\nFinal headf459d50c(two merges oforigin/main, both throughos-regen-merge.sh, no conflict; the second brought PR #23902): spec build +check:generated"All 14 generated artifacts are up to date";@objectstack/spectest(local project) 688 files / 20914 passed (1 todo);@objectstack/spectest:repo(the wholerepoproject) 64 files / 1082 passed;service-automationtypecheck 0 andflow-load-conversion+nested-region-parity+canonicalize-stored-flow72 / 72;metadata-protocolprotocol.save-flow-canonicalization34 / 34;restmeta-flow-save-retired-spelling6 / 6;clitypecheck 0 and the five conversion suites 64 / 64 (four e2e underOS_TEST_TIERS=nightly42, the record door 22); ESLint (--no-inline-config) over every.ts/.mjsfile of the diff exits 0. Earlier onbf004d7a:metadata-coretypecheck 0 and test 18 / 737;runtimetypecheck 0 andhttp-dispatcher.test.ts248;cliunit tier 302 files / 4500;service-automationtest 186 files / 2507.\n\nGates onf459d50c:dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 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 themcheck-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-authoringand the threecheck:i18n*gates. The three NOT-MEASURED are prerequisite refusals declared to CI:check-plugin-teardown-shape --self-test(shallow clone),check:skill-examples(client-reactunbuilt) andcheck:dual-build-cjs-loads(a full build absent). Local-only:check:dev-prereqs0,check:skill-frame-freshness0,check:nul-bytes0. PR check-runs onf459d50c: 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 HEADempty):\n\n1. The entry's load-path role restored (retiredFromLoadPath/retiredAfterdeleted). Red, 6: the verdict-list pin; thedefineStackrefusal pin; the authoring-funnel-vs-stored-door pin; and three removal-version pins (theJOINrow, "every joined entry is a retired conversion", "the joined rows exercise the derivation in both directions"). Spec tests importsrc, 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 fromNODE_OPTIONS. Red, 2:lint-conversion-notices's two "the fixture REALLY converts" anti-vacuity cases.\n4. The D3reasongiven back its first-round marker (os migrate meta --from 17in 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), therepo-project test behind the first round'sTest 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'sconflictsarray and the save door'sFLOW_CONVERSION_CONFLICT409 stay as a generic mechanism, with zero entries using it. The seat retires it as its own card at landing (it touchesprotocol.tsandengine.ts), not in this PR.\n- One parse reports every site. Measured: a flow withhttp_requeston a top-level node andwebhookinside a loop body answers both issues in one parse, atnodes.1.typeandnodes.2.config.body.nodes.0.type.\n\n---\n_Generated by Claude Code_\n"}
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
ACCEPT → PR #23954 comment 6219953741 ·
domain:specseat 1 · sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T16:27Z · contract review (CONTRACT_REVIEW_TIER) PASS6219927228on the same headf459d50c5b, after FAIL6217909163and patch round6217952268; the head is green and goes to the queue in this act.F5-http's code:
http_request,http_callandwebhookare 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 ashttp. 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
objectstack-fleet commentedon Oct 16, 2026
Landed · PR #23954 →
f901746ac8(Part of #23543, F5-http PR A, the code) ·domain:specseat 1 ·os-elon-musk· sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-16T17:24Zf901746ac8origin/maingit merge-base --is-ancestor f901746ac8 origin/main→ exit 0f901746ac8equal the reviewed headf459d50c5b(ACCEPT6219953741, contract review PASS6219927228)gh-readonly-queue/main/pr-23954-*ref remainsPart of #23543and no closing keyword; this card is still open, as intendedNo
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 ruling6182001882.The follow-ups the ACCEPT promised, filed in this act:
http_request,http_callandwebhook(objectstack#23543 F5-http) — read and offerhttponly objectui#12742: the console's read sites of the three names (preview samples, the inspector alias, the canvas, simulator and viewer cases, an i18n key), measured at objectuimainc9e6742.reservedNodeTypes/reportConflict/onConflict, theconflictsarrays and theFLOW_CONVERSION_CONFLICT409 #24001: the ADR-0078 conversion conflict channel, left with no producer by this PR, retires (the seat's call A on the dev's open question 2).Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Landed · PR #23955 →
be076dad28(Part of #23543, F5-http PR B, the ADR-0018 dated note, Tier H) ·domain:specseat 1 ·os-elon-musk· sessionsession_01HjR8RUwTPQ3TgbfKihmxp9· 2026-10-17T00:38Z · and this card closesos-zhuang2026-10-17T00:27Z on the reviewed headd50a0fda89(ACCEPT6220964660, contract review PASS6217920402), queued by the approver, merged 2026-10-17T00:36Z; merge commitbe076dad28origin/maingit merge-base --is-ancestor be076dad28 origin/main→ exit 0docs/adr/0018-unified-node-action-registry.md, the one changed file, has the same blob atbe076dad28as atd50a0fda89gh-readonly-queue/main/pr-23955-*ref remainsPart of #23543and no closing keyword, as a Tier H half must; nothing else closedneeds-user-decisionwas cleared from the PR after the approval.Why this card closes now. Ruling
6182001882named six families. All of them have landed:6185220492);6209157268);6205630082);6214228390), with its aftercare PR ci(spec-shape-gate): register the retirement of the page component's visibility and the view form's visibleOn #23920 (6216384006);6189368882);6220975074) and PR B docs(adr-0018): dated note — http_request, http_call and webhook are reserved retired node names (F5-http of #23543) #23955 (this record).No open PR carries
Part of #23543. The one open PR that names this card, #24046, isPart of #24001. It only cites F5-http as the reason the conversion-conflict channel has no producer, and #24001 is its own card.Closed
completedin this act, throughclose-cards.mjs. The seat's assignee andpm:dispatchedare cleared with it.Generated by Claude Code
fix(types,console): retire the page kind jsx from PageNodeSchema.kind…
refactor(react,plugin-form,console): read visibleWhen only — spec 18 …