Skip to content

platform-admin re-anchor L8 (cloud seam): control-plane env injection + invite-only interaction — cloud seat leg, designed blind #11977

Description

@os-support-ai

Leg L8 of the accepted #11663 platform-admin re-anchor design — a seam card: the fix lands in the cloud repo, which is not reachable from the filing session, so per the cross-repo rule it lives here with repo:cloud. Named reader: the cloud execution seat, at its queue-scan step — this card is its instruction to open the cloud-side issue and link it back here. Provenance: design document = #11663 comment 5394453215 (§6 row L8, §9 NOT MEASURED disclosure); maintainer acceptance = #11663 comment 5404675670 (2026-08-25, verbatim 「接受你的建议,继续」). Filed by PM session session_01KWRU3s15AJz7PGW7a7wdCh.

Blocked-by: #11970
Blocked-by: #11974

Content (cloud side): control-plane injection of OS_PLATFORM_OWNER_EMAIL per deployment (list form, Choice 2B); the invite-only interaction — self-registration must never confer platform admin, only configured verified emails do (this is the structural fix for cloud#1509's class); coordinate with the cloud seat's #1614→#1509 train, ⛔ do not collide with its in-flight acceptance.

⚠️ This leg was designed blind — the designer could not measure the cloud repo. The cloud seat's review of the design's cloud assumptions is a required first step, and contradictions come back as a fork on #11663, not as silent adaptation.

Acceptance criterion: a cloud-repo issue exists carrying this leg with a back-link here and Blocked-by: on its own repo's spellings; this card then flips to track it and closes when the cloud leg lands.

Activity

  1. claude commented on Aug 31, 2026

    @claude
    Contributor

    分诊解锁 · pm:blocked → pm:queue —— 阻塞已过期

    本轮「停放面专项」由 check-half-states.mjs 的 H19 扫出:本卡的 Blocked-by: 目标已全部关闭,阻塞比阻塞方活得久。

    ⛔ 本席没有采信 sweep 的那一行,逐个目标直读复核:

    Blocked-by: 目标 直读结果
    #11970(L2) closed / completed
    #11974(L4) closed / completed

    ⇒ 声明的前置条件已全部兑现 ⇒ 解除阻塞,回 pm:queue。

    ⚠️ 本席只解除了「机器可读的那条阻塞线」。若本卡另有未写进 Blocked-by: 的实际前置(设计未定、上游 PR 在飞、等某人一句话),⇒ 请补一条 Blocked-by: 或 Restart-when: 再挂回 pm:blocked,⛔ 不要只把标签改回去 —— 一条没有机器可读出口的阻塞,与被遗弃无法区分(H9 的判据)。

    ⚠️ 本卡是链上的 L8(cloud seam),与 #11975 / #11976 同批解除。⚠️ 它触 cloud 面 —— 本席 R+58/R+61 实测:cloud 的 API 通道可达,而 git ls-remote 仍 128。⇒ 接手方若需读 cloud 源码,先确认自己的通道,⛔ 不要假设「仓不可达」(它的 issue 面是活的,有 59 张 open)。


    Generated by Claude Code

  2. self-assigned this
    on Sep 3, 2026
  3. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    Contributor

    Claim: PM loop round R35 (wave 3) — the cloud seat's review this leg was filed for
    Session: session_017Wu48ZSjk7HJjyJmGNBtUk
    Branch: none — this card's deliverable is a review of the L8 design assumptions against cloud's tree and, if they hold, a cloud-repo issue carrying the leg (back-linked here); a fork on #11663 if they do not. No code in this dispatch.
    Worktree: cloud-readings-l8 (detached at cloud origin/main, read-only)
    Domain: repo:cloud (whole-repo seat, seat post #6026 — the named reader)
    File surface: none (reads only)
    Container & model: M design review, mode:subagent, model: opus
    Clause-②: no
    Serial constraints cleared: n/a — no writes to the tree. Coordination note from the card body: the cloud#1614→#1509 train it warns about is finished (cloud#1509 closed-completed 2026-08-30 via PR #1656 + objectstack#11343), so the "do not collide with its in-flight acceptance" caveat is moot and is verified rather than assumed by the dev.


    Generated by Claude Code

  4. claude commented on Sep 3, 2026

    @claude
    Contributor

    Cloud seat review of L8's cloud assumptions — result: FORK, no cloud card filed

    repo:cloud execution seat (seat post #6026), session session_017Wu48ZSjk7HJjyJmGNBtUk, PM round R35. This is the review the L8 card names as its required first step, and the leg was designed blind (design §9.1: "cloud#1509 / cloud#1614 — NOT MEASURED").

    Refs for every reading below

    Dependency ancestry — the framework surface L8 consumes is already inside cloud's pin. L2 landed as PR #13146, merge 33184fd29289cab2527dc295df4a67d6e17c013a; L4 landed as PR #13514, merge b9972720f843033d24ec657f3d17b75435fca74a. git merge-base --is-ancestor returns exit 0 for both against 655b106c. So a cloud card would carry no Blocked-by: on #11970 / #11974 — that half of the L8 gate is already discharged. Confirmed at the pin by reading the code, not the cards: packages/core/src/security/platform-admin.ts exists with parsePlatformAdminEmails / PLATFORM_ADMIN_EMAIL_SEPARATOR and fail-the-whole-variable-closed semantics; resolve-authz-context.ts:754-786 is the §6b-config anchor; plugin-security/src/bootstrap-platform-admin.ts:415-488 is the walled no-mint branch.


    Per-assumption table

    # design assumption (as the L8 row states it) measured on cloud 58c20e2c / pin 655b106c verdict
    A1 cloud can inject OS_PLATFORM_OWNER_EMAIL per deployment It already does, for the one plane that is walled. apps/cloud/cloudflare/worker.ts:240 forwards the variable; apps/cloud/wrangler.toml:243 and :396 set it. The plane is walled because apps/cloud/cloudflare/worker.ts:484 hard-codes OS_MULTI_ORG_ENABLED: 'true' into the container envVars defaults for every environment that Worker deploys. holds — and already landed, before this leg was filed
    A2 ...per tenant environment ("the control plane injects env into a tenant environment's runtime") ⛔ No such seam, and none is representable. One tenant-runtime container hosts up to 50 per-environment kernels in one process (apps/objectos/cloudflare/worker.ts:283 OS_KERNEL_CACHE_SIZE: '50', :284-308 a 4h LRU, packages/objectos-runtime/src/kernel-manager.ts), and env is assembled once per container at construction (apps/objectos/cloudflare/worker.ts:169 FORWARDED_ENV_KEYS, :279 envVars, :413 forwardWorkerEnv). A per-environment value cannot be expressed; a runtime-wide one names the same administrator across every tenant it hosts. CONTRADICTED
    A3 list form ("Choice 2B") is read at cloud's pin Yes at the framework, and cloud has zero code readers of its own to widen: the only cloud occurrences are the forward-list entry, the wrangler values, deploy templates/docs and test env assignments. objectstack#13147 (the five single-value readers) is closed/completed. holds
    A4 the source of truth for "the platform owner(s) of this deployment" on the cloud side For the control plane: the env var (A1). For a tenant environment it is not an env var at all — it is sys_environment.metadata.ownerSeed.email, derived from the creating control-plane sys_user at provisioning time (packages/service-tenant/src/environment-provisioning.ts:1062-1071), replayed at cold boot (packages/objectos-runtime/src/artifact-kernel-factory.ts:1446-1500). adjusted — it is a control-plane DB row, not config
    A5 that email is verified at the point cloud would inject it ⛔ No. environment-provisioning.ts:1064-1071 reads u.email and never email_verified; a repo-wide grep for email_verified|emailVerified across packages/service-cloud/src, packages/service-tenant/src, packages/objectos-runtime/src and apps/cloud/cloudflare returns 6 hits, none of them a check — and one of them is packages/objectos-runtime/src/environment-owner-seed.ts:91, which stamps email_verified: true into the tenant DB unconditionally. The only verification lives a layer up as a Worker default (apps/cloud/cloudflare/worker.ts:461 OS_AUTH_REQUIRE_EMAIL_VERIFICATION: 'true'), which is not a check at the seam and is overridable per deployment. CONTRADICTED
    B1 invite-only, control plane: self-registration must not confer platform admin Holds, and is already consumed. packages/service-cloud/src/control-plane-preset.ts:531 declares membershipPolicy: 'invite-only' (host-level, so packages/organizations/src/membership-policy-gate.ts accepts it). Cloud's own pin tests were already rewritten to the L4 contract by the pin bump PR #1817: apps/cloud/test/signup-org-flow.test.ts:399-413 and apps/cloud/test/unscoped-control-plane-tenant-wall.test.ts:2891-2916 now assert the grant row's absence and name objectstack#13514 for why. holds — already landed
    B2 invite-only, tenant runtime: "only configured verified emails confer platform admin" ⛔ False on cloud by design, and the framework currently agrees with cloud rather than with this sentence. The tenant runtime is not walled: git grep -c for OS_TENANCY_POSTURE|OS_MULTI_ORG_ENABLED|OS_PLATFORM_OWNER_EMAIL over the whole apps/objectos tree returns 0 (positive control: the same pattern returns 5 in apps/cloud/cloudflare/worker.ts and 7 in apps/cloud/wrangler.toml), and packages/objectos-runtime/src/artifact-kernel-factory.ts:841 gates multi-org on the demoted boolean, which is absent ⇒ single. Under Choice 4A the framework therefore keeps first-user promotion and its grant row there on purpose, and cloud's two owner-admin doors both write exactly that row. CONTRADICTED as framed
    C "do not collide with the #1614→#1509 train" Moot, verified rather than assumed: cloud#1509 closed completed 2026-08-30 (PR #1656, then #1684), and its closing comment records objectstack#11343's fix c0714eb5 as an ancestor of the then-pin. Nothing is in flight on that surface. holds (spent)

    The two contradictions, mechanically

    1. There is no per-environment env seam, and cloud's per-environment platform admin is a GRANT ROW.

    packages/objectos-runtime/src/env-owner-admin-grant.ts:67 ensurePlatformAdminGrant inserts an unscoped sys_user_permission_set row pointing at admin_full_access — :91 organization_id: null — under { context: { isSystem: true } }, best-effort, errors swallowed (:95-97). That is byte-for-byte the composite runtime FK the design's H2 describes and the legacy anchor #13515 deletes the read of. Two doors reach it, and neither is OS_PLATFORM_OWNER_EMAIL:

    • packages/objectos-runtime/src/auth-proxy-plugin.ts:319 — the console "Open" button's sso_as_owner handoff, elevating on payload.admin === true from a control-plane-signed token (and JIT-creating the user with emailVerified: true at :301);
    • packages/objectos-runtime/src/artifact-kernel-factory.ts:1461-1464 → registerEnvOwnerAdminGrant (env-owner-admin-grant.ts:126) — a sys_user-insert middleware that elevates the row whose email matches ownerSeed.email and reads verified (:143-147).

    So the cloud analogue of "the deployment declares its administrators in config" is "the control plane recorded who created this environment, in a row". The L8 row's content — inject the variable per deployment — has no target on this plane.

    2. The verified-email pin does not survive the cloud seam. The middleware at env-owner-admin-grant.ts:143-147 genuinely requires email_verified on the tenant row — but the tenant row it reads is frequently one cloud itself wrote with email_verified: true hard-coded (environment-owner-seed.ts:91), from an address the control plane copied without ever consulting emailVerified (environment-provisioning.ts:1064-1071). The framework's P1 is satisfied in form on the tenant side while the verification decision was never actually made anywhere. This one is independent of the fork and is worth fixing whichever way the fork is ruled.

    Sequencing correction — the trigger is #11979 (Choice 4B), not #13515 (L5). #13515's acceptance criterion explicitly protects single-posture standing ("single-posture first-user standing is unchanged unless #11979 landed first"), and the pin's deprecation pointer is posture-keyed for the same reason (resolve-authz-context.ts:790-828). So cloud's grant-row doors are safe today and safe through L5. They go dead when Choice 4B lands — and they go dead silently: ensurePlatformAdminGrant swallows its own errors, and after 4B the row it writes simply confers nothing. The observable symptom would be env owners losing Setup/Studio with no error anywhere.


    Collision list (open cloud cards and PRs on this surface)

    Read from the REST list endpoints on objectstack-ai/cloud (49 open issues, 7 open PRs), filtered locally on OS_PLATFORM_OWNER_EMAIL|platform_admin|platformAdmin|invite-only|walled|emailVerified|email_verified|ownerSeed|platform-admin|11663.

    card relation
    cloud#1332 (pm:blocked, finding) — "the hosted tenant runtime never reads OS_TENANCY_POSTURE; artifact-kernel-factory.ts still gates on the demoted OS_MULTI_ORG_ENABLED boolean" Adjacent and load-bearing. It measures the same absence B2 rests on and already frames the two defensible end states (make the tenant runtime posture-aware, or rule it posture-blind by design). A cloud L8 card must not re-decide that; it depends on it.
    objectstack#11225 (security, repo:cloud, dispatched — being measured in this container now) Same neighbourhood, different predicate: clause 2 of the #11184 ruling is about auto-join to the Default Organization in the enterprise packages/organizations; L8's B is about platform-admin standing. Cited, not duplicated, and deliberately not re-measured here.
    cloud#1452, cloud#1765, cloud#1331, cloud#874 Walled/isolated-posture neighbours (tenant Studio exposure, position picker, the hotcrm SaaS shape decision, ADR-0105 group mode). None touches the owner-email or platform-admin anchor.
    open PRs #1883 #1882 #1881 #1880 #1878 #1834 #1746 File lists checked individually: none touches env-owner-admin-grant.ts, environment-owner-seed.ts, environment-provisioning.ts, the worker env assembly, or the wrangler owner vars. No PR collision.

    Why no cloud card, and what the fork asks

    Per this card's own instruction — contradictions come back as a fork on #11663, never as a silent adaptation — I have posted the fork there and filed nothing in objectstack-ai/cloud. Filing now would require me to pick between two architectures for cloud's per-environment platform admin, which is exactly the decision the fork escalates.

    The card is drafted and mechanical to file the moment the fork is ruled. Recommended shape:

    One residue that is not a cloud card: the objectos-ee deploy surfaces still describe the variable as a single address (apps/objectos-ee/deploy/composed-artifact-boot.md:76,114, apps/objectos-ee/deploy/README.md:125). Under Choice 2B they are incomplete rather than wrong, and the operator runbook for that variable is L7's surface (#11976), not cloud's — recorded here so it is not lost, deliberately not filed.


    Generated by Claude Code

  5. claude commented on Sep 3, 2026

    @claude
    Contributor

    Fork posted — pointer. The two contradicted assumptions from the review above went back to the design as a fork on the L8 row: #11663 comment 5521187539 (#11663 (comment)). It carries the four-axis pass and the recommendation (option B — declare the owner on sys_environment.metadata.ownerSeed and keep one derivation site; option A named as the time-boxed interim), plus the sequencing correction that the cloud leg's real dependency is #11979 (Choice 4B), not #13515 (L5).

    ⛔ No cloud card filed, per this card's own instruction for the contradicted branch. The recommended card shape, its scope, its acceptance criterion and its Blocked-by: analysis are written out in the review above and are mechanical to file once the fork is ruled. This card's acceptance criterion ("a cloud-repo issue exists carrying this leg") is therefore not met and should not be marked as met — the leg cannot be carried into cloud as written.


    Generated by Claude Code

  6. claude commented on Sep 3, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 11977,
      "status": "needs_decision",
      "branch": null,
      "pr": null,
      "premise_still_valid": false,
      "summary": "Review-only dispatch (no code, no branch, no PR). The L8 row's cloud assumptions were measured against cloud origin/main 58c20e2c and its framework pin 655b106c; two are contradicted, so the leg went back as a fork on #11663 (comment 5521187539) and NO cloud card was filed. What HOLDS and is already landed before this leg was dispatched: apps/cloud already injects OS_PLATFORM_OWNER_EMAIL (cloudflare/worker.ts:240, wrangler.toml:243/:396), is walled (worker.ts:484), declares membershipPolicy 'invite-only' (service-cloud/src/control-plane-preset.ts:531), and its own pin tests were rewritten to the L4 no-mint contract by pin bump PR #1817 (apps/cloud/test/signup-org-flow.test.ts:399-413, unscoped-control-plane-tenant-wall.test.ts:2891-2916). Choice 2B costs cloud nothing: zero cloud code readers of the variable. CONTRADICTION 1 - there is no per-tenant-environment env seam and none is representable: one container LRU-hosts up to 50 per-environment kernels in one process (apps/objectos/cloudflare/worker.ts:283, packages/objectos-runtime/src/kernel-manager.ts) with env assembled once at construction (worker.ts:169/:279/:413), so a per-environment value cannot exist and a runtime-wide one would name one administrator across every tenant. Cloud's actual per-environment anchor is a control-plane DB row, sys_environment.metadata.ownerSeed.email (service-tenant/src/environment-provisioning.ts:1062-1071), conferring standing by WRITING the legacy unscoped admin_full_access grant row (objectos-runtime/src/env-owner-admin-grant.ts:67, :91) through two doors that are not the env variable (auth-proxy-plugin.ts:319 console handoff; env-owner-admin-grant.ts:126 OIDC middleware). CONTRADICTION 2 - P1 'verified-email match only' does not survive the seam: environment-provisioning.ts:1064-1071 copies the creator's email and never reads email_verified, and environment-owner-seed.ts:91 stamps email_verified: true into the tenant DB unconditionally, so the tenant-side verification check (env-owner-admin-grant.ts:143-147) reads a verification cloud asserted rather than performed; the only real check is a Worker default one layer up (apps/cloud/cloudflare/worker.ts:461). SEQUENCING CORRECTION in the design's favour: Choice 4A protects cloud today (the tenant runtime is single posture - zero hits for the three posture/owner variables across all of apps/objectos, positive control 5 and 7 hits in apps/cloud; artifact-kernel-factory.ts:841 gates on the demoted boolean, the same absence cloud#1332 files), and #13515 (L5) explicitly protects single-posture standing - so the cloud leg's real dependency is #11979 (Choice 4B), whose landing kills both cloud doors SILENTLY (the grant write still succeeds and simply stops conferring; the writer swallows its own errors). Dependency ancestry checked rather than assumed: L2's merge 33184fd2 and L4's merge b9972720 are both ancestors of the pin (git merge-base --is-ancestor, exit 0), so a cloud card would carry no Blocked-by on #11970/#11974. The card's process premise held (its own 'designed blind, review first' warning was correct); its content premise - that the cloud leg is control-plane env injection per deployment - is what the tree contradicts, and its acceptance criterion ('a cloud-repo issue exists carrying this leg') cannot be met as written.",
      "tests": "None run, and none owed: this dispatch writes no product code and was explicitly read-only (no install, no build, no branch, no edits) - so there is nothing of mine to verify, and reporting a build or a suite here would be reporting a measurement I did not make. Every claim is a read of cloud origin/main 58c20e2c in a detached read-only worktree (/home/user/cloud-readings-l8, removed at the end) or of the framework at pin 655b106c via `git show PIN:path` (the shared /home/user/objectstack checkout's HEAD was never moved; only `git fetch origin 655b106c`). Two mechanical checks were run rather than asserted. (1) Ancestry: `git merge-base --is-ancestor 33184fd2... 655b106c` and the same for b9972720... both returned exit 0, printing 'IS ancestor of pin'. (2) The zero-hit claim underpinning 'the tenant runtime is single posture' was run WITH a positive control, because a bare zero proves nothing: `grep -c 'OS_TENANCY_POSTURE\\|OS_MULTI_ORG_ENABLED\\|OS_PLATFORM_OWNER_EMAIL'` returns 0 for apps/objectos/cloudflare/worker.ts and apps/objectos/wrangler.toml and 0 files across the whole apps/objectos tree, while the same pattern returns 5 in apps/cloud/cloudflare/worker.ts and 7 in apps/cloud/wrangler.toml. Both posted comments were read back in full via REST and diffed byte-for-byte against the local source: the only differences are a trailing-newline normalization (diff shows one added blank line and 'No newline at end of file'), i.e. the body sanitizer stripped nothing.",
      "mcp_calls": "0 - the whole run went through the zero-quota REST channel, probed first as the discipline requires: an authenticated repo-scoped REST read returned HTTP 200 with a 15000/hr core budget, so reads (issues, comments, timeline, PR metadata, PR file lists, the open-issue listing) and the three comment writes all went over REST. `gh` is absent in this container. No MCP GitHub tool was called; the dedup/collision scan used the REST list endpoints (49 open issues, 7 open PRs on objectstack-ai/cloud) plus a local regex filter, never a wide search.",
      "open_questions": [
        {
          "question": "What anchors platform-admin standing for a cloud TENANT ENVIRONMENT once Choice 4B (#11979) lands, and what does 'verified' mean at the control-plane seam? Cloud has no per-environment env seam (50 kernels share one process), so its anchor today is the legacy unscoped grant row written from sys_environment.metadata.ownerSeed - the exact row the re-anchor retires - and the owner email behind it was never checked for verification.",
          "options": [
            "A - rule the row: declare that database-per-tenant, single-posture runtimes keep the grant-row anchor permanently; #11979/#13515 carve it out rather than removing it, and cloud fixes only the verification gap.",
            "B - declare the owner, keep one derivation site: make ownerSeed the per-environment analogue of the variable (control plane records a VERIFIED owner) and give the framework a non-env config source feeding the same 6b-config derivation, so the row stops being the anchor without a second derivation site appearing.",
            "C - make the env variable per-environment: one process per tenant environment so the design's shape applies literally."
          ],
          "recommendation": "B, with A named explicitly as the time-boxed interim. Long-term soundness leads and is the axis that decides it: B is the only option that keeps 'declared = enforced' and one derivation site, whereas A freezes the runtime-writable row the ruling set out to retire and leaves a permanent posture-keyed carve-out - two derivation shapes keyed on posture, which the design's own Choice 4 calls drift bait. AI-safety agrees (B > A > C): under A the superuser anchor stays a row any system-context write can insert, and cloud's writer swallows its own errors, so failure is invisible in both directions. Real business need: A and B both serve the shipped product; C serves nothing measured and contradicts the runtime's economics (50 kernels per container, 4h LRU, a keep-warm workflow). Startup scope: C is out of proportion, and B's framework half belongs inside L2's existing derivation site rather than as a new mechanism. Two riders on the recommendation: (1) #11979 must not land until the cloud anchor has moved, or 4B ships a silent lockout on the hosted fleet; (2) the ownerSeed verification gap is independent of this fork and weakens P1 today, so it should be fixed whichever way A/B is ruled."
        }
      ],
      "out_of_scope_findings": [
        "NOT filed, deliberately, and recorded in the review comment instead: the objectos-ee deploy surfaces still describe OS_PLATFORM_OWNER_EMAIL as a single address (apps/objectos-ee/deploy/composed-artifact-boot.md:76,114; apps/objectos-ee/deploy/README.md:125). Under Choice 2B they are incomplete rather than wrong, and the operator runbook for that variable is L7's surface (#11976), not cloud's. Filing it as a cloud card would also breach this dispatch's 'no cloud card on the contradicted branch' instruction.",
        "Not a new finding - cited as an existing adjacent card so it is not re-filed: cloud#1332 (pm:blocked) already measures that the hosted tenant runtime never reads OS_TENANCY_POSTURE and gates on the demoted OS_MULTI_ORG_ENABLED boolean, and it already frames the two defensible end states. Contradiction 1 depends on that card rather than re-deciding it.",
        "objectstack#11225 (security, repo:cloud, dispatched and being measured in this container now) is the same neighbourhood with a different predicate - auto-join to the Default Organization in the enterprise organizations package, versus platform-admin standing here. Cited, not duplicated, and deliberately not re-measured."
      ]
    }

    Generated by Claude Code

  7. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    Contributor

    决策卡:cloud 租户环境的 platform-admin 锚点在 Choice 4B 落地后落在哪里、以及「已验证邮箱」在控制面接缝处指什么 —— L8 设计在 cloud 树上被两处证伪,转决策箱

    repo:cloud 席(座位贴 #6026,session session_017Wu48ZSjk7HJjyJmGNBtUk,R35)。本卡原为「cloud 席复核 L8 设计假设后在 cloud 仓立执行卡」;复核已做(上方 dev 评论,cloud 58c20e2c、pin 655b106c,逐条 file:line),分叉已按卡面要求贴到 #11663(评论 5521187539)。结论不在本席裁量内 —— 它动的是安全/权限边界(谁在租户环境里是平台管理员、凭什么)—— 故本卡换 needs-user-decision,⛔ 未立 cloud 卡。

    一句话问题

    托管云上每个租户环境的「平台管理员」资格今天靠一行运行时可写的授权行(控制面在建环境时按创建者邮箱写入的 admin_full_access 行,env-owner-admin-grant.ts:67/:91)撑着;#11663 的重锚设计要退役的正是这类行,而它设想的替代物(每个部署注入一个 OS_PLATFORM_OWNER_EMAIL)在 cloud 的运行时里做不出来:一个容器同进程 LRU 托管最多 50 个租户内核(apps/objectos/cloudflare/worker.ts:283、kernel-manager.ts),环境变量只能是进程级的 —— 一个值就是全部租户共用一位管理员。问维护者:Choice 4B(#11979)落地后,租户环境的管理员锚点该是什么?

    前提(每条带 re-check,本席采信 dev 实测)

    1. cloud 控制面自身已具备设计要的一切:注入了 OS_PLATFORM_OWNER_EMAIL(apps/cloud/cloudflare/worker.ts:240)、walled、invite-only(control-plane-preset.ts:531),pin bump PR feat(spec): ADR-0047 — interface/list pages get a lean, relevant config form #1817 已把控制面的 pin 测试改到 L4 的 no-mint 契约。→ 控制面这一半无事可做。re-check:git grep -n OS_PLATFORM_OWNER_EMAIL origin/main -- apps/cloud。
    2. 租户运行时无 per-environment 环境变量接缝,且不可表示(同进程多内核,env 在构造时装配一次:worker.ts:169/:279/:413)。re-check:git grep -n -c 'OS_TENANCY_POSTURE\|OS_MULTI_ORG_ENABLED\|OS_PLATFORM_OWNER_EMAIL' origin/main -- apps/objectos = 0(阳性对照 apps/cloud = 5/7)。
    3. 「已验证邮箱」在接缝处不成立:environment-provisioning.ts:1064-1071 复制创建者邮箱、不读 email_verified;environment-owner-seed.ts:91 无条件把 email_verified: true 盖进租户库 —— 租户侧的验证检查(env-owner-admin-grant.ts:143-147)读的是 cloud 声称的验证,不是做过的验证。
    4. 时序:Choice 4A 今天仍保护 cloud(租户运行时单姿态;platform-admin re-anchor (L5 removal half): delete the legacy grant-row read — one minor after L4's landing #13515 明写保护单姿态资格);真正的依赖是 platform-admin re-anchor follow-up (Choice 4B): config-anchor the single posture — first-user promotion becomes development-only fallback #11979(Choice 4B),它一落地,cloud 的两扇门(console handoff auth-proxy-plugin.ts:319、OIDC 中间件 env-owner-admin-grant.ts:126)静默失效 —— 授权行照写、只是不再授予,写入方还吞掉自己的错误。L2/L4 的合并提交均已在 pin 内(merge-base 实测),cloud 卡不需要 Blocked-by 它们。

    选项 × 真实代价(从业务角度)

    选项 做什么 客户可感知的代价
    A. 裁定「行就是锚」 数据库按租户、单姿态的托管运行时永久保留授权行锚点;#11979/#13515 为它开豁免而非删除;cloud 只补验证缺口 租户环境的超级用户资格永远是一行任何 system-context 写入都能插的行;失败在两个方向都不可见(写入方吞错)。是设计自己称为「漂移温床」的按姿态双派生形状
    B. 声明 owner、单一派生点 控制面记录已验证的环境 owner(ownerSeed 升格为 per-environment 的变量对应物),框架提供非 env 的配置源喂给 L2 既有的 6b 派生 —— 行不再是锚,派生点仍只有一个 declared = enforced 成立;需要框架半边(在 L2 已有派生点内加一个配置源,不是新机制)+ cloud 半边(记录并核验 owner);过渡期需 A 作时限内的临时状态
    C. 每租户一进程 让设计的形状字面成立 推翻运行时经济模型(50 内核/容器、4h LRU、keep-warm 工作流),无任何实测拉动

    推荐

    B,并显式把 A 记为有时限的过渡态。两条附带条件不随 A/B 变:① #11979 不得先于 cloud 锚点迁移落地,否则托管舰队静默锁死管理员;② ownerSeed 的验证缺口(前提 3)独立于本分叉、今天就削弱 P1,无论裁 A 还是 B 都要修。

    os-decision-facets
    ① 项目长远合理性:B 缩小特例 —— 一个派生点、声明即强制;A 把设计要退役的可写行永久化并留下按姿态的豁免,是契约增生;C 与运行时模型相悖。
    ② 实际业务拉动:今天每个托管租户都靠这行授权行进入自己的环境(已发布产品的既有路径),4B 一落地即断 —— 拉动为实、且有截止期。
    ③ 防 AI 犯错:B > A > C —— A 让超级用户锚点停留在任何 system-context 写入都能插入、且写入方吞错的行上,失败双向不可见;B 把它收成一次可核验的声明。
    ④ 创业阶段不扩散:C 出局(零拉动、推翻经济模型);B 的框架半边住进 L2 既有派生点而非新机制;A 零新代码但把临时形状固化成永久义务。
    推荐:B(A 作时限过渡)。选项:A / B / C。
    本分析看不见什么:ownerSeed 在生产库中未验证邮箱的实际比例;#11979 的当前实现是否已带姿态豁免;框架侧「非 env 配置源」的具体形状(L2 派生点是否已预留)。

    裁后执行段

    裁 B ⇒ 本卡收窄为记录卡关闭,cloud 仓立执行卡(记录并核验 owner + 验证缺口修复),框架半边由分诊立 domain:services/engine 卡,#11979 挂 Blocked-by: 指向它;裁 A ⇒ cloud 仓立「验证缺口」执行卡,#11979/#13515 由其席补豁免,本卡关闭;裁 C ⇒ 升级为 ADR 级设计卡。任一裁定同笔摘 needs-user-decision。


    Generated by Claude Code

  8. removed their assignment
    on Sep 3, 2026
  9. os-project-manager commented on Sep 3, 2026

    @os-project-manager
    Collaborator

    Referred to the maintainer — not ruled (2026-09-03)

    Provenance. In the director seat's live session (session_01ShyhexkB2d1AeRZ85tgAAe), decision batch #24, this card was presented with the cloud seat's fork (comment 5521221594 here; #11663 comment 5521187539) and the recommendation B (declare a verified owner on sys_environment.metadata.ownerSeed, one derivation site; A as a time-boxed interim; two riders: #11979 must not land before the cloud anchor moves, and the ownerSeed verification gap is fixed either way). The maintainer's reply, verbatim: 「11977 转维护者,其他同意」 — this card is taken by the maintainer personally; no option was adopted and no seat may act on it as ruled.

    What this means for the seats.

    State. needs-user-decision → pm:awaiting-maintainer in the same stroke (the same disposition #13564 took in batch #11); repo:cloud kept; unassigned. Ledger: objectstack#12708, batch #24 ledger comment.


    Generated by Claude Code

  10. huangyiirene commented on Sep 9, 2026

    @huangyiirene
    Collaborator

    状态转换:pm:awaiting-maintainer → needs-user-decision(2026-09-09)

    维护者回批逐字:「B 桶 · 要你的判断,应转 needs-user-decision —— 23 张 转决策卡」。

    判据:欠判断不是动作 —— 卡面自陈 cloud 座位那条腿是「designed blind」(控制面 env 注入 + 仅邀请交互)。⇒ 它要的是维护者手里的 cloud 侧真实形状,据以定设计;⛔ 不是一次可执行的人工动作,也不是可由席位测量出来的读数。

    按 SKILL.md:110/:126:决定待做 = needs-user-decision。⇒ 此前为误分类。

    同笔摘 pm:awaiting-maintainer;repo:cloud 留下。

    ⚠️ 根因见 #17017。


    Generated by Claude Code

  11. os-bill commented on Sep 9, 2026

    @os-bill
    Collaborator

    维护者速读(2026-09-09 更新稿;四棱块与选项 A/B/C 的原分析在 5521221594)

    事情:托管云上每个租户环境的「平台管理员」资格,今天靠控制面在建环境时按创建者邮箱写入的一行 admin_full_access 授权行撑着;#11663 的重锚设计要退役这类行,替代物「每个部署注入一个 OS_PLATFORM_OWNER_EMAIL」在 cloud 的运行时里做不出来(一个容器同进程托管最多 50 个租户内核,环境变量只能是进程级)。cloud 席 09-03 把这一分叉转决策箱,您当时「转维护者」接手未裁。

    此后的新事实:ADR-0131(您 09-04 接受)D5 直接写了单姿态部署的锚点:「PLATFORM_ADMIN 来自 OS_PLATFORM_OWNER_EMAIL(配置);single 姿态的首用户晋升(Choice 4A)继续写授权行,改为由 Default Organization 拥有;带墙姿态不写行」——即托管租户运行时(单姿态)的锚点就是那行授权行,只是不再是 NULL 组织。#11979(4B「晋升改为仅开发用」)目前传递阻塞,且 hotlong 09-04 在其上记明 ADR-0131 保留了 single 下的首用户晋升(#15204 C3 验收原文),所以 cloud 席担心的「4B 一落地两扇门静默失效」今天不会发生。

    选项:A′(推荐) 按 ADR-0131 D5 关本卡(被取代):cloud 租户运行时的锚点 = Default Organization 拥有的首用户晋升行,不需要 per-environment 变量;剩下一件真实缺陷单独立 cloud 缝卡——控制面 ownerSeed 把 email_verified: true 直接盖进租户库、从不读 email_verified(前提 3),需改为只复制已验证的邮箱或只在验证后授予。B(cloud 席原推荐)另建「声明并核验的环境 owner」单一派生点——要在框架 L2 增一个非 env 的配置源,与 D5「配置或 Default-Org 行」的形状重叠,零额外拉动。C 每租户一进程——推翻运行时经济模型,否决。

    你要做的:回一个字母,A′ / B / C。

    • ① 项目长远合理性:A′ 让锚点由 ADR-0131 一处定义(配置,或 single 下的 Default-Org 行),缩小特例;B 加第三种派生源。
    • ② 实际业务拉动:今天每个托管租户都靠这行进入环境——拉动为实;A′ 不改它,只把它从 NULL 组织改为有主(ADR-0131 迁移承担)。
    • ③ 防 AI 犯错:真正的静默失败是验证缺口(cloud 声称已验证 ≠ 做过验证)——A′ 把它单独立卡响亮修;B 不修它也不成立。
    • ④ 创业阶段不扩散:A′ 零新机制;B 新配置源;C 出局。
      推荐 A′(回退 B)。置信缺口:cloud 仓本会话不可达,ownerSeed 现状按 cloud 席 09-03 实测(environment-provisioning.ts:1064-1071、environment-owner-seed.ts:91)采信,未重测。

    裁后执行

    总监席第 20 场(session_01Tep4AYXZvyBA7jsvne5KZV)按决策箱勤务补齐速读,2026-09-09T05:4xZ;⛔ 非裁决。


    Generated by Claude Code

  12. os-bill commented on Sep 9, 2026

    @os-bill
    Collaborator

    Ruling recorded — A′: superseded by ADR-0131 D5; the one real defect (ownerSeed verification gap) goes to the cloud seat as its own seam card (director seat, summon #20, decision batch #109, 2026-09-09T05:5xZ)

    Provenance (who / verbatim / where): maintainer, live PM chat with this seat (session_01Tep4AYXZvyBA7jsvne5KZV, os-bill), 2026-09-09T05:5xZ, replying to batch #109 in which this card was the single item with the updated 速读 and four-facet block at 5596431581 recommending A′. Reply, verbatim: 「11977 同意,然后处理契约复审」 — A′.

    Ruled. For a hosted tenant runtime (a single-posture kernel among up to 50 in one process, no per-environment environment variable), the platform-admin anchor is what ADR-0131 D5 states: PLATFORM_ADMIN derives from configuration where configuration exists, and under single the first-user promotion (Choice 4A) keeps writing the admin_full_access grant row — owned by the Default Organization, never NULL. No per-deployment OS_PLATFORM_OWNER_EMAIL injection into tenant runtimes is required or possible; L8's control-plane half (injection + invite-only on the control plane itself) is already in place per the cloud seat's 09-03 measurement (5521221594 premise 1). B (a new declared-owner derivation source in the framework) and C (one process per tenant) refused. #11979 (4B) stays as it is — transitively blocked, and, per hotlong's 09-04 pointer there, not made dev-only by ADR-0131 — so the cloud doors are not disabled by anything scheduled.

    Residual defect, split out: the control plane copies the creator's email into the tenant's owner seed without reading email_verified and stamps email_verified: true unconditionally (environment-provisioning.ts:1064-1071, environment-owner-seed.ts:91, cloud seat 09-03). That is a cloud-repo bug independent of this fork ⇒ seam card filed in this repo with repo:cloud (linked below).

    State, one write: closed not_planned (superseded by ADR-0131 D5); needs-user-decision removed; repo:cloud kept. Parent #11663's L8 row is answered by D5; the epic's own checklist is the epic seat's to update.


    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

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions