Skip to content

rest: filterAppForUser treats app hidden flag as builder-only access gate — built-in account app returns 404 for all normal users #4829

Description

@baozhoutao

现象(17.0.0-rc.1,真机 A/B 实测)

@objectstack/rest 的 filterAppForUser():

if (item.hidden === true && !sysPerms.has('studio.access') && !sysPerms.has('setup.access')) return null;

把应用的 hidden(语义=不进应用切换器的导航呈现开关)当成了「builder-only / 未发布」的访问开关。而平台内置 account(账户)应用按设计就是 hidden: true(@objectstack/platform-objects 的 ACCOUNT_APP,注释:「Surface via the avatar dropdown, not the App Switcher」;console 头像菜单也特判 e.name !== 'account' 单独给它「个人资料」入口)。

结果:

  • 普通用户 GET /api/v1/meta/app 中 account 应用被整个抹掉,点头像 →「个人资料」→ 整屏「App not available — it may still be publishing」;改密码/头像/已关联账户/活动会话/收件箱全部不可达;
  • 持 setup.access 的管理员一切正常(只挂 Unpublished 黄条)→ 极易被当成偶发故障,长期无人发现。

期望

hidden 只影响导航呈现(应用切换器/我的应用),不参与访问判定;或给内置 account 应用豁免。

复现

  1. 空库启动 17.0.0-rc.1,建任意普通用户(无 studio/setup.access);
  2. 普通用户登录 console,点头像 → 个人资料 → App not available;同会话 GET /api/v1/meta/app 无 account。

下游临时对策(修复后可整体删除)

os-project-titanwind-ehr 登记 PLAT-DEF-040,PR steedos-labs/os-project-titanwind-ehr#745:启动插件以系统身份幂等下发 {hidden:false} 的 env 级 overlay(即 UI「Publish」按钮做的事)。副作用是「账户」出现在应用切换器——正因如此更说明 hidden 的两个语义(导航 vs 访问)必须拆开。

