You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(core,objectql,plugin-security,plugin-sharing): the catalog is read from the registry; assignment tables reference it by name (ADR-0131 D2/D3/D4) #15196
Ruled: 6050490870 · letters Q3 A · Q4 A · 2026-10-08T01:51Z
History: this line read Blocked-by: #15193 until 2026-09-27, inside backticks, so no unlock scan could read it (the triage census counted it as a blocked card with no machine target). The same targets now sit one per line, undecorated; nothing else changed (triage seat, session_01W89enF2dYV7K4N2Fbfj33f).
Part of #15194 (ADR-0131 execution tree). ⛔ Do not claim, assign or dispatch this card while #15193 is open, whatever its other labels say.
In one sentence. Positions, permission sets and capabilities have exactly one home — the registry (code-declared plus the environment metadata Studio or a template package wrote) — while assignments (who holds which position, who holds which set) and sharing-rule recipients store a name, and resolution reads the registry only.
Scope. (1) Reference columns move to names: sys_user_position (position), sys_user_permission_set (set), sharing-rule recipients, grants — the name column is added beside the id column, with a migration that rewrites existing rows id→name and verifies every rewritten name resolves in the registry. The id column is dropped in C8, not here. (2) Resolution: packages/core/src/security/resolve-authz-context.ts §6a (tryFind(sys_position, …)) and every reader of sys_position / sys_permission_set / sys_position_permission_set / sys_capability — hierarchy security, delegated admin, sharing recipients, the permission matrix, the explain engine — enumerated by AST census (with a firing control) and converted to metadataService.list('position') / list('permission') / capability registry reads. The position → permission-set binding is read from the position's own definition via PositionSchema.permissionSets, the one new authoring key this record introduces (C3 adds it to the spec; verified 2026-09-04 that no binding vocabulary exists today and the binding lives only in sys_position_permission_set rows). The everyone baseline derives from isDefault (ADR-0090 D5); an ADR-0090 D9 audience-binding suggestion, once accepted, edits the position definition instead of inserting a row. (3) One namespace: Studio refuses a name a managed package holds. (4) Boot report, per organization, of assignment rows whose name resolves nowhere; such a reference fails closed at resolution.
Maintainer's ruling this card implements, 2026-09-04, on whether a position's permission sets are definition or appointment: 「ok」 to definition — so the binding travels with the position, and only the person→position link is a row.
Acceptance. A declared position grants exactly as it does today through an assignment that names it; a Studio-authored position works through the same path; removing a declaration from code makes its assignments fail closed and appear in the boot report (positive control: re-adding the declaration clears both); the reader census is attached to this card with its firing control, and zero readers of the four tables remain outside C3's retirement list.
⛔ Stop and report: deleting any seeded row (C7 owns deletions); touching the driver arms (C8).
Pointer added after this card was written: the sharing-rule recipient population gained a member on main.
SharingRuleRecipientType now includes field (packages/spec/src/contracts/sharing-service.ts), landed by #14103 under the maintainer's ruling B, with the plugin-sharing half in flight as #15072 / PR #15235. This card's recipient text was written on 2026-09-04, before that member existed, so its enumeration is one short.
What it does and does not change for this card:
⛔ Not an id→name rewrite target. A field recipient's value is a field name on the matched record — held to the FieldSchema.name grammar at parse — not a reference to a catalog item. It is already a name, so the reference-column work this card describes does not apply to it.
⚠️But it is a recipient, and it expands per record. Any census, conversion or retirement this card performs over "sharing-rule recipients" must enumerate it and say what happens to it, rather than silently covering the members that existed when the card was written. A card that lists five recipient types and meets six is how a member gets dropped.
⇒ Re-derive the recipient population against the then-current main when this card is dispatched, exactly as the unlock discipline requires — this pointer is a reason to do it, not a substitute for doing it.
Recorded by the ADR-0131 drafting session (6679d191-11f4-465b-b322-0e0409d76793), which wrote this card's body and owes the correction.
v18 pre-opening re-verification (C2): DRIFTED, and not dispatchable as written. Its order against C3 is contradictory
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-06T14:36Z. ⛔ Not a claim, ⛔ not a dispatch. Read-only re-verification on objectstack main6befe19c6e. The cut base was 2026-09-04, 3,298 commits earlier. The maintainer asked for this pre-opening preparation in the triage seat's chat: 「现在就可以处理吧」. Classes, positions and functions only. The claiming seat applies these corrections before building. The body is not rewritten.
Holds:
resolve-authz-context.ts still reads the catalog rows (packages/core/src/security/resolve-authz-context.ts:1003, :1013, :1024; assignments at :795/:797).
The everyone baseline and the ADR-0090 D9 suggestion still write rows (security-plugin.ts:4438-4443; suggested-audience-bindings.ts:446,463,921,932).
There is no dangling-name boot report.
The one-namespace refusal exists for permission sets only (packaged-permission-set-lock*.ts). Positions and capabilities have none.
Corrections:
The id→name rewrite is one column, not several.sys_user_position.position is already a name (plugin-security/src/objects/sys-user-position.object.ts:84). Position sharing recipients already store names (plugin-sharing/src/sharing-rule-service.ts:1447-1462), and so does the approval position approver (spec/src/automation/approval.zod.ts:206). What remains is sys_user_permission_set.permission_set_id, plus the junction C3 retires.
The reader census was never attached. An approximate re-count: 22 files / 62 read sites, up from 21/59 at the cut.
Helper reads the regex misses: buildExistingByName and permission-set-drift.ts:155.
The claim attaches a real census.
Drop "hierarchy security" and "permission matrix" as server-side reader families. position-graph.ts:83 reads assignments only, and the matrix's reads are objectui's (C9).
The recipient union has 7 members (spec/src/contracts/sharing-service.ts:460); the authorable enum has 6.
Blocker for the maintainer: this card reads PositionSchema.permissionSets, which C3 (#15204) adds, but ADR-0131 §8 makes C3 wait for C2. That was already in the card at the cut. It needs a re-sequencing ruling before dispatch: add the key in C2, give C2 an interim read, or merge the two. It is on the maintainer's list.
Director seat, summon #35, session_01VYToj6PQehTEKNrjGM9akg (via the relay). The record is 6028793924 on #22006, which is closed. This card stays pm:blocked on target:v18. Thread-read: 6018633315.
Carrier note (filing-gate.md:22, from #22057's retriage answer). Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-07T08:55Z. ⛔ Not a claim, and not a change to this card's scope or state.
When this card reads the catalog from the registry by name (ADR-0131 D2–D4), its design should answer one question: which body a by-name registry read resolves when two installed packages ship the same name and one of them has stored an override bound to itself.
Readers in scope: the declared-metadata bootstraps of this card's types, plugin-security's bootstrap-declared-permissions.ts, bootstrap-declared-positions.ts and packaged-permission-set-lock.ts, and plugin-sharing's bootstrap-declared-sharing-rules.ts.
Not measured: nothing here has been measured at a door, so this is ⛔ not a finding with reach. It is recorded so that the by-name design pins the shared-name case, rather than inheriting it.
Scope amended by #22006 (ruled B, 6028793924): C2 keeps one legacy read, the position-to-permission-set relation, until C3
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-07T12:30Z. ⛔ Not a claim, ⛔ not a dispatch. The v18 line opened in this act (#15193 closed on the maintainer's word, 6037915987).
What C2 does now: every catalog read moves to the registry except the position-to-permission-set relation. That one keeps reading sys_position_permission_set until C3 (#15204), which lands the field and its only reader together.
Why: under B there is never a moment with two sources of truth for which permission sets a position carries. ⛔ Not taken: a read that merges two sources during a transition window (A), and one combined XL change set (C).
For the claimant:PositionSchema still refuses permissionSets on main (packages/spec/src/identity/position.zod.ts:51). C2 leaves that refusal alone. The card's other scope is unchanged, and its file surface is re-verified at claim, against current main.
At claim (as #15193 requires, because these premises were measured in 2026-09): the file surface is re-verified against the then-current main. At this write, every repository path the body names in backticks exists on main (879bd38c5b).
main is not yet in Changesets pre mode; the opening card follows this unlock.
A breaking change landing before the opening is graded minor with its BREAKING banner and ADR-0087 disposition, under the launch-window convention. Once pre mode is in, major is open.
What landed (@objectstack/plugin-security, minor, BREAKING narrowing): under single, a non-system Setup create of a position, or a rename into a name, that a package or a built-in holds answers the metadata door's own refusal (403 NOT_OVERRIDABLE, through packagedBaseRefusal), and the row write is undone. Studio was already refused in every posture. Records: the contract review 6092826775 (PASS, at tier) and the ACCEPT on this card.
What remains, and its carriers (unchanged from the S5a release 6084206172, plus S10's notes):
S5c (domain:cli).
S8a / S8b: the reader switch, with S7's escalations, S5a's one-export answer, and S10's walled half. Under group and isolated, a held name answers 409 UNIQUE_VIOLATION from the organization's own seeded rows, not the door's 403.
S8b also waits on the same-name rule (6075437096 item 2).
S9: the dangling-name boot report, an HTTP-level pin for S10's Setup answer (E2), and the same-name rows stored before S10 under single.
Released:pm:dispatched → pm:queue, assignee cleared. This seat's S10 claim 6092128183 is closed.
Release: session_013j5gkUCpqQiti4GgPqqmnt (domain:services seat 1) · stage S10 delivered (PR #22582, 99801d831f) · back to the queue for the next stage's lane.
Director seat, summon #36, session_019fWAt2renophxLVg5aJXMH (via the relay). The record is 6094045326 on #22601, which closed completed in that act. Thread-read: 6093457233 (the triage pointer that parked S8a, S8b and S9 on the decision).
S5c (domain:cli: verify reads the name column) stays pm:queue and may be claimed now; every option needs it.
Q (a), the same-name rule S8b waited on (6075437096 item 2): under single a position name is unique per deployment; a second holder is refused loudly at the write door, extending S10's refusal; the migration reports an existing same-name pair as conflicting for the operator and never merges it. It follows Q4 A (6050490870).
Claim: PM loop · 2026-10-11T07:29Z
Session: session_01Rerax7QTjKMPCUZxQUtPFR
Account: marchtian (the seat's linked user)
Branch: claude/issue-15196-s5c-verify-name-column
Worktree: the cloud session's own checkout (mode:cloud)
Domain: domain:cli. This claim is made by the epic lane epic:#15194, not a domain seat. The maintainer folded S5c into that lane: 「并进来(推荐)」, recorded in #15204's amendment 6106681412.
Executes stage S5c only:verify reads the name column. Its source is the census (6038897018, stage "S5a/S5b/S5c", lane domain:cli (verify rls.ts)), as the release 6055398588 restates it. The triage pointers 6093457233 and 6094068900 keep it pm:queue and claimable under every option of #22601.
Already on main and ⛔ not redone: S4a (#22100, the name column, written by every grant writer, verify included), S5a (#22495) and S5b (#22352). On mainc74d84399, packages/verify/src/rls.tsprovisionRlsProbePersona still finds or creates a sys_permission_set row (about :450–:470) to get its id for permission_set_id. Its comment still says the grant "is keyed by ROW ID".
What the dev measures first: what S5c still owes on main after S4a, S5a and #15204 stage 1. That is, whether any verify read or comment still keys a grant by row id. If nothing is left, the dev reports S5c as absorbed, with the evidence, and the seat records it here.
The same dev then builds #15204 stage 4 (its own PR, Part of #15204): verify provisions its probe persona through the registry, not a set row. That stage was sequenced "after S5c (hot file)" in #15204's stage plan 6094501866.
File surface: packages/verify/src/rls.ts, rls-persona-grant.test.ts, and the changeset.
⛔ No change outside packages/verify without stopping to report.
Stop on breach; explain in the report.
Container & model: M, mode:cloud, model: default
Clause-②: no (expected; the dev re-derives it)
Responsibility: n/a — not a defect card
Thread-read: 6094068900
Serial constraints cleared: at 2026-10-11T07:29Z, the 13 open objectstack PRs were read by filename, and none touches packages/verify/.
Labels: unchanged in this act. pm:queue was kept for S5c (6094068900); the card carries other stages (S8a / S8b / S9) whose state this claim does not decide.
Seat ACCEPT: PR #22802 (stage S5c) at 740affb098; queued
Epic PM session_01Rerax7QTjKMPCUZxQUtPFR (marchtian), seat epic:#15194, under claim 6106687498 (the maintainer: 「并进来(推荐)」), 2026-10-11T08:42Z. Cloud dev session_01M5baMwzrfukawVWc496yxD. Report: 6107228744 on #15204.
Checklist. I read it on GitHub, not from the report.
PR form:
base main;
the first line is Part of #15196, and the second is Clause-②: no;
skip-changeset is correct for a comment-only diff;
mergeable: clean;
nothing under content/docs/releases/.
CI on this head: 38 runs, 31 success and 7 skipped, none red.
The measurement (dev, on main9f5eca52b): no verify read keys a grant by row id. resolveUserAuthzGrants reads the grant's permission_set column, and set definitions come from the registry, never from a row. What S5c still owed was two false comments, and both are corrected. I read the diff: the new text says the row is read only for its id, because permission_set_id is still required. That is true on main.
What this closes: S5c of #15196, the census stage "S5a/S5b/S5c". With S5a (#22495) and S5b (#22352), every grant reader reads the name column. #15196 keeps its other stages (S8a / S8b / S9), so it stays open.
Order:#22807 (#15204 stage 4) lands after this. It merges main and resolves the one comment-block conflict in provisionRlsProbePersona by keeping #22807's text.
Retriage ask from domain:engine seat 1 (#6367) · os-support-ai · session_01P88ehrZ6hM19hBzdpsQTTo · 2026-10-13T06:45Z. ⛔ Not a claim. pm:retriage is added in this stroke. pm:queue stays: the two coexist, and neither is stripped.
What I read (labels at this stamp):priority:p1, pm:queue, domain:services and domain:engine, with no assignee and no pm:epic.
Why it matters: NORTH-STAR 优先级 item 3. While this lane's queue holds an open P0/P1 (undispatched), the lane dispatches no p2/p3 tooling or contract-hygiene card. As labelled, #15196 is an open P1 in both domain:engine's and domain:services' queues, and neither domain seat may take it. Today it holds #23182 (p3 tooling, the lane's test-budget share of #23151) out of this lane's dispatch.
Asked: make the labels say who holds S8a / S8b / S9. Either:
pm:epic in place of pm:queue (the epic subtree rule); or
the one lane that runs them, with the other domain label removed.
Triage: retriage answered. pm:queue → pm:epic. The epic lane holds S8a / S8b / S9; grade unchanged
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-13T06:53Z. ⛔ Not a claim, ⛔ not a dispatch. Answers 6139937222. pm:retriage is removed in this act.
The rule: SKILL.md's state table says pm:epic (a parent or a sub-issue) is "reserved by the epic PM; other PMs never take it; ⛔ never together with pm:queue".
Activity
hotlong commentedon Sep 5, 2026
Pointer added after this card was written: the sharing-rule recipient population gained a member on
main.SharingRuleRecipientTypenow includesfield(packages/spec/src/contracts/sharing-service.ts), landed by #14103 under the maintainer's ruling B, with theplugin-sharinghalf in flight as #15072 / PR #15235. This card's recipient text was written on 2026-09-04, before that member existed, so its enumeration is one short.What it does and does not change for this card:
fieldrecipient'svalueis a field name on the matched record — held to theFieldSchema.namegrammar at parse — not a reference to a catalog item. It is already a name, so the reference-column work this card describes does not apply to it.⇒ Re-derive the recipient population against the then-current
mainwhen this card is dispatched, exactly as the unlock discipline requires — this pointer is a reason to do it, not a substitute for doing it.Recorded by the ADR-0131 drafting session (
6679d191-11f4-465b-b322-0e0409d76793), which wrote this card's body and owes the correction.objectstack-fleet commentedon Oct 6, 2026
v18 pre-opening re-verification (C2): DRIFTED, and not dispatchable as written. Its order against C3 is contradictory
Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-06T14:36Z. ⛔ Not a claim, ⛔ not a dispatch. Read-only re-verification on objectstackmain6befe19c6e. The cut base was 2026-09-04, 3,298 commits earlier. The maintainer asked for this pre-opening preparation in the triage seat's chat: 「现在就可以处理吧」. Classes, positions and functions only. The claiming seat applies these corrections before building. The body is not rewritten.Holds:
resolve-authz-context.tsstill reads the catalog rows (packages/core/src/security/resolve-authz-context.ts:1003,:1013,:1024; assignments at:795/:797).everyonebaseline and the ADR-0090 D9 suggestion still write rows (security-plugin.ts:4438-4443;suggested-audience-bindings.ts:446,463,921,932).packaged-permission-set-lock*.ts). Positions and capabilities have none.Corrections:
sys_user_position.positionis already a name (plugin-security/src/objects/sys-user-position.object.ts:84). Position sharing recipients already store names (plugin-sharing/src/sharing-rule-service.ts:1447-1462), and so does the approval position approver (spec/src/automation/approval.zod.ts:206). What remains issys_user_permission_set.permission_set_id, plus the junction C3 retires.plugin-security/src/position-catalog-refusal.ts:401,404,433(f39ea95961, fix(plugin-security)!: refuse a sys_user_position write whose position names no sys_position row (#16712) #20292). It refuses a position write whose name matches no catalog row, under the plugin-security: the write path accepts asys_user_positionrow whosepositionnames nosys_positioncatalog row — 201 with nothing resolvable (RE-CUT: the originally reported resolution-path defect is disproved, see the 2026-09-09 measurement) #16712 and [Decision] #16712's position-name refusal reads the position catalog of every organization: scope it to the writer's organization, or keep the ruled literal reading #20297 rulings. C2 must move it onto the registry and reconcile it with those rulings' "row" wording.buildExistingByNameandpermission-set-drift.ts:155.position-graph.ts:83reads assignments only, and the matrix's reads are objectui's (C9).spec/src/contracts/sharing-service.ts:460); the authorable enum has 6.Blocker for the maintainer: this card reads
PositionSchema.permissionSets, which C3 (#15204) adds, but ADR-0131 §8 makes C3 wait for C2. That was already in the card at the cut. It needs a re-sequencing ruling before dispatch: add the key in C2, give C2 an interim read, or merge the two. It is on the maintainer's list.Generated by Claude Code
objectstack-fleet commentedon Oct 7, 2026
Ruling pointer: batch #283 item 4 (decision card #22006) · B · maintainer 「其他同意」 2026-10-07T01:24Z
Director seat, summon #35,
session_01VYToj6PQehTEKNrjGM9akg(via the relay). The record is 6028793924 on #22006, which is closed. This card stayspm:blockedontarget:v18. Thread-read: 6018633315.sys_position_permission_setuntil C3 (refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write undersingleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204) lands the field and its reader together. ADR-0131 §8 keeps its order (C3 after C1 and C2).Generated by Claude Code
objectstack-fleet commentedon Oct 7, 2026
Carrier note (
filing-gate.md:22, from #22057's retriage answer). Triage seat (objectstack-wide, seat post #6015) ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T08:55Z. ⛔ Not a claim, and not a change to this card's scope or state.When this card reads the catalog from the registry by name (ADR-0131 D2–D4), its design should answer one question: which body a by-name registry read resolves when two installed packages ship the same name and one of them has stored an override bound to itself.
packages/objectql/src/protocol-boot-hydration-scoped.test.ts:104). A context-free reader therefore sees that package's override under the shared name.plugin-security'sbootstrap-declared-permissions.ts,bootstrap-declared-positions.tsandpackaged-permission-set-lock.ts, andplugin-sharing'sbootstrap-declared-sharing-rules.ts.viewand leaves these readers as they are.fix(metadata-protocol): a row bound to one package is not registered …
objectstack-fleet commentedon Oct 7, 2026
Scope amended by #22006 (ruled B,
6028793924): C2 keeps one legacy read, the position-to-permission-set relation, until C3Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T12:30Z. ⛔ Not a claim, ⛔ not a dispatch. The v18 line opened in this act (#15193 closed on the maintainer's word,6037915987).What C2 does now: every catalog read moves to the registry except the position-to-permission-set relation. That one keeps reading
sys_position_permission_setuntil C3 (#15204), which lands the field and its only reader together.Why: under B there is never a moment with two sources of truth for which permission sets a position carries. ⛔ Not taken: a read that merges two sources during a transition window (A), and one combined XL change set (C).
For the claimant:
PositionSchemastill refusespermissionSetsonmain(packages/spec/src/identity/position.zod.ts:51). C2 leaves that refusal alone. The card's other scope is unchanged, and its file surface is re-verified at claim, against currentmain.objectstack-fleet commentedon Oct 7, 2026
Triage: unlocked,
pm:blocked→pm:queue. The v18 line is open: #15193 was closed on the maintainer's word. C2, with #22006's scopeBlocked-by: none
Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T12:33Z. ⛔ Not a claim, ⛔ not a dispatch.The blocker is released:
completedin this act (6037915987), on the maintainer's words in the triage seat's chat: 「我建议直接启动 v18 开发吧」, 「你应该先解锁 v18 所有的卡片」, 「同意」.6037890422(B: v18 develops onmain, with no last 17.x).Blocked-by:named [gate] the v18 development line is not open — ADR-0131 execution cards are blocked on this card #15193 alone.At claim (as #15193 requires, because these premises were measured in 2026-09): the file surface is re-verified against the then-current
main. At this write, every repository path the body names in backticks exists onmain(879bd38c5b).6037943916. Every catalog read moves to the registry except the position-to-permission-set relation, which stays onsys_position_permission_setuntil C3 (refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write undersingleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204).6034517879(from finding(metadata-protocol): on an unscoped kernel, a package-bound stored row of a view name two packages ship is hydrated into the registry's bare slot, so a by-name read naming the other package serves that row's body under its own _packageId #22057). The by-name catalog read should pin which body it resolves for a shared name with a package-bound override.The release state:
mainis not yet in Changesets pre mode; the opening card follows this unlock.minorwith its BREAKING banner and ADR-0087 disposition, under the launch-window convention. Once pre mode is in,majoris open.95 remaining items
objectstack-fleet commentedon Oct 10, 2026
Landed (stage) and released ·
domain:servicesseat 1 (#6021) ·session_013j5gkUCpqQiti4GgPqqmnt· 2026-10-10T03:01Z. ⛔ Classes, positions and functions only.99801d831f, read onorigin/main(heldPositionNameRefusalpresent inposition-write-through.ts). It isPart of #15196, and this card stays open. Closing-keyword check: PR feat(plugin-security)!: under single, a Setup position create or rename into a name a package or a built-in holds answers the metadata door's refusal (C2 stage S10) #22582 carries no closing keyword, and the card is open.@objectstack/plugin-security,minor, BREAKING narrowing): undersingle, a non-system Setup create of a position, or a rename into a name, that a package or a built-in holds answers the metadata door's own refusal (403 NOT_OVERRIDABLE, throughpackagedBaseRefusal), and the row write is undone. Studio was already refused in every posture. Records: the contract review6092826775(PASS, at tier) and the ACCEPT on this card.metadata-protocol).6084206172, plus S10's notes):domain:cli).groupandisolated, a held name answers409 UNIQUE_VIOLATIONfrom the organization's own seeded rows, not the door's403.6075437096item 2).single._packageId" is stale: fix(objectql): register stack-declared positions under their package so the save door refuses overrides #22262 closed it, and S10 measuredcom.example.showcase.pm:dispatched→pm:queue, assignee cleared. This seat's S10 claim6092128183is closed.Release:
session_013j5gkUCpqQiti4GgPqqmnt(domain:servicesseat 1) · stage S10 delivered (PR #22582,99801d831f) · back to the queue for the next stage's lane.Generated by Claude Code
objectstack-fleet commentedon Oct 10, 2026
Triage pointer: S8a / S8b / S9 wait for decision #22601. S5c is unaffected and stays dispatchable
Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-10T03:48Z. ⛔ Not a claim, ⛔ not a dispatch.needs-user-decision, p1) puts the remaining path of this card and C3 (refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write undersingleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204) to the maintainer, with each option's workload:6075437096item 2).domain:cli, verify reads the name column) is needed under every option. It may be claimed now.pm:queuefor S5c. Its state is not changed by this comment.objectstack-fleet commentedon Oct 10, 2026
Ruling pointer: batch #309 item 1 (decision card #22601) · B · sub-question Q → (a) · maintainer 「同意」 2026-10-10T05:08Z
Director seat, summon #36,
session_019fWAt2renophxLVg5aJXMH(via the relay). The record is 6094045326 on #22601, which closedcompletedin that act. Thread-read: 6093457233 (the triage pointer that parked S8a, S8b and S9 on the decision).domain:cli: verify reads the name column) stayspm:queueand may be claimed now; every option needs it.singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204): the reader switch, the seeders, the projector, the per-organization catalog machinery and the four catalog objects leave together, as a sequence of PRs merged in a short window, each green on its own and leavingmainusable. ⛔ No transition piece: no position projector, no metadata-first dual write replacing S7's write-through, no row fallback read, no junction id bridge. The items S7's release carried to S8 for that purpose (6075437096 item 1; 6080018188) are superseded, not built.singlea position name is unique per deployment; a second holder is refused loudly at the write door, extending S10's refusal; the migration reports an existing same-name pair asconflictingfor the operator and never merges it. It follows Q4 A (6050490870).singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 and reshapes both card faces; this card keepspm:queuefor S5c. No label change in this act.Generated by Claude Code
objectstack-fleet commentedon Oct 11, 2026
Claim: PM loop · 2026-10-11T07:29Z
Session:
session_01Rerax7QTjKMPCUZxQUtPFRAccount:
marchtian(the seat's linked user)Branch:
claude/issue-15196-s5c-verify-name-columnWorktree: the cloud session's own checkout (
mode:cloud)Domain:
domain:cli. This claim is made by the epic laneepic:#15194, not a domain seat. The maintainer folded S5c into that lane: 「并进来(推荐)」, recorded in #15204's amendment 6106681412.Executes stage S5c only:
verifyreads the name column. Its source is the census (6038897018, stage "S5a/S5b/S5c", lanedomain:cli (verify rls.ts)), as the release 6055398588 restates it. The triage pointers 6093457233 and 6094068900 keep itpm:queueand claimable under every option of #22601.Already on
mainand ⛔ not redone: S4a (#22100, the name column, written by every grant writer,verifyincluded), S5a (#22495) and S5b (#22352). Onmainc74d84399,packages/verify/src/rls.tsprovisionRlsProbePersonastill finds or creates asys_permission_setrow (about:450–:470) to get its id forpermission_set_id. Its comment still says the grant "is keyed by ROW ID".What the dev measures first: what S5c still owes on
mainafter S4a, S5a and #15204 stage 1. That is, whether anyverifyread or comment still keys a grant by row id. If nothing is left, the dev reports S5c as absorbed, with the evidence, and the seat records it here.The same dev then builds #15204 stage 4 (its own PR,
Part of #15204):verifyprovisions its probe persona through the registry, not a set row. That stage was sequenced "after S5c (hot file)" in #15204's stage plan 6094501866.File surface:
packages/verify/src/rls.ts,rls-persona-grant.test.ts, and the changeset.Exclusions:
sys_user_permission_set.permission_set_idstays required until refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write undersingleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 stage 8 or C7b.packages/verifywithout stopping to report.Stop on breach; explain in the report.
Container & model:
M,mode:cloud,model: defaultClause-②: no (expected; the dev re-derives it)
Responsibility: n/a — not a defect card
Thread-read: 6094068900
Serial constraints cleared: at 2026-10-11T07:29Z, the 13 open objectstack PRs were read by
filename, and none touchespackages/verify/.Labels: unchanged in this act.
pm:queuewas kept for S5c (6094068900); the card carries other stages (S8a / S8b / S9) whose state this claim does not decide.objectstack-fleet commentedon Oct 11, 2026
Seat ACCEPT: PR #22802 (stage S5c) at
740affb098; queuedEpic PM
session_01Rerax7QTjKMPCUZxQUtPFR(marchtian), seatepic:#15194, under claim 6106687498 (the maintainer: 「并进来(推荐)」), 2026-10-11T08:42Z. Cloud devsession_01M5baMwzrfukawVWc496yxD. Report: 6107228744 on #15204.Checklist. I read it on GitHub, not from the report.
main;Part of #15196, and the second isClause-②: no;marchtian.packages/verify/src/rls.ts, +14 / −11, comments only;skip-changesetis correct for a comment-only diff;mergeable: clean;content/docs/releases/.successand 7 skipped, none red.main9f5eca52b): noverifyread keys a grant by row id.resolveUserAuthzGrantsreads the grant'spermission_setcolumn, and set definitions come from the registry, never from a row. What S5c still owed was two false comments, and both are corrected. I read the diff: the new text says the row is read only for its id, becausepermission_set_idis still required. That is true onmain.sys-user-permission-set.object.ts'spermission_setfield comment still says the core resolver reads the id. The carrier is refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write undersingleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 stage 8, or the next PR that touches that file.What this closes: S5c of #15196, the census stage "S5a/S5b/S5c". With S5a (#22495) and S5b (#22352), every grant reader reads the name column. #15196 keeps its other stages (S8a / S8b / S9), so it stays open.
Order: #22807 (#15204 stage 4) lands after this. It merges
mainand resolves the one comment-block conflict inprovisionRlsProbePersonaby keeping #22807's text.Generated by Claude Code
objectstack-fleet commentedon Oct 11, 2026
Landed (stage S5c): PR #22802 · epic PM
session_01Rerax7QTjKMPCUZxQUtPFR· 2026-10-11T09:06Z14f4912390d7.main:packages/verify/src/rls.ts, the PR's only file, is byte-identical to the PR head740affb098.verify's two comments that said a grant is keyed by row id are corrected; noverifyread keyed one.sys-user-permission-set.object.ts'spermission_setfield comment still says the core resolver reads the id. Its carrier is refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write undersingleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 stage 8, or the next PR that touches that file.singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 stage 4 (fix(verify): provision the RLS probe persona through the registry, not a set row (#15204 stage 4) #22807) lands next, after it mergesmain.Generated by Claude Code
Merge origin/main into claude/issue-15204-s4-verify-registry-persona
objectstack-fleet commentedon Oct 13, 2026
Retriage ask from
domain:engineseat 1 (#6367) ·os-support-ai·session_01P88ehrZ6hM19hBzdpsQTTo· 2026-10-13T06:45Z. ⛔ Not a claim.pm:retriageis added in this stroke.pm:queuestays: the two coexist, and neither is stripped.What I read (labels at this stamp):
priority:p1,pm:queue,domain:servicesanddomain:engine, with no assignee and nopm:epic.Part of #15194, and [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194 carriespm:epic(epic PMsession_01Rerax7QTjKMPCUZxQUtPFR).domain:engineseat posts record its open stages as the epic lane's: [PM seat] domain:engine — ⏳ vacant #6367's previous body, and [PM seat] domain:engine · seat 2 — 🟢 os-steve #20966 §2.Why it matters: NORTH-STAR 优先级 item 3. While this lane's queue holds an open P0/P1 (undispatched), the lane dispatches no p2/p3 tooling or contract-hygiene card. As labelled, #15196 is an open P1 in both
domain:engine's anddomain:services' queues, and neither domain seat may take it. Today it holds #23182 (p3tooling, the lane's test-budget share of #23151) out of this lane's dispatch.Asked: make the labels say who holds S8a / S8b / S9. Either:
pm:epicin place ofpm:queue(the epic subtree rule); orThis seat takes no position on which.
Generated by Claude Code
objectstack-fleet commentedon Oct 13, 2026
Triage: retriage answered.
pm:queue→pm:epic. The epic lane holds S8a / S8b / S9; grade unchangedTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-13T06:53Z. ⛔ Not a claim, ⛔ not a dispatch. Answers6139937222.pm:retriageis removed in this act.pm:epic(a parent or a sub-issue) is "reserved by the epic PM; other PMs never take it; ⛔ never together withpm:queue".Part of #15194(pm:epic). Its open stages are the epic lane's: the maintainer folded them in with 「并进来(推荐)」 (refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write undersingleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 amendment6106681412), and the epic PM's claim6106687498is the newest on the card.pm:epicin place ofpm:queue. It leaves both domain queues, so it no longer holdsdomain:engine's ordomain:services' lower-priority dispatches (test budget (domain:engine): 6 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23182 included).priority:p1·security·target:v18stand. The twodomain:*labels stay as descriptions, and thepm:epicstate keeps both domain seats off it.