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
docs: four pages walk operators through os migrate organization-ownership plan/apply with no 18.0 qualifier, and 18.0 refuses that command on every database (#24637, domain:devx row) #24653
Filing gate ④: a per-lane child of the coordination parent #24637 (18.0 release text family). Each row is ①'s release-text exception. Filed by the triage seat (seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U. ⛔ Not a claim. Reader who acts: the domain:devx seat, in one PR on the pages below.
Rows
In 18.0, os migrate organization-ownership refuses plan and apply on every database (ORGANIZATION_OWNERSHIP_UPGRADE_UNAVAILABLE, NOT_IMPLEMENTED). On origin/mainf89d29e382, these pages walk an operator through plan and apply with no 18.0 qualifier:
content/docs/deployment/cli.mdx: 5 hits, about :200–222, :1027–1029 and :1477–1494, including the gate that "waits for a verified … --apply --plan-file run";
Done: each passage either says what 18.0 supports for a v17 database in the landed member's terms (PR #24635, f89d29e382: "18.0 supports fresh installs only and does not upgrade a v17 database: keep a v17 database on a 17.x release until the 18.x release that carries the upgrade path."), or carries an 18.x qualifier where it describes the future ceremony. Census: git grep -n -E "organization-ownership (--apply|--out|--dev)|--plan-file" -- content/docs.
Dedupe
The parent's searches cover these rows: MCP search_issues "organization-ownership command refused in 18.0 still named in refusal text upgrade guide ADR-0087 entries plan-file", 45 hits, closed included. The family members are #24566, #24567 and #23871, all closed. None covers the docs pages.
Claim: PM loop round 9 · runs beside #24579 round 4, under the maintainer's 「并发2」 (this session's chat, 2026-10-19), which replaces 「后续并发保持1」
Session: session_01FM29ZqLTrnPNXxijioZwMp
Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-24653-docs-org-ownership-18-qualifier
Worktree: objectstack-issue-24653
Domain: domain:devx
Seat: domain:devx#1
File surface: the four pages the card names, and no other paths:
content/docs/deployment/cli.mdx (about :200–222, :1027–1029 and :1477–1494)
Stop if the change would breach that list, and explain why in the report. ⛔ No package code: the CLI's own refusal text and help example are #24567 row 3 (domain:cli), and the spec, runtime and plugin text are #24637's other lanes.
Container & model: S (docs-only qualifiers on four pages), mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate)
Clause-②: no
Responsibility: four docs pages walk an operator through os migrate organization-ownership plan/apply with no 18.0 qualifier, and 18.0 refuses that command on every database | none: the operator runs the command and reads the refusal | every operator reading the 18.0 docs with a v17 database
Thread-read: none
Serial constraints cleared: none of the 15 open PRs touches the four pages, read at 2026-10-19T22:24Z. The coordination parent #24637 is claimed by the domain:spec lane and its rows are in other files. #24579 round 4 (this seat, in flight) edits docs/qa/platform-checklist/areas/ only.
os-dev-report
{
"issue": 24653,
"status": "done",
"branch": "claude/issue-24653-docs-org-ownership-18-qualifier",
"pr": "#24678",
"session": "session_01FM29ZqLTrnPNXxijioZwMp — this run's harness-stamped id (subagent = parent's)",
"premise_still_valid": true,
"summary": "Docs only, the four claimed pages, head d989786 on BASE bfc1539 (origin/main unmoved at report time). Each passage that walks an operator through os migrate organization-ownership plan or apply now carries either (a) the landed 18.0 sentence or (b) an explicit 'In the 18.x release that carries the upgrade path' qualifier over the ceremony's mechanics. In cli.mdx, the os dev section's heading loses its false 'is upgraded in place', its callout says what os dev does in 18.0, and the os serve/os start sentence no longer depends on the boot refusal naming a command. The drop-gate bullet says that 18.0 never records a verified run, carries the landed sentence, and names the population the code actually holds back: every organization_id drop the drift offers, not only the D7 tables and the sys_metadata family. The os migrate organization-ownership callout ends with a qualifier covering its fence and list. metadata-lifecycle:109 carries (a) then (b); capabilities and permission-sets carry (b) with a link to the CLI page's callout. The first line of both cli.mdx callouts is kept byte-identical, because open draft PR #24667 rewrites exactly those lines; a trial merge of its hunks is clean (exit 0), and the control leg against my first commit conflicts (exit 1).",
"census": {
"command": "git grep -n -E "organization-ownership (--apply|--out|--dev)|--plan-file" -- content/docs",
"before_bfc1539fe0": [
"concepts/metadata-lifecycle.mdx:109",
"deployment/cli.mdx:213",
"deployment/cli.mdx:1029",
"deployment/cli.mdx:1492",
"deployment/cli.mdx:1493",
"deployment/cli.mdx:1494",
"permissions/capabilities.mdx:220",
"permissions/permission-sets.mdx:399"
],
"after_d989786746": [
"concepts/metadata-lifecycle.mdx:109 — (a)+(b): the landed sentence verbatim, then 'In that release, the v18 migration ceremony (… --out PLAN, then --apply --plan-file PLAN) carries such a row…'",
"deployment/cli.mdx:220 (os dev step 2, --dev) — (b) 'In the 18.x release that carries the upgrade path, os dev runs that ceremony for you…' (:215), under the (a) callout :205–213",
"deployment/cli.mdx:1047 (drop gate, --apply --plan-file FILE) — (a)+(b): :1043–1046 '18.0 itself never records a verified run, so on a v17 database this refusal holds on every run.' plus the landed sentence verbatim, then 'In that release, the ceremony's … run drops these columns itself…'",
"deployment/cli.mdx:1507 (fence --out) — (b) under the (a) callout :1498–1504, ending 'The invocations below, and what the list after them says the ceremony does, are that 18.x release's.'",
"deployment/cli.mdx:1508 (fence --apply --plan-file) — (b), same callout",
"deployment/cli.mdx:1509 (fence --dev) — (b), same callout",
"permissions/capabilities.mdx:223 — (b) 'In the 18.x release that carries the upgrade path (18.0 does not upgrade a v17 database: see os migrate organization-ownership)' :220–222, linking /docs/deployment/cli#os-migrate-organization-ownership",
"permissions/permission-sets.mdx:402 — (b), the same qualifier and link :399–401"
],
"counts": "8 before, 8 after; every after-hit sits under an (a) or (b) sentence"
},
"hypotheses": {
"1_os_dev": "Measured at BASE, and the step still runs and refuses. dev.ts recover calls upgradeDevelopmentDatabase. For a local SQLite file it copies the file and its telemetry sibling into the backups dir, then spawns 'migrate organization-ownership --dev --database-url URL --out PLAN'. The registered MigrateOrganizationOwnership.run() refuses that (NOT_IMPLEMENTED, exit 1, no plan written). os dev then prints the refusal, 'The upgrade plan was refused, and nothing was changed', the copy's location and the 18.0 sentence, and exits with the child's code; the apply step is never reached. Any other database: no copy, nothing run, the 18.0 sentence. Read from source; also pnpm --filter @objectstack/cli exec vitest run --maxWorkers=2 src/utils/dev-organization-ownership-upgrade.test.ts under os-verify-lock gave 'Tests 6 passed (6)', VERDICT command-exit 0 (the refused-plan case asserts one call, 'nothing was changed', the copy path, '17.x release', no --plan-file). NOT run live: docs-only card, and a live run needs the CLI closure built (turbo dry-run: 63 tasks, 49 cache misses).",
"2_docs_gates_on_fences": "Falsified: no gate reads that fence. check:cli-examples-parity compares one declared pair only (os package publish; --list prints '1 row(s) read'). check-cli-command-ids excludes content/docs by its own header. The fence names only flags the registered command declares, and all 45 derived gates exit 0 with it kept.",
"3_release_page": "Falsified: content/docs/releases/v18/index.mdx has no 'fresh install', '17.x release' or 'upgrade path'. The (a) passages therefore carry the sentence, and the permissions pages link to the cli.mdx callout. The release page is not touched."
},
"facts_measured_at_BASE": "Drop gate: apply.ts:555–611 refuses every --allow-destructive run whose intended drift holds an organization_id drop while readOrganizationOwnershipMarker is not verified (exit 1; --json message refused_organization_ownership_unmigrated, tables, detail, marker). Only the ceremony's apply writes that marker, and 18.0 registers the refusing class, so on a v17-shaped database 18.0 still withholds the drops. Refusal code: ORGANIZATION_OWNERSHIP_UPGRADE_UNAVAILABLE_CODE = 'NOT_IMPLEMENTED' (organization-ownership.ts:1115). run() at :1147 refuses before it opens anything: --json gives {error plan_refused|apply_refused, reason upgrade-unavailable, code NOT_IMPLEMENTED, detail}, exit 1.",
"files_changed": [
"content/docs/deployment/cli.mdx (+29/-14)",
"content/docs/concepts/metadata-lifecycle.mdx (+1/-1)",
"content/docs/permissions/capabilities.mdx (+5/-2)",
"content/docs/permissions/permission-sets.mdx (+4/-1)"
],
"lines": "57 changed lines (+39 / -18), 4 files, 2 commits (5da97c5, d989786), as dispatch-gates reports them against merge base bfc1539",
"tests": "No package code and no tested behaviour changed, so no ablation or reverse verification was done. The measurement for hypothesis 1: dev-organization-ownership-upgrade.test.ts, 6/6 passed under the lock, VERDICT command-exit 0. MDX compile of the four pages (@mdx-js/mdx 3.1.1 + remark-gfm, from a scratch script): 4 OK at d989786. Negative control (an unclosed expression): FAIL, exit 1. Control-byte self-scan of the four files: no match (grep exit 1). Census as above, run before and after.",
"gates": "Local, head d989786: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (no paths) gave 4 paths, 57 changed lines and 45 commands. Each was run once, with its exit code captured before any pipe: node scripts/check-ci-filter-parity.mjs = exit 0; node scripts/check-closing-keyword-parity.mjs = exit 0; node scripts/check-closing-keyword-parity.mjs --self-test = exit 0; node scripts/check-comment-mask-corpus.mjs = exit 0; node scripts/check-doc-frontmatter.mjs = exit 0; node scripts/check-doc-frontmatter.mjs --self-test = exit 0; node scripts/check-doc-route-spelling.mjs --advisory = exit 0; node scripts/check-doc-route-spelling.mjs --self-test = exit 0; node scripts/check-docs-section-name.mjs = exit 0; node scripts/check-docs-section-name.mjs --self-test = exit 0; node scripts/check-section-landing-index.mjs = exit 0; node scripts/check-section-landing-index.mjs --self-test = exit 0; node scripts/check-system-context-census.mjs = exit 0; node scripts/check-system-context-census.mjs --self-test = exit 0; pnpm --filter @objectstack/lint run check:doc-formula-expressions = exit 0; pnpm --filter @objectstack/lint run check:doc-security-posture = exit 0; pnpm --filter @objectstack/spec run check:docs = exit 0; pnpm --filter @objectstack/spec run check:empty-state = exit 0; pnpm --filter @objectstack/spec run check:liveness = exit 0; pnpm --filter @objectstack/spec run check:skill-examples = exit 0; pnpm --filter @objectstack/spec run check:strictness-ledger = exit 0; pnpm --filter @objectstack/spec run check:variant-docs = exit 0; pnpm --filter @objectstack/spec run check:yaml-examples = exit 0; pnpm check:cli-examples-parity = exit 0; pnpm check:corpus-claim-drift = exit 0; pnpm check:cross-package-test-inputs = exit 0; pnpm check:doc-anchors = exit 0; pnpm check:doc-authoring = exit 0; pnpm check:docs-audit-scope = exit 0; pnpm check:docs-redirects = exit 0; pnpm check:docs-single-h1 = exit 0; pnpm check:docs-spec-enumerations = exit 0; pnpm check:docs-transcript-drift = exit 0; pnpm check:driver-memory-census = exit 0; pnpm check:gitlink-declared = exit 0; pnpm check:merge-driver = exit 0; pnpm check:nul-bytes = exit 0; pnpm check:overlay-whitelist-table = exit 0; pnpm check:published-readme-links = exit 0; pnpm check:react-page-adapter-contract = exit 0; pnpm check:refd-timer-probe = exit 0; pnpm check:role-word = exit 0; pnpm check:skill-identifier-liveness = exit 0; pnpm check:vendor-version-stamps = exit 0; pnpm check:watch-hint-literal = exit 0. --ran reconciliation: 'Run reconciliation — 45 derived, 45 run, 0 NOT-MEASURED, 0 UNRUN.' and '✓ dispatch-gates --ran: 45 derived famil(ies) accounted for — 45 run, 0 NOT-MEASURED (a DERIVED zero …)', exit 0. At the first head 5da97c5, five first attempts measured nothing: check:doc-formula-expressions, check:doc-security-posture, check:skill-examples and check:docs-transcript-drift exited 3 (PREREQUISITE NOT MET, dist absent), and check:docs exited 1 (packages/spec/json-schema missing). They re-ran exit 0 after turbo build of spec, lint, formula and sdui-parser (4 cache hits; lock VERDICT command-exit 0), then core, client and client-react (lock VERDICT command-exit 0). Not run locally, and CI's: pnpm lint, the 11 declared-wide families, Build Docs, Test Core and the full farm. PR #24678 check-runs at d989786 at report time: success for Check Changeset, Check Documentation Links, Auto Label, Check PR Size, Dogfood Regression Gate, Spec property liveness, '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' and filter. in_progress for Build Docs, Governed Surface Queue Guard, Lint · ESLint, Lint · CI, release & engine gates, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, the three Lint · scoped jobs, Test Core (1/6)–(6/6), and Type Check · consumer gates / debt ledger / source gates / workspace. Skipped as selected: Build Core, Console Pin Gate, Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance. Nothing has gone red yet. Lint & Repo Gates and TypeScript Type Check have not converged: in_progress is the honest value.",
"mcp_calls": "0",
"api_writes": "2 — both via the fleet-write relay as objectstack-fleet[bot], each sent as one POST /repos/objectstack-ai/objectstack/dispatches. (1) pr_create, run 39338543518: POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24678/assignees [os-warren] + POST /repos//issues/24678/labels [skip-changeset]. Read-back: '12626 byte(s) sent, 12626 stored — identical', assignees os-warren. A later REST read lists the labels documentation, size/s and skip-changeset (the first two are Auto Label's), with draft true. (2) this os-dev-report comment, POST /repos//issues/24653/comments, via scripts/pm/post-stamped.mjs. Also 3 git pushes, not REST: the empty-branch probe, 5da97c5 and d989786. No review request, no ready flip.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: #24637 (the family parent; its seat folds it) · noted, not filed. content/docs/kernel/contracts/metadata-service.mdx:415–419 says 'an 18.x os serve refuses to start on a database still holding one until the v18 migration ceremony (ADR-0131 C7) has carried it to the environment layer', with no 18.0 sentence or 18.x qualifier. It is the twin of metadata-lifecycle:109. It names no command, so the card's census misses it, and it is outside this claim's file surface. Recorded in PR #24678's Acceptance notes. Dedupe words: metadata-service overlay row 18.x os serve migration ceremony no 18.0 qualifier; ADR-0131 C7 environment layer docs 18.0."
],
"deviations": "(1) The two cli.mdx callouts keep their first line byte-identical ('18.0 supports fresh single installs; upgrades and walled postures arrive in 18.x. …'), because open draft PR #24667 (18.x walled lift) rewrites exactly those lines. There, (a) is that line plus the landed sentence's second half ('18.0 does not upgrade a v17 database: keep a v17 database on a 17.x release until the 18.x release that carries the upgrade path' for os dev; BASE's own 'Keep a v17 database on a 17.x release until …' for the ceremony section), not the sentence verbatim. Trial merge: clean, exit 0; control leg: exit 1, CONFLICT. The claim's 'none of the 15 open PRs touches the four pages' no longer holds: #24667 now touches cli.mdx (lines 207, 1205, 1485 at BASE). (2) The drop-gate bullet's table population was corrected from code ('These tables are the ADR-0131 D7 tables and the sys_metadata family' was narrower than ceremonyOrganizationColumnDrops), under the dispatch's 'states what the code does at BASE'. (3) The harness attribution reminder asked for a Co-Authored-By trailer naming a model and an emoji PR footer. Per AGENTS.md, the commits carry the model-free pair (Claude-Session + Co-authored-by: Claude), and the PR body ends with the session-URL footer form. (4) Cleanup runs right after this comment is posted: rm -rf the worktree's node_modules, then git worktree remove without --force; the branch and PR stay."
}
The dev's report os-dev-report on this card found a fifth page with the same defect: content/docs/kernel/contracts/metadata-service.mdx:415–419.
It says "an 18.x os serve refuses to start on a database still holding one until the v18 migration ceremony (ADR-0131 C7) has carried it to the environment layer".
There is no 18.0 sentence and no 18.x qualifier. It is the twin of metadata-lifecycle.mdx:109.
It names no command, so the card's census misses it.
It is the same defect class and the same lane (content/docs/**), it is mechanical, and no open PR touches the page (read at 2026-10-19T23:03Z). So this seat adds it to the claim's file surface and folds it into PR #24678 in one patch round, rather than filing a sibling card.
New head:65b2b74b81 on PR #24678. It is one commit on top of d989786746. origin/main was not merged in: no conflict and no main-caused red, and main has not touched these five pages since bfc1539fe0. The PR body is unchanged.
The passage:content/docs/kernel/contracts/metadata-service.mdx, "Environment Customization", :414–424. It now carries (a) the landed sentence verbatim, and both ceremony halves (the overlay row and the public-form withdrawals) sit under the (b) qualifier.
BEFORE … An overlay row an earlier release stored under an organization is served by no read, and
an 18.x `os serve` refuses to start on a database still holding one until the v18 migration
ceremony (ADR-0131 C7) has carried it to the environment layer. The anonymous form doors read
the environment alone too: the ceremony carries every organization-layer public-form withdrawal
onto the environment, fail-closed.
AFTER … An overlay row an earlier release stored under an organization is served by no read. On a
SQL database (SQLite, PostgreSQL, MySQL) still holding one, a v18 `os serve` refuses to start,
because the `sys_metadata` family there still carries its `organization_id` column. 18.0
supports fresh installs only and does not upgrade a v17 database: keep a v17 database on a 17.x
release until the 18.x release that carries the upgrade path. In that release, the v18
migration ceremony (ADR-0131 C7) carries such a row to the environment layer. The anonymous
form doors read the environment alone too; in that release the ceremony carries every
organization-layer public-form withdrawal onto the environment, fail-closed.
The twin.concepts/metadata-lifecycle.mdx:109 said "a v18 os serve refuses to start on a database still holding one". It now says "on a SQL database (SQLite, PostgreSQL, MySQL) still holding one a v18 os serve refuses to start". The measurement below is why: the guard reads physical columns and is inert on memory and MongoDB. No other word changed, and the census is unchanged: 8 hits, the same lines.
os serve at BASE, measured.
Source.serve.ts:4116–4126 composes OrganizationOwnershipBootGuardPlugin on every served kernel. Its start() (runtime/organization-ownership-boot-guard.ts) refuses when an object declaring no organization column (sys_metadata: systemFields.tenant: false, metadata-core/src/objects/sys-metadata.object.ts:240) still carries a physical organization_id and the ceremony's marker is not verified. The error is OrganizationOwnershipBootRefusal, with code ORGANIZATION_OWNERSHIP_MIGRATION_REQUIRED, the host's discriminator. That code is not printed: os serve prints the refusal text and exits 1. Only SQL drivers are read.
Unit.pnpm --filter @objectstack/runtime exec vitest run --maxWorkers=2 src/organization-ownership-boot-guard.test.ts, under the lock: Tests 17 passed (17), VERDICT command-exit 0. This includes the case refusing a v17-shape sys_metadata with that code, and "a driver with no physical columns (memory, MongoDB) is inert".
Live, built CLI from examples/app-crm. The database: os migrate apply --yes --json on an empty SQLite file (exit 0), then ALTER TABLE sys_metadata ADD COLUMN organization_id TEXT and one view overlay row with organization_id = 'org_legacy'. os serve on a random port with OS_DATABASE_URL, OS_AUTH_SECRET and OS_SECRET_KEY set exited 1, printing "✗ This database is still in the v17 organization-ownership shape: sys_metadata still carries a physical organization_id column, and the ceremony has not run on it. The server refuses to start … 18.0 does not upgrade a v17 database: keep this one on a 17.x release until the 18.x release that carries the upgrade path …". The row was still there afterwards (1 of 1).
Control leg: the same file copied before the ALTER printed "✓ Server is ready" and was stopped by timeout (exit 124). Both ports were free afterwards.
Gates at 65b2b74b81.node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands derived 45 commands for the 5 paths (72 changed lines, +49 / -23), the same 45 as round 0. Every one exited 0 on its first attempt, each exit code captured before any pipe: check-ci-filter-parity.mjs, check-closing-keyword-parity.mjs, check-closing-keyword-parity.mjs --self-test, check-comment-mask-corpus.mjs, check-doc-frontmatter.mjs, check-doc-frontmatter.mjs --self-test, check-doc-route-spelling.mjs --advisory, check-doc-route-spelling.mjs --self-test, check-docs-section-name.mjs, check-docs-section-name.mjs --self-test, check-section-landing-index.mjs, check-section-landing-index.mjs --self-test, check-system-context-census.mjs, check-system-context-census.mjs --self-test, lint check:doc-formula-expressions, lint check:doc-security-posture, spec check:docs, spec check:empty-state, spec check:liveness, spec check:skill-examples, spec check:strictness-ledger, spec check:variant-docs, spec check:yaml-examples, check:cli-examples-parity, check:corpus-claim-drift, check:cross-package-test-inputs, check:doc-anchors, check:doc-authoring, check:docs-audit-scope, check:docs-redirects, check:docs-single-h1, check:docs-spec-enumerations, check:docs-transcript-drift, check:driver-memory-census, check:gitlink-declared, check:merge-driver, check:nul-bytes, check:overlay-whitelist-table, check:published-readme-links, check:react-page-adapter-contract, check:refd-timer-probe, check:role-word, check:skill-identifier-liveness, check:vendor-version-stamps, check:watch-hint-literal. --ran: "Run reconciliation — 45 derived, 45 run, 0 NOT-MEASURED, 0 UNRUN." MDX compile of the five pages: 5 OK. Control-byte scan: none.
Writes this round: one git push (d989786746..65b2b74b81) and this comment. No PR-body edit, review request or ready flip. MCP calls: 0.
PR #24678 merged at 2026-10-19T23:54:47Z as 0431002104 (not governed). This seat landed it on its ACCEPT 6279639697
origin/main, by content
All five pages are byte-identical to the PR head 65b2b74b81: deployment/cli.mdx, concepts/metadata-lifecycle.mdx, permissions/capabilities.mdx, permissions/permission-sets.mdx and kernel/contracts/metadata-service.mdx (the addendum 6279273698). The census git grep -n -E "organization-ownership (--apply|--out|--dev)|--plan-file" -- content/docs reads 8 hits on main. Each one sits under the landed 18.0 sentence or an 18.x qualifier
State change: PR #24678 closed this card through Fixes #24653 (completed). pm:dispatched comes off in this act. The family parent #24637 (domain:spec lane) keeps its other rows, and PR #24678 carried Refs #24637 without closing it.
Activity
objectstack-fleet commentedon Oct 19, 2026
Claim: PM loop round 9 · runs beside #24579 round 4, under the maintainer's 「并发2」 (this session's chat, 2026-10-19), which replaces 「后续并发保持1」
Session:
session_01FM29ZqLTrnPNXxijioZwMpAccount:
os-warren(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-24653-docs-org-ownership-18-qualifierWorktree:
objectstack-issue-24653Domain:
domain:devxSeat:
domain:devx#1File surface: the four pages the card names, and no other paths:
content/docs/deployment/cli.mdx(about:200–222,:1027–1029and:1477–1494)content/docs/concepts/metadata-lifecycle.mdx(:109)content/docs/permissions/capabilities.mdx(:220)content/docs/permissions/permission-sets.mdx(:399)Stop if the change would breach that list, and explain why in the report. ⛔ No package code: the CLI's own refusal text and help example are #24567 row 3 (
domain:cli), and the spec, runtime and plugin text are #24637's other lanes.Container & model:
S (docs-only qualifiers on four pages),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tier: no path-derived mandate)Clause-②: no
Responsibility:
four docs pages walk an operator through os migrate organization-ownership plan/apply with no 18.0 qualifier, and 18.0 refuses that command on every database|none: the operator runs the command and reads the refusal|every operator reading the 18.0 docs with a v17 databaseThread-read: none
Serial constraints cleared: none of the 15 open PRs touches the four pages, read at 2026-10-19T22:24Z. The coordination parent #24637 is claimed by the
domain:speclane and its rows are in other files. #24579 round 4 (this seat, in flight) editsdocs/qa/platform-checklist/areas/only.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
os-dev-report
{
"issue": 24653,
"status": "done",
"branch": "claude/issue-24653-docs-org-ownership-18-qualifier",
"pr": "#24678",
"session": "session_01FM29ZqLTrnPNXxijioZwMp — this run's harness-stamped id (subagent = parent's)",
"premise_still_valid": true,
"summary": "Docs only, the four claimed pages, head d989786 on BASE bfc1539 (origin/main unmoved at report time). Each passage that walks an operator through os migrate organization-ownership plan or apply now carries either (a) the landed 18.0 sentence or (b) an explicit 'In the 18.x release that carries the upgrade path' qualifier over the ceremony's mechanics. In cli.mdx, the os dev section's heading loses its false 'is upgraded in place', its callout says what os dev does in 18.0, and the os serve/os start sentence no longer depends on the boot refusal naming a command. The drop-gate bullet says that 18.0 never records a verified run, carries the landed sentence, and names the population the code actually holds back: every organization_id drop the drift offers, not only the D7 tables and the sys_metadata family. The os migrate organization-ownership callout ends with a qualifier covering its fence and list. metadata-lifecycle:109 carries (a) then (b); capabilities and permission-sets carry (b) with a link to the CLI page's callout. The first line of both cli.mdx callouts is kept byte-identical, because open draft PR #24667 rewrites exactly those lines; a trial merge of its hunks is clean (exit 0), and the control leg against my first commit conflicts (exit 1).",
"census": {
"command": "git grep -n -E "organization-ownership (--apply|--out|--dev)|--plan-file" -- content/docs",
"before_bfc1539fe0": [
"concepts/metadata-lifecycle.mdx:109",
"deployment/cli.mdx:213",
"deployment/cli.mdx:1029",
"deployment/cli.mdx:1492",
"deployment/cli.mdx:1493",
"deployment/cli.mdx:1494",
"permissions/capabilities.mdx:220",
"permissions/permission-sets.mdx:399"
],
"after_d989786746": [
"concepts/metadata-lifecycle.mdx:109 — (a)+(b): the landed sentence verbatim, then 'In that release, the v18 migration ceremony (… --out PLAN, then --apply --plan-file PLAN) carries such a row…'",
"deployment/cli.mdx:220 (os dev step 2, --dev) — (b) 'In the 18.x release that carries the upgrade path, os dev runs that ceremony for you…' (:215), under the (a) callout :205–213",
"deployment/cli.mdx:1047 (drop gate, --apply --plan-file FILE) — (a)+(b): :1043–1046 '18.0 itself never records a verified run, so on a v17 database this refusal holds on every run.' plus the landed sentence verbatim, then 'In that release, the ceremony's … run drops these columns itself…'",
"deployment/cli.mdx:1507 (fence --out) — (b) under the (a) callout :1498–1504, ending 'The invocations below, and what the list after them says the ceremony does, are that 18.x release's.'",
"deployment/cli.mdx:1508 (fence --apply --plan-file) — (b), same callout",
"deployment/cli.mdx:1509 (fence --dev) — (b), same callout",
"permissions/capabilities.mdx:223 — (b) 'In the 18.x release that carries the upgrade path (18.0 does not upgrade a v17 database: see os migrate organization-ownership)' :220–222, linking /docs/deployment/cli#os-migrate-organization-ownership",
"permissions/permission-sets.mdx:402 — (b), the same qualifier and link :399–401"
],
"counts": "8 before, 8 after; every after-hit sits under an (a) or (b) sentence"
},
"hypotheses": {
"1_os_dev": "Measured at BASE, and the step still runs and refuses. dev.ts recover calls upgradeDevelopmentDatabase. For a local SQLite file it copies the file and its telemetry sibling into the backups dir, then spawns 'migrate organization-ownership --dev --database-url URL --out PLAN'. The registered MigrateOrganizationOwnership.run() refuses that (NOT_IMPLEMENTED, exit 1, no plan written). os dev then prints the refusal, 'The upgrade plan was refused, and nothing was changed', the copy's location and the 18.0 sentence, and exits with the child's code; the apply step is never reached. Any other database: no copy, nothing run, the 18.0 sentence. Read from source; also pnpm --filter @objectstack/cli exec vitest run --maxWorkers=2 src/utils/dev-organization-ownership-upgrade.test.ts under os-verify-lock gave 'Tests 6 passed (6)', VERDICT command-exit 0 (the refused-plan case asserts one call, 'nothing was changed', the copy path, '17.x release', no --plan-file). NOT run live: docs-only card, and a live run needs the CLI closure built (turbo dry-run: 63 tasks, 49 cache misses).",
"2_docs_gates_on_fences": "Falsified: no gate reads that fence. check:cli-examples-parity compares one declared pair only (os package publish; --list prints '1 row(s) read'). check-cli-command-ids excludes content/docs by its own header. The fence names only flags the registered command declares, and all 45 derived gates exit 0 with it kept.",
"3_release_page": "Falsified: content/docs/releases/v18/index.mdx has no 'fresh install', '17.x release' or 'upgrade path'. The (a) passages therefore carry the sentence, and the permissions pages link to the cli.mdx callout. The release page is not touched."
},
"facts_measured_at_BASE": "Drop gate: apply.ts:555–611 refuses every --allow-destructive run whose intended drift holds an organization_id drop while readOrganizationOwnershipMarker is not verified (exit 1; --json message refused_organization_ownership_unmigrated, tables, detail, marker). Only the ceremony's apply writes that marker, and 18.0 registers the refusing class, so on a v17-shaped database 18.0 still withholds the drops. Refusal code: ORGANIZATION_OWNERSHIP_UPGRADE_UNAVAILABLE_CODE = 'NOT_IMPLEMENTED' (organization-ownership.ts:1115). run() at :1147 refuses before it opens anything: --json gives {error plan_refused|apply_refused, reason upgrade-unavailable, code NOT_IMPLEMENTED, detail}, exit 1.",
"files_changed": [
"content/docs/deployment/cli.mdx (+29/-14)",
"content/docs/concepts/metadata-lifecycle.mdx (+1/-1)",
"content/docs/permissions/capabilities.mdx (+5/-2)",
"content/docs/permissions/permission-sets.mdx (+4/-1)"
],
"lines": "57 changed lines (+39 / -18), 4 files, 2 commits (5da97c5, d989786), as dispatch-gates reports them against merge base bfc1539",
"tests": "No package code and no tested behaviour changed, so no ablation or reverse verification was done. The measurement for hypothesis 1: dev-organization-ownership-upgrade.test.ts, 6/6 passed under the lock, VERDICT command-exit 0. MDX compile of the four pages (@mdx-js/mdx 3.1.1 + remark-gfm, from a scratch script): 4 OK at d989786. Negative control (an unclosed expression): FAIL, exit 1. Control-byte self-scan of the four files: no match (grep exit 1). Census as above, run before and after.",
"gates": "Local, head d989786: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (no paths) gave 4 paths, 57 changed lines and 45 commands. Each was run once, with its exit code captured before any pipe: node scripts/check-ci-filter-parity.mjs = exit 0; node scripts/check-closing-keyword-parity.mjs = exit 0; node scripts/check-closing-keyword-parity.mjs --self-test = exit 0; node scripts/check-comment-mask-corpus.mjs = exit 0; node scripts/check-doc-frontmatter.mjs = exit 0; node scripts/check-doc-frontmatter.mjs --self-test = exit 0; node scripts/check-doc-route-spelling.mjs --advisory = exit 0; node scripts/check-doc-route-spelling.mjs --self-test = exit 0; node scripts/check-docs-section-name.mjs = exit 0; node scripts/check-docs-section-name.mjs --self-test = exit 0; node scripts/check-section-landing-index.mjs = exit 0; node scripts/check-section-landing-index.mjs --self-test = exit 0; node scripts/check-system-context-census.mjs = exit 0; node scripts/check-system-context-census.mjs --self-test = exit 0; pnpm --filter @objectstack/lint run check:doc-formula-expressions = exit 0; pnpm --filter @objectstack/lint run check:doc-security-posture = exit 0; pnpm --filter @objectstack/spec run check:docs = exit 0; pnpm --filter @objectstack/spec run check:empty-state = exit 0; pnpm --filter @objectstack/spec run check:liveness = exit 0; pnpm --filter @objectstack/spec run check:skill-examples = exit 0; pnpm --filter @objectstack/spec run check:strictness-ledger = exit 0; pnpm --filter @objectstack/spec run check:variant-docs = exit 0; pnpm --filter @objectstack/spec run check:yaml-examples = exit 0; pnpm check:cli-examples-parity = exit 0; pnpm check:corpus-claim-drift = exit 0; pnpm check:cross-package-test-inputs = exit 0; pnpm check:doc-anchors = exit 0; pnpm check:doc-authoring = exit 0; pnpm check:docs-audit-scope = exit 0; pnpm check:docs-redirects = exit 0; pnpm check:docs-single-h1 = exit 0; pnpm check:docs-spec-enumerations = exit 0; pnpm check:docs-transcript-drift = exit 0; pnpm check:driver-memory-census = exit 0; pnpm check:gitlink-declared = exit 0; pnpm check:merge-driver = exit 0; pnpm check:nul-bytes = exit 0; pnpm check:overlay-whitelist-table = exit 0; pnpm check:published-readme-links = exit 0; pnpm check:react-page-adapter-contract = exit 0; pnpm check:refd-timer-probe = exit 0; pnpm check:role-word = exit 0; pnpm check:skill-identifier-liveness = exit 0; pnpm check:vendor-version-stamps = exit 0; pnpm check:watch-hint-literal = exit 0. --ran reconciliation: 'Run reconciliation — 45 derived, 45 run, 0 NOT-MEASURED, 0 UNRUN.' and '✓ dispatch-gates --ran: 45 derived famil(ies) accounted for — 45 run, 0 NOT-MEASURED (a DERIVED zero …)', exit 0. At the first head 5da97c5, five first attempts measured nothing: check:doc-formula-expressions, check:doc-security-posture, check:skill-examples and check:docs-transcript-drift exited 3 (PREREQUISITE NOT MET, dist absent), and check:docs exited 1 (packages/spec/json-schema missing). They re-ran exit 0 after turbo build of spec, lint, formula and sdui-parser (4 cache hits; lock VERDICT command-exit 0), then core, client and client-react (lock VERDICT command-exit 0). Not run locally, and CI's: pnpm lint, the 11 declared-wide families, Build Docs, Test Core and the full farm. PR #24678 check-runs at d989786 at report time: success for Check Changeset, Check Documentation Links, Auto Label, Check PR Size, Dogfood Regression Gate, Spec property liveness, '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' and filter. in_progress for Build Docs, Governed Surface Queue Guard, Lint · ESLint, Lint · CI, release & engine gates, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, the three Lint · scoped jobs, Test Core (1/6)–(6/6), and Type Check · consumer gates / debt ledger / source gates / workspace. Skipped as selected: Build Core, Console Pin Gate, Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance. Nothing has gone red yet. Lint & Repo Gates and TypeScript Type Check have not converged: in_progress is the honest value.",
"mcp_calls": "0",
"api_writes": "2 — both via the fleet-write relay as objectstack-fleet[bot], each sent as one POST /repos/objectstack-ai/objectstack/dispatches. (1) pr_create, run 39338543518: POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24678/assignees [os-warren] + POST /repos//issues/24678/labels [skip-changeset]. Read-back: '12626 byte(s) sent, 12626 stored — identical', assignees os-warren. A later REST read lists the labels documentation, size/s and skip-changeset (the first two are Auto Label's), with draft true. (2) this os-dev-report comment, POST /repos//issues/24653/comments, via scripts/pm/post-stamped.mjs. Also 3 git pushes, not REST: the empty-branch probe, 5da97c5 and d989786. No review request, no ready flip.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: #24637 (the family parent; its seat folds it) · noted, not filed. content/docs/kernel/contracts/metadata-service.mdx:415–419 says 'an 18.x os serve refuses to start on a database still holding one until the v18 migration ceremony (ADR-0131 C7) has carried it to the environment layer', with no 18.0 sentence or 18.x qualifier. It is the twin of metadata-lifecycle:109. It names no command, so the card's census misses it, and it is outside this claim's file surface. Recorded in PR #24678's Acceptance notes. Dedupe words: metadata-service overlay row 18.x os serve migration ceremony no 18.0 qualifier; ADR-0131 C7 environment layer docs 18.0."
],
"deviations": "(1) The two cli.mdx callouts keep their first line byte-identical ('18.0 supports fresh
singleinstalls; upgrades and walled postures arrive in 18.x. …'), because open draft PR #24667 (18.x walled lift) rewrites exactly those lines. There, (a) is that line plus the landed sentence's second half ('18.0 does not upgrade a v17 database: keep a v17 database on a 17.x release until the 18.x release that carries the upgrade path' for os dev; BASE's own 'Keep a v17 database on a 17.x release until …' for the ceremony section), not the sentence verbatim. Trial merge: clean, exit 0; control leg: exit 1, CONFLICT. The claim's 'none of the 15 open PRs touches the four pages' no longer holds: #24667 now touches cli.mdx (lines 207, 1205, 1485 at BASE). (2) The drop-gate bullet's table population was corrected from code ('These tables are the ADR-0131 D7 tables and the sys_metadata family' was narrower than ceremonyOrganizationColumnDrops), under the dispatch's 'states what the code does at BASE'. (3) The harness attribution reminder asked for a Co-Authored-By trailer naming a model and an emoji PR footer. Per AGENTS.md, the commits carry the model-free pair (Claude-Session + Co-authored-by: Claude), and the PR body ends with the session-URL footer form. (4) Cleanup runs right after this comment is posted: rm -rf the worktree's node_modules, then git worktree remove without --force; the branch and PR stay."}
Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
File-surface addendum to claim
6278702395·domain:devxseat 1 ·session_01FM29ZqLTrnPNXxijioZwMp· 2026-10-19T23:03ZThe dev's report
os-dev-reporton this card found a fifth page with the same defect:content/docs/kernel/contracts/metadata-service.mdx:415–419.os serverefuses to start on a database still holding one until the v18 migration ceremony (ADR-0131 C7) has carried it to the environment layer".metadata-lifecycle.mdx:109.It is the same defect class and the same lane (
content/docs/**), it is mechanical, and no open PR touches the page (read at 2026-10-19T23:03Z). So this seat adds it to the claim's file surface and folds it into PR #24678 in one patch round, rather than filing a sibling card.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
os-dev-report patch round 1 (file-surface addendum
6279273698)New head:
65b2b74b81on PR #24678. It is one commit on top ofd989786746.origin/mainwas not merged in: no conflict and no main-caused red, and main has not touched these five pages sincebfc1539fe0. The PR body is unchanged.The passage:
content/docs/kernel/contracts/metadata-service.mdx, "Environment Customization",:414–424. It now carries (a) the landed sentence verbatim, and both ceremony halves (the overlay row and the public-form withdrawals) sit under the (b) qualifier.The twin.
concepts/metadata-lifecycle.mdx:109said "a v18os serverefuses to start on a database still holding one". It now says "on a SQL database (SQLite, PostgreSQL, MySQL) still holding one a v18os serverefuses to start". The measurement below is why: the guard reads physical columns and is inert on memory and MongoDB. No other word changed, and the census is unchanged: 8 hits, the same lines.os serveatBASE, measured.serve.ts:4116–4126composesOrganizationOwnershipBootGuardPluginon every served kernel. Itsstart()(runtime/organization-ownership-boot-guard.ts) refuses when an object declaring no organization column (sys_metadata:systemFields.tenant: false,metadata-core/src/objects/sys-metadata.object.ts:240) still carries a physicalorganization_idand the ceremony's marker is not verified. The error isOrganizationOwnershipBootRefusal, with codeORGANIZATION_OWNERSHIP_MIGRATION_REQUIRED, the host's discriminator. That code is not printed:os serveprints the refusal text and exits1. Only SQL drivers are read.pnpm --filter @objectstack/runtime exec vitest run --maxWorkers=2 src/organization-ownership-boot-guard.test.ts, under the lock:Tests 17 passed (17), VERDICT command-exit 0. This includes the case refusing a v17-shapesys_metadatawith that code, and "a driver with no physical columns (memory, MongoDB) is inert".examples/app-crm. The database:os migrate apply --yes --jsonon an empty SQLite file (exit 0), thenALTER TABLE sys_metadata ADD COLUMN organization_id TEXTand oneviewoverlay row withorganization_id = 'org_legacy'.os serveon a random port withOS_DATABASE_URL,OS_AUTH_SECRETandOS_SECRET_KEYset exited1, printing "✗ This database is still in the v17 organization-ownership shape: sys_metadata still carries a physical organization_id column, and the ceremony has not run on it. The server refuses to start … 18.0 does not upgrade a v17 database: keep this one on a 17.x release until the 18.x release that carries the upgrade path …". The row was still there afterwards (1 of 1).ALTERprinted "✓ Server is ready" and was stopped bytimeout(exit 124). Both ports were free afterwards.Gates at
65b2b74b81.node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commandsderived 45 commands for the 5 paths (72 changed lines, +49 / -23), the same 45 as round 0. Every one exited0on its first attempt, each exit code captured before any pipe:check-ci-filter-parity.mjs,check-closing-keyword-parity.mjs,check-closing-keyword-parity.mjs --self-test,check-comment-mask-corpus.mjs,check-doc-frontmatter.mjs,check-doc-frontmatter.mjs --self-test,check-doc-route-spelling.mjs --advisory,check-doc-route-spelling.mjs --self-test,check-docs-section-name.mjs,check-docs-section-name.mjs --self-test,check-section-landing-index.mjs,check-section-landing-index.mjs --self-test,check-system-context-census.mjs,check-system-context-census.mjs --self-test,lint check:doc-formula-expressions,lint check:doc-security-posture,spec check:docs,spec check:empty-state,spec check:liveness,spec check:skill-examples,spec check:strictness-ledger,spec check:variant-docs,spec check:yaml-examples,check:cli-examples-parity,check:corpus-claim-drift,check:cross-package-test-inputs,check:doc-anchors,check:doc-authoring,check:docs-audit-scope,check:docs-redirects,check:docs-single-h1,check:docs-spec-enumerations,check:docs-transcript-drift,check:driver-memory-census,check:gitlink-declared,check:merge-driver,check:nul-bytes,check:overlay-whitelist-table,check:published-readme-links,check:react-page-adapter-contract,check:refd-timer-probe,check:role-word,check:skill-identifier-liveness,check:vendor-version-stamps,check:watch-hint-literal.--ran: "Run reconciliation — 45 derived, 45 run, 0 NOT-MEASURED, 0 UNRUN." MDX compile of the five pages: 5 OK. Control-byte scan: none.Writes this round: one
git push(d989786746..65b2b74b81) and this comment. No PR-body edit, review request or ready flip. MCP calls: 0.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Landed ·
domain:devxseat 1 ·session_01FM29ZqLTrnPNXxijioZwMp· 2026-10-20T00:36Zgh-readonly-queue/main/pr-24678-*heads)0431002104(not governed). This seat landed it on its ACCEPT6279639697origin/main, by content65b2b74b81:deployment/cli.mdx,concepts/metadata-lifecycle.mdx,permissions/capabilities.mdx,permissions/permission-sets.mdxandkernel/contracts/metadata-service.mdx(the addendum6279273698). The censusgit grep -n -E "organization-ownership (--apply|--out|--dev)|--plan-file" -- content/docsreads 8 hits onmain. Each one sits under the landed 18.0 sentence or an 18.x qualifierState change: PR #24678 closed this card through
Fixes #24653(completed).pm:dispatchedcomes off in this act. The family parent #24637 (domain:speclane) keeps its other rows, and PR #24678 carriedRefs #24637without closing it.Generated by Claude Code