Activity

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

    @baozhoutao
    ContributorAuthor

    Claim: PM loop round 1 (explicit dispatch)
    Branch: claude/issue-4829-app-hidden-nav-only
    Worktree: framework-issue-4829

    Triage note: gate confirmed still present at packages/rest/src/rest-server.ts:1841, with a comment citing ADR-0045 (hidden: true = unpublished, externally invisible). That reading conflicts with platform-objects ACCOUNT_APP's authored hidden: true ("surface via avatar dropdown, not the App Switcher"). The fix must resolve the two semantics contract-first, not special-case blindly — agent will analyze against ADR-0045 and stop with needs_decision if the ADR genuinely mandates the current behavior.

  3. baozhoutao commented on Aug 3, 2026

    @baozhoutao
    ContributorAuthor

    Takeover: the 09:27 claim's session ended with no remote branch and no PR — presumed dead. This PM session (worktree objectstack-pm-dispatch-issues-8b2071) takes over the claim per maintainer's explicit dispatch instruction, reusing branch claude/issue-4829-app-hidden-nav-only. Dispatching now.

  4. baozhoutao commented on Aug 3, 2026

    @baozhoutao
    ContributorAuthor

    Escalation: App.hidden 的语义冲突需要维护者裁决

    开发 agent 已完成勘察,未写代码——两份已记录合同在同一个键上正面冲突,任一解法都要新增公共 spec 字段并修订 ADR,超出单个 PR 可单方面裁决的范围。

    背景(证据链,均已核实)

    1. App.hidden 与 ACCOUNT_APP 同一 commit 诞生(74470ad, 2026-05-28)。spec Zod 文档(packages/spec/src/ui/app.zod.ts:1072-1086)明确定义为纯导航语义:"Hidden apps stay fully routable and permission-checked",shell 经头像菜单呈现。
    2. ADR-0045(Accepted 2026-06-12, fa65285)把 hidden:true 重定义为 unpublished/外部不可见,依据是 "ADR-0019 launcher contract (hidden, active)"——但 ADR-0019 全文不含 hidden 一词,即 ADR-0045 引用了不存在的合同,且全文未提 account/头像菜单,从未有意识地废除导航语义。
    3. 两套语义各有完整活体实现:导航侧 = ACCOUNT_APP + console 头像菜单;访问侧 = rest gate(packages/rest/src/rest-server.ts:1841)+ publish-drafts 翻转(packages/runtime/src/domains/packages.ts:197-227)+ AI 物化路径。

    后果(本 issue 现象):普通用户的 account 应用被 REST 层整个抹掉,改密码/头像/会话管理全部 404;持 setup.access 的管理员无感,长期无人发现。

    待决问题

    App.hidden 的唯一语义应是哪个?unpublished(访问门)信号应落在哪里?

    方案 A —— hidden 恢复纯导航语义(spec 的出生合同),unpublished 另立机器管理键
    建议:app 上新增 machine-managed 布尔键,从 authorable input schema 排除,仅由 AI 物化路径写入、publish-drafts 清除;rest gate 改判该键。改动面:spec 新键 + ADR-0045 修订 + cloud 物化写入点 + runtime 翻转点 + rest gate + objectui Unpublished 横幅/Publish 按钮;存量 sys_metadata 行经 ADR-0087 转换(stored 行的 hidden:true 在现政权下语义唯一 = unpublished,可机械改写;代码态 ACCOUNT_APP 不入 sys_metadata,无歧义)。

    • 轴①(长期架构):呈现与生命周期是正交概念,合并进一个布尔正是本 bug 根因。A 保留 ADR-0045 全部机制(materialize-invisible、publish=翻转、外部 404),只换承载字段,并把悬空引用修正为真实合同——是修正记录,不是推翻决定。
    • 轴②(AI 难写错):hidden:true 是 AI/人类为个人设置类应用会自然写出的键(spec 文档至今就这么教)。A 政权下 unpublished 为机器专属键,input schema 不收,结构性杜绝误写。

    方案 B —— 维持 ADR-0045 的 hidden=unpublished,另铸导航呈现键(如 showInLauncher:false)
    改 ACCOUNT_APP 授权、重写 spec 文档字符串、objectui 切换器 + 头像菜单改读新键。改动面同样跨三仓。

    • 轴①:把误导性命名固化为公共合同,此后每个读到 hidden 的人都要背注解,长期成本显著。
    • 轴②:AI 自然写出的 hidden:true = 全员 404,且授权时零反馈,本类 bug 必然复发。

    方案 C —— rest 层特判 name==='account':已否决,无合同可指,纯打补丁。

    PM 推荐

    A,两轴同向,无需权衡。附属子问题(若采纳 A):unpublished 键放 app 级(忠实 ADR-0045 逐 app 翻转,改动最小)还是 package 级(概念上发布单元是包,但要改 gate 取数路径)——推荐 app 级。无论 A/B,均需修订 ADR-0045 并在 gate/翻转点留 ADR 锚(scripts/adr-anchors.json)。

    关联

  5. removed their assignment
    on Aug 3, 2026
  6. baozhoutao commented on Aug 3, 2026

    @baozhoutao
    ContributorAuthor

    Maintainer decision: 暂缓处理(2026-08-03)。issue 保持 needs-user-decision 挂起,不进入派发队列;上面的两轴分析为裁决时的输入。下游 titanwind 的 PLAT-DEF-040 overlay 临时对策继续生效。

  7. xuyushun441-sys commented on Aug 4, 2026

    @xuyushun441-sys
    Collaborator

    维护者裁决(2026-08-04,经 PM 会话 session_018iARDqtrhQgz6fVHDeDkbQ 转达并留档)—— 方向 A1,v17 后实施

    本条取代 2026-08-03 09:41 的「暂缓处理」记录。裁决过程说明:PM 曾按议题正文的三选项框架建议"hidden 直接退出访问判定",派发后 dev 正确地停手拒做并核出两个否定该方案的事实 —— ① 该访问门是 ADR-0045 §3(Accepted)的正文机制,带 4 个 pin 测试与 publish-drafts 的翻转实现,直接删除等于用 patch 静默推翻已接受的 ADR(PD #13 禁止);② 真正的病根是 spec 与 ADR 对同一个键各说各话:app.zod.ts:1073-1086 给 hidden 写的出生合同是纯导航("Hidden apps stay fully routable and permission-checked",且点名 Account 类应用),与 ADR-0045 §3 正面冲突。维护者据更正后的分析重新拍板:

    裁决内容

    1. 方向:A1(新机器管理键承载发布门) —— app 上新增机器专属键(如 unpublished,命名实施时定),从可作者化 input schema 排除:仅 AI 物化路径写入、publish-drafts 清除;REST 访问门改判该键;hidden 回归 spec 出生合同的纯导航语义。同时:修订 ADR-0045(修订状态行,非新 ADR)、在 rest-server.ts 门本体与 runtime/domains/packages.ts 翻转点补 adr-anchors 锚(dev 已核实两处均无锚,正是 PD [WIP] Add Chinese version of the documentation #13 的复发形态)、存量 sys_metadata 行走 ADR-0087 转换、顺带修 ADR-0045 对 ADR-0019 的悬空引用。键放 app 级(忠实 ADR-0045 逐 app 翻转)。
    2. 时机:v17 发布之后实施 —— 跨 spec/runtime/rest(+cloud/objectui)的协议变更不进发版窗口。期间下游 titanwind PLAT-DEF-040 的 overlay 临时对策继续有效,修复落地后整体删除。
    3. 车道:含 spec 可作者化面变更,实施需 spec 车道牵头或协同;本条裁决供其排批,实施单届时按 ADR-0087/retirement 流程拆分。

    归档要点(取自停手 dev 的核查,供实施者直接使用)

    • 门本体:packages/rest/src/rest-server.ts:1837-1843;pin 测试:packages/rest/src/rest.test.ts:2890-2922;publish 翻转:packages/runtime/src/domains/packages.ts:195-234;spec 合同:packages/spec/src/ui/app.zod.ts:1073-1086;ADR:docs/adr/0045-...md:96-102, 171-173。
    • 两轴论证:呈现与生命周期正交,压进一个布尔是病根;机器专属键让 AI 写出的 hidden:true 结构性地只影响导航(防误写),而删门方案的失败方向是误露且静默,比现状更糟。

    needs-user-decision 摘除,改挂 protocol:breaking 待 spec 车道排批。


    Generated by Claude Code

  8. 4 remaining items

  9. os-project-manager commented on Aug 8, 2026

    @os-project-manager
    Collaborator

    维护者裁定执行存档(2026-08-08 06:2xZ,domain:cli 席代执行)

    维护者已批准 cli 席决策箱分析中对本卡的处置:按既有裁定(本卡归 spec 车道 lead),标签 domain:cli → domain:spec,使 spec 席的 sweep 能够看见并派发本卡。本次改标是维护者裁定的代执行,非本席自行分诊(cli 席会话 session_017uFVNMmTxLpmfQYiuKM1Yx)。bug / pm:queue / protocol:breaking / target:v17 保持不变。


    Generated by Claude Code

  10. self-assigned this
    on Aug 9, 2026
  11. os-zhuang commented on Aug 9, 2026

    @os-zhuang
    Contributor

    Claim: PM loop (domain:spec seat, #6017; maintainer directive 2026-08-09: continue v17 spec tasks — this is the top open v17 board item)
    Session: session_011sGk4SKHqGRgmmqUok1P8M
    Branch: claude/issue-4829-unpublished-key-a1
    Worktree: cloud session (own container — per the 2026-08-07 window re-ruling's own sizing: «L 级,mode:cloud 单容器,spec 车道牵头跨 rest/runtime 协同»)
    Domain: domain:spec (maintainer-approved relabel 2026-08-08; spec-lane lead per the A1 ruling)
    File surface (cross-lane touches authorized by the ruling itself): packages/spec/src/ui/app.zod.ts (machine-managed key + hidden doc restored to birth contract, key EXCLUDED from authorable input schema); ADR-0087 conversion + registries; packages/rest/src/rest-server.ts gate (:1837-1843) re-judged on the new key + packages/rest/src/rest.test.ts pins (:2890-2922); packages/runtime/src/domains/packages.ts flip (~:195-234); docs/adr/0045-*.md revision (+ dangling ADR-0019 reference fix); scripts/adr-anchors.json (gate + flip anchors); generated trees. ⛔ cloud/objectui halves are follow-up cards filed at ACCEPT (materialization write point; Unpublished banner). (Stop on breach; explain in the report.)
    Serial constraints cleared: domain:cli in-flight = 0 (verified); domain:spec in-flight = #6866 only (landing lap; shares the ADR-0087/migrations tables ⇒ this card branches off main AFTER #6866 merges or re-merges over it — landing serialized by this seat). scripts/adr-anchors.json is tonight's known hot file (PR #6608's conflict) — union-keep discipline applies.
    Container assessment: L, mode:cloud (per the ruling).


    Generated by Claude Code

  12. os-zhuang commented on Aug 9, 2026

    @os-zhuang
    Contributor

    OS-DEV-REPORT

    {
      "issue": 4829,
      "status": "done",
      "branch": "claude/issue-4829-unpublished-key-a1",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/6942",
      "premise_still_valid": true,
      "summary": "Implemented direction A1 as ruled. The ADR-0045 §3 publish gate moves off `app.hidden` onto a new machine-managed key `app._unpublished`: declared on AppSchema, written by the AI materialization path (cloud), cleared by `publish-drafts`, and judged by `filterAppForUser`. `hidden` keeps its birth contract (navigation presentation only) with the incident written into its docblock, so the built-in Account app is served to every user again. ADR-0045 is amended (status line + §2/§3 + a closing amendment section) and its dangling ADR-0019 reference corrected — re-verified: ADR-0019 contains zero occurrences of the word `hidden`. Both implementation sites are now anchored in scripts/adr-anchors.json (neither carried an anchor before, which is why §3 could be changed without anyone knowing a decision was being changed). Stored rows cross over via ADR-0087 D2 conversion `app-hidden-to-unpublished`. NAMING: `_unpublished`, not bare `unpublished` — the repo has no per-key authorability switch (check:authorable-surface derives the surface from the Zod graph, so declared == authorable there), and the one marker it does have for machine-written keys is the `_` prefix (ADR-0010's `_lock`/`_provenance` envelope, the prefix lintAuthoredRecordKeys skips). A bare `unpublished` would have been advertised to authors by spec-changes.json, the upgrade guide and the generated reference — teaching exactly the mis-authoring axis ② wants prevented. It is nonetheless DECLARED rather than omitted, because the write path validates against that same schema (saveMetaItem → 422; Registry.validate('app') → AppSchema.parse at objectql/src/registry.ts:1627), so an undeclared key would make the platform's own flip unwritable; the strict door answers `unpublished`/`published`/`draft` with 'publish state is not authorable' instead of a rename suggestion. RETIRED-FROM-LOAD-PATH IS LOAD-BEARING: `hidden` is not retired, so a conversion running on the load path would rewrite defineApp({hidden:true}) and ACCOUNT_APP itself into unpublished apps and reproduce this very bug through the conversion layer; retiredFromLoadPath confines the rewrite to stored rows and that exclusion is pinned in the negative.",
      "tests": "ALL LOCAL GREEN. Suites: spec `vitest run` 349 files / 9058 tests passed (merged tree); rest `vitest run` 73 files / 1142 passed; runtime `vitest run` 115 files / 1744 passed; objectql sys-metadata-repository 36 passed. GATES — full lint.yml list enumerated and run one by one, ALL PASS: lint, check:slot-lookup, check:query-options-erasure, check:verify-stand-in, check:nul-bytes, check:doc-authoring, check:docs-audit-scope, check:role-word, check:quick-reference-counts, check:adr-anchors (43 anchors, both mine present), check:org-identifier, check:authz-resolver, check:service-providers, check:route-envelope, check:error-code-casing, check:wildcard-fallthrough, check:meta-type-normalized, check:init-service-contract, check:durability-log-level, check:startup-registry-verdict, check:objectui-changeset, check:release-notes, check:release-body, check:workflow-status-functions, check:shard-attestation, check:published-files, check:engine-double-contract, check:kernel-hook-pairs, check:resume-authority-declared, check:driver-memory-census, check:merge-driver, check:spec-parsed-alias, check:tenant-chokepoint, check:type-check-coverage, check:driver-conformance, check:stall-guard, check:skill-frame-sync, check:skill-compatibility, check:agent-model-declared, check:i18n, check:i18n-coverage, check:app-nav-i18n, spec tsc --noEmit, turbo typecheck (120/120 tasks), check:type-check-debt (re-measured after the closure build; no entry above its ceiling; the reported surpluses are pre-existing and in packages I did not touch), plus the spec-package artifact gates: check:generated --reconcile-only, check:skill-docs, check:spec-changes, check:upgrade-guide, check:authorable-surface, check:docs, check:skill-refs, check:react-blocks, check:api-surface, check:exported-any, check:dual-source-exports, check:skill-examples, check:doc-formula-expressions. PLUS the pr-automation.yml blind spot: node scripts/check-adr-0087-registration.mjs --base origin/main → '1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … registered app-hidden-to-unpublished (new here)'. REVERSE VERIFICATION (direction predicted BEFORE each run, work committed and pushed first): (1) gate reverted to `hidden` → predicted the account pins and the unpublished-drop pin fail; measured 10 failures across rest.test.ts + meta-app-publish-gate.test.ts, including 'LIST: a user with NO permissions receives the hidden `account` app' — the user-facing bug reproduced on the wire. (2) flip reverted to `hidden` → predicted 0 saveMetaItem calls and the hidden-untouched pin failing; measured 4 failures, exactly those plus the two log/mid-loop pins that read the key. (3) retiredFromLoadPath dropped from the conversion → predicted the authored Account app gets converted on the load path; measured 2 failures including '⛔ does NOT fire on the LOAD path'. Tree restored clean after each. REJECTION CASES assert code+status per ADR-0112: the single-item 404 pin asserts statusCode 404 AND error.code RESOURCE_NOT_FOUND. NEW TEST FILE: packages/rest/src/meta-app-publish-gate.test.ts — check-type-check-coverage --re-measure run after the closure build, no ledger entry raised. SERIALIZATION: #6866 merged mid-flight; merged origin/main (11 commits), resolved the one conflict (objectql test — union-kept main's `intent: 'runtime-only'` plus my key rename), committed the merge FIRST, then re-ran every generator on the merged tree; asserted both siblings' entries coexist (conversions major-17 list has appHiddenToUnpublished, migrations chain has notification-list-cursor-retired, adr-anchors 43 with both of mine, upgrade guide carries both). check:authorable-surface GREEN on the merged tree. CI ON PR #6942 (head 792475a) CONVERGED — no fleet stall: ESLint success, TypeScript Type Check success, Check Changeset success, Spec property liveness success, Test Core 1/3+2/3+3/3 success, Dogfood Regression Gate 1/3+2/3+3/3 success, Dogfood Verify CLI success, Build Core success, Build Docs success, Temporal Conformance (live PG + MySQL) success, Console Pin Freshness success, Check Documentation Links success, Check PR Size success. ONE RED, BY DESIGN: 'ADR maintainer approval' — the #6785 gate on docs/adr/** PRs. Its own log: 'Drafting this PR was fine and stays fine -- only the MERGE is reserved. Green path: the maintainer (@hotlong) reviews and approves'. Left as a DRAFT, not merged, not queued, no auto-merge armed (AGENTS.md PD #14).",
      "open_questions": [
        {
          "question": "Rename the `publish-drafts` response fields `unhiddenApps` / `unhideError` to match the new mechanism?",
          "options": [
            "A - leave them (what this PR did): they are a wire contract read by the objectui Publish button, and this repo cannot verify or update that consumer, so a rename here is a silent cross-repo break of exactly the kind #4829 is about. A code comment records that the name predates the split.",
            "B - rename now and document it in the changeset: the names are misleading the moment `hidden` stops being the mechanism, and this PR is already protocol:breaking with an upgrade-guide entry."
          ],
          "recommendation": "A, and fold the rename into the objectui follow-up card so both halves land together. The field is informational (a name list for the re-sync announce), so the cost of the stale name is one comment; the cost of getting B wrong is an objectui Publish button that silently stops reporting what it published — a silent failure, which is the failure class this whole card exists to remove."
        },
        {
          "question": "Should a STORED app row (sys_metadata, not a code artifact) be able to declare nav-hidden going forward?",
          "options": [
            "A - not yet (what this PR did): the conversion permanently rewrites stored `hidden: true` to `_unpublished: true`, so nav-hidden is declarable on the app ARTIFACT (which the conversion never touches) and not on a stored row. Measured as costless today: the Studio app form has no `hidden` control, and under the old regime a stored `hidden: true` could not mean nav-hidden anyway because it 404'd the app for everyone.",
            "B - make the stored population distinguishable now, e.g. by having the write path stamp `_unpublished: false` on every app save so the conversion can skip already-canonical rows."
          ],
          "recommendation": "A. B buys a capability nothing asks for today and pays for it with a stamp on every app write plus a rule about two populations that cloud and objectui would both have to honour. If a stored nav-hidden app is ever wanted it deserves its own decision (a Studio control and a coexistence rule), which the conversion's docblock says out loud rather than leaving the silence to be discovered."
        }
      ],
      "out_of_scope_findings": [
        "cloud (follow-up card, PM to file): the AI additive-materialization write point must stamp `_unpublished: true` where it stamps `hidden: true` today, and STOP writing `hidden` — writing it now only affects App Switcher placement and gates nothing. No other change to apply_blueprint's envelope.",
        "objectui (follow-up card, PM to file): Unpublished banner reads `app._unpublished === true` (was `app.hidden`); Publish button keeps calling POST /packages/:id/publish-drafts unchanged; a direct per-app publish becomes PUT /meta/app/{name} with body {\"_unpublished\": false} (was {\"hidden\": false}); the App Switcher KEEPS filtering on `hidden` and must NOT filter on `_unpublished` (the server already withholds those apps); `unhiddenApps` / `unhideError` unchanged in this PR — rename in lockstep or not at all.",
        "os-project-titanwind-ehr: PLAT-DEF-040 (PR steedos-labs/os-project-titanwind-ehr#745) — the startup {hidden:false} overlay is deletable once this ships, and its side effect (Account appearing in the App Switcher) goes with it. Verified NO in-repo action is needed for it.",
        "PM mechanism assumption CONFIRMED, not assumed: a whole-repo sweep found NO in-repo materialization writer of app-level `hidden: true`. The only in-repo writer of app visibility is the publish-drafts flip (which writes false), and the only in-repo `hidden: true` AUTHOR is platform-objects' ACCOUNT_APP, which is a navigation declaration and correctly stays as it is.",
        "check:type-check-debt reports pre-existing surpluses unrelated to this change (@objectstack/plugin-security TEST_DEBT 21 vs 10 measured; @objectstack/http-conformance 4 vs 3; 307 raw errors across 13 entries below their ceilings). Not touched here — lowering them is bookkeeping the gate itself calls optional, and #6376 already tracks the class."
      ]
    }

    Generated by Claude Code

  13. os-zhuang commented on Aug 9, 2026

    @os-zhuang
    Contributor

    ACCEPT → PR #6942. Reviewed under the report-missing fallback (no OS-DEV-REPORT comment landed; cloud session is IDLE/review-ready, the PR body carries the full delivery record, CI converged): 24/25 green, and the single red — ADR maintainer approval — is that gate working as designed, not a failure.

    ⛔ This seat does NOT arm auto-merge and does not merge: the diff touches docs/adr/**, so AGENTS.md Prime Directive #14 reserves the merge for the maintainer, by hand. The dev correctly recognised this, left the PR out of the queue, and requested @hotlong's review. Maintainer action required to land it.

    Review highlights: the naming call (_unpublished, not bare unpublished) was measured rather than chosen — there is no per-key authorability switch in this repo, check:authorable-surface derives authorability from the Zod graph, and the _ prefix is the repo's one existing "machine writes this" marker (ADR-0010 envelope, lintAuthoredRecordKeys skip); a bare spelling would have advertised itself in the upgrade guide as newly authorable, teaching the exact mis-authoring axis ② forbids. retiredFromLoadPath: true on the conversion is load-bearing and pinned in the negative — without it the repair machinery would rewrite defineApp({hidden:true}) and ACCOUNT_APP into unpublished apps, reproducing #4829 through its own fix. Three reverse verifications predicted-then-measured, incl. the user-facing repro ("a user with NO permissions receives the hidden account app", 10 reds). The PM's mechanism assumption (in-repo materialization writer) was tested and confirmed absent. The unhiddenApps / unhideError wire fields deliberately NOT renamed — correct call: renaming a contract this repo cannot verify would be the same class of silent break the PR exists to fix.

    Follow-up cards filed from the PR's mandatory-answer contracts: cloud half and objectui half (cross-referenced below).


    Generated by Claude Code

  14. claude commented on Aug 9, 2026

    @claude
    Contributor

    Queue steward — landing note for this issue's PR #6942 (round 71).

    PR #6942 entered the objectstack merge queue at 06:17:28Z and its ADR Merge Approval gate returned failure at 06:17:46Z, because the diff touches docs/adr/0045-additive-materialization-and-visibility-gate.md and the PR carries no APPROVED review from the maintainer's own account (the ruling being enforced is #6741). Full signature and the gate's verbatim output are on the PR: comment.

    This is a deterministic governance gate, not a flake — ⛔ the steward did not requeue, since every rebuild reproduces it identically. The only green path is @hotlong's own APPROVED review, which re-runs the check automatically via the pull_request_review trigger.

    Nothing here is code work and nothing is being asked of this lane beyond awareness: the queue entry will not land until the approval exists.


    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