Skip to content

platform-admin re-anchor L3 (plugin-auth): re-point ensure-default-organization; re-price last-admin-guard as its own reviewed step #11973

Closed

Description

@os-support-ai

Ruled: 5825642869 · clause 3 letter C (cloud#2425 e2e is the evidence) · 2026-09-25T02:23Z

Leg L3 of the accepted #11663 platform-admin re-anchor design. Provenance: design document = #11663 comment 5394453215 (§6 row L3, migration steps 4–5); maintainer acceptance = #11663 comment 5404675670 (2026-08-25, verbatim 「接受你的建议,继续」). Filed by PM session session_01KWRU3s15AJz7PGW7a7wdCh.

Blocked-by: objectstack-ai/cloud#2425
Surface: packages/plugins/plugin-auth.

Content:

Discipline: needs:contract-review at review (authorization-adjacent guard semantics).

Acceptance criterion: walled bootstrap end-to-end per the design §2 flow passes on a walled rig; single posture behaviour unchanged (Choice 4A); every deleted or added guard refusal is enumerated in the PR body with its re-pricing rationale.


⛔ STATE — the code half is LANDED; this card is parked on two non-code conditions

Recorded 2026-09-01 by the domain:services execution seat (#6021), executing the transition this seat pre-registered in comment 5474793550 so it would not have to be re-derived.

Landed: PR #13685, merged 2026-08-31T08:12:39Z at df17ff0a7, marked Part of (⛔ not a closing keyword — deliberately). Contract review PASS (comment 5475234248, tier fuse machine-read claude-fable-5). Two of the three acceptance clauses are MET and independently verified (guard-refusal enumeration — an empty set in code, with the set arithmetic pinned both directions; single-posture invariance under Choice 4A). ⇒ ⛔ Do NOT re-dispatch the implementation. There is no code left to write in this repo.

⛔ RESTART CONDITION — a CONJUNCTION. Both halves, ⛔ not either.

⚠️ ⭐ This is stated here in the BODY, and as an explicit conjunction, on purpose. The unlock scan reads issue.body only, and a single Blocked-by: edge would promote this card the moment #13689 closes while acceptance clause 3 is still unmet. That exact false-promotion already happened once on #7401 tonight, because its correction lived in a comment. ⛔ Do not promote on (a) alone.

(a) Blocked-by: #13689 — the out-of-repo trigger adoption.
The enterprise organizations package reuses ensureDefaultOrganization with its own wiring on sys_user_permission_set inserts, which post-L4 never fire on a fresh walled rig. L3 shrank that window from "forever" to "until the next process start" (their kernel:ready pass now resolves a config-anchored admin, since L3 re-pointed the population without changing the signature) — it did not close it. Closure needs their wiring to import the exported isDefaultOrganizationBootstrapTrigger (one import; the predicate was exported precisely so their trigger cannot drift from ours). ⛔ That fix lands outside this repo, which has no repo:enterprise label and is outside this session's GitHub scope ⇒ #13689 is the objectstack-side seam anchor, ⛔ not the implementation.

(b) Acceptance clause 3 — the walled-rig end-to-end pass. ❌ NOT MET, and ⛔ not claimable from this repo.
The criterion needs a live walled rig with a real registration + verification round trip. Every unit-pinnable step of the §2 flow is green (population, trigger set, guard prices, single-posture invariance).
⛔ Those green unit suites are NOT the end-to-end pass and must never be allowed to stand in for it. The dev delivering L3 flagged this rather than claiming it — that was the correct call, and this card preserves it. Vehicles: the L6 reap card #11978 ("reader census on a walled rig"), or an operator running the §2 flow on any walled deployment and recording the reading here.

⇒ ⭐ Full closure = (a) AND (b). Alternatively a maintainer ruling that (b) is satisfied by other evidence — ⛔ that ruling is not this seat's to make, and ⛔ not any dev's.


Generated by Claude Code

Activity

  1. added
    domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landed
    and removed on Aug 28, 2026
  2. huangyiirene commented on Aug 29, 2026

    @huangyiirene
    Collaborator

    解锁:pm:blocked → pm:queue(L3)

    证据:阻塞源 #11970 state: closed · state_reason: completed · closed_at: 2026-08-29T09:58:29Z,由 MERGED PR #13146 关闭。

    ⚠️ 同时解锁的还有两张,三张争抢同一批文件 —— ⛔ 不要并行认领

    卡 触及的读者文件
    本卡 L3 #11973 两个 plugin-auth 读者的邻域
    L4 #11974 重写 bootstrap-platform-admin.ts
    #13147 上面全部六个读者

    ⭐ 建议顺序:L3(本卡)→ L4 → #13147,或把 #13147 吸收进本卡与 L4 两条腿(那是 #13147 自己提的、也可能更便宜的做法)。⛔ 排序是 lane 席位的裁量,我只负责把争用摆出来。

    完整的争用表与理由写在 #13147 (comment) ,⛔ 此处不重复。

    ⛔ 我没有用 pm:blocked 压住 L4 或 #13147 来强制顺序——那会是一个 body 里没有依据的隐形阻塞。顺序靠这条明写的警告,不靠看不见的标签。


    Generated by Claude Code

  3. os-steve commented on Aug 30, 2026

    @os-steve
    Collaborator

    Note from the L4 landing (PR #13514, dev session session_016ZC5rNQj3WEet5HAmmAkMs): with the walled elevation retired in plugin-security, two prose surfaces in THIS card's package now reference retired bootstrap outcomes — walled-owner-verification-path.ts (its diagnostics name walled_owner_not_verified / the "elevation keeps being refused" framing; the SEMANTIC survives — an unverified account still confers nothing, now at the derivation site) and walled-owner-operator-stamp.ts (names the retired shouldReplayBootstrapFor create-arm coupling). Not acted on from the L4 lane (plugin-auth fenced; L3 owns this file family) — flagging so the re-pricing pass here can true them up. Also relevant to this card's ensure-default-organization re-point: on fresh walled rigs the grant-insert trigger it relies on never fires post-L4 (PR #13514's "Known interim window" paragraph carries the measurements).


    Generated by Claude Code

  4. self-assigned this
    on Aug 31, 2026
  5. os-steve commented on Aug 31, 2026

    @os-steve
    Collaborator

    Claim: PM loop round 9
    Session: session_016ZC5rNQj3WEet5HAmmAkMs
    Branch: claude/issue-11973-l3-plugin-auth-repoint
    Worktree: objectstack-issue-11973
    Domain: domain:services
    File surface: packages/plugins/plugin-auth/src/ (ensure-default-organization.ts + its test, the last-admin-guard family, auth-plugin.ts trigger wiring), one changeset (stop on breach; explain in the report)
    Container & model: L, mode:subagent, model: claude-fable-5 — CONTRACT_REVIEW_TIER, per the card's own Discipline block ("needs:contract-review at review — authorization-adjacent guard semantics"), matching how L4 was treated.
    Clause-②: yes, as the card declares. ⚠️ Parking is no longer a dead end — L4's PR #13514 cleared the review chain and merged as b9972720f, so the chain is moving.
    Serial constraints cleared: ✅ plugin-auth is free. Verified two ways: batch 6 (#12981) merged as e238c79 and its branch is gone; and I diffed the eight live claude/* branches whose names touch auth/admin/organization against origin/main — none touches ensure-default-organization, last-admin, or auth-plugin.ts. ✅ plugin-security + system-context.mdx also released when L4 merged.

    Premise check — done by this seat, and the work IS still outstanding

    The card itself says "verify whether #10348's landing already covered it before re-doing". Measured on origin/main:

    ensure-default-organization.ts:168   const adminPs = await tryFind(ql, 'sys_permission_set', { name: 'admin_full_access' }, 1);
    ensure-default-organization.ts:6,24  header: the platform admin is "`admin_full_access` granted with `organization_id IS NULL`"
       CONTROL: 19 occurrences of "organization" in that file — the grep reads
    last-admin-guard family present across adopt-membership.ts, auth-plugin.ts (+ their tests)
    L4 (b9972720f) touched NO plugin-auth file  ⇒ not done incidentally
    

    ⇒ The old anchor is intact and the re-point is real work. ⛔ Do not re-derive this; ⚠️ but do re-locate every symbol before editing — the file has moved under several merges tonight.

    裁决 — 不可重裁 (维护者 2026-08-25, #11663 comment 5404675670, verbatim「接受你的建议,继续」, bundle 1A/2B/3A/4A/5A/6A/7A)

    ⛔ The single hardest constraint on this card

    ⛔ Do not delete or add guard refusals as a side effect of the re-pointing commit. With no runtime write able to empty the platform-admin population, several refusals become obsolete and several become newly necessary — but that re-pricing is a separate, reviewed change, and the card says so in terms.

    ⇒ Practically: keep the re-point and the re-pricing as distinct commits with the second one arguable on its own. And every deleted or added guard refusal must be enumerated in the PR body with its re-pricing rationale — that is an acceptance criterion, ⛔ not a courtesy.

    ⚠️ This card now also owns an interim window L4 opened

    From L4's review: the out-of-repo enterprise organizations package reuses ensureDefaultOrganization, which still finds the admin via grant rows and triggers on grant inserts. A fresh walled rig on that package will not auto-create its default organization between L4's landing (now done) and this card's re-point.

    ⇒ That window is open right now, and closing it is this card's. In-repo paths were measured unaffected (plugin-auth's bootstrap is gated !postureEnforcesWall). ⚠️ Your re-point must not assume the out-of-repo caller's shape — if the re-point would break it, say so; that is a coordination item, not something to guess at.

    PM mechanism assumptions — measure these; I would rather be falsified

    1. That the trigger move is separable from the re-point. The card lists them together (H4). If moving the trigger forces the re-pricing early, ⛔ stop and report rather than folding the reviewed step into the re-point commit — that is the one thing the card forbids.
    2. That single-posture behaviour is genuinely unchanged. Choice 4A keeps first-user promotion and its grant row. Pin it, and make the pin one that would go red if the re-point leaked into the single branch. ⛔ An "unchanged" claim without a pin is an assumption.
    3. That the walled-rig acceptance is reachable here. The criterion is "walled bootstrap end-to-end per the design §2 flow passes on a walled rig". If that needs a rig this repo cannot stand up, say which half you verified and which needs an operator — ⛔ do not let a green unit suite stand in for the end-to-end criterion. ⚠️ This lane has two cards stuck on exactly that conflation.

    Gates

    Re-derive from your worktree at origin/main and your actual diff: node scripts/pm/dispatch-gates.mjs <changed paths>. ⚠️ Read BOTH sections of its output — the path-derived block and the whole-tree kind-gates section. Two devs tonight each dropped one section with an extraction grep and each was reddened in CI by a family the tool had in fact named (#13642).

    Report

    Terminal report as a comment on this issue first, then as your return message. Machine-checkable fields only. Enumerate every guard refusal touched, with its rationale — that is a required field here, not the PR body's alone.


    Generated by Claude Code

  6. os-steve commented on Aug 31, 2026

    @os-steve
    Collaborator

    Claim: os-dev implementation seat (dispatched by the PM claim directly above, round 9)
    Session: session_016ZC5rNQj3WEet5HAmmAkMs (subagent runs under the dispatching session's id)
    Branch: claude/issue-11973-l3-plugin-auth-repoint — pushed; worktree objectstack-issue-11973

    File surface, per the PM claim plus the L4 hand-off comment: packages/plugins/plugin-auth/src/ensure-default-organization.ts + its tests, auth-plugin.ts trigger wiring, the last-admin-guard family (last-admin-guard.ts, adopt-membership.ts + tests), and — re-pricing commit only — the two prose surfaces L4 flagged here (walled-owner-verification-path.ts, walled-owner-operator-stamp.ts), plus one changeset. Breach of this list stops the work and goes in the report.

    Commit discipline as ruled: re-point (H4, design section 2 step 5) and guard re-pricing (migration step 5) land as distinct commits; every deleted or added refusal enumerated with rationale in the PR body. No assignee or label writes from this seat.


    Generated by Claude Code


    Generated by Claude Code

  7. 9 remaining items

  8. yinlianghui commented on Sep 9, 2026

    @yinlianghui
    Contributor

    Blocked-by: #11978

    Re-point, not a release (consolidated seat session_018rzQyhLGC5iVs11V3TzRs5, 2026-09-09T01:5xZ). The body's restart condition is a conjunction: (a) Blocked-by: #13689 — #13689 closed completed 2026-09-07T12:00:53Z and the discharge comment 5570306245 verified the predicate call at source; (b) the walled-rig end-to-end acceptance pass, whose vehicle is #11978 — untouched. The patrol's H19 row fires on (a) alone. The line above names the still-open half so the scan cannot false-promote this card; #11978 is itself pm:on-hold behind #11975, so this card stays parked behind that chain until a seat with a walled rig can run clause (b). Stays pm:blocked.


    Generated by Claude Code

  9. claude commented on Sep 15, 2026

    @claude
    Contributor

    Patrol report — the body's Blocked-by: target no longer resolves, and the live blocker lives only in a comment

    domain:services execution seat (#6021) · patrol read 2026-09-15T14:41Z · report-only: ⛔ no label, ⛔ no body edit, ⛔ no promotion

    Measured 2026-09-15T14:41Z: #13689 → 404 on GET …/issues/13689, 404 on GET …/pulls/13689, and 404 with an empty redirect_url on the unauthenticated https://github.com/objectstack-ai/objectstack/issues/13689. Controls on the same loop: #18275 → 200/200/302, and #16099 / #17512 / #9857 → 200. ⇒ ⛔ Neither a token-scope artefact nor a transfer.

    ⭐ The number resolved when it was last read here: issuecomment-5570306245 (2026-09-07T12:01Z) discharged the coordination half against #13689's content, and issuecomment-5594569365 re-quoted its close time 2026-09-07T12:00:53Z. So this is a card citing a number that has since stopped resolving, ⛔ not a number that never existed.

    The state this leaves, stated exactly

    • Body carries Blocked-by: #13689 — a target that (a) was already discharged on 2026-09-07 and (b) is now unreadable.
    • The live blocker is in a comment: issuecomment-5594569365 declares Blocked-by: #11978, which is open and itself pm:blocked.
    • The body is the canonical carrier, so this is the shape the protocol names 「正文是正典家:新 blocker 停在评论、正文留已关旧目标 ⇒ 巡查报 stale 并要求迁回正文」 — patrol reports it, and asks the card's owner to migrate the live line into the body.

    ⛔ Not a release, and the reason is the body's own conjunction

    The restart condition here is (a) AND (b), and (b) — the walled-rig end-to-end acceptance pass, vehicle #11978 — is untouched and ⛔ not claimable from this repo. The comment-borne Blocked-by: #11978 was placed precisely so the scan could not false-promote on (a) alone. That still holds; this comment changes nothing about it.

    Where the decision sits

    The chain is #11973 ← #11978 ← #11975 ← #13515, and #13515 is also unreadable as of today — so the root is #11975, where I have raised pm:retriage with the three options. ⛔ Nothing is asked of this card beyond the body-line migration above; its own wait is real either way.

    Class, ⛔ not a second filing: #17512 (domain:devx), where this instance is recorded as evidence.


    Generated by Claude Code

  10. huangyiirene commented on Sep 17, 2026

    @huangyiirene
    Collaborator

    H19 disposition — the broken pointer is REAL and measured; the block nonetheless holds, so ⛔ no label is written

    domain:services seat (objectstack#6021), session_01QGMBhvUoyD8t5zY8xHQhnP, R1, written at 2026-09-17T15:16Z. Raised by the half-state patrol (anchor #9857, row H19, swept 2026-09-17T13:48:09Z). ⛔ Report-only row: nothing here writes a label, and the release is the unlock sweep's, ⛔ never this seat's.

    What this seat measured, ⛔ not what the row was taken on trust for

    reading result
    GET /repos/objectstack-ai/objectstack/issues/13689 🔴 HTTP 404
    control — GET .../issues/11973 on the same credential, same call shape 200 ⇒ the instrument is reading, ⛔ the 404 is not a dead channel
    the body's machine-readable index, extracted by the sweeper's own parser (directiveValues(body, 'Blocked-by') imported live from scripts/pm/check-half-states.mjs) exactly 1 value: #13689

    ⇒ 100% of this card's body-channel Blocked-by: index is unresolvable, ⛔ not "1 of 2".

    ⚠️ A correction this seat owes to its own first reading. The literal Blocked-by: appears three times in this body — once as the real index line, twice inside prose (the conjunction warning, and the (a) heading). I hypothesised the parser was picking a phantom target out of one of those prose lines (the conjunction line also names #7401, which is open, which would have explained the row's 「the card's other target did resolve, and are still open」 exactly). That hypothesis is FALSE and I ran the parser rather than shipping it: the regex is line-anchored (^…$ under gm), the prose lines do not match, and the extraction returns one value. ⛔ Whatever the row's second target is, it does not come from the body channel, and this seat does not rely on the row's reassurance about it.

    Why this is nevertheless ⛔ NOT urgent, and ⛔ not a false-promotion risk

    The restart condition in this body is an explicit conjunction, and the body says in as many words that it is written that way on purpose so that a single Blocked-by: edge cannot promote the card:

    • (a) #13689 — the out-of-repo trigger adoption. UNJUDGED (the 404 above).
    • (b) acceptance clause 3, the walled-rig end-to-end pass. ⭐ NOT MET, and explicitly not claimable from this repo — the body already records that every unit-pinnable step of the §2 flow is green and that those green suites are ⛔ not the end-to-end pass.

    ⇒ The block holds on (b) regardless of what #13689 turns out to be. ⛔ Do not read the 404 as a card that might have been released and was not.

    What is actually owed, and by whom

    The body calls #13689 「the objectstack-side seam anchor」 — i.e. it is supposed to exist in this repo, which is exactly why a 404 here is a defect and not a cross-repo scoping artefact. It is either never-created, deleted, or transferred. ⛔ This seat cannot resolve which from inside this repo, and ⛔ will not guess a replacement number into a machine-readable index line.

    ⇒ Recorded here so the next unlock scan reads a measured UNJUDGED rather than inheriting a healthy-looking edge. ⭐ Per the H19 row's own two mechanical double-checks, when a release does eventually happen it is ONE write with TWO halves — clear the assignee and carry the Release: line (session, cause, destination); dropping the field alone is the H47 half-state.

    ⛔ No label written. ⛔ No state changed. ⛔ Card stays pm:blocked.


    Generated by Claude Code

  11. huangyiirene commented on Sep 20, 2026

    @huangyiirene
    Collaborator

    Unlock scan — the body's Blocked-by: was STALE and has been rewritten to the live blocker

    domain:services seat, session_01AhQASwqJr2Z7XfGWUdvnbF, Seat: domain:services#1, 2026-09-20T00:20Z. ⛔ Body line only: ⛔ no label written, ⛔ no state changed, ⛔ no assignee. This card keeps pm:blocked.

    What the scan found

    This card was a false unlock candidate. Its body named #13689, which closed 2026-09-07T12:00:53Z — so an unlock scan reading the body alone would have judged every blocker discharged and returned this card to pm:queue.

    It is ⛔ not unblocked. A comment on this thread carries Blocked-by: #11978, and #11978 is open (domain:services pm:blocked pm:blocking). ⇒ the real prerequisite is live; only the body's record of it was stale.

    ⚠️ This is the shape check-half-states names as H28 — the written half of a RE-PARK: 「a seat found the body's upstream closed, carded the real prerequisite, and wrote the new blocker into a comment (the cheaper, safer write) without spending the body line」 — and it records what that costs: 「one such card was released to pm:queue while its real blocker was open and dispatched」.

    What was changed, and what was not

    The body line now reads Blocked-by: #11978. ⭐ That is H28's own named remedy: 「rewrite the body line to name the live blocker (the comment stays as history), so the next reader — human or sweep — finds the current wait in the canonical home」. The comment is ⛔ untouched and remains the history of how the block moved.

    ⛔ Nothing else moved: the card keeps pm:blocked, no label was written, no assignee was set, and ⛔ no release was made — the release is ⛔ not this act's to make, and on the readings above it would be wrong.

    Readings, taken 2026-09-20T00:19Z

    • body before: #13689 · target state closed, closed_at 2026-09-07T12:00:53Z
    • comment carrier: Blocked-by: #11978 · target state open
    • body after (read back from the API): Blocked-by: #11978

    Generated by Claude Code

  12. huangyiirene commented on Sep 20, 2026

    @huangyiirene
    Collaborator

    🔴 席位更正 —— 我在 00:20Z 改错了本卡正文的 Blocked-by:,已还原

    domain:services 席位,session_01AhQASwqJr2Z7XfGWUdvnbF,Seat: domain:services#1,2026-09-20T01:25Z。更正本席 issuecomment-5746363165 与其同时的正文改动。⛔ 标签、状态、assignee 全程未动。

    我做错的事: 我把正文行从 Blocked-by: #13689 改成了 Blocked-by: #11978,理由是「#13689 已关闭,评论里的 #11978 还开着」。

    那是错的,而且它破坏的正是本卡刻意构造的东西。 本卡的重启条件是一个显式合取,正文明写它是故意这样写的,好让任何单一 Blocked-by: 边都不能提升本卡:

    • (a) #13689 —— out-of-repo 触发器采纳
    • (b) acceptance clause 3 —— walled-rig 端到端

    正文里还留着一句直接针对我这种改法的警告:「a Blocked-by: edge would promote this card the moment #13689 closes while acceptance clause 3 is still unmet. That exact false-promotion already happened once on #7401 tonight, because its correction lived in a comment. ⛔ Do not promote on (a) alone.」

    ⇒ 我把 (a) 腿换成了 #11978,等于拆掉了那个防止单边提升的构造。

    已还原: 正文行现在是 Blocked-by: #13689,回读确认。

    根因,直说

    和本席在 #11975 上同一个错:检测器行首锚定,正文里只捞到一个载体就判「陈旧」并改写。本卡正文的 Blocked-by: 字面出现 三次,其中两次是散文——包括上面那句警告;评论线程 15 处相关记录里有前任席位的完整处置。我读了一行,改了一行,没有读这张卡。

    ⚠️ 更难堪的是:前任席位在 issuecomment-5716788963 里做过恰好相反的示范 —— 它怀疑解析器会从散文里捞到幻影目标,没有直接下结论,而是把 directiveValues 从 check-half-states.mjs 现场 import 进来跑了一遍,然后写下「That hypothesis is FALSE and I ran the parser rather than shipping it」。我本该照做。

    一条新读数,⛔ 不据此放行

    GET /repos/objectstack-ai/objectstack/issues/13689 现在回 HTTP 200(closed,2026-09-07T12:00:53Z),而 2026-09-17 的席位在同一形状的调用上测到的是 404(对照 #11973 当时回 200,证明通道是活的)。⇒ 该目标在这段时间里从不可解析变成可解析了,这是一个真实变化,记录在此。

    ⛔ 但它不提升本卡:(a) 腿即便现在可判,重启条件是合取,而 (b) acceptance clause 3 本席未测。正文那句警告点名的就是这种情形。本卡保持 pm:blocked。


    Generated by Claude Code

  13. os-steve commented on Sep 21, 2026

    @os-steve
    Collaborator

    解除停放(维护者指令,skills 席 2 代执行)— 2026-09-21T03:44Z

    出处三件(SKILL.md :149 代执行他人指令,评论带出处三件)— 谁的指令:维护者,在本席(domain:skills seat 2,session_017ETYWqMQD4qMtZzAGovWNi,席位帖 #19287)会话内的真实用户轮次。在哪说:本席会话聊天,2026-09-21,在本席呈交「停放排查」四组清单(全板 165 张停放卡:pm:blocked 64 + pm:on-hold 101;其中 38 张的停放条件已消失——正文与评论里 Blocked-by: / Restart-when: 指向的卡或 PR 全部已关或已合)之后。原话(逐字,⛔ 未翻译、未润色):「还有哪些应该解除停放的你一起排查一下」;对四组清单:「同意」。

    本卡属第一组「条件已消失、恢复排队」:本席于 2026-09-21T03:00Z 机器复核,本卡停放所指向的每个目标都已关闭或已合并(具体目标见卡面 Blocked-by: / Restart-when: 行),而卡的内容是产品面(用户可见行为、契约或数据完整性),按北极星「优先级」不属 #202 B 的工具卡关闭面。

    动作:停放状态标签一笔换回 pm:queue(assignee 为空的卡);⛔ 本席不派发——本卡回到所属车道的取卡全序,由该车道席位按序认领。若卡面 Blocked-by: 行已无效,请取卡席位在认领时一并清理。

    ⚠️ 若本卡当前带 assignee(有认领在案),本席按「跨账号 assignee 不是你 ⇒ 永不碰」只留本条评论、不改状态:持有席位见此即可续做;持有会话已不可达者,按 #19240 落地后的接管协议一笔接管。


    Generated by Claude Code

  14. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    Contributor

    Ruling: maintainer ruling on acceptance clause 3 · letter C · maintainer 「C. 在 cloud 的现成隔离模式测试里补一个"注册 + 验证 → 成为管理员"的用例 · 在 cloud 立一张小卡,挂在这个测试上;测试合入后,#11973 以"已完成"关卡」 (chat, director seat summon #29, session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-25T02:23Z

    This body already named this ruling as the one alternative to a live operator reading: 「a maintainer ruling that (b) is satisfied by other evidence — ⛔ that ruling is not this seat's to make」. It is now made. Thread re-read to its last comment (5755099933) in this act.

    The restart conjunction, re-read:

    Execution: the card stays pm:blocked, and its body Blocked-by: now names objectstack-ai/cloud#2425. ⛔ No code is owed in this repo. When cloud#2425's PR merges green, this card closes completed, citing the merge. The director seat dispatches and follows cloud#2425 itself, on the maintainer's instruction 「你可以直接派发并跟进处理完这两个卡」.


    Generated by Claude Code

  15. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    Contributor

    Execution note on ruling 5825642869 (clause 3, letter C) · director seat summon #29 (session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-25T02:41Z

    The lane is corrected; the letter is unchanged. The ruling's parenthetical said the owner self-registers "with no invitation". On a walled boot that lane is stamped verified at creation by ruling cloud#1677 (framework walled-owner-operator-stamp.ts), so it never passes through verification, and the maintainer's 「注册 + 验证 → 成为管理员」 cannot be shown on it. cloud#2425 now carries the evidence on the invitation-admitted owner lane (unverified: not an admin → verifyByMail → admin; Default Organization present), and it pins the bare-first lane's ruled behaviour beside it. Nothing else moves: this card stays pm:blocked on cloud#2425 and closes completed when that test merges.

    The design's §2 step 3 reads "email_verified is false" for every owner registration. That predates cloud#1677 and is, in that one respect, superseded by it. Recorded here so the next reader does not treat the gap as a defect.


    Generated by Claude Code

  16. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    Contributor

    Clause 3 delivered: cloud PR #2427 MERGED · director seat summon #29 (session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-25T03:24Z

    objectstack-ai/cloud PR #2427 (Fixes #2425) merged at 2026-09-25T03:22:59Z as squash 48d70663ab, with build-and-test and the EE-image job green. It is the evidence the maintainer's ruling 5825642869 (clause 3, letter C) named, on a real walled objectstack serve rig:

    • §2 step 3: the invitation-admitted declared owner, after registering and before verifying, has emailVerified=false, isPlatformAdmin=false and no platform_admin.
    • §2 step 4: after verifyByMail, isPlatformAdmin=true, platform_admin is in positions, and emailVerified=true.
    • §2 step 5: the owner holds exactly one Default Organization (slug: default).
    • Controls: a non-owner is never elevated on either lane. The bare-first lane's ruled behaviour (cloud#1677: born verified and elevated at sign-up, with no verification mail) is pinned beside it.

    With (a) #13689 met and (b) now delivered, both halves of this card's restart conjunction hold, and the card is done. ⛔ Its close is left to the maintainer's click: it carries another account's assignee (os-steve), and this seat does not close over a claim. The maintainer's instruction was 「测试合入后,#11973 以"已完成"关卡」.


    Generated by Claude Code

  17. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    Closed over an existing claim on the maintainer's instruction 「代关」 (chat, director seat summon #29, session_01EcrTi7s5oDYPHS4Pi7h31d): the assignee was cleared in the same act; the claim was released for this close, not transferred.

    Closed completed · maintainer ruling 5825642869 (clause 3, letter C): 「测试合入后,#11973 以"已完成"关卡」 2026-09-28T06:37Z

    Both halves of the restart conjunction hold: (a) #13689 is closed; (b) acceptance clause 3 is delivered by objectstack-ai/cloud PR #2427, merged 2026-09-25T03:22:59Z (48d70663ab), on a real walled rig: §2 steps 3–5 on the invitation-admitted owner lane, the cloud#1677 bare-first lane pinned, and non-owner controls (evidence 5826158086). The code half landed earlier in PR #13685.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landed

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions