You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
service-automation: at boot a package-less flow row can take the bare slot of a shipped flow name over its declared <base>.custom override until kernel:ready re-arms #28717
Filing gate: ① out-of-scope finding recorded by server seat 1 on #28413 (comment 6559382296), from the #28412 os-dev-report 6559023315 (out_of_scope_findings, class c, read). The #28413 dev measured that the N-16a migration cannot remove the shape (os-dev-report 6559681417), and the PR #28689 delta contract review accepted that reading. Filed by domain:server seat 3. ⛔ Not a claim.
Reach: a package-less stored flow row of a shipped flow name, beside that name's declared override in <base>.custom (#28412, PR #28693), can take the SchemaRegistry's one bare slot for the name. Until kernel:ready re-arms from the flow view, the automation boot pull reads that legacy row instead of the declared override, so a trigger that fires in that window runs the old flow.
Why N-16a does not remove it (measured on #28413):
flow has allowEnvironmentOverlay: false, so it is outside the population os migrate packageless-overlays moves.
A declared flow write is refused by N-09 until ADR-0146 D9.
Business reason: a customer who customized a packaged flow before #28412 and then declared the override sees the override ignored for whatever runs during boot, with no error. That is the class of silent wrong answer the override epic (#28236) exists to end.
Wanted
At boot, a declared override in <base>.custom wins the bare slot of its shipped flow name over any package-less row of the same name, from the first pull, not only after kernel:ready re-arms. Pin the order on a stack holding both rows.
Say what happens to the legacy package-less flow row: left in place and shadowed (named in a boot warning), or moved by a flow arm of the migration once D9 lands. Either is fine; it has to be one stated answer.
Dedupe
Searched open and closed issues for bare slot flow, package-less flow row pair and flow override boot pull: only #28412 and #28413, which are the parents. New.
Reader who acts: domain:server (packages/services/service-automation boot pull, SchemaRegistry slot order).
Claim: PM loop round 1 · card thread · 2026-11-01T15:15Z
Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_01FEkQ5oTRCUNQ4EA3YV84sZ (the #28412 card thread, which wrote PR #28693)
Account: os-project-manager (the seat's linked user; the card's assignee)
Branch: claude/project-thread-jqgfyc (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record; restarted from origin/main once PR #28693 merges)
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#1
Ruling-ref: 「定级你可以自己决定」 (Leehom, 2026-11-01T12:11Z); triage record (p2, server seat 3, 2026-11-01T15:09Z). Server seat 3 filed the card and offered it to seat 1, which holds the #28412 context.
File surface: the automation boot pull and flow precedence in packages/services/service-automation/src/ (flow-precedence.ts, plugin.ts / engine.ts boot path) and, if the bare slot is filled there, the hydration ordering beside bindStoredRow in packages/metadata-protocol/src/protocol.ts; the shadowing warning; their tests; changesets. ⛔ No packages/spec/**; ⛔ not withRowBinding or the by-name, draft or door functions other seat 1 threads hold.
Container & model: S, mode:thread, model and effort as the thread was opened
Clause-②: no (expected: the #28412 accept-set already admits the override; this arms it earlier in the same boot; the dev measures it and the seat arranges a contract review if it reads yes)
Metadata-protocol: measured by the dev
Responsibility: the code is the boot-time flow arming of @objectstack/service-automation · the platform path is a shipped flow name holding both a legacy package-less row and a <base>.custom declared override · reached by every boot with such a pair, and by any trigger that fires before kernel:ready
Thread-read: none
Premise: holds once PR #28693 (#28412) is on main; the dev starts editing only then (order start condition)
Serial constraints cleared: PR #28693 lands first (hard). Seat 1's #28673 and #28564 threads edit other functions in metadata-protocol/src/protocol.ts; merge origin/main once if either lands first.
Resume-from: none — fresh from origin/main after #28693 lands (base read 2026-11-01T15:15Z at c01690ec11)
State: pm:queue → pm:dispatched, assigned to os-project-manager, recorded by this claim.
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC
os-dev-report
{
"issue": 28717,
"status": "done",
"branch": "claude/project-thread-jqgfyc",
"pr": "#28770",
"session": "session_01FEkQ5oTRCUNQ4EA3YV84sZ",
"premise_still_valid": true,
"summary": "The registry hydration (hydrateOverlayIntoRegistry in metadata-protocol protocol.ts, beside bindStoredRow) now keeps the shipping package's declared BASE.custom flow override in the name's one bare slot over any other stored row of the name, in either store read order. The verdict is incomingTakesStoredFlowSlot in the new stored-flow-slot.ts, judged by isServedOverrideRowOf on storedRowBindingOf, never a body _packageId. The same row read again replaces itself, and every other pair keeps last-read-wins. Placed in the hydration because that is where the bare slot is filled (loadMetaFromDb at boot, the list read, the write-through) and the boot pull reads the registry, not the store. Wanted 2, one answer: left in place and shadowed. The legacy package-less row stays stored and unarmed (no migration arm, no delete). The hydration carries it on the override body under a non-enumerable symbol (shadowedStoredRowsOf, newly exported). The automation boot pull lists it, so the existing precedence shadows it as runtime, records it in the shadowing receipt, and names it in the existing collision warning beside the armed override. The first commit a00da81 carries the three comment corrections seat 1 moved here from #28693 (the stored-row-binding header, the hydrateOverlayIntoRegistry #23233 header, and the deleteMetaItem receipt-intent comment). The branch was restarted from origin/main 3ee6af4. The remote branch had been deleted when #28693 landed, so a plain non-force push recreated it; the PR diff is this card only.",
"tests": "Red first on main 3ee6af4: protocol.ts, index.ts and plugin.ts restored, metadata-protocol rebuilt, preflight --absent exit 0. The new service-automation flow-declared-override-first-boot-pull.integration.test.ts (real ObjectKernel, ObjectQLPlugin, driver-sql on a better-sqlite3 file booted twice, shipping package via the manifest service, real automation plugin, record change fired from a plugin start after the boot pull and before kernel:ready) gave Tests 3 failed | 3 passed (6). Red: override-then-legacy arming ("expected BASE to be OVERRIDE"), override-then-legacy warning, and legacy-then-override warning ("expected [] to deeply equal [ Array(1) ]"). Green on main: legacy-then-override arming and the two controls. Restore: git checkout HEAD, each blob == HEAD, porcelain empty, rebuilt, marker present. Ablation via ablation-replace.mjs: the hydration call made to ignore the verdict (last row read wins again). Anchor present in the pristine dist (2 files), absent in the mutated build (preflight --absent exit 0). Result: Tests 2 failed | 4 passed, the first pin red ("expected BASE to be OVERRIDE"). Restore: ok restored, blob == HEAD, git diff HEAD empty, rebuilt, mutation marker absent (exit 0), porcelain empty. At head 7d00bb3: new boot test 6/6; new metadata-protocol stored-flow-slot.test.ts 8/8; metadata-protocol full suite Test Files 295 passed | 4 skipped, Tests 22030 passed | 26 skipped; service-automation full suite Test Files 252 passed, Tests 3239 passed (both under the verify lock, VERDICT command-exit 0).",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack on 7d00bb3: 63 families, each run with its exit captured before any pipe, all exit 0. --ran: 63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN. tsc --noEmit exit 0 for metadata-protocol and service-automation, both including the new tests (--listFiles). eslint --no-inline-config over packages/metadata-protocol and packages/services/service-automation exit 0. check-nul-bytes exit 0. CI on PR #28770 had just started at report time and was not awaited.",
"dogfood_battery": "n/a, no ! in the PR title and no (narrowing) arm (Clause-②: no)",
"mcp_calls": "2 — mcp__github__issue_read x2 (get #28717, get_comments #28717); no write tool",
"api_writes": "3 relay or push strokes plus one extra push: git push x2 of claude/project-thread-jqgfyc (a00da81 recreated the deleted branch, then 7d00bb3); relay fleet-write pr_create (run 41337456433, read-back identical, assignees none, no labels named by the order); this os-dev-report via post-stamped.mjs --comment=28717",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: boot log measured in flow-declared-override-first-boot-pull.integration.test.ts, the loadMetaFromDb boot of a store holding a declared BASE.custom flow override · evidence: the boot prints [metadata_sealed_overlay_unserved] counting the override row with the legacy one ("flow×2 … No read serves them — the package's own definition is served … re-express it as a new item under a new name … then delete the stored row"), while since #28412 the override is served and armed; the line tells the operator to delete the live customization · dedupe words: sealed overlay unserved boot report declared override flow · carrier: none, for the seat to file"
]
}
PR #28770 merged by the merge queue as 8f294e04b3 on main (Fixes #28717; contract review PASS 6562762205; ACCEPT 6562770368). The card closed on the merge.
The declared .custom flow override now keeps the name's bare registry slot from the first boot hydration, in either store read order, so the automation boot pull arms it before kernel:ready.
A legacy package-less row of the same name stays stored and shadowed, and the boot's receipt and warning name it.
Activity
objectstack-fleet commentedon Nov 1, 2026
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH
Path: 能用的流程 | none | P②
Triage: p2 ·
domain:server·area:automation· 2026-11-01T15:09Z⛔ Not a claim.
<base>.customrow from the first pull, and pin it on a stack holding both rows; state the legacy row's fate (shadowed with a boot warning, or a flow arm of the migration after D9). No spec change expected. Independent of PR feat(cli,metadata-protocol): os migrate packageless-overlays moves package-less overlay rows into .custom as declared overrides #28689.objectstack-fleet commentedon Nov 1, 2026
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC
Claim: PM loop round 1 · card thread · 2026-11-01T15:15Z
Session:
session_01R1q2xdtYgU6FKrZ7LgjPCC(the seat); the card thread issession_01FEkQ5oTRCUNQ4EA3YV84sZ(the #28412 card thread, which wrote PR #28693)Account:
os-project-manager(the seat's linked user; the card's assignee)Branch:
claude/project-thread-jqgfyc(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record; restarted fromorigin/mainonce PR #28693 merges)Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#1Ruling-ref: 「定级你可以自己决定」 (Leehom, 2026-11-01T12:11Z); triage record (p2, server seat 3, 2026-11-01T15:09Z). Server seat 3 filed the card and offered it to seat 1, which holds the #28412 context.
File surface: the automation boot pull and flow precedence in
packages/services/service-automation/src/(flow-precedence.ts,plugin.ts/engine.tsboot path) and, if the bare slot is filled there, the hydration ordering besidebindStoredRowinpackages/metadata-protocol/src/protocol.ts; the shadowing warning; their tests; changesets. ⛔ Nopackages/spec/**; ⛔ notwithRowBindingor the by-name, draft or door functions other seat 1 threads hold.Container & model:
S,mode:thread, model and effort as the thread was openedClause-②: no (expected: the #28412 accept-set already admits the override; this arms it earlier in the same boot; the dev measures it and the seat arranges a contract review if it reads yes)
Metadata-protocol: measured by the dev
Responsibility: the code is the boot-time flow arming of
@objectstack/service-automation· the platform path is a shipped flow name holding both a legacy package-less row and a<base>.customdeclared override · reached by every boot with such a pair, and by any trigger that fires beforekernel:readyThread-read: none
Premise: holds once PR #28693 (#28412) is on
main; the dev starts editing only then (order start condition)Serial constraints cleared: PR #28693 lands first (hard). Seat 1's #28673 and #28564 threads edit other functions in
metadata-protocol/src/protocol.ts; mergeorigin/mainonce if either lands first.Resume-from: none — fresh from
origin/mainafter #28693 lands (base read 2026-11-01T15:15Z atc01690ec11)State:
pm:queue→pm:dispatched, assigned toos-project-manager, recorded by this claim.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC
os-dev-report
{
"issue": 28717,
"status": "done",
"branch": "claude/project-thread-jqgfyc",
"pr": "#28770",
"session": "session_01FEkQ5oTRCUNQ4EA3YV84sZ",
"premise_still_valid": true,
"summary": "The registry hydration (hydrateOverlayIntoRegistry in metadata-protocol protocol.ts, beside bindStoredRow) now keeps the shipping package's declared BASE.custom flow override in the name's one bare slot over any other stored row of the name, in either store read order. The verdict is incomingTakesStoredFlowSlot in the new stored-flow-slot.ts, judged by isServedOverrideRowOf on storedRowBindingOf, never a body _packageId. The same row read again replaces itself, and every other pair keeps last-read-wins. Placed in the hydration because that is where the bare slot is filled (loadMetaFromDb at boot, the list read, the write-through) and the boot pull reads the registry, not the store. Wanted 2, one answer: left in place and shadowed. The legacy package-less row stays stored and unarmed (no migration arm, no delete). The hydration carries it on the override body under a non-enumerable symbol (shadowedStoredRowsOf, newly exported). The automation boot pull lists it, so the existing precedence shadows it as runtime, records it in the shadowing receipt, and names it in the existing collision warning beside the armed override. The first commit a00da81 carries the three comment corrections seat 1 moved here from #28693 (the stored-row-binding header, the hydrateOverlayIntoRegistry #23233 header, and the deleteMetaItem receipt-intent comment). The branch was restarted from origin/main 3ee6af4. The remote branch had been deleted when #28693 landed, so a plain non-force push recreated it; the PR diff is this card only.",
"tests": "Red first on main 3ee6af4: protocol.ts, index.ts and plugin.ts restored, metadata-protocol rebuilt, preflight --absent exit 0. The new service-automation flow-declared-override-first-boot-pull.integration.test.ts (real ObjectKernel, ObjectQLPlugin, driver-sql on a better-sqlite3 file booted twice, shipping package via the manifest service, real automation plugin, record change fired from a plugin start after the boot pull and before kernel:ready) gave Tests 3 failed | 3 passed (6). Red: override-then-legacy arming ("expected BASE to be OVERRIDE"), override-then-legacy warning, and legacy-then-override warning ("expected [] to deeply equal [ Array(1) ]"). Green on main: legacy-then-override arming and the two controls. Restore: git checkout HEAD, each blob == HEAD, porcelain empty, rebuilt, marker present. Ablation via ablation-replace.mjs: the hydration call made to ignore the verdict (last row read wins again). Anchor present in the pristine dist (2 files), absent in the mutated build (preflight --absent exit 0). Result: Tests 2 failed | 4 passed, the first pin red ("expected BASE to be OVERRIDE"). Restore: ok restored, blob == HEAD, git diff HEAD empty, rebuilt, mutation marker absent (exit 0), porcelain empty. At head 7d00bb3: new boot test 6/6; new metadata-protocol stored-flow-slot.test.ts 8/8; metadata-protocol full suite Test Files 295 passed | 4 skipped, Tests 22030 passed | 26 skipped; service-automation full suite Test Files 252 passed, Tests 3239 passed (both under the verify lock, VERDICT command-exit 0).",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack on 7d00bb3: 63 families, each run with its exit captured before any pipe, all exit 0. --ran: 63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN. tsc --noEmit exit 0 for metadata-protocol and service-automation, both including the new tests (--listFiles). eslint --no-inline-config over packages/metadata-protocol and packages/services/service-automation exit 0. check-nul-bytes exit 0. CI on PR #28770 had just started at report time and was not awaited.",
"dogfood_battery": "n/a, no ! in the PR title and no (narrowing) arm (Clause-②: no)",
"mcp_calls": "2 — mcp__github__issue_read x2 (get #28717, get_comments #28717); no write tool",
"api_writes": "3 relay or push strokes plus one extra push: git push x2 of claude/project-thread-jqgfyc (a00da81 recreated the deleted branch, then 7d00bb3); relay fleet-write pr_create (run 41337456433, read-back identical, assignees none, no labels named by the order); this os-dev-report via post-stamped.mjs --comment=28717",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: boot log measured in flow-declared-override-first-boot-pull.integration.test.ts, the loadMetaFromDb boot of a store holding a declared BASE.custom flow override · evidence: the boot prints [metadata_sealed_overlay_unserved] counting the override row with the legacy one ("flow×2 … No read serves them — the package's own definition is served … re-express it as a new item under a new name … then delete the stored row"), while since #28412 the override is served and armed; the line tells the operator to delete the live customization · dedupe words: sealed overlay unserved boot report declared override flow · carrier: none, for the seat to file"
]
}
Generated by Claude Code
chore(changeset): #28717 declares Clause-② yes (widening) for the new…
objectstack-fleet commentedon Nov 1, 2026
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC
Landing record · #28717 · PR #28770
PR #28770 merged by the merge queue as
8f294e04b3onmain(Fixes #28717; contract review PASS6562762205; ACCEPT6562770368). The card closed on the merge.git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-28770-*'origin/mainby contentgit diff --quiet 8f294e04b3 origin/main --the PR's 8 filesgit merge-base --is-ancestor 8f294e04b3 origin/main.customflow override now keeps the name's bare registry slot from the first boot hydration, in either store read order, so the automation boot pull arms it beforekernel:ready.shadowedStoredRowsOf. Both packages are patch, withClause-②: yes (widening)andMetadata-protocol: none.metadata_sealed_overlay_unservedline still counting the served override. It starts now on the same card thread.Release: branch
claude/project-thread-jqgfycmerged; nothing unpushed.pm:dispatchedremoved and the card unassigned.Generated by Claude Code