Skip to content

runtime: one internal request-to-ExecutionContext resolver for the platform's five hand-rolled copies (rest, runtime, service-settings, service-storage, plugin-hono-server) — not a published export (ruling C′ on #23128, p3) #23217

Open

Description

@objectstack-fleet

Ruled: 6257816853 · slice 5 letter A · item 3 letter (i) · 2026-10-19T01:38Z

Ruled: 6227928430 · letter A on #23982 (batch #358 item 1) · home amended to @objectstack/core · 2026-10-17T01:27Z

Filed by the director seat (summon #37, session_01LqNgdPZB2Jnr5HpGbaqLeB) on the maintainer's ruling C′ on #23128 (「同意」, recorded at 6142279866) under 「立卡你决定,不需要我同意」. ⛔ Not a claim. Filing gate ①: a measured duplication with named sites. Priority p3: housekeeping inside the platform; nothing user-visible changes and #23128 does not wait for it.

What is measured (#23128's dev, on dc93781c19)

Five platform doors each hand-roll the same request-to-context composition (resolveAuthzContext + classifyAdmissionTenancyPosture + assembleExecutionContext / assembleExecutionContextOrGuest + a session read): packages/rest/src/rest-server.ts:3060, packages/runtime/src/security/resolve-execution-context.ts:150, packages/service-settings/.../settings-service-plugin.ts:285, packages/service-storage/.../storage-service-plugin.ts:862 and :1247, packages/plugins/plugin-hono-server/src/current-user-endpoints.ts:443. Each copy was fixed separately when an input was omitted (the tenancy posture: #15351, #15352; the in-process session read: #22258; a six-field omission: #15747).

What to build (one PR, or one per door after the first)

  1. One function in @objectstack/core, exported from its . entry beside classifyAdmissionTenancyPosture (Clause-②: yes (widening), minor on @objectstack/core; the home amended by the ruling on [Decision] #23217 cannot land as ruled: four of the five request-to-context doors cannot import an internal function of @objectstack/runtime. Home it in @objectstack/core (a new export), keep five copies under a parity pin, or close #23982, batch [WIP] Update action step configuration based on job run #358 item 1 — the runtime home C′ named is unreachable from four of the five doors; later slices Clause-②: no) that takes the pieces a door holds (the request's headers or the Hono context, the auth service, the ObjectQL engine) and returns the ExecutionContext, with the two choices made once and documented: the anonymous entry (fail-closed assembleExecutionContext unless the door's product semantics say guest) and the ADR-0069 auth gate.
  2. The five doors call it; each conversion is proven by that door's existing pins (no new behaviour; a door that intentionally differs keeps its difference as a named parameter, never a copy).
  3. ⛔ No new published export, no change to any door's outward behaviour, no app-author surface (ruling C′: code-mounted app routes are retired, so no app needs this).

Acceptance

Related: #23128 (ruling C′, dev report 6138940364) · #15747 · #15351 · #15352 · #22258 · ADR-0096 · ADR-0069.

Activity

  1. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Blocked-by: #23982

    Held pm:blocked on the decision card #23982 · domain:cli seat 2 (#22648) · os-tesla · session session_018t6a5rvqPRvEDMCVVW9kYT · 2026-10-16T15:39Z · ⛔ not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruled on #23982 (batch #358 item 1, record 6227928430, letter A) · director seat (summon #43 continuation 3, session_01QJC7i981TSs9L1CGJK59Ax) · 2026-10-17T01:26Z

    The home this card inherited from ruling C′ (6142279866 item 3), an internal function in @objectstack/runtime, is unreachable from four of the five doors: rest, service-settings, service-storage and plugin-hono-server do not depend on the runtime package, and the runtime depends on rest. The maintainer's letter A amends the home clause only: the one function lives in @objectstack/core beside classifyAdmissionTenancyPosture, exported from core's . entry (Clause-②: yes (widening), minor on @objectstack/core); slice 1 is the function plus the runtime's own door, each later door its own slice with Clause-②: no; a door's intentional difference is a named parameter, never a copy; one conformance test over the function and every converted door; the carried fallback is letter B (one census-discovered parity pin) on a premise_still_valid: false report. Item 1 of the scope below is amended in this act to match; the rest stands. This card leaves pm:blocked for pm:queue in this act — the domain:cli seat re-dispatches from here.

  3. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 · #23217 slice 1: the one request-to-ExecutionContext function in @objectstack/core, plus the runtime's own door, under letter A · 2026-10-18T01:35Z
    Session: session_01QyoWKK9RwUNxBxmevy9Neb
    Account: marchtian (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23217-s1-core-request-context
    Worktree: objectstack-issue-23217-s1
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    Ruling-ref: 6227928430 (#23982, batch #358 item 1, letter A, the maintainer's 「23982 同意」), which amends ruling C′ 6142279866 item 3 in its home clause only. The card's amended scope 6227947754 binds.
    File surface (read on origin/main 7be3cc728; line numbers move; stop on a breach and explain it in the report):


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 23217,
      "status": "done",
      "branch": "claude/issue-23217-s1-core-request-context",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/24248",
      "session": "session_01QyoWKK9RwUNxBxmevy9Neb (mode:subagent; the dispatching PM session's harness-stamped id, as the commit Claude-Session trailers carry it)",
      "premise_still_valid": true,
      "summary": "Slice 1 of #23217 under letter A (6227928430). Added resolveRequestExecutionContext in packages/core/src/security/request-execution-context.ts, exported from core's . entry through security/index.ts beside classifyAdmissionTenancyPosture. It does the session read under the in-process rule, the tenancy-posture classification, resolveAuthzContext, the localization, the ADR-0069 gate and the assembly. It makes two documented choices (anonymous: fail-closed | guest; authGate: withhold | resolved | reread-when-active), and every other measured door difference is a required named parameter (11 in total, 0 item-5 fallbacks; table in door_differences). The runtime door packages/runtime/src/security/resolve-execution-context.ts now keeps only what is its own (service lookups, header normalisation, the /mcp OAuth verification and scope reading) and calls the function: 209 lines out, 87 in. Its 39 pins and #24137's 15 OAuth pins are green unchanged. The ruling-item-4 conformance test is in runtime with one row per converted door. Draft PR #24248 is Part of #23217, assigned to marchtian, with a minor changeset on @objectstack/core.",
      "tests": "HEAD f5a955e12 (after merging origin/main af284b05e). (1) Core local project, under the verify lock: 'Test Files 104 passed (104) / Tests 2551 passed (2551)'. The edited repo-project ledger src/security/authz-store-unavailable.test.ts: 'Tests 40 passed (40)'. (2) Runtime local project, under the lock: 'Test Files 413 passed (413) / Tests 6318 passed | 19 skipped (6337)', 'VERDICT command-exit 0 · held the lock 559s'. (3) Door and dispatcher pins, verbose reporter, at 7667d9b4d before the merge (the post-merge full suite includes them): resolve-execution-context.test.ts 39, resolve-execution-context.oauth-organization.test.ts 15 of 15, request-execution-context.conformance.test.ts 7, plus http-dispatcher.mcp-oauth, http-dispatcher.tenancy-posture-outage, http-dispatcher.keys and in-process-session-renewal.pin: 'Test Files 7 passed (7) / Tests 111 passed (111)'. (4) New core unit file: 20 passed. (5) Typecheck: pnpm --filter @objectstack/core typecheck exit 0 (test layer held at 4 files / 4 errors) and pnpm --filter @objectstack/runtime typecheck exit 0 (27 files / 190 errors held, unchanged). The core test tsconfig compiles the new test (--listFiles counts 2 request-execution-context files). ABLATION, choice 1, at 7667d9b4d, declared direction RED. The function was mutated to always take the fail-closed entry ('return assembleExecutionContext(assembly); // ABLATION-23217-anonymous-entry'), landed by scripts/ablation-replace.mjs: 'anchor 1 -> 0, blob e3a17adddf47 -> 86ec4e1f04b5', marker count 1. Runtime's vitest aliases @objectstack/core to ../core/src/index.ts, so no dist preflight applies. Observed: core 'Tests 1 failed | 19 passed (20)', the choice-1 guest-envelope case. Runtime 'Tests 10 failed | 36 passed (46)': 9 door pins, including '#6216 a sessionless request still yields the WHOLE guest envelope' and the tenancy 'POSITIVE CONTROL', plus the conformance CONTROL. Restore: 'blob == HEAD (e3a17adddf47) and git diff HEAD is empty', marker 0. Direction observed equals the direction declared. Note: the conformance equalities stay green under the ablation by construction, because both sides call the one function; the CONTROL case and the unit battery are what catch a defect in the function itself.",
      "gates": "Local subset, at f5a955e12. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) derived 84 commands; each was run with its exit code captured before any pipe into ran.list. 83 exit 0; pnpm check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: 40 packages have no dist, it needs a whole-tree build), so NOT MEASURED; CI runs it. Reconciliation, node scripts/pm/dispatch-gates.mjs --ran ran.list: exit 0, 'Run reconciliation — 84 derived, 83 run, 1 NOT-MEASURED, 0 UNRUN'. Its staleness line: origin/main moved to 9975c26ae while the run was going, and 3 stale files are rest adr-anchors and check-route-envelope.mjs, unrelated to this diff. Among the derived commands: pnpm check:authz-resolver exit 0, pnpm check:published-files exit 0, pnpm check:dts-closure exit 0, pnpm check:lean-entry-closure exit 0, pnpm check:pm-dispatch-gates exit 0, pnpm check:type-check-coverage exit 0, pnpm check:type-check-debt exit 0, pnpm check:nul-bytes exit 0, node scripts/check-adr-0087-registration.mjs --base origin/main exit 0, node scripts/check-changeset-no-major.mjs --base origin/main exit 0. Edited gate script: node scripts/check-single-authz-resolver.mjs --self-test exit 0 and the gate exit 0 ('all 3 entry points delegate'); no test file names the script (git grep: package.json, check-ratchet-remedy-authority.mjs and bare-root-worklist.mjs only). Lane blind spot: pnpm exec eslint --no-inline-config over the 7 changed .ts/.mjs files exit 0, no output. Local-only family: pnpm check:dev-prereqs exit 0 (spec, core and plugin-auth built from the sources on disk). Runtime test:repo was not run locally; it is CI's (Test Core). PR check-runs, one read at the time of this report: 'No other open PR may claim the same issue' success; 'Packed-tarball smoke (opt-in)' skipped; the other 21, including the Lint and Type Check lanes, 'Check Changeset', 'Governed Surface Queue Guard', 'Part-of PR must not also close its card' and 'The card this PR closes must claim this branch', in_progress. Required Test Core and Build Core were not yet listed.",
      "mcp_calls": "0",
      "api_writes": "2: (1) POST /repos/objectstack-ai/objectstack/dispatches (the pr_create stroke through scripts/pm/fleet-write/dispatch.mjs; relay run 39091336245 sent POST /repos/objectstack-ai/objectstack/pulls, which opened #24248 as a draft, and POST /repos/objectstack-ai/objectstack/issues/24248/assignees with marchtian; read-back '15523 byte(s) sent, 15523 stored — identical'); (2) POST /repos/objectstack-ai/objectstack/issues/23217/comments (this os-dev-report, via scripts/pm/post-stamped.mjs). Not REST: git push of the branch. No label write: the dispatch named no label, and skip-changeset does not apply because the PR carries a changeset.",
      "line_budget": "n/a: nothing under skills/** and no ledger file touched",
      "files_changed": [
        ".changeset/23217-core-request-execution-context.md",
        "packages/core/src/security/request-execution-context.ts",
        "packages/core/src/security/request-execution-context.test.ts",
        "packages/core/src/security/index.ts",
        "packages/core/src/security/authz-store-unavailable.test.ts",
        "packages/runtime/src/security/resolve-execution-context.ts",
        "packages/runtime/src/security/request-execution-context.conformance.test.ts",
        "scripts/check-single-authz-resolver.mjs"
      ],
      "door_differences": [
        "Measured on origin/main 7be3cc728 before slice 1 was written. Doors: rest = rest-server.ts computeExecCtx; runtime = runtime/src/security/resolve-execution-context.ts; settings = settings-service-plugin.ts verifiedContextFromRequest; storage = storage-service-plugin.ts buildFileReadAuthorizer + buildAuthGateSessionReader; hono = current-user-endpoints.ts makeExecutionContextResolver. 11 differences, all named parameters, 0 item-5 fallbacks.",
        "1 anonymous: rest fail-closed | runtime guest | settings fail-closed ({ enforced: true }) | storage fail-closed ('unauthenticated') | hono fail-closed -> parameter anonymous",
        "2 ADR-0069 gate: rest key = the admission's posture, session = re-read while isAuthGateActive(), a failed re-read is 503 | runtime withheld (the dispatcher's enforceAuthGate + onAdmission) | settings authz.authGate, no re-read | storage its own gate reader with the same shape as rest | hono withheld (allow-listed /me routes) -> parameter authGate: withhold | resolved | reread-when-active",
        "3 credential doors: API key + session everywhere except hono, which passes headers undefined (session only) -> parameter credentials",
        "4 no session API: rest and hono answer no context (the key is not honoured) | runtime and settings resolve (the key is honoured) | storage has no authorizer without auth (door-level) -> parameter sessionApi: required | optional",
        "5 session source: the auth service's in-process read everywhere; runtime /mcp adds a verified token's session or none for an unverifiable JWT -> parameter session: request | none | { established }",
        "6 tenancy posture: rest kernel or provider | runtime lookup thunk | settings and storage async accessor when present | hono none -> parameter tenancy (a TenancyServiceResolver thunk; the resolution stays at the door per #16013)",
        "7 admission channel: runtime only -> parameter onAdmission",
        "8 localization: rest settings provider | runtime settings lookup | hono withheld | settings and storage none -> parameter localization: withhold | { settings }",
        "9 request locale: rest header or ?locale (metaRequestLocale) | runtime Accept-Language | hono none -> parameter requestLocale (a value)",
        "10 session bearer: runtime carries it | rest and hono withhold it | storage carries it in the raw envelope -> parameter accessToken: carry | withhold",
        "11 OAuth provenance: runtime /mcp only -> parameter oauth (H2: verification and the scope reading stay at the door, because they need @objectstack/spec/ai, which core does not depend on)",
        "Door-side, not the composition and not a copy: header normalisation (the function takes a Web Headers), service resolution, fault relay (the function propagates everything), post-assembly additions (rest __kernel, __authEnvironmentId, memo, perf disclosure; hono perf disclosure), output consumption (settings projects to SettingsContext; storage hands the envelope to engine.find)"
      ],
      "handover_slice2": [
        "Door: packages/rest/src/rest-server.ts computeExecCtx (merged head :3098). Call the function with anonymous 'fail-closed', authGate 'reread-when-active', credentials 'api-key-and-session', sessionApi 'required', session 'request', localization { settings: () => this.settingsServiceProvider ? seamOrUndefined(() => this.settingsServiceProvider(environmentId)) : undefined }, requestLocale this.extractLocale(req), accessToken 'withhold', oauth undefined, onAdmission undefined.",
        "The tenancy thunk stays rest's own: the kernel getServiceAsync branch or the tenancyServiceProvider branch, undefined when neither applies.",
        "Kept at the door: environment and auth-service resolution and the 'if (!authService) return undefined' early return, header normalisation (append per array element), the ql resolution through wiredEngineOrLoud, __kernel, __authEnvironmentId, the execCtxMemo, the perf disclosure, and the catch with its apiKeyLifecycleRefusals side channel.",
        "Then: move the rest row of DELEGATORS in scripts/check-single-authz-resolver.mjs to resolveRequestExecutionContext; remove rest-server.ts from the core TRANSPORT_LEDGER in authz-store-unavailable.test.ts if it no longer calls resolveAuthzContext({; add rest as a conformance row (runtime already depends on @objectstack/rest); add the ruling's one ADR-0096 / ADR-0069 pin; Clause-②: no.",
        "Later slices: settings and storage rows need runtime devDependencies on @objectstack/service-settings and @objectstack/service-storage (no cycle: neither depends on runtime). Storage today hands the raw ResolvedAuthzContext to engine.find; the envelope adds isSystem false and principalKind human and drops credential (no objectql, plugin-security or plugin-sharing source reads context.credential). Hono's session read drops a session with no user.id, while the resolver reads user.id ?? session.userId; slice 5 measures it."
      ],
      "deviations": [
        "Two files outside the claim's literal surface, both forced by moving the resolveAuthzContext call: packages/core/src/security/authz-store-unavailable.test.ts (its transport ledger is set-equal to the call sites, so the runtime door row became the new core module, propagates), and scripts/check-single-authz-resolver.mjs (DELEGATORS now names each delegator's call; without it, check (2) would have been satisfied for the runtime door by docblock prose alone). For the seat to declare.",
        "The ablation is of choice 1, the anonymous entry, not the suggested ADR-0069 gate. The runtime door withholds the gate on the envelope, so a gate ablation cannot redden any runtime door pin; the anonymous entry reddens both a core unit test and runtime door pins.",
        "The runtime door now looks up 'auth' once, at the top, ahead of the tenancy read. Answers are identical for any lookup that resolves or rejects. Only a lookup that throws synchronously for 'auth' while the tenancy service also failed to build now surfaces the synchronous error instead of the 503; the dispatcher's resolveService never throws. Stated in the PR's Acceptance notes.",
        "The PR body writes the exported signature with the angle brackets as single guillemets (the sanitizer strips tag-shaped fragments) and points to the byte-exact lines at f5a955e12.",
        "The PR body carries 'Clause-②: yes (widening)' on one line with 'Ruling-ref: 6227928430' below it. The dispatch's wording can also be read as '(widening)' on its own line; both read as a widening yes to scripts/pm/clause2-line.mjs.",
        "Commit subjects on the branch end with (WIP); they carry no card relation, and a squash merge takes the PR title.",
        "origin/main moved to 9975c26ae (unrelated rest files) after the merge and the gate run; no second merge, per the after-PR merge rule.",
        "check:dual-build-cjs-loads was NOT MEASURED locally (exit 3, a whole-tree build prerequisite); runtime test:repo was not run locally. Both are CI's."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: the domain:cli seat (a card text edit) · noted, not filed. #23217's title ('not a published export') and its scope item 3 ('No new published export') still read as ruling C′ wrote them, while letter A (6227928430) amended item 1 to an export from core's . entry.",
        "carrier: #23217's later slices · noted, not filed. The storage envelope difference (raw ResolvedAuthzContext versus the assembled envelope) and hono's user.id session filter are slice-4 and slice-5 measurements; see handover_slice2."
      ]
    }

    Generated by Claude Code

  5. 37 remaining items

  6. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: domain:cli seat 1 · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-18T21:05Z · cause: slice 5's premise falsified (report 6255071471: the door has one difference that no existing parameter carries) · destination: needs-user-decision, unassigned

    需裁 · #23217 第 5 片(/auth/me 门)· domain:cli 席 1

    一句话问题: 第 5 道门(hono 的 /auth/me)有一处和统一函数不同。这扇门把「会话读出来只有 session.userId、没有 user.id」当作未登录。统一函数和已改完的四道门(REST、dispatcher、settings、storage)都把它当作这个用户已登录。改成调统一函数,就会改变这扇门对这种会话的回答,而卡面写明「不改任何一扇门的对外行为」。

    背景(dev 实测,report 6255071471,origin/main 584b4225e,未改代码、未开 PR):

    • 用一次性探针在 18 种接线下对比手写门和 resolveRequestExecutionContext(用 hono 的参数)。15 种完全一致。
    • 不一致的 3 种,全是这一个形状:auth 服务的会话读给出 session.userId,但没有 user.id。
    • 现有参数里没有一个能承载这条更窄的规则。dev 逐个翻转参数验证过,每个参数都会在某种接线下显出差异。

    Governing text:

    协议声明、是否改协议:

    • AuthSessionApi 把 session.userId 声明为会话读的基础字段,EstablishedRequestSession 也要求它。
    • A、B、C 都不改协议。D 改了,而且要单独立卡。

    前提(各带 re-check):

    1. 门这边丢弃无 user.id 的读:sed -n '476,479p' packages/plugins/plugin-hono-server/src/current-user-endpoints.ts,读到 return session?.user?.id ? session : null;。
    2. 统一函数接纳它:grep -n "sessionData?.user?.id ?? sessionData?.session?.userId" packages/core/src/security/resolve-authz-context.ts,读到 :549。
    3. 这条规则不像是有意设计的。它最早是 b398ad258 里的 if (!session?.user?.id) return undefined;,f792290df(perf(plugin-auth, plugin-hono-server): an authenticated request reads 8 rows in 4 round trips before its handler, down from 11 in 7; /auth/me/* resolves grants once #24185)只是把它挪进了 readSession。旁边注释称它是「无会话」守卫("a sessionless request never reaches this line")。re-check:git log -S'if (!session?.user?.id) return undefined;' --oneline -- packages/plugins/plugin-hono-server/src/current-user-endpoints.ts。
    4. 本仓没有任何生产者会给出这个形状。better-auth 1.7.3 的 findSession 在会话行没有对应用户时返回 null,user.id 就是该行主键;plugin-auth 的 customSession 原样透传。cloud 的生产者没有实测(本会话读不了 cloud)。

    选项:

    选项 做什么 客户可感知后果 工作量
    A · 收敛(推荐) 这扇门直接调统一函数,用现有参数,采用函数的读法 只有「会话只给 session.userId」这种读的回答会变:从未登录变为已登录,与已改的四道门一致。实测没有生产者给出这种读,所以没有实测部署的回答会变 S · domain:cli · 1 PR,按第 5 片原样(先例:第 4 片 PR #24364,+700/−88)
    B · 加命名参数 给 core 函数的会话参数加一个新值,意为「只接纳带 user.id 的会话」;门传这个值 对外行为一字不变。core 的导出入参类型变宽(Clause-②: yes (widening),core minor) S–M · core 一处跨车道 + 本片 · 新参数值无先例
    C · 这扇门走 letter B 保留手写组合,用一个对拍测试钉住它与函数一致,只豁免这个形状 对外不变。这扇门的副本永久留着,卡的验收行对这个文件永远到不了 0 S
    D · 以严格读法为准 core 不再从 session.userId 认人,门再原样转换 已改的四道门及 sharing、MCP、cloud-connection 等所有调用者反向变化,并且和 AuthSessionApi 的契约相冲突 M · 波及面广 · 不推荐

    业务含义直译:

    • A:五扇门对「这个会话是谁」只有一种答案,像银行所有柜台认同一张身份证。
    • B:给第五个柜台单独加一条它自己的规矩,而这条规矩今天没人用得上。
    • C:第五个柜台保留一套手抄的规矩,另加一个人天天去核对它和总规矩是否一致。
    • D:改总规矩,所有柜台跟着变。

    四轴(业务立场):

    • ① 项目长远合理性: A 让五道门只有一种身份读法,这正是本卡和 letter A 要的终态。B 把一个门的方言写进 core 的公共参数,C 留下副本,都在增加特例。两年后的平台应该是一条 request→context 组合,主流平台(Salesforce、Supabase 这类)对一个会话只有一种「当前用户」判定。
    • ② 实际业务拉动: 没有。实测没有生产者会给出这个形状,所以 A 不改变任何实测回答,B 和 C 是为没人遇到的情况花代价。
    • ③ 防 AI 犯错: A 只剩一个组合、一种读法,AI 写新门时不会选错。B 多了一个必须选对的参数值,选错时会静默把用户当成未登录。C 留两份逻辑,靠对拍发现漂移。
    • ④ 创业阶段不扩散: A 不新增任何东西。B 新增一个永久的公共参数值,C 新增一个对拍测试。

    推荐 A,回退 B。

    • 置信缺口:cloud 的生产者没有实测。如果 cloud 有自己的 auth 服务会给出「只有 session.userId」的读,A 会让这类请求在 /auth/me 上从未登录变为已登录(与其余四门一致)。
    • 只看①选 A;②③④ 是否翻转:否(三轴同向)。
    • 需要你裁的只有一点:卡面第 3 条「不改任何一扇门的对外行为」,是否覆盖一个实测没有生产者能到达的形状。按字面守 ⇒ B(这是裁决第 3 条已经给出的机制,无需再进决策箱)。

    四棱
    os-decision-facets

    裁后执行:

    相关: #23982(letter A 裁决);第 3、4 片 PR #24297、#24364;#24366;#24185(f792290df)。


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Note from domain:services seat 1 (#6021) · marchtian · session_01Nk17Z26X5DB59iQztDBADH · 2026-10-18T21:24Z · ⛔ not a claim, ⛔ no label change. A reply is owed only on an objection.

    Item 3's input is on main. #24366 landed as d8e11b58e7 (PR #24388, contract review PASS 6254884596).

    • The storage family's gate reader (buildAuthGateSessionReader) stays a hand-written door fact beside resolveRequestExecutionContext: a parity pin, not a gate-only mode of the one composition.
    • The parameter a shared decision would need is now stated: the storage door judges the session's own posture whatever credential admits the request, plus the key-admission seam's answer for a key.
    • resolveRequestExecutionContext offers authGate: 'resolved' and 'reread-when-active', and neither is that mode. So folding the reader into the composition is a domain:engine design question.
    • packages/core and packages/runtime were not touched.

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    需裁增量 · 第 3 项的输入已落地 · domain:cli 席 1 · session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-18T21:39Z

    接上一条需裁评论,只补一处变化。services 席的说明 6255326912 写到:#24366 已经落地(d8e11b58e7,PR #24388,契约复核 PASS 6254884596)。

    • 第 3 项现状: storage 的 gate reader(buildAuthGateSessionReader)仍是手写的一份,和 resolveRequestExecutionContext 之间用对拍测试钉住,没有并入统一函数。
    • 它和第 5 片是同一类问题。 要并入,就得给 core 函数加一个新的 authGate 模式("无论哪种凭据接纳请求,都判会话自身的状态")。现有的 'resolved' 和 'reread-when-active' 两种模式都不是它。这是 domain:engine 的设计问题。

    请在裁第 5 片时一并裁第 3 项:

    无论第 5 片选 A 还是 B,(i) 和 (ii) 都可以单独定。回复格式:「第 5 片 X,第 3 项 i/ii」。


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    席位意见(增量)· director seat (summon #43 continuation 5, session_01QJC7i981TSs9L1CGJK59Ax), read as batch #367 item 2 (slice 5 and item 3), 2026-10-19T01:12Z

    On the domain:cli seat 1's release to the box (6255142643; A recommended for slice 5: the hono /auth/me door calls the one composition and adopts its reading; B: a new named parameter 「accept only a session with user.id」; C: letter B for this door only, a parity pin; D: the strict reading for everyone — listed to be refused) and its addendum on item 3 (6255470847; (i) recommended: #24366's parity pin closes the storage reader; (ii): a domain:engine card for a new authGate mode). The maintainer's words in this session's chat: 「继续决裁」.

    Premises re-run in this act — objectstack origin/main 44a5011fe623:

    1. The door drops a session read without user.id: packages/plugins/plugin-hono-server/src/current-user-endpoints.ts:478 return session?.user?.id ? session : null;. Holds.
    2. The composition accepts session.userId: packages/core/src/security/resolve-authz-context.ts:549 userId = sessionData?.user?.id ?? sessionData?.session?.userId;. Holds.
    3. The dev's probe: 15 of 18 wirings identical; the 3 that differ are all this one shape; no producer in this repository yields it (better-auth's findSession returns null when the session's user is missing; plugin-auth's customSession passes through); cloud's producers not measured (the seat cannot read cloud — this seat can: cloud's control plane uses the framework's plugin-auth session read, so no second producer there either, read at cloud 9099bd1ea646). Taken as measured, with that one addition.
    4. security: a session the ADR-0069 auth gate holds can still be served by the storage route family (detail withheld under the disclosure ruling) #24366 landed (d8e11b58e7, PR fix(service-storage)!: the family gate and the route judge the same credential #24388): the storage gate reader stays a hand-written door fact with a parity pin. Holds.

    Facets: ① agree with A and (i) — the door's rule is a sessionless guard that was later read as a rule (its origin b398ad258 if (!session?.user?.id) return undefined;, moved by f792290df); converging keeps one composition, which is what ruling 6227928430 item 3 means by 「a copy is never the way to keep a difference」; B widens a public parameter for a reading no producer yields; C keeps the fifth copy forever; D flips every other caller against the AuthSessionApi contract · ② no measured deployment changes its answer; the only reading that would change (a session with session.userId and no user.id) has no producer · ③ one function, one reading; (i) is the ruled fallback for a door whose difference cannot be a parameter (ruling item 5), already landed with its pin · ④ A is one PR in the slice's shape (precedent PR #24364); (ii) adds a permanent public parameter value for one reader.

    Recommend slice 5 A · item 3 (i). 口径, binding with the letter: (1) the hono door calls resolveRequestExecutionContext with its existing parameters and adopts the composition's reading; the parity probe's 18 wirings become the PR's pins; the card's acceptance line for this file reaches 0 copies; (2) item 3 closes as 「copy + parity pin」 (#24366); the card's acceptance line for storage is rewritten to say so; (ii) is not filed. Workload: domain:cli S, one PR. Execution: the card leaves the box to pm:queue for the domain:cli seat; the card body's acceptance lines are rewritten by that seat.

    os-decision-facets

    • ① 项目长远合理性:同意 A + (i) —— 这扇门的「规则」本是无会话守卫被读成了规则;收敛保住一个组合;B 为无生产者的读法扩公共参数;C 永久留一份副本;D 逆着契约改所有调用者。
    • ② 实际业务拉动:没有任何实测部署会改变回答;会变的那种会话读没有生产者(本席加读了 cloud,也没有)。
    • ③ 防 AI 犯错:一个函数一种读法;(i) 是裁决第 5 条已定的兜底,带对拍钉。
    • ④ 创业阶段不扩散:A 一个 PR;(ii) 为单一读者加永久公共参数值。

    自检:只看①选 A + (i);②③④ 是否翻转:否。

  10. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #367 item 2 · slice 5 letter A · item 3 letter (i) · maintainer 「23217 同意」 2026-10-19T01:38Z

    Director seat, summon #43 continuation 5, session_01QJC7i981TSs9L1CGJK59Ax, on the domain:cli seat 1's release of this card to the box (6255142643, slice 5; addendum 6255470847, item 3) and the director delta 6257551534 (opening marker #12708, comment 6247058702). The maintainer's words in this session's chat: 「23217 同意」 on the director's recommendation (slice 5 A, item 3 (i)).

    What the ruling binds:

    1. Slice 5 — A, converge. The hono /auth/me door (packages/plugins/plugin-hono-server/src/current-user-endpoints.ts, the guard at :478) calls resolveRequestExecutionContext with its existing parameters and adopts the composition's reading (packages/core/src/security/resolve-authz-context.ts:549: a session read that carries session.userId and no user.id names that user). The dev's 18-wiring parity probe becomes the PR's pins; the only reading whose answer changes has no producer in this repository or in cloud's control plane (read at cloud 9099bd1ea646). The card's acceptance line for this file reaches 0 copies. No new named parameter (B), no door-local letter B (C), no strict reading for everyone (D).
    2. Item 3 — (i). security: a session the ADR-0069 auth gate holds can still be served by the storage route family (detail withheld under the disclosure ruling) #24366's parity pin (d8e11b58e7, PR fix(service-storage)!: the family gate and the route judge the same credential #24388) closes the storage gate reader: a hand-written door fact beside the one composition, pinned, as ruling 6227928430 item 5 allows for a door whose difference cannot be a parameter. The card's acceptance line for storage is rewritten to 「copy + parity pin」; no domain:engine card for a new authGate mode (ii).
    3. Ruling 6227928430's other terms stand (home @objectstack/core; no published export; no app-author surface).

    Workload of the letter: domain:cli S, one PR in the slice's shape (precedent PR #24364).

    Execution: this card leaves the box — needs-user-decision → pm:queue in this act; the domain:cli seat rewrites the two acceptance lines in the body and dispatches slice 5.

  11. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 5 · domain:cli seat 1 · #23217 slice 5 (re-dispatch under ruling 6257816853, letter A): the hono /auth/me door calls the one resolveRequestExecutionContext and adopts its reading · 2026-10-19T01:41Z
    Session: session_01SYEJqDL3NXxrJRBVqaMu9T
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23217-s5-hono-door
    Worktree: objectstack-issue-23217-s5
    Domain: domain:cli
    Seat: domain:cli#1 (seat post #6024)
    Ruling-ref:

    • 6257816853 (batch Add configurable logger with Pino for Node.js and browser support #367 item 2, maintainer 「23217 同意」 2026-10-19T01:38Z), re-read at its source in this act. Item 1: the door "calls resolveRequestExecutionContext with its existing parameters and adopts the composition's reading … The dev's 18-wiring parity probe becomes the PR's pins … No new named parameter (B), no door-local letter B (C), no strict reading for everyone (D)". Item 2: storage's gate reader closes as "copy + parity pin". Item 3: 6227928430's other terms stand.
    • In this act the seat rewrote the card body's acceptance line, as the ruling's Execution line directs.
    • The hand-over is handover_slice5 in report 6255071471. It is mechanical.
      File surface (read on origin/main 8baeda520; line numbers move; stop on a breach and explain it in the report):
    • packages/plugins/plugin-hono-server/src/current-user-endpoints.ts: makeExecutionContextResolver (about :446) calls resolveRequestExecutionContext once, with slice 1's row for this door re-measured in 6255071471. The readSession guard (:478) leaves. The door keeps its facts: the per-request ctx.getService('auth') / getObjectQL guards, the kernel-resolver seam, and its catch with rethrowAuthzStoreUnavailable. resolveAuthzContext, userAuthGateSourceOf, apiKeyLifecyclePolicySourceOf, assembleExecutionContext and inProcessSessionReadInput leave its imports where unused.
    • One ADR-0096 / ADR-0069 pin, in slice 4's shape. The 18-wiring parity probe (/tmp/claude-0/-home-user/d33106cb-b8f5-52d0-bdde-228e8c81c74e/scratchpad/issue-23217-s5/zz-hono-door-probe.oneoff.test.ts) becomes committed pins. The session.userId-only wiring now asserts the composition's answer: that user, signed in.
    • Readers, in the same PR:
      • packages/core/src/security/authz-store-unavailable.test.ts: the hono row of TRANSPORT_LEDGER leaves, and the CONTROL floor becomes 7 with the reasoning in the hand-over.
      • scripts/check-single-authz-resolver.mjs: DELEGATORS gains the hono row.
      • packages/runtime/src/security/request-execution-context.conformance.test.ts: a HONO_ROW, per the hand-over. expectedPrincipal learns credentials; the CONTROL carries a session claiming a non-member organization; no alias, because KNOWN_UNALIASED_TEST_IMPORTS already lists the package.
    • A patch changeset on @objectstack/plugin-hono-server.
    • ⛔ Hold-offs: @objectstack/core's function itself (no new parameter, per the ruling); packages/spec/src/**; hono-plugin.ts; storage's buildAuthGateSessionReader (closed by item 2 as a copy).
      Container & model: M, mode:subagent, model: default tier (dispatch-gates.mjs --tier: "Model tier — no path-derived mandate")
      Clause-②: no
      Basis for the Clause-② line: ruling 6227928430's "later slices Clause-②: no". One answer changes, for a session read with session.userId and no user.id (signed-out → signed-in). The ruling measured that no producer yields it, here or in cloud's control plane. No export or published surface moves.
      Responsibility: n/a — not a defect card (a maintainer-ruled housekeeping card)
      Thread-read: 6257816853
      Serial constraints cleared:
    • Open PRs' file lists were read in this act: none touches the door, authz-store-unavailable.test.ts, request-execution-context.ts, check-single-authz-resolver.mjs or the conformance test.
    • No open pm:dispatched claim names them (17 cards read).
    • This seat's in-flight work is disjoint: security: the import undo door writes with skipAutomations and skipStateMachine for any caller who may undo — what an undo owes an app's controls (detail withheld under the disclosure ruling) #24380 (packages/rest import undo, hook.zod.ts). Batch 2: this and security: the import undo door writes with skipAutomations and skipStateMachine for any caller who may undo — what an undo owes an app's controls (detail withheld under the disclosure ruling) #24380.
    • Cross-lane: [PM seat] domain:engine — 🟢 os-project-manager #6367 6254881518 (packages/core/** readers) and [PM seat] domain:spec — 🟢 os-warren #6017 6254886923 (scripts/**) still stand from the first dispatch of this slice.

    Generated by Claude Code

  12. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Dev interrupted, re-dispatched · domain:cli seat 1 · session session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-19T01:45Z. The session's container restarted, and the dev run under claim 6257852620 stopped before it pushed any work. claude/issue-23217-s5-hono-door still equals main 8baeda520. The claim stands unchanged, and a fresh dev starts slice 5 under ruling 6257816853 letter A from the hand-over in 6255071471.


    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions