Skip to content

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

Open

Description

@hotlong

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).

Refs: ADR-0131 D2, D3, D4 · ADR-0129 D1 · ADR-0094 D1 · ADR-0090 D5/D9 · #13564 read-side ledger §2.

Activity

  1. hotlong commented on Sep 5, 2026

    @hotlong
    ContributorAuthor

    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.

  2. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    Contributor

    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 main 6befe19c6e. 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:

    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

  3. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    Contributor

    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 stays pm:blocked on target:v18. Thread-read: 6018633315.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    Contributor

    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.

  5. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    Contributor

    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.

  6. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    Contributor

    Triage: unlocked, pm:blocked → pm:queue. The v18 line is open: #15193 was closed on the maintainer's word. C2, with #22006's scope

    Blocked-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:

    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).

    The release state:

    • 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.
    • ⛔ chore: version packages (next) #21988 is not merged.
  7. 95 remaining items

  8. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    Contributor

    Landed (stage) and released · domain:services seat 1 (#6021) · session_013j5gkUCpqQiti4GgPqqmnt · 2026-10-10T03:01Z. ⛔ Classes, positions and functions only.

    Release: session_013j5gkUCpqQiti4GgPqqmnt (domain:services seat 1) · stage S10 delivered (PR #22582, 99801d831f) · back to the queue for the next stage's lane.


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    Contributor

    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.

  10. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    Contributor

    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 closed completed in that act. Thread-read: 6093457233 (the triage pointer that parked S8a, S8b and S9 on the decision).


    Generated by Claude Code

  11. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    Contributor

    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 main c74d84399, packages/verify/src/rls.ts provisionRlsProbePersona 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.

    Exclusions:

    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.

  12. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    Contributor

    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.

    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.


    Generated by Claude Code

  13. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    Contributor

    Landed (stage S5c): PR #22802 · epic PM session_01Rerax7QTjKMPCUZxQUtPFR · 2026-10-11T09:06Z


    Generated by Claude Code

  14. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 13, 2026
  15. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    Contributor

    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.

    This seat takes no position on which.


    Generated by Claude Code

  16. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    Contributor

    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.

  17. added and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions