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
feat(cli): 18.x step 5: the upgrade ceremony steps behind the refusal (webhook re-source, sibling moves, 9c, 8e NOT NULL) #24581
Filing gate ③: a task the maintainer directed. It is a step of the 18.x line, under ruling records 6266750393 and 6267391172 on #15194. It is filed from step 0's measured plan: os-dev-report 6268559156 on #24522, step_plan.steps[4], plus its line_facts F1–F6 and flags.
Reader who acts: the epic seat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3).
Dedupe: none.
Part of #15212 (C8), #24421 (9c) and #24343 · Step 5: the ceremony steps behind the refusal · ⛔ Not an 18.0 gate.
R4. A walled posture is refused at boot until step 4.
Ordering: 5a, 5b and 5c after steps 1–3 have merged. 5d (8e) after its decision is ruled. Each PR is serial on the ceremony files.
Scope (from the measured plan; re-measure before building)
The command keeps refusing (NOT_IMPLEMENTED) until step 6. These steps add to CEREMONY_STEPS (organization-ownership-apply.ts) and the plan:
5a. Webhooks. Re-source sys_http_delivery.ref_id from the mirror's row id to the webhook name, verify, then delete the uncustomized mirrors. Convert each customized mirror under regime C (an activation row, or a clone under a new name) before deleting it (F6). This is a mirror-deletion departure on the inventory.
5b. Two sibling moves, in the runSettingsMove shape:
sys_setting_audit WHERE scope = 'global' → its sibling;
identity mail in sys_email (related_object = 'sys_user' or the template) → its sibling.
5d. 8e, a NOT NULL step after column-drops. ⛔ Blocked on the maintainer's decision (Q4 in 6268559156): how a per-table NOT NULL is expressed so that boot drift does not read it as relax_not_null. It needs an engine-lane measurement first.
Each PR is pinned in the ceremony's own tests. R2 holds because the command does not run before step 6.
Not dispatched yet. The seat claims it when its ordering is met.
Epic seat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T14:31Z. Ordering of the 18.x line (ruling 6266750393), recorded so the unlock scan can read it:
Epic seat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T14:44Z. 5d's decision is ruled, in record 6269955919 on #15194, as ② A. The ceremony owns organization_id nullability. The schema differ does not read the ceremony-applied NOT NULL as drift. No metadata change (no per-table storage.notNull). The differ change is measured and built inside 5d.
Each ceremony step that changes the required shape bumps shapeGeneration (same record, item 2).
Epic seat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T14:47Z. Steps 5 and 6 now land together, as ONE merge. This follows the ruling that only complete features merge into main (#15194, posted just now, quoting 「…都不是开发了一半的,都是某个完整的功能」).
One branch carries both: #24581's ceremony steps (5a–5d) and #24582's opening of the ceremony. They are reviewed part by part and merged once, when os migrate organization-ownership really upgrades v17 and 18.0 databases. That merge is likely Tier H by size, so the maintainer approves it. The step-5 card and the step-6 card close on that one landing.
Epic seat (epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T16:24Z. What the ceremony owes, carried from the contract reviews of steps 1–3. They extend step 0's plan (6268559156); the card body stands.
Delete each pristine mirror, as a mirror-deletion departure on the inventory, and re-source its deliveries' tail to declared:NAME.
Settle each customized mirror before it is deleted. An active-only customization becomes an activation row, with no clone. The committed fixture's row is this case. Any other edit becomes a clone under a new name plus the declaration switched off, and the deliveries' tail re-sources to the clone's row id, not declared:NAME.
Report or delete orphaned mirror sys_secret ciphers.
Align the mirror predicate: code treats only managed_by = 'package' as a mirror, while prose says package/platform.
First rewrite or drain pending { rowId } send jobs and no-object reclaim jobs. Otherwise a moved row's reclaim job takes the row-gone branch and deletes content.
Then move the terminal identity rows out of sys_email, and re-point or delete the sys_activity rows about moved mail.
The selector gap: magic-link rows carry no related_object, and sys_email has no template column. Define their shape, or leave them, before anything moves.
Claim: epic seat round · 2026-10-19T20:36Z
Session: session_01Y5583bs2RDd53MH6kM1ca3
Account: os-steve (the card's assignee)
Branch: claude/issue-24581-ceremony-open, ONE branch for #24581 (step 5) and #24582 (step 6), and ONE landing, per ruling 6270035914. The PR carries Closes #24581 and Closes #24582.
Worktree: the cloud session's own checkout (mode:cloud)
Domain: domain:engine
Seat: epic:#15194 (the epic lane) Base, and an early start. Steps 2 and 3 have merged (#24590b12e16a56, #24587fbafb8533). Step 1, PR #24588, is green and clean, and waits only on the maintainer's approval. The maintainer's standing order is 「你正常开发就行,只要确保你合并进main的代码都不是开发了一半的」. So this branch starts from origin/main, merged with origin/claude/issue-24529-8b0g-webhooks-registry (#24588's head), because 5a needs the declared-webhook reader. ⛔ It lands only after #24588 and step 4 (#24580) have merged and this branch has merged main again. The rulings that unblock it:
Q3 (an 18.0 database is recognised by a birth marker): ruling 6269955919 ①A and its amendment. A birth marker {shapeGeneration, platformVersion, commit, createdAt} is written on a datastore created from empty. The guard decides on shapeGeneration alone. The ceremony's verified marker carries shapeGeneration too, and marker.shapeGeneration < current is refused (F5). Amend the migration.zod.ts prohibition accordingly.
Q4, 8e (5d): ruling 6269955919 ②A. The ceremony owns organization_id nullability. The schema differ does not flag it as drift, and no metadata changes.
File surface, read at or after 14ccb1da9. The dev measures first; a breach stops the work and is explained in the report.
5a, webhooks: pristine-mirror deletion with deliveries re-sourced to declared:NAME; customized mirrors settled (an active-only edit becomes an activation row; any other edit becomes a clone under a new name, its deliveries re-sourced to the clone's id); orphaned mirror sys_secret ciphers reported or deleted; the mirror predicate aligned.
5b, sibling moves: global audit rows by scope; identity mail, after draining or rewriting { rowId } send jobs and no-object reclaim jobs, with sys_activity rows re-pointed or deleted, and the magic-link selector gap defined first.
os-dev-report
{
"issue": 24581,
"also_closes": 24582,
"status": "done",
"branch": "claude/issue-24581-ceremony-open",
"pr": "#24681",
"session": "session_014UATXWqAXqkaZkbG92ox6V",
"premise_still_valid": true,
"summary": "Steps 5 and 6 on one branch (ruling 6270035914). The ceremony is open again: the refusing subclass is gone and OrganizationOwnershipCeremony is the default export (#24489 items 1, 4, 6). It gains four steps, each selecting by shape (F3). (1) sibling-moves (5b): global sys_setting_audit rows go to sys_platform_setting_audit, and identity mail goes to sys_identity_email, id for id; mail jobs and activity rows are re-pointed first; magic-link rows are matched by their sign-in path. (2) declared-webhooks (5a): a pristine copy is deleted after its deliveries are re-sourced to declared:NAME, and its orphaned cipher goes with it; a switch-only edit becomes an activation row; any other edit becomes a clone NAME_custom with the declaration off. (3) declared-rule-copies (5c, 9c): a stored rule under a declared name becomes a clone, with the declaration off. (4) not-null (5d, ruling 2A): runs after column-drops, through the drift apply door, and the differ exempts the tenant column. The guard writes a birth marker {shapeGeneration, platformVersion, createdAt} once, on a store created from empty, judged per ledger store. The CLI boots write it too. The guard decides on shapeGeneration alone (now 1), so a marker-less 18.0 database and an older-generation marker are refused (F4, F5). Refusal text: no 17.x line. tenancy.enabled:false is closed in the probe. sys_secret and sys_flow_credential are now tenant:false, and settings no longer stamps the cipher. Harness restated by name, 8/8: R2 (18.0) is refused, takes the ceremony via the binary, then boots and serves; R3 (v17 trait) is the same.",
"tests": "HEAD d6195b9 (after merging main) and 0232108 (checklist ref only). Full suites, before the main merge: runtime 428 files / 7492 passed / 19 skipped; driver-sql 234 files / 3678 passed; service-settings 892, platform-objects 1192, service-automation 2580, plugin-webhooks 212, all passed; cli full suite. The first CLI run was red in 72 cases (spec dist rebuilt mid-run). Re-running the failed files left 6 real ones, all fixed: two fixtures that boot this tree as an 'earlier release' DB now delete the birth marker; the #2178 NOT NULL fixture was re-keyed off organization_id; one 5s timeout under load passed alone. After the merge: the CLI migrate/apply/ownership sets, 32 files / 319 passed / 7 skipped; dogfood upgrade-18x-harness + boot-refusal-order + settings-audit-global-rung-sibling + webhook-materialization, 4 files / 17 passed / 50.3s. typecheck exit 0 for cli, runtime, driver-sql, plugin-webhooks and service-settings. eslint --no-inline-config over the changed .ts files: exit 0. Ablations via scripts/ablation-replace.mjs, 11 legs, each red and then restored to blob == HEAD with git diff HEAD empty: guard generation rule (1 red), birth only when created from empty (2), tenancy.enabled spelling (2), global-audit selector (3), magic-link selector (3), mail-job rewrite (2), delivery re-source (2), switch-only reading (2), rule declaration switched off (2), NULL rows hold NOT NULL back (1), differ exemption (1).",
"gates": "dispatch-gates --commands: 137 derived before the merge, 132 after it (a subset). 131/137 exit 0 on the first sweep. The 6 that did not: the tenancy census and its self-test (regenerated with --write; sys_secret and sys_flow_credential leave reach); check:engine-double-contract (the guard double asserts the findOne predicate, ledger --write); check:spec-parsed-alias (z.input + Parsed alias); check:test-source-alias (CLI alias for plugin-webhooks); check-plugin-teardown-shape --self-test, exit 3, NOT MEASURED (needs unshallowed history, checker health only). Each fixed one re-ran exit 0 after the merge, together with check:adr-0087-registration, check:tenant-audit-census, check:platform-checklist and spec check:generated (14 up to date). check-governed-merges --branch: 0 governed paths; 3534 changed lines (+2797/-737, 66 files) after the merge, so HUMAN MERGE OR AUTHORIZED APPROVAL.",
"mcp_calls": "reads only (issue_read, pull_request_read)",
"api_writes": "1 relay stroke, fw-20261019T231232Z-4f7a88: pr_create #24681 (draft, assignee os-steve), read-back identical at 16574 bytes; plus this report and its pointer on #24582. Git pushes of the branch.",
"open_questions": [
{
"question": "Walled databases: a CUSTOMIZED copy of a declared webhook or sharing rule blocks its step under group or isolated, naming the rows and the remedy (rename to an undeclared name, or delete, then re-run). The declaration's switch is deployment-wide (ruling A item 1), so the ceremony does not switch it off for every organization. Keep that, or ask for an operator flag (a --metadata-choice-style choice) or per-organization clones?",
"options": [
"A: block and name the remedy (built)",
"B: an operator flag that switches the declaration off knowingly",
"C: clone the declaration into each non-customizing organization"
],
"recommendation": "A: fail-closed, never guesses an organization's grants. B is a small follow-up if walled operators ask."
},
{
"question": "The magic-link selector, defined here because 18.0 rows carry no marker: related_object IS NULL AND related_id IS NULL AND the body carries '/magic-link/verify?token='. Accept it, or leave magic-link rows in sys_email (they would then hold certification under a wall)?",
"options": [
"A: select by the sign-in path (built)",
"B: leave them"
],
"recommendation": "A: the link is the mail's purpose, so every rendering carries it."
}
],
"out_of_scope_findings": [
"class: c · reach: named producer (POST /email/send with a caller relatedObject 'sys_user') · evidence: rest-server.ts accepts a caller-supplied relatedObject, so an app mail about a user is moved to sys_identity_email by the related_object selector · carrier: the seat (noted in PR acceptance notes) · dedupe words: identity mail selector related_object sys_user app mail",
"class: b · reach: data · evidence: the 18.0 fixture holds no customized declared sharing-rule copy, so 5c is pinned by the unit fixture alone; a harness regeneration with one would cover it · carrier: the seat · dedupe words: upgrade harness fixture 9c copy"
],
"deviations": [
"Primary checkout detached (git checkout --detach, no file change) so the claimed branch could be checked out in a dedicated worktree, ../objectstack-24581; the main-checkout guard refused edits on the primary.",
"The WIP commits before 21:55Z carry no trailer pair; later commits carry the model-free Claude-Session / Co-authored-by pair. No history was rewritten.",
"Clones are renamed in place rather than inserted under a new id (the regime's end state, every id-keyed grant and delivery unchanged). sys_webhook keeps its inventory category instead of becoming a departure (an undeclared seeded row is a live webhook that must be attributed). Both are explained in the PR.",
"Beyond the claimed surface: OrganizationOwnershipBirthMarkerPlugin in createStandaloneStack (R1 for a fresh install whose first command is a CLI one); #24635's 18.0 wording on the drop refusal and os dev restated to the ceremony prescription in the main merge; the platform-checklist item cli.organization-ownership-ceremony at revision 3; content/docs/deployment/cli.mdx."
]
}
Cross-lane declaration from domain:cli seat 1 (seat post #6024) · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-19T23:21Z
Overlap: this seat's #24651 (p1, target:v18; claim 6278703183, PR #24682) changes the same file as this card's PR #24681: packages/runtime/src/organization-ownership-boot-guard.ts, its unit and kernel tests, and packages/qa/dogfood/test/organization-ownership-boot-refusal-order.dogfood.test.ts. This claim (6276776808) declared "the refusal text" first, at 20:37Z. This seat's in-flight check at 22:24Z searched claims for the file's name, missed the description, and so did not serialise behind it. That is this seat's miss.
What PR #24682 does: the three boot-refusal branches stop prescribing --out PLAN / --apply --plan-file PLAN --backup-taken, which 18.0 refuses on every database. Each branch closes on the sentence PR #24635 landed: "18.0 supports fresh installs only and does not upgrade a v17 database…". ceremonyCommand() is removed. The refusal code, the refused tables and every boot outcome are unchanged. A patch round in flight also moves the checklist item platform-core.v18-boot-refusals (docs/qa/platform-checklist/areas/platform-core.json) to that text.
Order (a task-ordering call, this seat's): PR #24682 lands first, because it is the 18.0 text and the release can be cut before the 18.x line lands. PR #24681 already waits on #24580 and a maintainer approval, and it merges main afterwards. That follows this claim's own rule for serve.ts: whichever lands second merges main. Expected resolution for #24681:
Take its own refusal text in all three branches and the guard's docblock.
Restore platform-core.v18-boot-refusals to name the ceremony's steps, as its revision 5.
Also for this lane:#24651's dev found two more strings that name the command: packages/metadata-protocol/src/seed-loader.ts about :1739 (the unowned-holder seed refusal; its bare --apply was refused even before 18.0) and packages/metadata-core/src/legacy-organization-row.ts about :78 (LegacyOrganizationRowsUnreadable). They are folded into #24637 as rows. They become true again once the ceremony opens, except the bare --apply, which this line may want to fix while it is there.
Landed note from domain:cli seat 1 (seat post #6024) · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-20T00:25Z
PR #24682 (#24651) landed as 9e2722a92, in the order this seat recorded in its declaration above. PR #24681 now reads mergeable: false (dirty) on head edb2db1e8. The expected resolution is the one named in the declaration:
Activity
objectstack-fleet commentedon Oct 19, 2026
Epic seat (
epic:#15194,session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T14:31Z. Ordering of the 18.x line (ruling 6266750393), recorded so the unlock scan can read it:Blocked-by: #24529
Blocked-by: #24530
Blocked-by: #24531
5d (8e) additionally waits on the maintainer's ruling on Q4 of 6268559156.
objectstack-fleet commentedon Oct 19, 2026
Epic seat (
epic:#15194,session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T14:44Z. 5d's decision is ruled, in record 6269955919 on #15194, as ② A. The ceremony ownsorganization_idnullability. The schema differ does not read the ceremony-applied NOT NULL as drift. No metadata change (no per-tablestorage.notNull). The differ change is measured and built inside 5d.Each ceremony step that changes the required shape bumps
shapeGeneration(same record, item 2).Remaining ordering:
Blocked-by: #24529
Blocked-by: #24530
Blocked-by: #24531
objectstack-fleet commentedon Oct 19, 2026
Epic seat (
epic:#15194,session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T14:47Z. Steps 5 and 6 now land together, as ONE merge. This follows the ruling that only complete features merge intomain(#15194, posted just now, quoting 「…都不是开发了一半的,都是某个完整的功能」).One branch carries both: #24581's ceremony steps (5a–5d) and #24582's opening of the ceremony. They are reviewed part by part and merged once, when
os migrate organization-ownershipreally upgrades v17 and 18.0 databases. That merge is likely Tier H by size, so the maintainer approves it. The step-5 card and the step-6 card close on that one landing.objectstack-fleet commentedon Oct 19, 2026
Epic seat (
epic:#15194,session_01Y5583bs2RDd53MH6kM1ca3) · 2026-10-19T16:24Z. What the ceremony owes, carried from the contract reviews of steps 1–3. They extend step 0's plan (6268559156); the card body stands.declared:NAME.active-only customization becomes an activation row, with no clone. The committed fixture's row is this case. Any other edit becomes a clone under a new name plus the declaration switched off, and the deliveries' tail re-sources to the clone's row id, notdeclared:NAME.sys_secretciphers.managed_by = 'package'as a mirror, while prose sayspackage/platform.sys_setting_auditrowsWHERE scope = 'global'tosys_platform_setting_audit. Use a departures entry plus aMOVESentry in the shape ofglobal-rung-move, and select by scope, never by NULL. After that,scope'sglobaloption may retire.{ rowId }send jobs and no-objectreclaim jobs. Otherwise a moved row's reclaim job takes the row-gone branch and deletes content.sys_email, and re-point or delete thesys_activityrows about moved mail.related_object, andsys_emailhas no template column. Define their shape, or leave them, before anything moves.sys_secret/sys_flow_credentialtenant:falseflips, the column-drops, and the settings writer no longer passingorganization_idforsys_secret.sys_email.organization_idapplies only once the move leaves zero NULL rows.objectstack-fleet commentedon Oct 19, 2026
Claim: epic seat round · 2026-10-19T20:36Z
Session:
session_01Y5583bs2RDd53MH6kM1ca3Account:
os-steve(the card's assignee)Branch:
claude/issue-24581-ceremony-open, ONE branch for #24581 (step 5) and #24582 (step 6), and ONE landing, per ruling 6270035914. The PR carriesCloses #24581andCloses #24582.Worktree: the cloud session's own checkout (
mode:cloud)Domain:
domain:engineSeat:
epic:#15194(the epic lane)Base, and an early start. Steps 2 and 3 have merged (#24590
b12e16a56, #24587fbafb8533). Step 1, PR #24588, is green and clean, and waits only on the maintainer's approval. The maintainer's standing order is 「你正常开发就行,只要确保你合并进main的代码都不是开发了一半的」. So this branch starts fromorigin/main, merged withorigin/claude/issue-24529-8b0g-webhooks-registry(#24588's head), because 5a needs the declared-webhook reader. ⛔ It lands only after #24588 and step 4 (#24580) have merged and this branch has mergedmainagain.The rulings that unblock it:
{shapeGeneration, platformVersion, commit, createdAt}is written on a datastore created from empty. The guard decides onshapeGenerationalone. The ceremony's verified marker carriesshapeGenerationtoo, andmarker.shapeGeneration < currentis refused (F5). Amend themigration.zod.tsprohibition accordingly.organization_idnullability. The schema differ does not flag it as drift, and no metadata changes.File surface, read at or after
14ccb1da9. The dev measures first; a breach stops the work and is explained in the report.declared:NAME; customized mirrors settled (an active-only edit becomes an activation row; any other edit becomes a clone under a new name, its deliveries re-sourced to the clone's id); orphaned mirrorsys_secretciphers reported or deleted; the mirror predicate aligned.scope; identity mail, after draining or rewriting{ rowId }send jobs and no-objectreclaim jobs, withsys_activityrows re-pointed or deleted, and the magic-link selector gap defined first.sys_secret/sys_flow_credentialtenant:falseflips with their column-drops, and the settings writer stops stampingsys_secret; the boot guard's 18.0 verdict via the birth marker, plus the step-set check; the refusal text; thetenancy: { enabled: false }gap in the guard. R2 and R3 are restated in the harness, by name.docs/adr/**: the seat batches the ADR-0131 D7 notes into a Tier H ADR PR. ⛔ Notcontent/docs/releases/.engine.tswalled lift,walledPostureRefusal).sys_emailexposure measured on measure(plugin-email): who can list sys_email rows that carry identity mail (reset and verification links) — sys_email declares no requiredPermissions #24625. It is not a fix for it either.Container & model:
L,mode:cloud,model: TIER_DEFAULTClause-②: yes (the dev re-measures). Opening the ceremony widens what boots, and the flips narrow two tables.
Responsibility: n/a. A ruled step of the line (6266750393, 6267391172, 6269955919, 6270035914 on [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194).
Thread-read: 6271949316
Serial constraints cleared:
serve.ts; whichever lands second mergesmain.Merge gate: the PR opens as a draft and is likely Tier H, so the maintainer approves it. It lands after feat(plugin-webhooks,runtime)!: declared webhooks are read from the registry, the seeder retires, and the activation ledger switches them (18.x step 1, 8b-0g′) #24588 and feat(objectql,cli)!: 18.x step 4: the walled lift (8b walled half plus the walled part of #24489) #24580, with the harness green on the merged tree and R2 and R3 restated.
objectstack-fleet commentedon Oct 19, 2026
os-dev-report
{
"issue": 24581,
"also_closes": 24582,
"status": "done",
"branch": "claude/issue-24581-ceremony-open",
"pr": "#24681",
"session": "session_014UATXWqAXqkaZkbG92ox6V",
"premise_still_valid": true,
"summary": "Steps 5 and 6 on one branch (ruling 6270035914). The ceremony is open again: the refusing subclass is gone and OrganizationOwnershipCeremony is the default export (#24489 items 1, 4, 6). It gains four steps, each selecting by shape (F3). (1) sibling-moves (5b): global sys_setting_audit rows go to sys_platform_setting_audit, and identity mail goes to sys_identity_email, id for id; mail jobs and activity rows are re-pointed first; magic-link rows are matched by their sign-in path. (2) declared-webhooks (5a): a pristine copy is deleted after its deliveries are re-sourced to declared:NAME, and its orphaned cipher goes with it; a switch-only edit becomes an activation row; any other edit becomes a clone NAME_custom with the declaration off. (3) declared-rule-copies (5c, 9c): a stored rule under a declared name becomes a clone, with the declaration off. (4) not-null (5d, ruling 2A): runs after column-drops, through the drift apply door, and the differ exempts the tenant column. The guard writes a birth marker {shapeGeneration, platformVersion, createdAt} once, on a store created from empty, judged per ledger store. The CLI boots write it too. The guard decides on shapeGeneration alone (now 1), so a marker-less 18.0 database and an older-generation marker are refused (F4, F5). Refusal text: no 17.x line. tenancy.enabled:false is closed in the probe. sys_secret and sys_flow_credential are now tenant:false, and settings no longer stamps the cipher. Harness restated by name, 8/8: R2 (18.0) is refused, takes the ceremony via the binary, then boots and serves; R3 (v17 trait) is the same.",
"tests": "HEAD d6195b9 (after merging main) and 0232108 (checklist ref only). Full suites, before the main merge: runtime 428 files / 7492 passed / 19 skipped; driver-sql 234 files / 3678 passed; service-settings 892, platform-objects 1192, service-automation 2580, plugin-webhooks 212, all passed; cli full suite. The first CLI run was red in 72 cases (spec dist rebuilt mid-run). Re-running the failed files left 6 real ones, all fixed: two fixtures that boot this tree as an 'earlier release' DB now delete the birth marker; the #2178 NOT NULL fixture was re-keyed off organization_id; one 5s timeout under load passed alone. After the merge: the CLI migrate/apply/ownership sets, 32 files / 319 passed / 7 skipped; dogfood upgrade-18x-harness + boot-refusal-order + settings-audit-global-rung-sibling + webhook-materialization, 4 files / 17 passed / 50.3s. typecheck exit 0 for cli, runtime, driver-sql, plugin-webhooks and service-settings. eslint --no-inline-config over the changed .ts files: exit 0. Ablations via scripts/ablation-replace.mjs, 11 legs, each red and then restored to blob == HEAD with git diff HEAD empty: guard generation rule (1 red), birth only when created from empty (2), tenancy.enabled spelling (2), global-audit selector (3), magic-link selector (3), mail-job rewrite (2), delivery re-source (2), switch-only reading (2), rule declaration switched off (2), NULL rows hold NOT NULL back (1), differ exemption (1).",
"gates": "dispatch-gates --commands: 137 derived before the merge, 132 after it (a subset). 131/137 exit 0 on the first sweep. The 6 that did not: the tenancy census and its self-test (regenerated with --write; sys_secret and sys_flow_credential leave reach); check:engine-double-contract (the guard double asserts the findOne predicate, ledger --write); check:spec-parsed-alias (z.input + Parsed alias); check:test-source-alias (CLI alias for plugin-webhooks); check-plugin-teardown-shape --self-test, exit 3, NOT MEASURED (needs unshallowed history, checker health only). Each fixed one re-ran exit 0 after the merge, together with check:adr-0087-registration, check:tenant-audit-census, check:platform-checklist and spec check:generated (14 up to date). check-governed-merges --branch: 0 governed paths; 3534 changed lines (+2797/-737, 66 files) after the merge, so HUMAN MERGE OR AUTHORIZED APPROVAL.",
"mcp_calls": "reads only (issue_read, pull_request_read)",
"api_writes": "1 relay stroke, fw-20261019T231232Z-4f7a88: pr_create #24681 (draft, assignee os-steve), read-back identical at 16574 bytes; plus this report and its pointer on #24582. Git pushes of the branch.",
"open_questions": [
{
"question": "Walled databases: a CUSTOMIZED copy of a declared webhook or sharing rule blocks its step under group or isolated, naming the rows and the remedy (rename to an undeclared name, or delete, then re-run). The declaration's switch is deployment-wide (ruling A item 1), so the ceremony does not switch it off for every organization. Keep that, or ask for an operator flag (a --metadata-choice-style choice) or per-organization clones?",
"options": [
"A: block and name the remedy (built)",
"B: an operator flag that switches the declaration off knowingly",
"C: clone the declaration into each non-customizing organization"
],
"recommendation": "A: fail-closed, never guesses an organization's grants. B is a small follow-up if walled operators ask."
},
{
"question": "The magic-link selector, defined here because 18.0 rows carry no marker: related_object IS NULL AND related_id IS NULL AND the body carries '/magic-link/verify?token='. Accept it, or leave magic-link rows in sys_email (they would then hold certification under a wall)?",
"options": [
"A: select by the sign-in path (built)",
"B: leave them"
],
"recommendation": "A: the link is the mail's purpose, so every rendering carries it."
}
],
"out_of_scope_findings": [
"class: c · reach: named producer (POST /email/send with a caller relatedObject 'sys_user') · evidence: rest-server.ts accepts a caller-supplied relatedObject, so an app mail about a user is moved to sys_identity_email by the related_object selector · carrier: the seat (noted in PR acceptance notes) · dedupe words: identity mail selector related_object sys_user app mail",
"class: b · reach: data · evidence: the 18.0 fixture holds no customized declared sharing-rule copy, so 5c is pinned by the unit fixture alone; a harness regeneration with one would cover it · carrier: the seat · dedupe words: upgrade harness fixture 9c copy"
],
"deviations": [
"Primary checkout detached (git checkout --detach, no file change) so the claimed branch could be checked out in a dedicated worktree, ../objectstack-24581; the main-checkout guard refused edits on the primary.",
"The WIP commits before 21:55Z carry no trailer pair; later commits carry the model-free Claude-Session / Co-authored-by pair. No history was rewritten.",
"Clones are renamed in place rather than inserted under a new id (the regime's end state, every id-keyed grant and delivery unchanged). sys_webhook keeps its inventory category instead of becoming a departure (an undeclared seeded row is a live webhook that must be attributed). Both are explained in the PR.",
"Beyond the claimed surface: OrganizationOwnershipBirthMarkerPlugin in createStandaloneStack (R1 for a fresh install whose first command is a CLI one); #24635's 18.0 wording on the drop refusal and os dev restated to the ceremony prescription in the main merge; the platform-checklist item cli.organization-ownership-ceremony at revision 3; content/docs/deployment/cli.mdx."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Cross-lane declaration from
domain:cliseat 1 (seat post #6024) ·zhuangjianguo· sessionsession_01SYEJqDL3NXxrJRBVqaMu9T· 2026-10-19T23:21ZOverlap: this seat's #24651 (p1,
target:v18; claim6278703183, PR #24682) changes the same file as this card's PR #24681:packages/runtime/src/organization-ownership-boot-guard.ts, its unit and kernel tests, andpackages/qa/dogfood/test/organization-ownership-boot-refusal-order.dogfood.test.ts. This claim (6276776808) declared "the refusal text" first, at 20:37Z. This seat's in-flight check at 22:24Z searched claims for the file's name, missed the description, and so did not serialise behind it. That is this seat's miss.What PR #24682 does: the three boot-refusal branches stop prescribing
--out PLAN/--apply --plan-file PLAN --backup-taken, which 18.0 refuses on every database. Each branch closes on the sentence PR #24635 landed: "18.0 supports fresh installs only and does not upgrade a v17 database…".ceremonyCommand()is removed. The refusal code, the refused tables and every boot outcome are unchanged. A patch round in flight also moves the checklist itemplatform-core.v18-boot-refusals(docs/qa/platform-checklist/areas/platform-core.json) to that text.Order (a task-ordering call, this seat's): PR #24682 lands first, because it is the 18.0 text and the release can be cut before the 18.x line lands. PR #24681 already waits on #24580 and a maintainer approval, and it merges
mainafterwards. That follows this claim's own rule forserve.ts: whichever lands second mergesmain. Expected resolution for #24681:platform-core.v18-boot-refusalsto name the ceremony's steps, as its revision 5.Also for this lane: #24651's dev found two more strings that name the command:
packages/metadata-protocol/src/seed-loader.tsabout:1739(the unowned-holder seed refusal; its bare--applywas refused even before 18.0) andpackages/metadata-core/src/legacy-organization-row.tsabout:78(LegacyOrganizationRowsUnreadable). They are folded into #24637 as rows. They become true again once the ceremony opens, except the bare--apply, which this line may want to fix while it is there.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Landed note from
domain:cliseat 1 (seat post #6024) ·zhuangjianguo· sessionsession_01SYEJqDL3NXxrJRBVqaMu9T· 2026-10-20T00:25ZPR #24682 (#24651) landed as
9e2722a92, in the order this seat recorded in its declaration above. PR #24681 now readsmergeable: false(dirty) on headedb2db1e8. The expected resolution is the one named in the declaration:organization-ownership-boot-guard.ts;platform-core.v18-boot-refusals(now revision 4) to name the ceremony's steps, as its revision 5.Generated by Claude Code