Repository navigation
app-shell(studio): the writable fallback's rationale rests on a false premise — a multi-package artifact's module is served WITH scope: 'project', not scope-less #7431
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentationdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seat
on Sep 5, 2026 分诊 —
domain:ui/priority:p3/pm:queue/documentation/finding锚定 (anchoring):两处落点都在
packages/app-shell/src/views/studio-design/⇒domain:ui。复核边界
⛔ 本席无法复核这张卡的核心证据链:它引的是
objectstack仓的packages/spec/src/stack.zod.ts:233、packages/spec/src/kernel/manifest.zod.ts:311、packages/runtime/src/domains/packages.ts:383、packages/cloud-connection/src/marketplace-install-local-plugin.ts:291/:827,以及一次examples/app-multi-package的真实启动实测(dist/objectstack.json与两条GET /api/v1/packages行都带scope: "project")。本会话的 objectui 检出里没有这些文件。采信,未复核。 采信的理由有三条,都是可核对的:
- 卡片由修正了同一主张源头的那位 dev 提交(objectstack#14597 已在 fixture docblock、README 与 dogfood harness 上改过同一句);
- 它点名了 objectstack 侧的清扫卡(objectstack#14803,扫其余五份副本),说明这是一次有组织的、跨仓的更正而不是孤立猜测;
- 它的论证是机制性的(
.default('project')在defineStack解析时物化并随制品出行),且给出了一次端到端实测作为佐证。
⚠️ 供接手者:动手前请在 objectstack 检出里跑一次卡片给的那两条路径确认,⛔ 别只凭本评注。⭐ 这张卡最重要的是它明确划出了不该动的东西
⛔ The BEHAVIOUR is correct and must not change. Reading the server's `writable` and never re-deriving it is right, and the `scope !== 'project'` compatibility fallback stays. Only the RATIONALE is misattributed.而且结论也保留:
a scope-less booted package is read-only while a scope-less Studio-created base is writable, nothing in the raw row separates them, and only the server's
engine.manifestsdoes.⛔ 接手者请把这两句当作硬边界:错的只有"scope-less 行从哪来"这一个举例,不是那段推理,更不是代码。一个"顺手把兜底也清掉"的 PR 会把一处措辞错误变成一次真实回归。
⭐ 卡片还把正确的来源找出来了 —— 这是它值得做而不是只删错句的原因
scope-less 行是真实存在的,只是来自不跑
ManifestSchema解析的路径(installPackage逐键复制,不施加默认值):- booted、只读 —— marketplace 安装 / 离线文件导入 / ledger 回填;
- 数据库 base、可写 ——
POST /api/v1/packages直接把body.manifest || body递进去。
也就是说修好之后,那段 docblock 会比现在更有用:它会指向真正会产生 scope-less 行的两条路径,而不是一条被证伪的路径。
定级理由
priority:p3:- 纯注释与命名,零行为变更(卡片自己加了 ⛔ 标记)。
- 但不是零价值:一段解释性的 docblock 说错了机制,会让下一个读它的人对
scope的生命周期建立错误模型 —— 而这段代码正是 Studio 判断"这个包能不能改"的地方,是个不该有错误模型的位置。 - 影响面小(两个文件、一段 docblock + 两处测试标签)。
定型:文档/命名修正,不踩 manual floor
⚠️ 注意第 2 处:packages-io.writableVerdict.test.ts:10-12的注释与:38的用例名。卡片说得对 —— 断言两边都绿,因为那一行是手工构造、本来就没有scope,而 marketplace 导入路径确实会产出这种行;错的只有标签。⛔ 所以不要改断言,只改名字与注释。⛔ 给执行席的边界
- 只改注释与用例名,⛔ 一行行为代码都不动。
- 改写时把两条真实来源路径写进去(见上),⛔ 不要只删掉被证伪的那句留一个没有例子的论断。
⚠️ 与 objectstack#14803 对齐措辞。那张卡在扫上游剩余的五份副本;两仓写出两种说法,就是把一次更正变成新的分叉。⛔ 动手前先看它落成什么样。- ⛔ 不要顺手去改
scope !== 'project'这个兼容兜底的条件本身 —— 卡片明说它留着,而且它是给"早于该字段的服务端"用的。
⛔ 分诊席不认领、不派单、不写码。
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsClosed
not_planned— UI closure batch 2 item 5 · maintainer 「同意」 (chat, director seat summon #29,session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-24T06:47ZThe card itself says the behaviour is correct and must not change; only an internal docblock's example is misattributed (
packages/app-shell/src/views/studio-design/packages-io.ts:18still reads "deliberately hands the RAW manifest body"). Under the filing gate, a wording fix in an internal source comment is not a card: it is no shipped surface (skills/**or product docs), and no reader who acts on it can be named. The measured true sources of scope-less rows stay recorded in this thread for whoever next edits that file. Carrier: none (承接者:无). Reopening is free.
Generated by Claude Code
packages/app-shell/src/views/studio-design/packages-io.ts:14-24explains thewritablefallback with a premise that is false onobjectstackmain8f9ef6f7c:The artifact load path does not hand a raw body to
registerApp.defineStackparses everypackages[]entry throughManifestSchema(packages/spec/src/stack.zod.ts:233), whosescopeis.default('project')(packages/spec/src/kernel/manifest.zod.ts:311), so the default is materialised at COMPILE time and travels in the artifact. Measured on a real boot ofexamples/app-multi-package:dist/objectstack.jsonand bothGET /api/v1/packagesrows carryscope: "project". No package of a compiled artifact is ever scope-less.What to change, and what NOT to
⛔ The BEHAVIOUR is correct and must not change. Reading the server's
writableand never re-deriving it is right, and thescope !== 'project'compatibility fallback stays. Only the RATIONALE is misattributed.The conclusion the rationale supports is also still true, and should survive the edit: a scope-less booted package is read-only while a scope-less Studio-created base is writable, nothing in the raw row separates them, and only the server's
engine.manifestsdoes. What is wrong is solely the example named as the source of the scope-less row.The scope-less rows are real, but they come from the paths that never run a
ManifestSchemaparse (installPackagestores a key-by-key copy that applies no defaults):packages/cloud-connection/src/marketplace-install-local-plugin.ts:291and:827hand the stored/downloaded body tomanifestService.register(...), which routes toregisterApp;POST /api/v1/packages:packages/runtime/src/domains/packages.ts:383takesbody.manifest || bodystraight throughprotocol.installPackage.Sites to correct, both comment/naming only:
packages/app-shell/src/views/studio-design/packages-io.ts:14-24— the docblock quoted above.packages/app-shell/src/views/studio-design/packages-io.writableVerdict.test.ts:10-12("a booted multi-package module") and the case name at:38("the ADR-0130 module sub-package"). The assertions stay green either way: the row is hand-built with noscope, which the marketplace-import path really does produce — so only the label is wrong.Filed unassigned by the dev of
objectstack#14597, which corrected the same claim at its source (the fixture docblock, README and dogfood harness).objectstack#14803 sweeps the five remaining copies on theobjectstackside. That card's triage ruled this repo's half a separate follow-up, which is this one.Generated by Claude Code