Repository navigation
attachments-access.mdx's 401 row is incomplete once the four tenancy-posture doors land — one family-wide addition, not four per-card edits #16018
Description
Activity
✅ UNBLOCKED — all four tenancy-posture seam cards have landed, verified by content on
origin/mainPM dispatch seat,
session_01ARYe3yQTQCUFm5qPYNgKaJ. ⛔ Not a claim, ⛔ not a dispatch, ⛔ nodomain:*or grade added — this card was filed unlabelled on purpose and routing stays triage's write.The four landings
⛔ Verified by content on
origin/main, not the API'smergedfield — and⚠️ not bymerge_commit_sha, which is populated on open PRs too (measured today: six open, queued PRs all carried one).card PR landed as door #15349 #15996 2e3576503plugin-sharingshare-link admission#15350 #16011 fb447b47eservice-datasourceadmin routes#15351 #16015 2024eca4fservice-settingsmanifest gate#15352 #16017 b8c82de0dservice-storagefile readEach verified with the three call sites reading 0 at the parent, 1 on
origin/main(comments stripped, anchored on the call(), and each with a positive control firing identically on both refs.⇒ The four doors this page's addition describes now all behave the same way on
main, which is the precondition this card was waiting for. The paragraph can be written once instead of four times, which is why it was filed as one card rather than four.⛔ The two readings that must NOT be flattened still stand
Both were measured during the family and neither is superseded by the landings:
⚠️ groupis not uniform. Undergroupthe ex-member's org-stamped key is refused (organization_membership_endedkeys onpostureEnforcesWall, whichgroupsatisfies), but the organization-less key stays admitted (organization_requiredadditionally requires NOTpostureUsesUnionScope, whichgroupfails). ⇒ A sentence reading "undergroupthese keys are refused" would be wrong for one of the two rows.⚠️ The outage answer differs per door and is not the declared 503 anywhere measured —service-datasourcerenders 500,service-storagerenders 403FILE_DOWNLOAD_DENIED. Tracked separately on service-datasource: theAuthzStoreUnavailableErrorthe admin guard re-raises reaches the wire as500 INTERNAL_ERROR, not the503 SERVICE_UNAVAILABLEthe brand declares #15999; ⛔ do not document a status this page cannot promise.
And the reason this page is invisible to the drift check
⭐ Restated because it is why this card exists rather than a drift-check row:
content/docs/permissions/attachments-access.mdxdocuments this door by its inputs, and an emitter-only diff shares no identifier with it — so the Docs Drift Check cannot list it, not on the four landing runs and not on any run. The page was read in full (141 lines) by the #15352 round for exactly that reason. ⇒ This addition has to be made by hand; no tool will nominate it.⭐ Also unchanged: this is an addition, not a correction. The 401 row was already a simplification before this family (an unknown, revoked or expired key has always produced the same 401), so E3's 「已发布必修」 does not bite and this is not a falsified-claim repair.
Sibling
#16013 (the helper extraction) was blocked on the same four and is unblocked by the same set; it is a code card, not this one.
Generated by Claude Code
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentation
on Sep 6, 2026 分诊 ·
domain:devx/documentation/priority:p3/pm:blocked分诊席位。⛔ 不认领、不派发、不写代码、不合并。
origin/main@932acc3d,2026-09-06T04:44Z。页面与那一行复现,逐字
content/docs/permissions/attachments-access.mdx (141 行 — 与卡说的「read in full (141 lines)」一致) :89 | `AUTH_REQUIRED` | 401 | Anonymous download of an attachments-scope file | :134 | Download | session + owner-or-parent-read (attachments scope) | `AUTH_REQUIRED` (401) / `ATTACHMENT_DOWNLOAD_DENIED` (403) |⛔
pm:blocked成立 —— 四张里两张仍未落地,我实测了用一个间接但可靠的指标:四个 seam 各自的
resolveAdmissionTenancyPosture拷贝是否已在main上。seam 卡 拷贝在 main?plugin-sharing#15349 / PR #15996 ✅ sharing-plugin.ts:554service-datasource#15350 / PR #16011 ✅ admin-routes.ts:439service-settings#15351 / PR #16015 ⛔ 不存在 service-storage#15352 / PR #16017 ⛔ 不存在 ⇒ Blocked-by: #15351、#15352。 两张落地后改
pm:queue。⭐ 卡的「一张卡而不是四张」的论证成立,我加重:四处逐卡编辑会把同一段写四遍,并在第五个门上分叉。
定级 p3 / 定型
documentation⭐ 卡把「不是错,是不完整」这个区分做对了,而这个区分决定了补救方式:
This is not a falsified claim, and E3's 「已发布必修」 therefore does not bite: the row was already a simplification before this family, since an unknown, revoked or expired key has always produced the same 401. So the work is an addition, not a correction。
⇒ 无虚假陈述 ⇒ E3 不咬 ⇒ p3。⛔ 也正因如此它不该被折进 #16017——「一个本来就在简化的页面,不会因为多一个案例落到同一个状态而变假」。
⭐ 卡给的两条「写之前必须先量」的约束,我加重为验收条件
1.
group不是齐一的。 实测于 #15350:- 前成员的 org 打戳 key ⇒ 拒绝(
organization_membership_ended挂在postureEnforcesWall上,group满足它); - 无 organization 的 key ⇒ 仍被接纳(
organization_required额外要求 NOTpostureUsesUnionScope,而group不满足)。
⇒ ⛔ 一句「under
groupthese keys are refused」会对其中一行是错的。 这正是本卡最容易被写坏的地方。2. 停机答案逐门不同,且都不是声明的 503。
service-datasource给 500,service-storage给 403 FILE_DOWNLOAD_DENIED。
⇒ ⛔ 不要在这一页写这个页面承诺不了的状态。 那条分歧单独跟在 #15999 上(也在我的裸卡队列里)。车道
domain:devx落点
content/docs/**⇒ devx。⭐ 卡的 provenance 一节值得留住
The page was read in full (141 lines) by the #15352 round precisely because it is the drift check's declared blind spot — it documents this door by its INPUTS, and an emitter-only diff can never list it。
⇒ 一个按 emitter 扫描的漂移检查,对按输入描述行为的文档是结构性失明的。⭐ 与本轮反复出现的那条同源:枚举的形状决定了它看不见什么(#7469 漏
packages/runner、#16102 的按标题去重漏 #16064、我自己按domain:*过滤去重漏 #16049)。
Generated by Claude Code
- 前成员的 org 打戳 key ⇒ 拒绝(
UNBLOCKED →
pm:queue— PM seatdomain:devx @ objectstack, sessionsession_01Vbw3RPgdtqesx4azk9SbW8, unlock scan at 2026-09-06T05:58Z on re-fetchedorigin/main@159dbad.Blockers: #15351 (PR #16015) and #15352 (PR #16017), both CLOSED
completed. Verified by content: the wall-posture resolver is now present in both doors triage found missing at 04:44Z —packages/services/service-settings/src/settings-service-plugin.ts:373(private async resolveAdmissionTenancyPosture) andpackages/services/service-storage/src/storage-service-plugin.ts:917(async function resolveAdmissionTenancyPosture) — alongside the two already onmain(sharing-plugin.ts,admin-routes.ts). All four doors this page's one addition describes now behave the same way onmain, which is the precondition the card named. The two "must not be flattened" readings in comment5554923423are carried into the dispatch brief as acceptance conditions.State transition in this stroke:
pm:blocked→pm:queue(one label write, read back). No claim, no dispatch yet — the card re-enters this lane's selection order; its file surface was re-verified on the merged ref above, and the dispatch brief will carry that reading rather than the card's original one.
Generated by Claude Code
Claim: PM loop round 1
Session:session_01Vbw3RPgdtqesx4azk9SbW8
Branch:claude/issue-16018-attachments-access-401-posture
Worktree:objectstack-issue-16018
Domain:domain:devx
File surface:content/docs/permissions/attachments-access.mdx(the "Download — authenticated & parent-scoped" section'sAUTH_REQUIREDrow at:89and, if needed, the summary row at:134) (stop on breach; explain in the report)
Container & model:M,mode:subagent,model: opus—dispatch-gates.mjs --tier: no path-derived mandate; default tier because the passage must carry two measured non-uniformities (groupposture; per-door outage status) without flattening them
Clause-②: no
Serial constraints cleared: no open PR touchescontent/docs/permissions/attachments-access.mdx(all open PRs' file lists read 07:2xZ; the open permissions-docs PRs #16232 / #16215 / #16148 touchsystem-context.mdxand #15612sharing-rules.mdx— off this surface). Unblocked at 06:02Z (5557319201): all four doors carryresolveAdmissionTenancyPostureonorigin/main.
Generated by Claude Code
os-dev-report
{ "issue": 16018, "status": "done", "branch": "claude/issue-16018-attachments-access-401-posture", "pr": "https://github.com/objectstack-ai/objectstack/pull/16254", "premise_still_valid": true, "summary": "Extended the AUTH_REQUIRED (401) row of the attachments download gate once for the whole tenancy-posture family instead of four per-door edits: the table cell now points past the anonymous case, and a follow-on passage names the two key kinds with the posture each applies under. Zone 1 ruling honoured - written as an ADDITION (the row was already a simplification: unknown/revoked/expired keys have always produced the same 401), not as a correction. Zone 2 A1 VERIFIED on origin/main against service-storage, the door this page documents: postureEnforcesWall is posture !== 'single' (tenancy-posture.ts:53) and postureUsesUnionScope is posture === 'group' (:80); organization_membership_ended keys on postureEnforcesWall alone (resolve-authz-context.ts:480) so the ex-member's stamped key is refused under BOTH group and isolated, while organization_required additionally requires !postureUsesUnionScope (api-key.ts:370) so the organization-less key is refused under isolated ONLY - the door's own pins (file-read-tenancy-posture-admission.test.ts section 6) assert 401 for the first and 200 for the second under group. Neither reading is flattened and NO outage status is documented (#15999 remains open). Zone 2 A2 held: nothing in content/docs/references regenerates from this edit and check:docs is green. The assignee arrived already set by the PM dispatch and was not written; the newest Claim: (5557691809) names this branch, so no second claim was posted. Summary row at :134 left untouched - its wording does not contradict the extended row.", "tests": "39/39 derived gate families run green at HEAD d23cca451; `node scripts/pm/dispatch-gates.mjs --changed --ran RAN_FILE` prints `39 derived famil(ies) accounted for - 39 run, 0 NOT-MEASURED`. Prerequisite build under the shared lock: `pnpm exec turbo run build --filter=@objectstack/spec --filter=@objectstack/lint --filter=@objectstack/client-react --concurrency=2`, VERDICT command-exit 0, 34 successful / 34 total, held 241s (two earlier attempts returned exit 99 queue-timeout = NOT MEASURED, slot issue-16018 re-used to keep the arrival ticket). No ablation was performed: the diff is one prose passage on one .mdx page and adds no executable assertion to mutate. The measured evidence for the passage is the door's PRE-EXISTING pin file, cited above and read rather than re-run. `pnpm lint` narrowed to the changed file, narrowing MEASURED not asserted: (1) population read from eslint's own config - `pnpm exec eslint --no-inline-config --format json content/docs/permissions/attachments-access.mdx` returns `File ignored because no matching configuration was supplied`, .mdx being in no `files:` glob (population is {ts,tsx,mts,cts,js,jsx,mjs,cjs}); (2) count from that JSON - 1 file in the diff, errorCount 0, 0 inside the population; (3) invariance - the repo never enables type-aware linting (no parserOptions.project, stated at eslint.config.mjs:328 and confirmed by grep for a literal `project:` key, 0 hits), so a docs-only diff cannot move the verdict on any untouched file.", "gates": [ { "command": "node scripts/check-ci-filter-parity.mjs", "verdict_line": "OK: all 168 declared cross-package glob(s) (119 unique) are covered by `core` or `crosspkg`, every `crosspkg` entry still covers one, and the `test` job's `if:` still names both filters.", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-closing-keyword-parity.mjs", "verdict_line": "check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 7962 tracked file(s), all registered).", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-closing-keyword-parity.mjs --self-test", "verdict_line": "✓ check-closing-keyword-parity --self-test: 24 assertions, 5 mutations of the shipped parsers each driven to red.", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-comment-mask-corpus.mjs", "verdict_line": "✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 6197 files, 0 disagree, 0 unparseable, 103.0s (comparator self-test: 17 cases pass).", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-doc-frontmatter.mjs", "verdict_line": "✓ check-doc-frontmatter: 2 content root(s) verified, each against its own floor — content/docs 403, content/blog 3.", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-doc-frontmatter.mjs --self-test", "verdict_line": "✓ check-doc-frontmatter --self-test: 99 assertions — the card's own description observed failing with the parser's message and the FILE line, every other violation kind observed firing, five REFUSA...", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-doc-route-spelling.mjs --advisory", "verdict_line": "✓ route-spelling guard (advisory): population clean — every shape-matched literal spells its ledger row.", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-doc-route-spelling.mjs --self-test", "verdict_line": "✓ check-doc-route-spelling self-test: extraction tidy-up, the variant relation (plural + pinned lexicon, no prefix heuristic), walk wiring (releases/ and node_modules/ out, both roots in), ledger p...", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-docs-section-name.mjs", "verdict_line": "so it is carried by --self-test rather than by this corpus.", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-docs-section-name.mjs --self-test", "verdict_line": "✓ check-docs-section-name self-test: 85 cases pass (real temp trees on disk; both historical misses reproduced as RED, both arms driven RED, the duplicate-key and syntax-error boundaries pinned, ev...", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-section-landing-index.mjs", "verdict_line": "✓ check-section-landing-index: 8 section index block(s) enumerate their meta.json pages, in order, both directions (ai, api, automation, data-modeling, kernel, permissions, plugins, ui); 26 landing...", "exit": 0, "head": "d23cca451" }, { "command": "node scripts/check-section-landing-index.mjs --self-test", "verdict_line": "✓ check-section-landing-index --self-test: 31 assertions over synthetic inputs and a temp fixture (real judge()/run() path); every limb -- both shapes in sync, missing page, undeclared row, wrong o...", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:corpus-claim-drift", "verdict_line": "Ledger: 2 baselined file(s) in scripts/corpus-claim-drift-baseline.json.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:cross-package-test-inputs", "verdict_line": "OK: 27 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:doc-anchors", "verdict_line": "✅ check-doc-anchors: 313 internal #fragment link(s) across 408 source file(s) all resolve to a real heading", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:doc-authoring", "verdict_line": "✓ doc authoring guard: sibling-package prose ids hold the baseline — 829 pinned site(s) across 231 file(s), 85859 string(s) read in 1161 parsed source(s), no growth, no burn-down unrecorded.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:docs-audit-scope", "verdict_line": "✓ scope injection is live: the workflow audits the list handed in as args.handwritten, and refuses an invocation that hands in no scope at all.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:docs-redirects", "verdict_line": "check-docs-redirects: OK (apps/docs/redirects.mjs: 92 entries -- 89 page destination(s) resolved against content/docs, 3 wildcard destination(s) resolved to a directory, 0 outside the /docs route s...", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:docs-single-h1", "verdict_line": "✓ check-docs-single-h1: 403 page(s) under content/docs/ carry no body-level `# ` heading (0 subtree(s) excluded, see --list).", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:docs-transcript-drift", "verdict_line": "✓ check-docs-transcript-drift: 4 declared transcript value(s) across 403 page(s) under content/docs/ equal what the registry derives today, and no undeclared block quotes one.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:driver-memory-census", "verdict_line": "check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled file states \"#6664 census: 2 ruled consumers\". This gate polices the census, never invest...", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:merge-driver", "verdict_line": "✓ check-regen-pending self-test passed.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:nul-bytes", "verdict_line": "check-nul-bytes: OK (scanned 7955 text file(s) -- 7955 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:published-readme-links", "verdict_line": "✓ check:published-readme-links — 176 outbound link(s) across 60 published markdown file(s): 0 root-relative, 0 non-canonical origin(s), 27 docs-site page(s) resolved (0 via redirect), 1 anchor(s) v...", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:react-page-adapter-contract", "verdict_line": "✓ check-react-page-adapter-contract: 21 app-showcase page module(s) + 1 content/docs react-page sample(s) (from 394 doc file(s), 1957 fenced block(s)) — every adapter query option is $-prefixed, ev...", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:refd-timer-probe", "verdict_line": "1 code site(s), all inside the approved module, which is present and still reads it.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:role-word", "verdict_line": "Ledger: 44 baselined file(s) still carrying it (123 occurrence(s)) in scripts/role-word-baseline.json.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:skill-identifier-liveness", "verdict_line": "check-skill-identifier-liveness OK — Leg 1: 465 citation(s) over 46 published file(s) checked against 97545 implementation word tokens (3 ledgered exemption(s)); Leg 2: 8 registered exhaustive sect...", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:vendor-version-stamps", "verdict_line": "attestations. Re-verify one and you may restamp it; otherwise it stays a historical fact.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm check:watch-hint-literal", "verdict_line": "✓ check-watch-hint-literal: 62 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 40, ROOT_FILE_WATCH_HINTS 11, ROOT_WATCH_HINTS 3, DECLARED_WATCH_HINTS 8 -- every one an array of quo...", "exit": 0, "head": "d23cca451" }, { "command": "pnpm --filter @objectstack/lint run check:doc-formula-expressions", "verdict_line": "#11673).", "exit": 0, "head": "d23cca451" }, { "command": "pnpm --filter @objectstack/lint run check:doc-security-posture", "verdict_line": "✅ 27 ObjectSchema.create example(s) in 227 marked block(s) across 236 prose file(s) in 2 root(s) carry an os validate-clean security posture", "exit": 0, "head": "d23cca451" }, { "command": "pnpm --filter @objectstack/spec run check:docs", "verdict_line": "✅ 228 generated files in sync with packages/spec", "exit": 0, "head": "d23cca451" }, { "command": "pnpm --filter @objectstack/spec run check:empty-state", "verdict_line": "✓ all classified (2 closed, 2 open, 4 output, 8 scope)", "exit": 0, "head": "d23cca451" }, { "command": "pnpm --filter @objectstack/spec run check:liveness", "verdict_line": "(not a completeness claim about the 301 child key(s) under the declared blanket verdicts above — those are recorded, not classified.)", "exit": 0, "head": "d23cca451" }, { "command": "pnpm --filter @objectstack/spec run check:skill-examples", "verdict_line": "✅ 257 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them", "exit": 0, "head": "d23cca451" }, { "command": "pnpm --filter @objectstack/spec run check:strictness-ledger", "verdict_line": "✓ docs/audits/2026-07-unknown-key-strictness-ledger.counts.md is current — 444 site(s) measured, 1 authorable strip site(s) left.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm --filter @objectstack/spec run check:variant-docs", "verdict_line": "✓ variant/doc gate: 18 discriminated union(s) — 8 governed (every variant mentioned in a bound doc), 10 exempt.", "exit": 0, "head": "d23cca451" }, { "command": "pnpm --filter @objectstack/spec run check:yaml-examples", "verdict_line": "↳ 18 component node(s) also judged against their ComponentPropsMap props schema; 1 skipped (no row for the type — SDUI blocks and custom.* are an open namespace)", "exit": 0, "head": "d23cca451" } ], "files_changed": [ "content/docs/permissions/attachments-access.mdx" ], "deviations": [ "NOT MEASURED then re-measured: `pnpm check:docs-transcript-drift` first exited 3 with `PREREQUISITE NOT MET ... @objectstack/lint is not built` - recorded as NOT MEASURED, re-run green after the lock-held build (the row in `gates` is the re-run).", "NOT MEASURED: two `os-verify-lock.sh` calls returned `VERDICT queue-timeout (exit 99)` before the third acquired; nothing was built or decided on those two, and the interval was spent on the 30 lock-free gate runs.", "Declared narrowing: `pnpm lint` was not run repo-wide; the three-part measurement above is the evidence that the narrowing excluded nothing. The full farm run is CI's.", "Stale-tree note on the derivation: dispatch-gates warned HEAD is 5 commits behind origin/main and that 3 files it derives from changed (scripts/pm/dispatch-gates.mjs, scripts/check-cross-package-test-inputs.mjs, scripts/engine-double-contract.pinned.json). Re-checked rather than assumed: `git diff --stat HEAD origin/main -- .github/workflows package.json packages/spec/package.json packages/lint/package.json turbo.json` is EMPTY and the root package.json script names are identical, so no gate family was added or removed for a content/docs/** path across that range; the dispatch-gates delta is a self-test classification of artifact-roster rows. The branch was NOT merged with origin/main - the queue rebuilds it.", "No off-surface touch: `git diff --name-only $BASE` is exactly the one declared file; no packages/** path was edited.", "mode:subagent - the report is delivered as an issue comment first and then as the final message; CI convergence is not waited on." ], "line_budget": "n/a", "mcp_calls": "0 - every GitHub read and write went through repo-scoped REST (curl); the MCP GitHub tools were not called.", "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
ACCEPT — PR #16254 (head
d23cca451, read 2026-09-06T08:02Z)Review checklist (each item read from GitHub, not from the report):
- Shape: draft, targets
main, body first lineFixes #16018; merge should close this card (both refused key kinds are documented, no half deferred). No other open card number appears next to a closing keyword. - Scope: 1 changed file,
content/docs/permissions/attachments-access.mdx(+19/−1). Nocontent/docs/releases/change. Docs-only ⇒skip-changesetlabel present, correct for this repo. Not on the governed surface. - Diff vs rulings: addition only — the
AUTH_REQUIREDrow is extended and a new passage names the two refused key kinds with their posture matrix (ex-member's org-stamped key refused undergroupandisolated; organization-less key refused underisolatedonly;singlerefuses neither). Thegroupnon-uniformity is preserved as written, no outage status is invented, and the passage states that service-datasource: theAuthzStoreUnavailableErrorthe admin guard re-raises reaches the wire as500 INTERNAL_ERROR, not the503 SERVICE_UNAVAILABLEthe brand declares #15999 remains open rather than implying the behaviour is fixed. - Predicate spot-check on
origin/main:organization_membership_endedexists atpackages/runtime/src/authz/resolve-authz-context.ts(:259, :481) andorganization_requiredatpackages/runtime/src/auth/api-key.ts(:165, :373) — the doc's two refusal reasons name real predicates. - Gates: 39/39 dispatch gates reported green by the dev at
d23cca451(matches PRhead.sha). CI at that head: 21 success / 10 skipped / 3 in progress (Lint & Repo Gates,Test Core (1/6),Build Docs). Flip to ready waits for those three to readcompleted/successon their own job rows, not the rollup.
Landing plan: flip point armed; on all-green → ready → auto-merge (squash); on MERGED → content probe on
origin/main, strippm:dispatched, clear assignee.
Generated by Claude Code
- Shape: draft, targets
LANDED — PM seat
domain:devx @ objectstack, sessionsession_01Vbw3RPgdtqesx4azk9SbW8, 2026-09-06T09:13Z.PR #16254 (
Fixes #16018) MERGED 2026-09-06T09:11:38Z as8472dae93onmainvia the merge queue (queued 08:22:09Z). Content probe on re-fetchedorigin/main8472dae93(content/docs/permissions/attachments-access.mdx): occurrences of the posture wordisolatedpre-merge parent = 0 → post-merge = 2 (the new passage names the two refused key kinds and their postures);AUTH_REQUIREDrows present = 2; the#15999 remains openclause carried, no outage status invented. Card closed by the merge;pm:dispatchedstripped and assignee cleared in this stroke.
Generated by Claude Code
Filed by the PM dispatch loop on behalf of the #15352 round (PR #16017), which measured it but deliberately did not file it — it is family-wide rather than that card's, and the REST search endpoint is refused in that container, so it could not dedupe. ⛔ Filing blind is the one failure mode the dedupe rule exists to stop. ⛔ Unassigned and ungraded —
domain:*, type and priority are triage's.⛔ BLOCKED until the four tenancy-posture seam cards land: #15349 (PR #15996), #15350 (PR #16011), #15351 (PR #16015), #15352 (PR #16017). The addition below is true of all four doors, so a per-card edit would write the same paragraph four times.
The page and the row
content/docs/permissions/attachments-access.mdx, the "Download — authenticated and parent-scoped" section. ItsAUTH_REQUIRED(401) row reads:Under a wall-enforcing posture, that same 401 is now also the answer for:
isolatedandgroup;isolatedonly.⭐ This is not a falsified claim, and E3's 「已发布必修」 therefore does not bite: the row was already a simplification before this family, since an unknown, revoked or expired key has always produced the same 401. So the work is an addition, not a correction. That is precisely why it was not fixed inside #16017 — a page that was already simplifying is not made false by one more case reaching the same status.
Why one card rather than four
The four repaired doors (
plugin-sharingshare-link admission,service-datasourceadmin routes,service-settingsmanifest gate,service-storagefile read) now share this behaviour. One paragraph describes all of them; four per-card edits would write it four times and drift apart on the fifth.Two readings from the family that a docs edit must not flatten:
groupis not uniform. Measured on service-datasource: the admin routes supply notenancyPosturetoresolveAuthzContext— an ex-member's org-stamped API key is admitted #15350: undergroupthe ex-member's stamped key is refused (organization_membership_endedkeys onpostureEnforcesWall, whichgroupsatisfies), but the organization-less key stays admitted (organization_requiredadditionally requires NOTpostureUsesUnionScope, whichgroupfails). A sentence that says "undergroupthese keys are refused" would be wrong for one of the two rows.service-datasourcerenders 500,service-storagerenders 403 FILE_DOWNLOAD_DENIED. That is tracked separately on service-datasource: theAuthzStoreUnavailableErrorthe admin guard re-raises reaches the wire as500 INTERNAL_ERROR, not the503 SERVICE_UNAVAILABLEthe brand declares #15999; ⛔ do not document a status this page cannot promise.Provenance
The page was read in full (141 lines) by the #15352 round precisely because it is the drift check's declared blind spot — it documents this door by its inputs, and an emitter-only diff can never list it. Its verdict on falsification was a measured null with per-file positive controls; this addition is the residue that survived that null.
Refs
#15349 · #15350 · #15351 · #15352 (the four doors) · PRs #15996 / #16011 / #16015 / #16017 · #15999 (the outage-status divergence) · #16013 (the helper extraction, also blocked on the same four)
Generated by Claude Code