docs(core): narrow ANONYMOUS_DENY_BODY to the REST seam + pin both declared 401 envelopes (#5632) - #5801
Merged
os-zhuang merged 1 commit intoAug 6, 2026
Conversation
…velopes (#5632) `ANONYMOUS_DENY_BODY` 的注释自称 "The single 401 body shape every seam returns",但只有 `@objectstack/rest` 的 `enforceAuth` 消费它;dispatcher 侧 五个 domain(ai / meta / security / actions / automation)走 `deps.error(...)`,发的是 wrapper 信封。注释窄化为 REST seam 的形状,并写明 另一半的归属;两个信封均为 live(ADR-0112 2026-07-30 修正案),收敛归 envelope-convergence 线(#3843 family),本单不动 wire。 conformance:在 PR #5631 落的匿名面切片同文件里补「每个 seam 的 401 body 属于且仅属于两种已声明形状之一 + 归属映射」,判形状用互斥显式判别,code / message 直接对 `@objectstack/core` 导出的常量断言,不写 `??` 跨族容忍读。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V7WetGmnfoXNn8cLieKKmx
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 24 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
marked this pull request as ready for review
August 6, 2026 07:09
os-zhuang
deleted the
claude/issue-5632-anonymous-deny-docstring-conformance
branch
August 6, 2026 07:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5632
按分诊预裁范围(评论 5197848801 = 正文方案 1 + 3)执行。方案 2(wire 收敛)未做:
rest-server.ts与 runtimedomains/*.ts行为一行未动,两个 live 信封的收敛归 envelope-convergence 线(#3843 family)统一排期。最终 diff 仅注释 + 测试,无运行时可见改动 → 请 PM 打
skip-changeset标签(#4898 路线)。packages/qa/dogfood是private: true,不发版。前提复核(先证后改,rule 6)
在动手时刻的
origin/main(f205c32)上重核:前提成立。ANONYMOUS_DENY_BODY的唯一消费者是packages/rest/src/rest-server.ts:1961(res.status(ANONYMOUS_DENY_STATUS).json(ANONYMOUS_DENY_BODY)),全仓 grep 除测试与security/index.ts的再导出外零命中。deps.error(ANONYMOUS_DENY_MESSAGE, ANONYMOUS_DENY_STATUS, { code: ANONYMOUS_DENY_CODE }):domains/ai.ts:131、domains/meta.ts:62、domains/security.ts:95、domains/actions.ts:132、domains/automation.ts:154。两形状归属表
GET /meta@objectstack/restenforceAuthANONYMOUS_DENY_BODY原样:{ error: 'UNAUTHENTICATED', message }GET /data/...POST /actions/:object/:action/:iddomains/actions.ts{ success: false, error: { code, message, httpStatus } }POST /automation/:name/triggerdomains/automation.tsGET /automationDELETE /automation/:namestatus / code / message 三者全平台一致,分歧只在 wrapper;两者均为 live(ADR-0112 2026-07-30 修正案 / #4007 记录在案)。
1. 说谎的 docstring(
packages/core/src/security/anonymous-deny.ts,仅注释)ANONYMOUS_DENY_BODY的一行注释扩成一段,窄化为 REST seam 的形状,并写全另一半:五个 dispatcher domain 走deps.error(...)的 wrapper 信封;两个信封均 live 且收敛归 #3843 family;明确劝阻body.error?.code ?? body.error这类跨族容忍读(#5632 立单理由之一,#5569 的集成用例里就出现过这条??链);末尾指向本 PR 的 conformance 用例文件。导出值一字未改。写法上刻意让下一个读者(尤其 AI)拿不到「唯一形状」这个读法:第一句就是 "NOT the platform's only one",并给出「你调哪个面就读哪个面 DECLARES 的信封」的操作性指令。
2. conformance 用例(
packages/qa/dogfood/test/showcase-anonymous-deny-surfaces.dogfood.test.ts,+7 例,11 → 18)落在 PR #5631 的匿名面切片同一文件,沿用其既有 harness(
getSharedShowcase(),shared-showcaseproject),未新建基建、未改 vitest 配置、未增加 boot 开销。与 #5631 切片的分工(测试注释里也写了这一段):#5631 那条用例把两族各按自身声明显式断言、并单独钉住共享的 code/message —— 用的是字符串字面量。它按构造无法失败的两件事:
toMatchObject,忽略未知键,重新嵌套 / 混合的第三种方言只要保留被匹配的子集就能过;@objectstack/core实际导出的常量之间的漂移 —— 字面量只会静静变陈旧。本 PR 补的正是这两处,不重复已覆盖的部分:
DENY_ENVELOPES把两个信封声明成互斥谓词的闭世界(一族error是字符串且无success,另一族success === false且error是带code/message/httpStatus的对象且顶层无message);declaredFamiliesOf(body)返回它满足的所有已声明族,契约是恰好一个。DENIED_SEAMS是 seam → owner → 族 的归属映射;it.each逐 seam 断言declaredFamiliesOf(body)恰等于[该 seam 声明的族]。第三种方言 →[]红;某 seam 换族 → 另一个族名 红,且两种失败在报错里可区分。ANONYMOUS_DENY_CODE/ANONYMOUS_DENY_MESSAGE比较(不再是本文件里的字面量)。⛔ 全程无??跨族容忍读。toEqual(ANONYMOUS_DENY_BODY)(窄化后 docstring 的正面主张,落到线上),且 dispatcher 面not.toEqual(ANONYMOUS_DENY_BODY)(反面那半)。将来 Envelope drift is not just service-storage: four more route modules emit bare bodies, two of them the pre-#3675{ error: '<string>' }#3843 家族真收敛、dispatcher 改发扁平信封时,红的就是这条 —— 它同时是「该回去重写那段注释」的提醒。覆盖面据实申报(实测,非假设):五个带匿名门的 dispatcher domain 里,本 boot 只有 actions / automation 可驱动。同一 shared showcase 上探针实测:
GET /ai/status答 501NOT_IMPLEMENTED(开源框架不含@objectstack/service-ai,且 ai domain 的门位于路由匹配之后,本 boot 根本不执行);GET /security/permissions答 404(showcase 注册路径不挂/security);/meta在本 stack 由@objectstack/rest提供,走的是扁平族而非 dispatcher 的 meta domain。所以 wrapper 族由 actions + automation 代表 —— 这段话写进了测试注释,哪天某个 domain 变得可达,加一行表项即可。反向验证(方向先判后跑)
预判先写(仅测试内 fixture 层面,产品代码零改动):
GET /automation行喂第三种方言{ error: { code, message } }(无success/httpStatus)declaredFamiliesOf得[]POST /actions/...行喂扁平信封(换族)[ 'rest-flat' ],报错与 M1 可区分ANONYMOUS_DENY_BODY.not.toEqual(ANONYMOUS_DENY_BODY)实跑,逐条命中:
变异已用
git checkout还原,树与提交08111f5一致。实跑记录(还原后)
自限
packages/core/src/security/anonymous-deny.ts(仅注释,导出值一字未改)与packages/qa/dogfood/test/showcase-anonymous-deny-surfaces.dogfood.test.ts。packages/rest/**、packages/runtime/**、content/docs/releases/;未改authz-conformance.matrix.ts(test(dogfood): cover /actions and /automation in the anonymous-deny proof artifact (#5570) #5631 已按 [security] Anonymous posture inconsistent across surfaces: dispatcher /graphql and raw hono /data bypass requireAuth (/meta now gated) #2567 惯例登记 actions / automation 两行,本 PR 不重复登记)。packages/spec/authorable-surface.base.json被gen:schema顺带重锚到本分支基点,已git checkout还原,未进提交。顺带发现(未在本 PR 修)
packages/runtime/src/endpoint-policy.ts:273的anonymousDenial()注释写着 "same code, same message, same envelope",而它调用的apiErrorResponse(error-envelope.ts:129)产出的正是 wrapper 信封 —— 与 REST seam 并非同一个信封,是 #5632 同一句谎话的第二个落点,而 #5632 正文未枚举到。已按 Prime Directive #10 单独立单 #5800(unassigned,查重后无重复),不在本 PR 修:分诊预裁把文件面锁死在上述两个文件,改第三个文件越界。🤖 Generated with Claude Code
https://claude.ai/code/session_01V7WetGmnfoXNn8cLieKKmx