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
os migrate organization-ownership --apply never resolves the built-in positions: plugin-security declares them in start() and the everyone baseline at kernel:ready, so authored-conversion blocks on every v17 database's seeded everyone binding #23397
Filing gate ① a product defect with a public door (class a). Filed by the repo:cloud#1 seat (seat post #6026, session session_01WVbr5J6u8BHh8EyFtcWciH) from cloud#2868's dev report (objectstack-ai/cloud#2868 6161163819), measured at framework pin 5b68524b93 in a rehearsal on copies of two v17 tenant databases (an AI environment and a plain one), the cloud#2867 method. ⛔ Not a claim; grade and lane are triage's. Priority p1: it blocks cloud's v18 move (objectstack-ai/cloud#2709), under the maintainer's rule that a platform defect affecting cloud's v18 upgrade is filed to its lane at high priority.
Dedupe: I listed open and closed issues since 2026-10-10 for "ceremony", "organization-ownership", "built-in position", "fate", "column-drop" and "presentational". The nearest is #23359 (p2): the same apply boot without the security plugin composed gives a misleading remedy on shipped permission sets. This is a different step and a different cause: the plugin is composed, but only for its declarations.
What happens
The command:os migrate organization-ownership --apply --backup-taken --fate-supplement FILE at 5b68524b93.
The data: a copy of a v17 tenant database, after cloud's own migration had retired its org_member binding (objectstack-ai/cloud#2869).
The result: exit 1, blocking 1, step authored-conversion: "Binding rows give position everyone the sets member_default, and the catalog holds no position of that name to carry them."
With OS_MULTI_ORG_ENABLED=true: the rewrite gate blocks on the same binding ("deleting them would lose a grant").
Reach: every v17 environment database holds that seeded row, so the ceremony cannot complete on any database a v17 environment wrote.
Control: a started v18 environment kernel on the same database does resolve everyone with member_default.
Cause (read on main0add8a49ce)
The apply boot composes host plugins for their declarations only (composeForDeclarations, packages/cli/src/utils/schema-migration-plugins.ts).
plugin-security declares the six built-in positions in start() (registerBuiltinPositions, security-plugin.ts around line 1747).
It declares the everyone baseline at kernel:ready (declareEveryoneBaseline, around line 4835).
So the ceremony's catalog never holds everyone or org_member.
Ask (the fixing seat's call)
The ceremony's catalog resolves the built-in positions and the everyone baseline that a started kernel serves. Two routes were seen; there may be others:
(a) declare them where a declarations-only composition reaches them;
(b) export the apply with its ports, so a host runs it inside its own started environment kernel.
applyOrganizationOwnership and convertStoredCommentReactions live in @objectstack/cli's private utils; the package's exports map publishes neither.
A host whose environment databases are built by a kernel factory (cloud) therefore runs them as child processes, with a manifest-only config standing in for the composition.
⛔ No host workaround: re-declaring the built-ins in a host's ceremony config would be one.
Read fresh, and the cause checked on main0add8a49ce:
the apply boot composes for declarations only (composeForDeclarations, packages/cli/src/utils/schema-migration-plugins.ts:119-125);
plugin-security declares the built-in positions in start() (security-plugin.ts:1747) and the everyone baseline at kernel:ready (:4835).
The card holds as filed.
p1 stands. The ceremony cannot complete on any database a v17 environment wrote. That blocks cloud's v18 move (objectstack-ai/cloud#2709, the maintainer's rule for v18-upgrade defects). It also blocks every self-hosted v17 → 18 GA upgrade.
If the fixing seat takes route (b) and publishes the apply through @objectstack/cli's exports map, that widens a public surface. Clause ② is then yes, and that half is spec-lane work.
Route (a) touches plugin-security. The cli seat owns the card and reviews the plugin half with the services lane.
Claim: PM loop round 2 (#23397: the organization-ownership ceremony's catalog resolves the built-in positions and the everyone baseline that a started kernel serves) · 2026-10-14T06:31Z
Session: session_015sSBzUJfLxTo3ZZ68LLfCG
Account: huangyiirene (the seat's linked user as GET /user answers it; the card's assignee from this act)
Branch: claude/issue-23397-ceremony-builtin-positions
Worktree: objectstack-issue-23397
Domain: domain:cli
Seat: domain:cli#1 (seat post #6024)
File surface (read on origin/maine4ec6ec1a; stop on a breach and explain it in the report):
packages/cli/src/utils/schema-migration-plugins.ts: composeForDeclarations and the composition the apply boot uses. On main it composes a host plugin for init() and suppresses its start() (read in this act).
The four plugin-security grant goldens beside it (grant-permission-set-name-backfill.test.ts, grant-permission-set-name.equivalence.test.ts, grant-readers-by-name.golden.test.ts, resolve-authz-grant-set-by-name.golden.test.ts) are tests beside a changed file. Each moved by one recorded step.
Tests beside each changed file, and one .changeset/23397-*.md.
⛔ No new entry in @objectstack/cli's exports map. The card's route (b) widens a public surface: Clause ② yes, spec-lane work, and a decision first.
⛔ No host workaround. Re-declaring the built-ins in a host's ceremony config is one; the card says so.
⛔ No edit under packages/spec.
Container & model: M, judged (one boot-composition gap, with a plugin-phase choice inside the security plugin), mode:subagent, model: default tier (dispatch-gates --tier --repo objectstack-ai/objectstack: "no path-derived mandate"). check-governed-merges --test over the claimed paths: NOT governed. If the fix moves a declaration of the security plugin between plugin phases, the seat runs one CONTRACT_REVIEW_TIER review of record before the queue. That is the seat's judgment for a security boot path, not a Clause-② mandate.
Clause-②: no (the authored-conversion guard and the rewrite gate are unchanged; the catalog they read gains what a started kernel already serves, per schema-migration-plugins.ts's "What a schema command needs from a plugin is its DECLARATIONS, and the kernel contract puts those in init()"; no export is added)
Responsibility: the ceremony's declarations-only composition in packages/cli (this lane), and where plugin-security declares its built-in positions and the everyone baseline (start() and kernel:ready) | none: a started v18 kernel resolves everyone with member_default on the same database (the card's control), but nothing reaches the ceremony's catalog | every operator who runs os migrate organization-ownership --apply on a database a v17 environment wrote: cloud's v18 move (objectstack-ai/cloud#2709) and every self-hosted 17 → 18 GA upgrade
Thread-read: 6161307756
Serial constraints cleared:
Open PRs: none of the 5 open PRs touches a claimed path. The file lists were read in this act. The Version PR chore: version packages (next) #23382 carries only .changeset/pre/22937-cli-organization-ownership-apply.md.
{
"issue": 23397,
"status": "done",
"branch": "claude/issue-23397-ceremony-builtin-positions",
"pr": "https://github.com/objectstack-ai/objectstack/pull/23433",
"session": "session_015sSBzUJfLxTo3ZZ68LLfCG — mode:subagent, the dispatching PM's session (CLAUDE_CODE_REMOTE_SESSION_ID of this container)",
"head": "1ebf9c5d7",
"premise_still_valid": true,
"summary": "Route (a), inside plugin-security: SecurityPlugin.init() now declares the six built-in positions and the everyone anchor naming the deployment baseline (app isDefault set + member_default), through the existing registerBuiltinPositions / declareEveryoneBaseline seam; start() no longer declares them, and the kernel:ready declareEveryone re-derivation (full capability context + accepted package defaults) is unchanged and shares one baseline filter (private everyoneBaseline). The init() baseline is the fail-closed high-privilege reading (no declared-capability context: the stack is still declaring during init), so it is never wider than the kernel:ready one. Measured on the card's own case with the real command: before, authored-conversion blocked on everyone/member_default (single) and the rewrite gate blocked on it under OS_MULTI_ORG_ENABLED=true; after, both steps are done and mirror-deletion deletes the 3 seeded rows (the runs then stop at column-drops on sys_metadata*, the #23399 rows, out of bounds). No cli source, no export, no host workaround; zero edits in organization-ownership-apply.ts / organization-ownership-plan.ts / schema-migration-plugins.ts (coordinator's #15211 footprint note satisfied). Started-kernel behaviour, final catalog unchanged; three moves: the six positions and everyone's baseline exist from init() instead of start()/kernel:ready, everyone keeps the init() baseline if the kernel:ready derivation throws (it used to name nothing), and the no-registry warning prints from init(). Four plugin-security grant goldens whose harness runs init()+start() but never fires kernel:ready moved by one recorded step (member_default through everyone, what the hook-firing builtin-positions.boot.test.ts golden already carries). H1 confirmed (and refined: the apply boot composes the security plugin twice; the provider-posture instance survives, which withholds every hook, so only init() reaches the ceremony). H2 confirmed. H3: both steps compare binding rows against the catalog position's permissionSets; both need the position and the deployment baseline; the accepted-default half stays a kernel:ready DB read the ceremony does not perform. H4 held: no write added on plan; no-write pins green. #23359: symptom not altered (without the plugin composed nothing declares the built-ins either).",
"tests": "plugin-security full suite at 1ebf9c5d7: 186 files, 3781 passed, 45 skipped (VERDICT command-exit 0). New plugin pin src/builtin-positions.declaration-phase.test.ts 5/5. New cli pin src/utils/organization-ownership-apply.served-catalog.integration.test.ts 3/3 (vitest --project integration). H4 no-write pins (cli integration): schema-migrate.host-composition.integration.test.ts + schema-migration-plugins.declaration-boot-write-guard.test.ts + commands/migrate/security-catalog-overlays.integration.test.ts: 3 files, 40 passed. cli unit tier in 3 shards (--shard=1/3,2/3,3/3): 96+96+95 files, 1644+1299+1335 passed; the two published-subpath-*.pin tests first PREREQUISITE NOT MET (cli dist absent), after pnpm --filter @objectstack/cli build: 2 files, 29 passed. Consumers booting the plugin without kernel:ready: plugin-auth 5 files/41, rest 9 files/120, runtime share-links-enforcement-context 28, organizations create-explicit-organization-wall 21, all pass. Card's case via the real command in-process (scratch fixture: a DB this release's apply composition provisioned + the 17.x everyone/member_default/binding rows): after = single and isolated both authored-conversion done, rewrite done, mirror-deletion deleted 3. NEGATIVE CONTROL at 7f3b67b69 (trap-restored script): security-plugin.ts restored from base 5656c5638 (on-disk hash b042c660f9 == base blob), plugin-security rebuilt, ablation-dist-preflight --absent 'this.declareBuiltinPositions(ctx)' exit 0 (absent from all 6 built files); predicted direction red, observed red: plugin pin 4 failed / 1 passed (the no-engine case), cli pin 3/3 failed, card's case reproduced verbatim (single: 'Binding rows give position everyone the sets member_default, and the catalog holds no position of that name to carry them.'; isolated: 'Binding rows give position everyone sets its catalog definition does not name (member_default); deleting them would lose a grant.'). Restore: git checkout HEAD, hash 7a64f14215 == HEAD blob, git diff HEAD empty, rebuilt, preflight marker present in 2 built files, both pins green. Full lint at 1ebf9c5d7 exit 0.",
"gates": [
"node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0",
"node scripts/check-adr-0087-registration.mjs --self-test :: exit 0",
"node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0",
"node scripts/check-changeset-no-major.mjs --self-test :: exit 0",
"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-adoption.mjs :: exit 0",
"node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0",
"node scripts/check-comment-mask-corpus.mjs :: exit 0",
"node scripts/check-dts-emitted.mjs --self-test :: exit 0",
"node scripts/check-empty-changeset.mjs --base origin/main :: exit 0",
"node scripts/check-empty-changeset.mjs --self-test :: exit 0",
"node scripts/check-issue-citations.mjs :: exit 0",
"node scripts/check-keyed-text-bounds.mjs :: exit 0",
"node scripts/check-keyed-text-bounds.mjs --self-test :: exit 0",
"node scripts/check-platform-object-tenancy-census.mjs :: exit 0",
"node scripts/check-platform-object-tenancy-census.mjs --self-test :: exit 0",
"node scripts/check-plugin-teardown-shape.mjs :: exit 0",
"node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0",
"node scripts/check-registry-log-declared.mjs :: exit 0",
"node scripts/check-registry-log-declared.mjs --self-test :: exit 0",
"node scripts/check-rest-log-spy-declared.mjs :: exit 0",
"node scripts/check-rest-log-spy-declared.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",
"node scripts/check-tenant-audit-census.mjs :: exit 0",
"node scripts/check-tenant-audit-census.mjs --self-test :: exit 0",
"node scripts/check-undeclared-dep-imports.mjs :: exit 0",
"node scripts/check-undeclared-dep-imports.mjs --self-test :: exit 0",
"node scripts/docs-audit/check-affected-docs.mjs :: exit 0",
"node scripts/docs-audit/check-drift-comment.mjs :: exit 0",
"node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0",
"node scripts/release-pending-publish.mjs --self-test :: exit 0",
"pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0",
"pnpm check:changeset-gate-self-tests :: exit 0",
"pnpm check:cross-package-test-inputs :: exit 0",
"pnpm check:doc-authoring :: exit 0",
"pnpm check:driver-memory-census :: exit 0",
"pnpm check:dts-closure :: exit 0",
"pnpm check:dual-build-cjs-loads :: exit 0 (first run exit 3 PREREQUISITE NOT MET: dist of unrelated packages absent; re-run with dist present)",
"pnpm check:engine-double-contract :: exit 0",
"pnpm check:error-status-conformance :: exit 0",
"pnpm check:gitlink-declared :: exit 0",
"pnpm check:i18n :: exit 0",
"pnpm check:i18n-coverage :: exit 0 (first run exit 3 PREREQUISITE NOT MET: dist of unrelated packages absent; re-run with dist present)",
"pnpm check:i18n-stale-fill :: exit 0",
"pnpm check:i18n-walk-parity :: exit 0",
"pnpm check:issue-citations :: exit 0",
"pnpm check:lean-entry-closure :: exit 0",
"pnpm check:logger-receiver-detach :: exit 0",
"pnpm check:nul-bytes :: exit 0",
"pnpm check:objectql-double-limit :: exit 0",
"pnpm check:objectui-changeset :: exit 0",
"pnpm check:org-identifier :: exit 0",
"pnpm check:page-declaration-shape :: exit 0",
"pnpm check:pm-changeset-deadline-census :: exit 0",
"pnpm check:published-files :: exit 0",
"pnpm check:query-options-erasure :: exit 0",
"pnpm check:refd-timer-probe :: exit 0",
"pnpm check:slot-lookup :: exit 0",
"pnpm check:sourcemap-no-sources-content :: exit 0",
"pnpm check:test-source-alias :: exit 0",
"pnpm check:tier-file-adoption :: exit 0",
"pnpm check:type-check-coverage :: exit 0",
"pnpm check:type-check-debt :: exit 0",
"pnpm check:watch-hint-literal :: exit 0",
"pnpm check:where-matcher :: exit 0",
"node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran RANFILE :: exit 0 (68 derived, 68 run, 0 NOT-MEASURED, 0 UNRUN; every family recorded exit 0)",
"pnpm lint (eslint . --no-inline-config, full) at 1ebf9c5d7 :: exit 0",
"pnpm --filter @objectstack/plugin-security typecheck :: exit 0",
"pnpm --filter @objectstack/cli typecheck :: exit 0"
],
"line_budget": {
".changeset/23397-ceremony-builtin-positions.md": "+17/-0",
"packages/cli/src/utils/organization-ownership-apply.served-catalog.integration.test.ts": "+166/-0",
"packages/plugins/plugin-security/src/builtin-positions.declaration-phase.test.ts": "+101/-0",
"packages/plugins/plugin-security/src/builtin-positions.ts": "+7/-4",
"packages/plugins/plugin-security/src/grant-permission-set-name-backfill.test.ts": "+14/-8",
"packages/plugins/plugin-security/src/grant-permission-set-name.equivalence.test.ts": "+11/-6",
"packages/plugins/plugin-security/src/grant-readers-by-name.golden.test.ts": "+15/-10",
"packages/plugins/plugin-security/src/resolve-authz-grant-set-by-name.golden.test.ts": "+27/-12",
"packages/plugins/plugin-security/src/security-plugin.ts": "+85/-35"
},
"files_changed": [
".changeset/23397-ceremony-builtin-positions.md",
"packages/cli/src/utils/organization-ownership-apply.served-catalog.integration.test.ts",
"packages/plugins/plugin-security/src/builtin-positions.declaration-phase.test.ts",
"packages/plugins/plugin-security/src/builtin-positions.ts",
"packages/plugins/plugin-security/src/grant-permission-set-name-backfill.test.ts",
"packages/plugins/plugin-security/src/grant-permission-set-name.equivalence.test.ts",
"packages/plugins/plugin-security/src/grant-readers-by-name.golden.test.ts",
"packages/plugins/plugin-security/src/resolve-authz-grant-set-by-name.golden.test.ts",
"packages/plugins/plugin-security/src/security-plugin.ts"
],
"mcp_calls": "0",
"api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, run as objectstack-fleet[bot]) executing 3 REST writes: POST /repos/objectstack-ai/objectstack/pulls (draft PR #23433), POST /repos/objectstack-ai/objectstack/issues/23433/assignees (huangyiirene), POST /repos/objectstack-ai/objectstack/issues/23397/comments (this report). git push of the branch (fast-forwards only) is not a REST write. Reads: single-card REST reads of #23397, #23359 and their comments, PR #23433, and two earlier os-dev-report comments for format.",
"deviations": [
"File surface: security-plugin.ts changed in a THIRD hunk beside the two claimed regions: init() at about :1575 (+7 lines: one this.declareBuiltinPositions(ctx) call and its comment). The phase move cannot land without it. The method body sits in the declareEveryone region. init() is a boot region inside #15194's territory and is disjoint from #23403's gate (about :2536); security-plugin.test.ts is untouched.",
"Four plugin-security golden test files beside security-plugin.ts were edited (one recorded move each, noted in each golden's doc comment): their init()+start() harness fires no kernel:ready, so everyone used to name nothing there. The backfill's unnamed-grant check moved from toEqual([]) to toEqual(['member_default']).",
"Two comments in packages/objectql/src/registry.ts (about :2795 and :4468) still say the platform declares its built-ins in its own start(); left as they are because they are outside the claimed surface (PR Acceptance notes). The code they explain stays correct and load-bearing.",
"No label written: the dispatch named none, and skip-changeset does not apply (the changeset is present). label-write budget unused.",
"An unsharded cli unit run hit the 580 s foreground timeout (exit 124, a non-measurement). It was replaced by three --shard runs, all reported above.",
"Did not merge origin/main: it is 6 commits ahead of the base 5656c5638, and none touches a changed file or plugin-security/cli/objectql/core-security sources (the merge-after-open-only-on-conflict rule from #23405).",
"Attribution: commits carry the model-free trailer pair the dispatch ordered, and the PR body ends with the AGENTS.md session-URL footer form; the harness's attribution reminder (a model-named trailer and a different PR footer) was not followed, because AGENTS.md takes precedence."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted in PR #23433 Acceptance notes, not filed — the ceremony does not read the accepted package defaults (the everyone half that is a sys_audience_binding_suggestion read at kernel:ready). A binding to a set that only a deployment-level acceptance puts on everyone would still block. Read only, not reproduced: a 17.x database holds no deployment-level acceptance. Dedupe words: ceremony accepted package default everyone binding; readAcceptedEveryoneSets ownership apply; audience binding suggestion ceremony catalog",
"carrier: none · noted, not filed — the stale objectql registry.ts comments (about :2795 and :4468) on built-in declaration timing; documentation drift only.",
"carrier: #23359 (domain:cli, p2, open) · noted, not filed — without the security plugin composed, a 17.x database also stops at authored-conversion on everyone, with the 'Declare the position (or remove the bindings)' remedy. That is the same cause and remedy shape #23359 names for the shipped sets; this PR does not change it. Fold into #23359's text fix.",
"carrier: none · noted, not filed — the curated capabilities (registerBuiltinCapabilities) are still declared in start(); no ceremony step resolves a capability from the catalog (authored-conversion reports sys_capability rows without a catalog read), so nothing is broken today."
]
}
init() declares the six built-ins and everyone's baseline through the existing registerBuiltinPositions / declareEveryoneBaseline seam. These are registry writes only.
start() no longer declares them.
kernel:ready's declareEveryone is unchanged except that its filter moved into the shared private everyoneBaseline.
Three checks, made in this act:
init() always reaches the engine.SecurityPlugin.dependencies = ['com.objectstack.engine.objectql'] (security-plugin.ts:1184), and ObjectQLPlugin registers objectql inside its own init() (objectql/src/plugin.ts:615). So the getService('objectql') early return is not a path a composed kernel takes.
The init() baseline is never wider.describeHighPrivilegeBits(def, undefined) excuses no system-permission token (spec/src/security/high-privilege.ts:153–:160: with no declared capabilities, unexcused = sys). So the init() list is a subset of the kernel:ready list, which replaces it.
The one failure-mode move.everyone keeps the init() baseline when the kernel:ready derivation throws, where before it named no set. That is a subset of the steady-state grant, never wider, and the changeset says so.
Pins and the negative control. The cli pin (3/3) drives the ceremony's own composition, and includes "authored-conversion blocks on the undeclared position, and not on everyone" (single) and the walled rewrite-gate twin. A binding to a position that really is absent still blocks.
Ablation: with security-plugin.ts restored from base, the plugin pin went 4/5 red, the cli pin 3/3 red, and the card's two messages reproduced verbatim. The restore was proven against HEAD.
The four goldens each move by one recorded step: member_default through everyone. Their harness runs init() and start() but no kernel:ready, and the flipped values assert the new answer.
Changeset, sentence by sentence against the diff.@objectstack/plugin-securitypatch and @objectstack/clipatch, Clause-②: no.
"What changed" (init() declares the six positions and everyone naming the deployment baseline; registry only) matches declareBuiltinPositions.
"The baseline in init() is the fail-closed reading" matches everyoneBaseline(undefined) and check 2.
"What a started kernel sees" (the three moves) matches the diff and check 3.
"A binding that names a position no catalog declares still blocks" matches the cli pin.
Contract review: none owed by face, so none is run.contract-review.md as of 4f81f3152 (on main at 07:44Z, after the claim) judges by the three faces: a Clause-②: yes declaration, published packages/spec/src/** schema, and governed rule text. This diff touches none of them, so the review is "CI 加席位自读 ⛔ 不起第二个 agent", and this ACCEPT is that read. The claim's "the seat runs one CONTRACT_REVIEW_TIER review" is superseded by the stricter current text.
Local evidence at 1ebf9c5d7 (the PR head, origin/main not merged; base 5656c5638):
plugin-security, 186 files / 3,781 tests;
cli unit, three shards;
the H4 no-write pins, 3 files / 40 tests;
68 of 68 derived gates exit 0, reconciled with --ran;
full pnpm lint exits 0 at 1ebf9c5d7;
both packages typecheck.
CI on 1ebf9c5d7 at this stamp: 21 success, 6 skipped, 10 in progress, none failed. Landing waits for every check, including Lint and Type Check, to be green on this head.
Out-of-scope lines (one each):
The ceremony does not read accepted package defaults onto everyone: Acceptance notes. No 17.x database holds a deployment-level acceptance, so there is no reach today.
The two stale objectql/src/registry.ts comments on declaration timing: dropped. They are comment drift in another lane's package, and the code they explain stays correct.
The curated capabilities are still declared in start(): dropped. No ceremony step resolves a capability from the catalog.
Landing:pr_ready then automerge_enable through the relay, once the head is green. The card closes through Fixes #23397, and this seat removes pm:dispatched in the landed note.
{
"issue": 23397,
"round": "patch round 1 (queue removal: queue build 38537845899 red on plugin-security DTS)",
"status": "done",
"branch": "claude/issue-23397-ceremony-builtin-positions",
"pr": "https://github.com/objectstack-ai/objectstack/pull/23433",
"session": "session_015sSBzUJfLxTo3ZZ68LLfCG — mode:subagent, the dispatching PM's session",
"merge_commit": "cd5f3b4bc (merge of origin/main a7a135dc2 into 1ebf9c5d7, --no-ff, textually clean; pnpm-lock.yaml unchanged)",
"head": "35ab3835f",
"premise_still_valid": true,
"summary": "The seat's reading held exactly. After merging origin/main, be50633be (#23412) has removed the `import type { AnchorBindingContext } from '@objectstack/spec/security'` line together with the audience-anchor gate, while this PR's everyoneBaseline(context: AnchorBindingContext | undefined, ...) still names the type, so the DTS build fails. Fix: one line, the type import restored directly under the file's other '@objectstack/spec/security' imports (commit 35ab3835f). Nothing else changed. #23412's deletions stay absent: each of the 14 files be50633be touched is byte-identical to origin/main on this head, except security-plugin.ts, whose diff against main holds 0 lines about the gate (no assertAudienceAnchorBindingGate and no describeAnchorForbiddenBits in security-plugin.ts or security-plugin.test.ts). The branch's diff against main is still the 9 files of the PR (+444/-75). The first pushes of 35ab3835f were refused by branch protection ('A pull request for this branch has been added to a merge queue'), although the queue run had concluded. I did not touch the queue. A later plain push went through (fast-forward from 1ebf9c5d7 through the merge commit), and PR #23433's head is now 35ab3835f.",
"tests": "RED before the fix, on the merged head cd5f3b4bc (dependency closure rebuilt first): pnpm --filter @objectstack/plugin-security build printed 'src/security-plugin.ts(4796,14): error TS2304: Cannot find name 'AnchorBindingContext'.' and 'DTS Build error', VERDICT command-exit 1 (the queue's exact failure). GREEN after, on 35ab3835f: the same build printed 'DTS Build success', check-dts-emitted 1/1, VERDICT command-exit 0. plugin-security full suite: 186 files, 3778 passed, 45 skipped (3 fewer than the last round: the three gate cases #23412 deleted). Pins: builtin-positions.declaration-phase.test.ts 5/5; cli organization-ownership-apply.served-catalog.integration.test.ts 3/3 (cli dependency closure rebuilt on the merged tree first). plugin-security typecheck exit 0 (check:test-typecheck OK); cli typecheck exit 0. Full pnpm lint at 35ab3835f: EXIT=0.",
"gates": [
"pnpm --filter '@objectstack/plugin-security^...' build (merged tree) :: exit 0",
"pnpm --filter @objectstack/plugin-security build @ cd5f3b4bc (merged, before the fix) :: exit 1 (TS2304 AnchorBindingContext at security-plugin.ts:4796, DTS Build error)",
"pnpm --filter @objectstack/plugin-security build @ 35ab3835f :: exit 0",
"pnpm --filter '@objectstack/cli^...' build (merged tree) :: exit 0",
"pnpm --filter @objectstack/plugin-security typecheck @ 35ab3835f :: exit 0",
"pnpm --filter @objectstack/cli typecheck @ 35ab3835f :: exit 0",
"pnpm --filter @objectstack/plugin-security exec vitest run --maxWorkers=2 @ 35ab3835f :: exit 0 (186 files, 3778 passed, 45 skipped)",
"pnpm --filter @objectstack/plugin-security exec vitest run src/builtin-positions.declaration-phase.test.ts @ 35ab3835f :: exit 0 (5/5)",
"pnpm --filter @objectstack/cli exec vitest run --project integration src/utils/organization-ownership-apply.served-catalog.integration.test.ts @ 35ab3835f :: exit 0 (3/3)",
"pnpm lint (full eslint . --no-inline-config) @ 35ab3835f :: exit 0",
"pnpm check:nul-bytes @ 35ab3835f :: exit 0",
"dispatch-gates derived families on the merged head :: NOT MEASURED, reason: not re-run this round (the order named the list above); the branch's change set against main is the same 9 files plus one import line, and on 1ebf9c5d7 the round-1 reading was 68/68 exit 0"
],
"lint_head": "35ab3835f",
"line_budget": {
"packages/plugins/plugin-security/src/security-plugin.ts": "+1/-0 this round"
},
"files_changed": [
"packages/plugins/plugin-security/src/security-plugin.ts"
],
"mcp_calls": "0",
"api_writes": "1 relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches) executing POST /repos/objectstack-ai/objectstack/issues/23397/comments (this report). git pushes, which are not REST writes: the branch (refused twice by the merge-queue branch lock, then accepted as a fast-forward to 35ab3835f), and a backup ref claude/issue-23397-ceremony-builtin-positions-r2 at 35ab3835f, pushed while the branch was locked so that the work was on the remote. Reads: REST pulls/23433, its timeline and comments, actions runs.",
"deviations": [
"A backup branch claude/issue-23397-ceremony-builtin-positions-r2 (same sha, 35ab3835f) was pushed while the PR branch was locked. Deleting it after the real push landed was refused: 'git push --delete' got HTTP 403 from the proxy. I did not retry. It is a stale duplicate ref with no PR, and the seat can delete it.",
"The PR branch push was refused twice by GitHub ('added to a merge queue') after the queue run had already concluded failure and auto_merge read null. No dequeue or other queue act was taken. A later plain push succeeded.",
"The derived gate families were not re-run on the merged head (see gates). CI's run on 35ab3835f is the reading for them."
],
"open_questions": [],
"out_of_scope_findings": []
}
Seat record (席位核对) for PR #23433 at 35ab3835f, the patch round after queue removal: 6165436956 on the PR. ACCEPT 6164143618 stands. The delta is one restored type import after merging main (be50633be/#23412 had removed it); CI on that head is 34 success + 6 expected skips. · domain:cli seat 1 · session_015sSBzUJfLxTo3ZZ68LLfCG · 2026-10-14T09:40Z
domain:cli seat 1 (#6024) · huangyiirene · session session_015sSBzUJfLxTo3ZZ68LLfCG · 2026-10-14T10:08Z · claim 6162398535, released by this landing. The seat record is 6165436956, on the PR.
Probe
Reading
PR object
merged: true at 2026-10-14T10:06Z, merge_commit_sha0d784da01, from head 35ab3835f
origin/main
0d784da01 is an ancestor of origin/main7cfc3400c. It is a single-parent squash whose diff is the PR's 9 files, +444 / −75. No queue branch for #23433 remains on the remote.
State change:Fixes #23397 closed the card as completed. pm:dispatched is removed in this act; domain:cli, priority:p1, target:v18 and bug stay. Holds released: the three security-plugin.ts regions, builtin-positions.ts, the four plugin-security goldens, the two new pins, and the changeset.
Activity
objectstack-fleet commentedon Oct 14, 2026
Triage · p1
target:v18·domain:cli·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-14T05:03ZRead fresh, and the cause checked on
main0add8a49ce:composeForDeclarations,packages/cli/src/utils/schema-migration-plugins.ts:119-125);start()(security-plugin.ts:1747) and theeveryonebaseline atkernel:ready(:4835).The card holds as filed.
18.0.0-next.1(PR chore: version packages (next) #23382), which is a prerelease.target:v18.domain:cli. The ceremony, its composition and the apply live inpackages/cli, the same lane as its sibling os migrate organization-ownership --apply, run where the security plugin is not composed (no auth secret), blocks its rewrite on the platform's own shipped permission sets and prescribes removing the admin's grants, without naming the cause #23359 (p2,domain:cli).@objectstack/cli's exports map, that widens a public surface. Clause ② is thenyes, and that half is spec-lane work.plugin-security. The cli seat owns the card and reviews the plugin half with the services lane.objectstack-fleet commentedon Oct 14, 2026
Claim: PM loop round 2 (#23397: the organization-ownership ceremony's catalog resolves the built-in positions and the
everyonebaseline that a started kernel serves) · 2026-10-14T06:31ZSession:
session_015sSBzUJfLxTo3ZZ68LLfCGAccount:
huangyiirene(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch:
claude/issue-23397-ceremony-builtin-positionsWorktree:
objectstack-issue-23397Domain:
domain:cliSeat:
domain:cli#1(seat post #6024)File surface (read on
origin/maine4ec6ec1a; stop on a breach and explain it in the report):packages/cli/src/utils/schema-migration-plugins.ts:composeForDeclarationsand the composition the apply boot uses. Onmainit composes a host plugin forinit()and suppresses itsstart()(read in this act).packages/cli/src/utils/organization-ownership-apply.ts: the apply boot and the catalog read thatauthored-conversionand the rewrite gate consult. ⛔ NotCEREMONY_STEPSand not any step body; os migrate organization-ownership has no step for the inventory's organization-presentational-promotion category: views saved through the v17 /meta door stay unserved at v18, and column-drops blocks on sys_metadata forever #23398 holds those this round.packages/plugins/plugin-security/src/builtin-positions.ts, and inpackages/plugins/plugin-security/src/security-plugin.tsonly two regions:start()(registerBuiltinPositions, about:1747);everyonebaseline declaration atkernel:ready(declareEveryoneBaseline, about:4835).SecurityPlugin.init()(about:1575on the PR head): onethis.declareBuiltinPositions(ctx)call and its comment. The phase move cannot land without it. It is a boot region in the same territory, disjoint from docs(adr),plugin-security: retire the dead audience-anchor binding gate and restate the ADR text that names the C3-retired security modules (ADR-0138, 0094, 0126, 0131, 0103) #23403's gate.grant-permission-set-name-backfill.test.ts,grant-permission-set-name.equivalence.test.ts,grant-readers-by-name.golden.test.ts,resolve-authz-grant-set-by-name.golden.test.ts) are tests beside a changed file. Each moved by one recorded step.security-plugin.ts"). This seat posts a cross-lane declaration there.:2536), which docs(adr),plugin-security: retire the dead audience-anchor binding gate and restate the ADR text that names the C3-retired security modules (ADR-0138, 0094, 0126, 0131, 0103) #23403 holds..changeset/23397-*.md.@objectstack/cli's exports map. The card's route (b) widens a public surface: Clause ②yes, spec-lane work, and a decision first.packages/spec.Container & model:
M, judged (one boot-composition gap, with a plugin-phase choice inside the security plugin),mode:subagent,model: default tier(dispatch-gates --tier --repo objectstack-ai/objectstack: "no path-derived mandate").check-governed-merges --testover the claimed paths: NOT governed. If the fix moves a declaration of the security plugin between plugin phases, the seat runs oneCONTRACT_REVIEW_TIERreview of record before the queue. That is the seat's judgment for a security boot path, not a Clause-② mandate.Clause-②: no (the
authored-conversionguard and the rewrite gate are unchanged; the catalog they read gains what a started kernel already serves, perschema-migration-plugins.ts's "What a schema command needs from a plugin is its DECLARATIONS, and the kernel contract puts those ininit()"; no export is added)Responsibility: the ceremony's declarations-only composition in
packages/cli(this lane), and whereplugin-securitydeclares its built-in positions and theeveryonebaseline (start()andkernel:ready) | none: a started v18 kernel resolveseveryonewithmember_defaulton the same database (the card's control), but nothing reaches the ceremony's catalog | every operator who runsos migrate organization-ownership --applyon a database a v17 environment wrote: cloud's v18 move (objectstack-ai/cloud#2709) and every self-hosted 17 → 18 GA upgradeThread-read: 6161307756
Serial constraints cleared:
.changeset/pre/22937-cli-organization-ownership-apply.md.organization-ownership-apply.ts, and the later lander mergesmain.pm:retriage), not dispatched.domain:engine#2, in flight): it holdssecurity-plugin.ts's audience-anchor gate and its call site (about:2536), a disjoint region.security-plugin.tsregions above. A cross-lane declaration is posted on [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194 in this act. The territory is declared, not a lock.Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
os-dev-report
{ "issue": 23397, "status": "done", "branch": "claude/issue-23397-ceremony-builtin-positions", "pr": "https://github.com/objectstack-ai/objectstack/pull/23433", "session": "session_015sSBzUJfLxTo3ZZ68LLfCG — mode:subagent, the dispatching PM's session (CLAUDE_CODE_REMOTE_SESSION_ID of this container)", "head": "1ebf9c5d7", "premise_still_valid": true, "summary": "Route (a), inside plugin-security: SecurityPlugin.init() now declares the six built-in positions and the everyone anchor naming the deployment baseline (app isDefault set + member_default), through the existing registerBuiltinPositions / declareEveryoneBaseline seam; start() no longer declares them, and the kernel:ready declareEveryone re-derivation (full capability context + accepted package defaults) is unchanged and shares one baseline filter (private everyoneBaseline). The init() baseline is the fail-closed high-privilege reading (no declared-capability context: the stack is still declaring during init), so it is never wider than the kernel:ready one. Measured on the card's own case with the real command: before, authored-conversion blocked on everyone/member_default (single) and the rewrite gate blocked on it under OS_MULTI_ORG_ENABLED=true; after, both steps are done and mirror-deletion deletes the 3 seeded rows (the runs then stop at column-drops on sys_metadata*, the #23399 rows, out of bounds). No cli source, no export, no host workaround; zero edits in organization-ownership-apply.ts / organization-ownership-plan.ts / schema-migration-plugins.ts (coordinator's #15211 footprint note satisfied). Started-kernel behaviour, final catalog unchanged; three moves: the six positions and everyone's baseline exist from init() instead of start()/kernel:ready, everyone keeps the init() baseline if the kernel:ready derivation throws (it used to name nothing), and the no-registry warning prints from init(). Four plugin-security grant goldens whose harness runs init()+start() but never fires kernel:ready moved by one recorded step (member_default through everyone, what the hook-firing builtin-positions.boot.test.ts golden already carries). H1 confirmed (and refined: the apply boot composes the security plugin twice; the provider-posture instance survives, which withholds every hook, so only init() reaches the ceremony). H2 confirmed. H3: both steps compare binding rows against the catalog position's permissionSets; both need the position and the deployment baseline; the accepted-default half stays a kernel:ready DB read the ceremony does not perform. H4 held: no write added on plan; no-write pins green. #23359: symptom not altered (without the plugin composed nothing declares the built-ins either).", "tests": "plugin-security full suite at 1ebf9c5d7: 186 files, 3781 passed, 45 skipped (VERDICT command-exit 0). New plugin pin src/builtin-positions.declaration-phase.test.ts 5/5. New cli pin src/utils/organization-ownership-apply.served-catalog.integration.test.ts 3/3 (vitest --project integration). H4 no-write pins (cli integration): schema-migrate.host-composition.integration.test.ts + schema-migration-plugins.declaration-boot-write-guard.test.ts + commands/migrate/security-catalog-overlays.integration.test.ts: 3 files, 40 passed. cli unit tier in 3 shards (--shard=1/3,2/3,3/3): 96+96+95 files, 1644+1299+1335 passed; the two published-subpath-*.pin tests first PREREQUISITE NOT MET (cli dist absent), after pnpm --filter @objectstack/cli build: 2 files, 29 passed. Consumers booting the plugin without kernel:ready: plugin-auth 5 files/41, rest 9 files/120, runtime share-links-enforcement-context 28, organizations create-explicit-organization-wall 21, all pass. Card's case via the real command in-process (scratch fixture: a DB this release's apply composition provisioned + the 17.x everyone/member_default/binding rows): after = single and isolated both authored-conversion done, rewrite done, mirror-deletion deleted 3. NEGATIVE CONTROL at 7f3b67b69 (trap-restored script): security-plugin.ts restored from base 5656c5638 (on-disk hash b042c660f9 == base blob), plugin-security rebuilt, ablation-dist-preflight --absent 'this.declareBuiltinPositions(ctx)' exit 0 (absent from all 6 built files); predicted direction red, observed red: plugin pin 4 failed / 1 passed (the no-engine case), cli pin 3/3 failed, card's case reproduced verbatim (single: 'Binding rows give position everyone the sets member_default, and the catalog holds no position of that name to carry them.'; isolated: 'Binding rows give position everyone sets its catalog definition does not name (member_default); deleting them would lose a grant.'). Restore: git checkout HEAD, hash 7a64f14215 == HEAD blob, git diff HEAD empty, rebuilt, preflight marker present in 2 built files, both pins green. Full lint at 1ebf9c5d7 exit 0.", "gates": [ "node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0", "node scripts/check-adr-0087-registration.mjs --self-test :: exit 0", "node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0", "node scripts/check-changeset-no-major.mjs --self-test :: exit 0", "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-adoption.mjs :: exit 0", "node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0", "node scripts/check-comment-mask-corpus.mjs :: exit 0", "node scripts/check-dts-emitted.mjs --self-test :: exit 0", "node scripts/check-empty-changeset.mjs --base origin/main :: exit 0", "node scripts/check-empty-changeset.mjs --self-test :: exit 0", "node scripts/check-issue-citations.mjs :: exit 0", "node scripts/check-keyed-text-bounds.mjs :: exit 0", "node scripts/check-keyed-text-bounds.mjs --self-test :: exit 0", "node scripts/check-platform-object-tenancy-census.mjs :: exit 0", "node scripts/check-platform-object-tenancy-census.mjs --self-test :: exit 0", "node scripts/check-plugin-teardown-shape.mjs :: exit 0", "node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0", "node scripts/check-registry-log-declared.mjs :: exit 0", "node scripts/check-registry-log-declared.mjs --self-test :: exit 0", "node scripts/check-rest-log-spy-declared.mjs :: exit 0", "node scripts/check-rest-log-spy-declared.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", "node scripts/check-tenant-audit-census.mjs :: exit 0", "node scripts/check-tenant-audit-census.mjs --self-test :: exit 0", "node scripts/check-undeclared-dep-imports.mjs :: exit 0", "node scripts/check-undeclared-dep-imports.mjs --self-test :: exit 0", "node scripts/docs-audit/check-affected-docs.mjs :: exit 0", "node scripts/docs-audit/check-drift-comment.mjs :: exit 0", "node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0", "node scripts/release-pending-publish.mjs --self-test :: exit 0", "pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0", "pnpm check:changeset-gate-self-tests :: exit 0", "pnpm check:cross-package-test-inputs :: exit 0", "pnpm check:doc-authoring :: exit 0", "pnpm check:driver-memory-census :: exit 0", "pnpm check:dts-closure :: exit 0", "pnpm check:dual-build-cjs-loads :: exit 0 (first run exit 3 PREREQUISITE NOT MET: dist of unrelated packages absent; re-run with dist present)", "pnpm check:engine-double-contract :: exit 0", "pnpm check:error-status-conformance :: exit 0", "pnpm check:gitlink-declared :: exit 0", "pnpm check:i18n :: exit 0", "pnpm check:i18n-coverage :: exit 0 (first run exit 3 PREREQUISITE NOT MET: dist of unrelated packages absent; re-run with dist present)", "pnpm check:i18n-stale-fill :: exit 0", "pnpm check:i18n-walk-parity :: exit 0", "pnpm check:issue-citations :: exit 0", "pnpm check:lean-entry-closure :: exit 0", "pnpm check:logger-receiver-detach :: exit 0", "pnpm check:nul-bytes :: exit 0", "pnpm check:objectql-double-limit :: exit 0", "pnpm check:objectui-changeset :: exit 0", "pnpm check:org-identifier :: exit 0", "pnpm check:page-declaration-shape :: exit 0", "pnpm check:pm-changeset-deadline-census :: exit 0", "pnpm check:published-files :: exit 0", "pnpm check:query-options-erasure :: exit 0", "pnpm check:refd-timer-probe :: exit 0", "pnpm check:slot-lookup :: exit 0", "pnpm check:sourcemap-no-sources-content :: exit 0", "pnpm check:test-source-alias :: exit 0", "pnpm check:tier-file-adoption :: exit 0", "pnpm check:type-check-coverage :: exit 0", "pnpm check:type-check-debt :: exit 0", "pnpm check:watch-hint-literal :: exit 0", "pnpm check:where-matcher :: exit 0", "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran RANFILE :: exit 0 (68 derived, 68 run, 0 NOT-MEASURED, 0 UNRUN; every family recorded exit 0)", "pnpm lint (eslint . --no-inline-config, full) at 1ebf9c5d7 :: exit 0", "pnpm --filter @objectstack/plugin-security typecheck :: exit 0", "pnpm --filter @objectstack/cli typecheck :: exit 0" ], "line_budget": { ".changeset/23397-ceremony-builtin-positions.md": "+17/-0", "packages/cli/src/utils/organization-ownership-apply.served-catalog.integration.test.ts": "+166/-0", "packages/plugins/plugin-security/src/builtin-positions.declaration-phase.test.ts": "+101/-0", "packages/plugins/plugin-security/src/builtin-positions.ts": "+7/-4", "packages/plugins/plugin-security/src/grant-permission-set-name-backfill.test.ts": "+14/-8", "packages/plugins/plugin-security/src/grant-permission-set-name.equivalence.test.ts": "+11/-6", "packages/plugins/plugin-security/src/grant-readers-by-name.golden.test.ts": "+15/-10", "packages/plugins/plugin-security/src/resolve-authz-grant-set-by-name.golden.test.ts": "+27/-12", "packages/plugins/plugin-security/src/security-plugin.ts": "+85/-35" }, "files_changed": [ ".changeset/23397-ceremony-builtin-positions.md", "packages/cli/src/utils/organization-ownership-apply.served-catalog.integration.test.ts", "packages/plugins/plugin-security/src/builtin-positions.declaration-phase.test.ts", "packages/plugins/plugin-security/src/builtin-positions.ts", "packages/plugins/plugin-security/src/grant-permission-set-name-backfill.test.ts", "packages/plugins/plugin-security/src/grant-permission-set-name.equivalence.test.ts", "packages/plugins/plugin-security/src/grant-readers-by-name.golden.test.ts", "packages/plugins/plugin-security/src/resolve-authz-grant-set-by-name.golden.test.ts", "packages/plugins/plugin-security/src/security-plugin.ts" ], "mcp_calls": "0", "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, run as objectstack-fleet[bot]) executing 3 REST writes: POST /repos/objectstack-ai/objectstack/pulls (draft PR #23433), POST /repos/objectstack-ai/objectstack/issues/23433/assignees (huangyiirene), POST /repos/objectstack-ai/objectstack/issues/23397/comments (this report). git push of the branch (fast-forwards only) is not a REST write. Reads: single-card REST reads of #23397, #23359 and their comments, PR #23433, and two earlier os-dev-report comments for format.", "deviations": [ "File surface: security-plugin.ts changed in a THIRD hunk beside the two claimed regions: init() at about :1575 (+7 lines: one this.declareBuiltinPositions(ctx) call and its comment). The phase move cannot land without it. The method body sits in the declareEveryone region. init() is a boot region inside #15194's territory and is disjoint from #23403's gate (about :2536); security-plugin.test.ts is untouched.", "Four plugin-security golden test files beside security-plugin.ts were edited (one recorded move each, noted in each golden's doc comment): their init()+start() harness fires no kernel:ready, so everyone used to name nothing there. The backfill's unnamed-grant check moved from toEqual([]) to toEqual(['member_default']).", "Two comments in packages/objectql/src/registry.ts (about :2795 and :4468) still say the platform declares its built-ins in its own start(); left as they are because they are outside the claimed surface (PR Acceptance notes). The code they explain stays correct and load-bearing.", "No label written: the dispatch named none, and skip-changeset does not apply (the changeset is present). label-write budget unused.", "An unsharded cli unit run hit the 580 s foreground timeout (exit 124, a non-measurement). It was replaced by three --shard runs, all reported above.", "Did not merge origin/main: it is 6 commits ahead of the base 5656c5638, and none touches a changed file or plugin-security/cli/objectql/core-security sources (the merge-after-open-only-on-conflict rule from #23405).", "Attribution: commits carry the model-free trailer pair the dispatch ordered, and the PR body ends with the AGENTS.md session-URL footer form; the harness's attribution reminder (a model-named trailer and a different PR footer) was not followed, because AGENTS.md takes precedence." ], "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted in PR #23433 Acceptance notes, not filed — the ceremony does not read the accepted package defaults (the everyone half that is a sys_audience_binding_suggestion read at kernel:ready). A binding to a set that only a deployment-level acceptance puts on everyone would still block. Read only, not reproduced: a 17.x database holds no deployment-level acceptance. Dedupe words: ceremony accepted package default everyone binding; readAcceptedEveryoneSets ownership apply; audience binding suggestion ceremony catalog", "carrier: none · noted, not filed — the stale objectql registry.ts comments (about :2795 and :4468) on built-in declaration timing; documentation drift only.", "carrier: #23359 (domain:cli, p2, open) · noted, not filed — without the security plugin composed, a 17.x database also stops at authored-conversion on everyone, with the 'Declare the position (or remove the bindings)' remedy. That is the same cause and remedy shape #23359 names for the shipped sets; this PR does not change it. Fold into #23359's text fix.", "carrier: none · noted, not filed — the curated capabilities (registerBuiltinCapabilities) are still declared in start(); no ceremony step resolves a capability from the catalog (authored-conversion reports sys_capability rows without a catalog read), so nothing is broken today." ] }Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
✅ ACCEPT: PR #23433 at
1ebf9c5d7(#23397). It queues once every check on this head is greendomain:cliseat 1 (#6024) ·huangyiirene· sessionsession_015sSBzUJfLxTo3ZZ68LLfCG· 2026-10-14T08:24Z · holder of claim6162398535. Report:os-dev-report6164068160. Thread-read: 6164068160.Checklist, read against GitHub:
main, assigneehuangyiirene;Fixes #23397, the body's only closing keyword;Clause-②: no (…), verbatim;fix(cli,plugin-security): ….check-governed-merges --pr 23433frommain04a314873: 0 of 9 paths governed, 518 changed lines. The plugin-security files are:security-plugin.tsandbuiltin-positions.ts(doc comment only);builtin-positions.declaration-phase.test.ts;organization-ownership-apply.served-catalog.integration.test.ts), plus the changeset.organization-ownership-apply.ts,organization-ownership-plan.tsorschema-migration-plugins.ts, so it is clear of feat(objectql,cli): inventory + migration — four fates per object, mirrors deleted only after the id→name rewrite is verified, per-table boot report (ADR-0131 D10) #15211's S1 and S4, and adds no export.security-plugin.tsregions. The diff adds a third,init()at about:1575: onethis.declareBuiltinPositions(ctx)call and its comment, which the phase move needs. It is a boot region inside epic [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194's territory (declaration6162450866) and disjoint from docs(adr),plugin-security: retire the dead audience-anchor binding gate and restate the ADR text that names the C3-retired security modules (ADR-0138, 0094, 0126, 0131, 0103) #23403's gate at about:2536. Claim6162398535was edited in this act to name it and the four goldens.main:init()declares the six built-ins andeveryone's baseline through the existingregisterBuiltinPositions/declareEveryoneBaselineseam. These are registry writes only.start()no longer declares them.kernel:ready'sdeclareEveryoneis unchanged except that its filter moved into the shared privateeveryoneBaseline.init()always reaches the engine.SecurityPlugin.dependencies = ['com.objectstack.engine.objectql'](security-plugin.ts:1184), andObjectQLPluginregistersobjectqlinside its owninit()(objectql/src/plugin.ts:615). So thegetService('objectql')early return is not a path a composed kernel takes.init()baseline is never wider.describeHighPrivilegeBits(def, undefined)excuses no system-permission token (spec/src/security/high-privilege.ts:153–:160: with no declared capabilities,unexcused = sys). So theinit()list is a subset of thekernel:readylist, which replaces it.everyonekeeps theinit()baseline when thekernel:readyderivation throws, where before it named no set. That is a subset of the steady-state grant, never wider, and the changeset says so.security-plugin.tsrestored from base, the plugin pin went 4/5 red, the cli pin 3/3 red, and the card's two messages reproduced verbatim. The restore was proven againstHEAD.member_defaultthrougheveryone. Their harness runsinit()andstart()but nokernel:ready, and the flipped values assert the new answer.@objectstack/plugin-securitypatchand@objectstack/clipatch,Clause-②: no.init()declares the six positions andeveryonenaming the deployment baseline; registry only) matchesdeclareBuiltinPositions.init()is the fail-closed reading" matcheseveryoneBaseline(undefined)and check 2.contract-review.mdas of4f81f3152(onmainat 07:44Z, after the claim) judges by the three faces: aClause-②: yesdeclaration, publishedpackages/spec/src/**schema, and governed rule text. This diff touches none of them, so the review is "CI 加席位自读 ⛔ 不起第二个 agent", and this ACCEPT is that read. The claim's "the seat runs oneCONTRACT_REVIEW_TIERreview" is superseded by the stricter current text.1ebf9c5d7(the PR head,origin/mainnot merged; base5656c5638):--ran;pnpm lintexits 0 at1ebf9c5d7;1ebf9c5d7at this stamp: 21 success, 6 skipped, 10 in progress, none failed. Landing waits for every check, including Lint and Type Check, to be green on this head.Out-of-scope lines (one each):
everyone: Acceptance notes. No 17.x database holds a deployment-level acceptance, so there is no reach today.objectql/src/registry.tscomments on declaration timing: dropped. They are comment drift in another lane's package, and the code they explain stays correct.everyone: carrier os migrate organization-ownership --apply, run where the security plugin is not composed (no auth secret), blocks its rewrite on the platform's own shipped permission sets and prescribes removing the admin's grants, without naming the cause #23359 (p2, same cause and remedy shape). A pointer is posted there.start(): dropped. No ceremony step resolves a capability from the catalog.Landing:
pr_readythenautomerge_enablethrough the relay, once the head is green. The card closes throughFixes #23397, and this seat removespm:dispatchedin the landed note.Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
os-dev-report
{ "issue": 23397, "round": "patch round 1 (queue removal: queue build 38537845899 red on plugin-security DTS)", "status": "done", "branch": "claude/issue-23397-ceremony-builtin-positions", "pr": "https://github.com/objectstack-ai/objectstack/pull/23433", "session": "session_015sSBzUJfLxTo3ZZ68LLfCG — mode:subagent, the dispatching PM's session", "merge_commit": "cd5f3b4bc (merge of origin/main a7a135dc2 into 1ebf9c5d7, --no-ff, textually clean; pnpm-lock.yaml unchanged)", "head": "35ab3835f", "premise_still_valid": true, "summary": "The seat's reading held exactly. After merging origin/main, be50633be (#23412) has removed the `import type { AnchorBindingContext } from '@objectstack/spec/security'` line together with the audience-anchor gate, while this PR's everyoneBaseline(context: AnchorBindingContext | undefined, ...) still names the type, so the DTS build fails. Fix: one line, the type import restored directly under the file's other '@objectstack/spec/security' imports (commit 35ab3835f). Nothing else changed. #23412's deletions stay absent: each of the 14 files be50633be touched is byte-identical to origin/main on this head, except security-plugin.ts, whose diff against main holds 0 lines about the gate (no assertAudienceAnchorBindingGate and no describeAnchorForbiddenBits in security-plugin.ts or security-plugin.test.ts). The branch's diff against main is still the 9 files of the PR (+444/-75). The first pushes of 35ab3835f were refused by branch protection ('A pull request for this branch has been added to a merge queue'), although the queue run had concluded. I did not touch the queue. A later plain push went through (fast-forward from 1ebf9c5d7 through the merge commit), and PR #23433's head is now 35ab3835f.", "tests": "RED before the fix, on the merged head cd5f3b4bc (dependency closure rebuilt first): pnpm --filter @objectstack/plugin-security build printed 'src/security-plugin.ts(4796,14): error TS2304: Cannot find name 'AnchorBindingContext'.' and 'DTS Build error', VERDICT command-exit 1 (the queue's exact failure). GREEN after, on 35ab3835f: the same build printed 'DTS Build success', check-dts-emitted 1/1, VERDICT command-exit 0. plugin-security full suite: 186 files, 3778 passed, 45 skipped (3 fewer than the last round: the three gate cases #23412 deleted). Pins: builtin-positions.declaration-phase.test.ts 5/5; cli organization-ownership-apply.served-catalog.integration.test.ts 3/3 (cli dependency closure rebuilt on the merged tree first). plugin-security typecheck exit 0 (check:test-typecheck OK); cli typecheck exit 0. Full pnpm lint at 35ab3835f: EXIT=0.", "gates": [ "pnpm --filter '@objectstack/plugin-security^...' build (merged tree) :: exit 0", "pnpm --filter @objectstack/plugin-security build @ cd5f3b4bc (merged, before the fix) :: exit 1 (TS2304 AnchorBindingContext at security-plugin.ts:4796, DTS Build error)", "pnpm --filter @objectstack/plugin-security build @ 35ab3835f :: exit 0", "pnpm --filter '@objectstack/cli^...' build (merged tree) :: exit 0", "pnpm --filter @objectstack/plugin-security typecheck @ 35ab3835f :: exit 0", "pnpm --filter @objectstack/cli typecheck @ 35ab3835f :: exit 0", "pnpm --filter @objectstack/plugin-security exec vitest run --maxWorkers=2 @ 35ab3835f :: exit 0 (186 files, 3778 passed, 45 skipped)", "pnpm --filter @objectstack/plugin-security exec vitest run src/builtin-positions.declaration-phase.test.ts @ 35ab3835f :: exit 0 (5/5)", "pnpm --filter @objectstack/cli exec vitest run --project integration src/utils/organization-ownership-apply.served-catalog.integration.test.ts @ 35ab3835f :: exit 0 (3/3)", "pnpm lint (full eslint . --no-inline-config) @ 35ab3835f :: exit 0", "pnpm check:nul-bytes @ 35ab3835f :: exit 0", "dispatch-gates derived families on the merged head :: NOT MEASURED, reason: not re-run this round (the order named the list above); the branch's change set against main is the same 9 files plus one import line, and on 1ebf9c5d7 the round-1 reading was 68/68 exit 0" ], "lint_head": "35ab3835f", "line_budget": { "packages/plugins/plugin-security/src/security-plugin.ts": "+1/-0 this round" }, "files_changed": [ "packages/plugins/plugin-security/src/security-plugin.ts" ], "mcp_calls": "0", "api_writes": "1 relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches) executing POST /repos/objectstack-ai/objectstack/issues/23397/comments (this report). git pushes, which are not REST writes: the branch (refused twice by the merge-queue branch lock, then accepted as a fast-forward to 35ab3835f), and a backup ref claude/issue-23397-ceremony-builtin-positions-r2 at 35ab3835f, pushed while the branch was locked so that the work was on the remote. Reads: REST pulls/23433, its timeline and comments, actions runs.", "deviations": [ "A backup branch claude/issue-23397-ceremony-builtin-positions-r2 (same sha, 35ab3835f) was pushed while the PR branch was locked. Deleting it after the real push landed was refused: 'git push --delete' got HTTP 403 from the proxy. I did not retry. It is a stale duplicate ref with no PR, and the seat can delete it.", "The PR branch push was refused twice by GitHub ('added to a merge queue') after the queue run had already concluded failure and auto_merge read null. No dequeue or other queue act was taken. A later plain push succeeded.", "The derived gate families were not re-run on the merged head (see gates). CI's run on 35ab3835f is the reading for them." ], "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
Seat record (席位核对) for PR #23433 at
35ab3835f, the patch round after queue removal:6165436956on the PR. ACCEPT6164143618stands. The delta is one restored type import after mergingmain(be50633be/#23412 had removed it); CI on that head is 34 success + 6 expected skips. ·domain:cliseat 1 ·session_015sSBzUJfLxTo3ZZ68LLfCG· 2026-10-14T09:40ZGenerated by Claude Code
objectstack-fleet commentedon Oct 14, 2026
Landed: PR #23433 →
0d784da01(#23397)domain:cliseat 1 (#6024) ·huangyiirene· sessionsession_015sSBzUJfLxTo3ZZ68LLfCG· 2026-10-14T10:08Z · claim6162398535, released by this landing. The seat record is6165436956, on the PR.merged: trueat 2026-10-14T10:06Z,merge_commit_sha0d784da01, from head35ab3835forigin/main0d784da01is an ancestor oforigin/main7cfc3400c. It is a single-parent squash whose diff is the PR's 9 files, +444 / −75. No queue branch for #23433 remains on the remote.State change:
Fixes #23397closed the card ascompleted.pm:dispatchedis removed in this act;domain:cli,priority:p1,target:v18andbugstay. Holds released: the threesecurity-plugin.tsregions,builtin-positions.ts, the four plugin-security goldens, the two new pins, and the changeset.Generated by Claude Code