Repository navigation
[finding] enableOnInstall is declared in three schemas and honoured by no handler — an author sets it and the runtime silently ignores it #18605
Description
Activity
Ruling: batch #153 item 5 · letter 1 (the install door honours
enableOnInstall— the registry row'senabledis written from the request, defaulttrue; the request contract inpackage-api.zod.tsis the one authority, the other two declarations are re-read and folded to it if they are copies) · maintainer 「其他同意」 2026-09-18T03:59ZDirector seat, summon #24,
session_01Wj1HUjzyeiBQ8atRf1ZhaL. Presented in detail with the recommendation 1 (fallback 2); the maintainer agreed. Facts (this card; triage 5716495362; seat re-check):enableOnInstallis declared atpackage-api.zod.ts:261(defaulttrue),package-registry.zod.ts:283andmarketplace.zod.ts:494; the first-party SDK sends it (packages/client/src/index.ts:2525) and a test pins that it does (client.test.ts:2666); no handler inruntime,metadata-protocolorobjectqlreads it. The package registry row already carriesenabled: z.boolean().default(true)(package-registry.zod.ts:98) — 「installed but not yet enabled」 is an existing state; the install door simply never copies the request key into it. Installing a package disabled for a staged roll-out is ordinary operations.Ruling — 1
- The install door (the live one,
POST /api/v1/packages, per [finding]PackageInstallRequestSchemais a published, route-bound request contract that no layer parses — the install door is declared and enforced nowhere (ADR-0049) #18058's ruling A) writes the registry row'senabledfromenableOnInstall ?? true; a package installed withfalseis present, not active, until enabled through the existing enable path. Pins:enableOnInstall: falseyields a row withenabled: false(red on the current head); the default yieldstrue(control); the zero-reader claim is re-established first with a same-subject control that hits, as the card demands. - One authority: the request contract in
package-api.zod.ts. The claimant re-reads the two other declarations — a copy of the request key is folded to a reference; a declaration that means something else (a stored-row field, a marketplace listing attribute) stays and says so. ⛔ No silent unification of three published declarations. Clause-②: no(the accept set does not move; a declared key starts being honoured); changeset on the runtime package that owns the door, minor. The same seat may take this with [finding]PackageInstallRequestSchemais a published, route-bound request contract that no layer parses — the install door is declared and enforced nowhere (ADR-0049) #18058 ruling A — one door, one round.- ⛔ 2 — a breaking retraction of a key the official SDK sends, for a capability the registry model already has.
Four-facet reading: ① the official client is the measured victim; ② declaration honoured, state already present; ③ the purest AI-metadata trap — accepted, pinned, ignored — closed; ④ one branch at one door.
Execution
needs-user-decision→pm:queue;domain:spec,priority:p1stay.
Generated by Claude Code
- The install door (the live one,
os-elon-musk commented
on Sep 18, 2026 CollaboratorMore actionsDeferral note +
pm:retriage— this p1 card's fix is measurably already in flight on another seat's PR, and this card is not linked to it.domain:specseat 3,session_019srGWGCBBCBHqcDoRZpQRh, R1. ⛔ Not claimed, ⛔ not dispatched, ⛔ no label of this card's own state stripped.Why this card was skipped rather than taken
This card sits in the lane's p1 band, so the take order reached it before the p2s this seat did dispatch. It was skipped on a measurement, not a preference:
PR #18752 (card #18058,
os-litant, seat 1, draft) carries 68enableOnInstallmentions in its patch, read from the per-PR files endpoint at 2026-09-18T04:13Z:file in PR #18752 enableOnInstallmentions in the patchpackages/runtime/src/domains/packages-install-enable-on-install.test.ts34 packages/spec/src/api/package-api.test.ts9 .changeset/18058-install-door-contract-rebind.md6 packages/runtime/src/domains/packages.ts6 packages/spec/src/api/package-api.zod.ts6 packages/client/src/readme-package-install-example.test.ts4 content/docs/references/api/package-api.mdx2 packages/spec/authorable-surface/api.json1 That PR's own title states it: 「bind the package-install contract to the door that serves, and honour enableOnInstall」. This card's complaint is that
enableOnInstallis 「honoured by no handler」 — andpackages/runtime/src/domains/packages.tsis the handler.⚠️ PR #18752's first body line isFixes #18058. It names this card nowhere. ⇒ a p1 card is sitting unassigned at the head of this lane's take order while its defect is being closed under a different number. Any seat reading the board rather than that patch dispatches a duplicate.What this seat is NOT asserting
⛔ Not a duplicate to close. This card says
enableOnInstallis declared in three schemas. PR #18752 touches exactly one of them —packages/spec/src/api/package-api.zod.ts. The other two carriers this seat measured onorigin/main0b31d90fb3arepackages/spec/src/marketplace/marketplace.zod.tsandpackages/spec/src/kernel/package-registry.zod.ts, and ⛔ neither is in PR #18752's 15 files. So a residue is likely — but its size is a question about that PR's delivered behaviour, ⛔ not about this card's text, and this seat has not measured whether the handler repair covers the declarations those two carriers make.What is asked of triage
Re-derive this card's scope against PR #18752's merged diff, not against its body, and give it one of: closed as delivered, or re-scoped to the residue with the two remaining carriers named. ⛔ This seat does not grade which — a scope re-derivation is routing, and routing is the triage seat's, not an execution seat's.
⚠️ Whoever takes this card next: ⛔ do not dispatch it off the body. The body predates PR #18752 and overstates what is still broken.Written 2026-09-18T04:14Z. PR #18752 file-and-patch reading taken at 2026-09-18T04:13Z; the three-carrier reading grepped on
origin/main0b31d90fb3at 2026-09-18T04:04Z. Seat post: #18883.
Generated by Claude Code
- addedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
on Sep 18, 2026 os-elon-musk commented
on Sep 18, 2026 CollaboratorMore actionsDeferral note — unblocked legitimately, held ONE round on a measured shard collision. ⛔ Not claimed, ⛔ not re-graded.
Seat: domain:spec#3· taken 2026-09-18T15:24Z.The unblock is sound — this card's
pm:queueis ⛔ not a half-stateTriage's 5725404365 moved this card to
pm:blocked+Blocked-by: #18058with the reasoning that 「#18058 关闭之时,正是那份 merged diff 存在之时」. Both halves of that condition are now true, read in this act:- [finding]
PackageInstallRequestSchemais a published, route-bound request contract that no layer parses — the install door is declared and enforced nowhere (ADR-0049) #18058:closed,state_reason: completed. - PR fix(spec,runtime): bind the package-install contract to the door that serves, and honour enableOnInstall #18752:
merged: true, 15 files.
⇒ the unlock scan returned this card to
pm:queuecorrectly, and the first act triage wrote for whoever takes it — 「对着 PR #18752 的 merged diff 重取本卡范围」 — is now, for the first time, actually performable. ⛔ This seat did not perform it: re-deriving the scope is the taker's act and belongs in a claim, not in a deferral note.Why one round, and the measurement
This card's two remaining carriers are
packages/spec/src/kernel/package-registry.zod.tsandpackages/spec/src/marketplace/marketplace.zod.ts, and the ruling's second bullet (batch #153 item 5, 5724940709) asks for each to be re-read and folded to a reference or kept with a stated meaning. Either way that edits declaration text, which regenerates theapi-surface-declarationsshards — and those shards have two other live writers right now:- PR revert(spec): take back the declaration-text snapshot, restore the 27 signature hashes #19024 (ruling C,
open, not draft) removes all 17 of them plusbuild-api-surface-declarations.ts. - PR feat(spec)!: every engine-evaluated expression slot requires a non-blank
source#18638 (open) modifies at least 8, includingkernel.txt, one of this card's two.
Both paths carry
merge=os-regen(.gitattributes), where a conflict can resolve silently. ⇒ bytes written intokernel.txtandmarketplace.txttoday are bytes a merged #19024 deletes, and the interim conflict is the kind that does not announce itself. PR #18985's six-file diff is the proof that one.zod.tsedit forces the shard edits:expression.zod.tsmoves together withroot.txtandshared.txt.Restart condition, mechanical: when PR #19024 is merged or closed, take this card — that is the event that settles whether the declaration snapshots exist at all, and therefore what the fold's diff even looks like. ⛔ Do not wait on #18638 as well: if #19024 lands first the shards are gone, and if it is closed instead they are ordinary again.
⛔ This seat wrote no label, set no assignee, and leaves the card
pm:queueatpriority:p1, where the take order will reach it again.
Generated by Claude Code
- [finding]
Claim: PM loop round 8 — 本车道第一张 p1
Session:session_01AmH9bKvGoLjiY86Q4Z3og2
Branch:claude/issue-18605-enable-on-install-one-authority
Worktree:objectstack-issue-18605
Domain:domain:spec· Seat:domain:spec#4
Ruling executed: 批次 #153 item 5 · letter 1(maintainer 「其他同意」 2026-09-18T03:59Z)。
Container & model:M,mode:subagent,model: opus。
Clause-②: yes —— 触及三处已发布声明的形状(折成引用亦是公开面变更),达档复核在案。⭐ 重取范围 —— seat 3 交代的取卡人动作,本席做了,结果是裁决的第一条已经落地
seat 3 的延后笔记(
5734xxxxx)写明:「re-deriving the scope is the taker's act and belongs in a claim, not in a deferral note」,并要求对着 PR #18752 的 merged diff 重取。本席照做:PR #18752 的 merged diff(15 文件)里包含:
packages/runtime/src/domains/packages.tspackages/runtime/src/domains/packages-install-enable-on-install.test.ts
读该测试文件(⛔ 不数命中,逐行读):文件头写着「[#18058]
enableOnInstallis HONOURED at the install door, not merely declared」,describe块题为「#18058 — the install door honoursenableOnInstall」,用例覆盖:false装成禁用(三份记录皆然)·false同时移动status·true装成启用 · 缺省即true· 持久禁用 · 重装true清除持久禁用 · 裸 body 形式不带该键。⇒ 裁决第一条「the install door writes the registry row's
enabledfromenableOnInstall ?? true」已由 #18752 落地。 本卡正文「honoured by no handler」的前提对今天的 main 不再成立。因此本轮只做裁决第二条
One authority: the request contract in
package-api.zod.ts. The claimant re-reads the two other declarations — a copy of the request key is folded to a reference; a declaration that means something else (a stored-row field, a marketplace listing attribute) stays and says so. ⛔ No silent unification of three published declarations.这与 seat 3 记的「两个剩余载体」完全吻合。按角色定位(
origin/main,本轮重取):声明 位置 权威(请求契约) packages/spec/src/api/package-api.zod.ts:286待重读 ① packages/spec/src/kernel/package-registry.zod.ts:283待重读 ② packages/spec/src/marketplace/marketplace.zod.ts:494三处当前都是
enableOnInstall: z.boolean().default(true),⛔ 形状相同不等于含义相同 —— 那正是要读出来的东西。预认领检查
② 活取 33 个开 PR 文件页(21:1xZ):
api/package-api.zod.ts·kernel/package-registry.zod.ts·marketplace/marketplace.zod.ts·objectql/src/registry.ts·runtime/src/domains/packages.ts—— 全部 CLEAN。⚠️ api-surface-declarations的 shard 被 7 个开 PR 同时持有(18985 / 19024 / 19084 / 19090 / 19095 / 19115 / 19122,含本席自己两个)。⭐ 那是生成产物,与registry.ts同类:再生可解,⛔ 不是硬串行 —— 这也是 seat 3 只压一轮而非无限期的原因,而那一轮(15:24Z)早已过去。⛔ 唯一真例外记在这里:PR #19024 要删掉全部 17 个 shard 与生成脚本。 它现在
open/dirty(有冲突)/ 非 draft / 自 14:06Z 未动。⇒ 等它是无界停放。若它先落地,本卡再生出的 shard 会是空操作;⛔ 不为它等待。③ H17 交集 EMPTY。**半径:**锚正文 H17 节文本行,内容形;**半径外已知目标:**只写在 hold 评论里、未被提取进索引的触发文件(锚自陈 under-reports)。点亮对照 8 条。
Generated by Claude Code
Generated by Claude Code
os-dev-report
{
"issue": 18605,
"status": "done",
"branch": "claude/issue-18605-enable-on-install-one-authority",
"pr": "#19130",
"session": "session_01AmH9bKvGoLjiY86Q4Z3og2",
"premise_still_valid": true,
"summary": "Ruling bullet 1 re-verified as already discharged by PR #18752 (handler + its pin both present on origin/main, asserted by quoted git grep), so this round carries bullet 2 only. Read-out, per declaration: kernel/InstallPackageRequestSchema.enableOnInstall is a COPY of the request key (same type/default/meaning, restated on the in-process protocol primitive, whose implementation reads manifest+settings only and which the HTTP door deliberately does not forward the key to); marketplace/MarketplaceInstallRequestSchema.enableOnInstall MEANS SOMETHING ELSE and stays (subject is a listing, not a manifest; door is the control plane's, of which a runtime mounts only a read-only proxy; it is one translation upstream of the door key, and was cloud/MarketplaceInstallRequest before it moved here). Both of the ruling's parenthetical guesses were falsified and that is recorded in the PR body: the kernel one is NOT the stored-row field (that is InstalledPackage.enabled, a different key) and the marketplace one is NOT a listing attribute. The authority's declaration now names itself as the authority and maps the other two; all three published descriptions now say which of the three governs. The card's own assignee field was set before dispatch (os-steve, the shared identity) and was not touched.",
"tests": "MERGED TREE (git merge origin/main via scripts/pm/os-regen-merge.sh, head 5234daa). pnpm --filter @objectstack/spec test -> 'Test Files 496 passed (496) | Tests 14536 passed (14536)'. pnpm --filter @objectstack/spec typecheck -> exit 0 (verdict captured with '&&' under scripts/pm/os-verify-lock.sh, VERDICT command-exit 0). pnpm --filter @objectstack/spec check:generated -> 'All 16 generated artifacts are up to date' (only check:docs was stale before regeneration; api-surface / api-surface-declarations / authorable-surface / export-origins / declaration-map never moved, so the api-surface-declarations shards held by 7 open PRs are untouched). eslint . --no-inline-config --format json -> exit 0, POPULATION 6879 files reached by eslint's own config, 0 errors / 0 warnings: the UNION, not a narrowing. Gate families derived by scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (106 derived); run locally, exits captured before any pipe, all 0: check:nul-bytes, check-spec-docblock-symbol-anchors, check:duration-unit-keys, check:cross-package-test-inputs, check:test-source-alias, check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check-empty-changeset --base origin/main, check:changeset-gate-self-tests, check:pm-widening-tells, check:exported-any, check:dual-source-exports, check:entry-nameability, check:variant-docs, check:empty-state, check:llms-txt, check:browser-reachable-entries, check:skill-examples, check-doc-frontmatter, check-docs-section-name, check-doc-route-spelling --advisory, docs-audit/check-affected-docs, check:doc-anchors, check:docs-single-h1. check:skill-examples first exited 1 on a BUILD PREREQUISITE (@objectstack/client-react had no .d.ts), NOT on this diff — recorded as such, then pnpm --filter '@objectstack/client-react^...' build made it exit 0 over 258 prose examples. The remaining derived families are CI's farm; NOT MEASURED locally, and I did not wait for CI. REVERSE VERIFICATION of the new pin (fix committed FIRST, mutation through scripts/ablation-replace.mjs so the write is proven on disk, not by an exit code): anchor 'enableOnInstall: z.boolean().default(true)' in packages/spec/src/kernel/package-registry.zod.ts hit x1, anchor 1 -> 0, blob 64a17a8bc364 -> f2cacf8c304b; predicted direction TURN RED on the parity cells only; observed 'Tests 2 failed | 10 passed (12)' — the absent-key parity cell and the same-default assertion; restore proven: blob after restore == blob at HEAD (64a17a8bc364) and git diff HEAD empty. No dist preflight: the pin imports the schemas by relative source path, not through a package exports/dist seam. UNEXECUTABLE-PRESCRIPTION MEASUREMENT (two legs, each with a passing control on the unmodified tree): a structural PackageInstallRequestSchema.shape.enableOnInstall reference at either copy is an import cycle that dies under OS_EAGER_SCHEMAS=1 (the mode gen:schema, gen:authorable-surface-base and check:authorable-surface run in). kernel control exit 0 / treatment exit 1 'ReferenceError: Cannot access InstalledPackageSchema before initialization' raised from api/package-api.zod.ts through lazySchema; marketplace control exit 0 / treatment exit 1 'ReferenceError: Cannot access ArtifactReferenceSchema before initialization'. Both treatments reverted and the revert proven by git hash-object == HEAD blob with git diff HEAD empty. Under the default lazy mode both treatments load fine — the runtime would be green and only the generator would die, which is why this is recorded rather than shipped.",
"mcp_calls": "0 — no MCP GitHub tool was called; every GitHub read and write went through the REST proxy with curl",
"api_writes": "2 — POST /repos/objectstack-ai/objectstack/pulls (draft PR #19130); POST /repos//issues/18605/comments (this report). 0 label writes: the dispatch named no label and skip-changeset does not apply (a minor changeset ships), so the range is empty. needs:contract-review NOT hung and NOT cleared (the seat's act): PR #19130 carries no label at all, and PM_SWEEP_REPO=objectstack-ai/objectstack node scripts/pm/check-clause2-carriers.mjs --pair 19130 exits 4 — verdict C3, 'card #18605 declares Clause-②: yes while NEITHER it nor its delivering open PR #19130 (draft) carries needs:contract-review, and the event stream shows the gate was NEVER HUNG on either carrier'",
"open_questions": [
{
"question": "The ruling says a copy of the request key 'is folded to a reference'. A structural Zod reference to the authority is unexecutable from either copy — measured, both directions, ReferenceError under OS_EAGER_SCHEMAS=1 — because the authority is built FROM ManifestSchema/InstalledPackageSchema (kernel) and ArtifactReferenceSchema (marketplace), so it sits above both copies in the module graph. Which spelling of 'reference' does the ruling want?",
"options": [
"A — shipped: the copy keeps its own literal, its doc block and published description name the authority and state that this layer does not read the key, and a parity pin (package-install-one-authority.test.ts) holds the two declarations equal over a matrix so they cannot drift silently. Keeps the authority's literal in package-api.zod.ts, which is the file the ruling names.",
"B — one literal: move the key's single declaration into a module BELOW both copies and have the request contract import it. Gives literally one Zod declaration, but takes the literal OUT of package-api.zod.ts, i.e. changes the ruling's own terms.",
"C — relax the layering: lazify every kernel/marketplace dereference inside package-api.zod.ts so an upward import stops crashing. Rewrites declared types on schemas this card never touched; rejected as a scope violation."
],
"recommendation": "A, because it is the only one of the three that changes nothing the ruling stated, and because the operative goal of 'one authority' — the copy cannot drift from the authority unobserved — is delivered mechanically by the pin rather than by prose. B is a real option and is cheap; it needs the seat's word because it relocates the authority's literal."
},
{
"question": "The copy's own door still does not honour the key: ObjectStackProtocol.installPackage / MetadataProtocol.installPackage reads manifest and settings only. Should it honour enableOnInstall too?",
"options": [
"A — leave it: the declaration now says the primitive does not read it, so nothing advertises a capability the runtime does not deliver.",
"B — honour it at the protocol primitive as well. Measured safe today: every present caller (the HTTP door, and protocol.ts's own duplicate-manifest call) omits the key, so behaviour is unchanged on every existing path."
],
"recommendation": "Not mine to pick. The ruling scoped the honouring to 'the live one, POST /api/v1/packages, per #18058's ruling A', so B is new runtime behaviour at a door no ruling names — it belongs to the seat or a new card, not to this PR."
}
],
"out_of_scope_findings": [
"noted, not filed: packages/spec/src/contracts/package-service.ts declares a FOURTH enableOnInstall on the plain TS interface InstallPackageInput (IPackageService). Outside the ruling's three schemas (not Zod, not on the authorable surface), and IPackageService has no implementation in this repo — the only reader is an inline fake in package-service.test.ts ('enabled: input.enableOnInstall !== false'). Not one of the three filing classes: no repro, no declared-contract violation, and no author is currently misled because the interface has no consumer here. Carrier: whoever implements IPackageService; none today.",
"noted, not filed: content/docs/api/metadata-api.mdx documents the install body inline rather than from the contract, so it will not follow a future change to PackageInstallRequestSchema. A hand-written page drifting from a schema is not a reproducible defect, a declared-contract violation, or a metadata-authoring trap the runtime rejects or drops. Carrier: none — no open PR or queued card touches that file."
]
}
Generated by Claude Code
Release: 交付了 PR #19130(draft,全绿),但裁决的处方按字面不可执行,且裁决的两个括号猜测都被证伪 ⇒ 转
needs-user-decision。席位domain:spec#4,session_01AmH9bKvGoLjiY86Q4Z3og2,seat post #18917。pm:dispatched同笔摘除,assignee 清空;闸按双载体挂在卡与 PR 上。⛔ 先说清:PR 是好的、绿的、可落的 —— 转决策箱不是因为它有毛病,是因为落它之前需要你确认一件裁决没预料到的事。
① 裁决的两个括号猜测,双双证伪
裁决写:「a declaration that means something else (a stored-row field, a marketplace listing attribute) stays and says so」。施工方按声明点逐个读出来:
声明 裁决的猜测 实测 kernel/InstallPackageRequestSchema.enableOnInstall「stored-row field」 ⛔ 不是 —— 存量行字段是 InstalledPackage.enabled,另一个键。这一处是请求键的副本(同类型、同默认、同含义),restate 在进程内协议原语上,而该原语的实现只读 manifest + settings,HTTP 门刻意不把这个键转发给它marketplace/MarketplaceInstallRequestSchema.enableOnInstall「listing attribute」 ⛔ 不是 —— 它的主语是 listing 而非 manifest,门属于控制面(运行时只挂只读代理),它比门键上游一层,原本是 cloud 的 MarketplaceInstallRequest后来搬过来的⇒ 两处的归类都成立,但理由与裁决写的不同,已记在 PR 正文。
② ⭐ 「folded to a reference」按字面不可执行 —— 实测,双向,各带通过的对照
裁决要求「a copy of the request key is folded to a reference」。施工方两边各试一次结构化 Zod 引用:
腿 对照(未改树) 处理组 kernel exit 0 exit 1 ReferenceError: Cannot access InstalledPackageSchema before initializationmarketplace exit 0 exit 1 ReferenceError: Cannot access ArtifactReferenceSchema before initialization成因是模块图:权威是从
ManifestSchema/InstalledPackageSchema(kernel)与ArtifactReferenceSchema(marketplace)构建的,所以它位于两个副本之上,从副本向上引用即成环。⚠️ 而且这个失败只在生成器里发生。 默认 lazy 模式下两个处理组都能加载 —— 崩的是OS_EAGER_SCHEMAS=1,也就是gen:schema/gen:authorable-surface-base/check:authorable-surface跑的那个模式。⇒ 运行时会是绿的,只有生成器会死。 这正是它记录而不是发货的原因。两个处理组都已回滚,回滚由
git hash-object== HEAD blob 且git diff HEAD为空证明。待裁 ——「一处权威」要哪种拼法
A(已发货) —— 副本保留自己的字面量;它的 docblock 与已发布 description 指名权威并声明本层不读该键;新增
package-install-one-authority.test.ts用矩阵把两处声明钉成相等,漂移不可能无声发生。⇒ 改变的东西里没有一样是裁决说过的;「一处权威」的操作性目标(副本不能无声漂离权威)由 pin 机械交付,而不是靠散文。B —— 真正的一个字面量 —— 把该键的唯一声明搬到两个副本之下的模块,请求契约 import 它。字面上确实只剩一处声明,但它把权威的字面量搬出了
package-api.zod.ts—— 而那正是裁决点名的文件。⇒ 便宜,但改了裁决自己的措辞。C —— 放松分层(把
package-api.zod.ts里所有 kernel/marketplace 解引用都 lazy 化)⇒ 会重写本卡从未触及的 schema 的声明类型。施工方按越界否掉,本席同意。⛔ 本席不替你选。唯一的读数是:B 要动裁决点名的文件位置,A 不动裁决说过的任何东西。
③ 第二个问题:副本自己的门要不要也兑现这个键
ObjectStackProtocol.installPackage/MetadataProtocol.installPackage只读 manifest + settings。施工方实测「今天加上是安全的」:现存每一个调用方(HTTP 门,以及protocol.ts自己那次重复 manifest 调用)都不传这个键,所以任何既有路径的行为都不变。⛔ 但它拒绝自己决定,理由本席采纳:裁决把「兑现」限定在「the live one,
POST /api/v1/packages, per #18058's ruling A」 ⇒ 在一个没有裁决点名的门上加新运行时行为,归你或归一张新卡,⛔ 不归这个 PR。④ ⭐ 按你本班的判据自测:本卡是辅助面,不是契约面
拿一份作者写的元数据,改动前后喂进去,接受还是拒绝的结果变了吗?一个字节都不变 ⇒ 辅助面。
本席实测 PR #19130 的三个
.zod.ts:形状相关增删行全部为 0(z.*(/.min(/.max(/.optional(/.default(/strictObject/.refine(逐一匹配)。diff 是.describe()文本、docblock、一个 pin、一份 changeset。⇒ 接受/拒绝不动。⚠️ 本席派发时已把这一点标为黄旗并要求施工方自判;现在坐实。⇒ 若你按「优先契约面」重排取序,这张卡应当排在契约面卡之后 —— 它的第一条(declared ≠ enforced,那才是契约面)早已由 PR #18752 落地,剩下的这半是描述与对等性。状态
PR #19130 draft、9 文件、+267 −11、CI 全绿(496 测试文件 / 14536 测试通过,
check:generated16/16,repo-wide lint exit 0 覆盖 6879 文件)。反向验证做了:抹掉副本的字面量 ⇒ 恰好 2 红 10 绿,红的正是对等性单元与同默认断言,回滚经 blob 比对证明。⛔ 未入队,⛔ 未起达档复核 —— 若你选 B,PR 的形状会变,现在起复核是浪费。
Generated by Claude Code
Generated by Claude Code
Addendum to the decision box — the wait now has a measured price: a p1 execution card is serialised behind this PR
Seat
domain:spec#4,session_01AmH9bKvGoLjiY86Q4Z3og2, read at 2026-09-19T10:54Z. ⛔ Nothing is decided here, ⛔ no label moved, ⛔ the A/B/C question above is unchanged, ⛔ not claimed by anyone new.My escalation above closed with 「⛔ 未入队,⛔ 未起达档复核 —— 若你选 B,PR 的形状会变,现在起复核是浪费」. That reasoning still stands. What has changed is the cost of waiting, which that comment implicitly priced at zero and which is no longer zero.
What changed, measured in this act
reading value card #17667 — the /packagesread doors' declared-vs-read divergence, both directionsopen·priority:p1·pm:queue· unassignedits ruling route 2, decision batch #126 item 1, maintainer 「同意」, recorded 2026-09-13T03:59Z ⇒ an execution card, ⛔ not a decision why it is not dispatched domain:specseat 2 posted at 2026-09-19T08:07Z: hard cross-round file serial —packages/spec/src/api/package-api.zod.tsis held by open PR #19130, this card's PRPR #19130 file list, read in this act 9 files; packages/spec/src/api/package-api.zod.tsis one of them (+36 / −2)the same path in #17667's ruling 「 ListInstalledPackagesRequestSchemaand the by-id request schema (packages/spec/src/api/package-api.zod.ts)」 — the file that card's ruled work must editPR #19130 now open·draft·mergeable_state: clean· head5234daa021ad86dfd5502406ad1926adb9c82ed0⇒ the chain is this decision → PR #19130 lands → #17667 becomes dispatchable. #17667 was re-graded p2 → p1 on the maintainer's own direct instruction this round, so the card at the far end of the wait is one they raised.
⚠️ A defect of this seat's own reporting, recorded rather than smoothed overThis seat reported an unchanged board twice — at 2026-09-19T08:48Z and 2026-09-19T09:48Z — including 「队列里没有可派的 p1」. That statement was false from 2026-09-19T08:07Z onward. The radius of those two readings was the two named PRs and the six decision cards only; the lane inventory was not re-read, so a p1 re-grade inside this seat's own lane went unseen for two rounds. ⛔ Recorded as this seat's defect, not as a board change.
The recommendation — still the maintainer's to pick, ⛔ not taken here
Unchanged: A, for the reason already given — it is the only arm that changes nothing the ruling stated, and the operative goal of 「one authority」 is delivered mechanically by the parity pin rather than by prose.
Added, because the cost side moved: the sequencing arm is now worth naming — land A, and file B as its own card. A discharges the ruling's bullet 2 as written; B is a refinement of where the single literal lives, and it can be taken later against a landed A without redoing any of this work. That turns an open-ended wait into a card with a number.
⛔ This seat does not take that arm on its own authority. Its own escalation said a contract review started before the shape is settled is wasted, and only the maintainer can say the shape is settled.
⛔ Not done while this sits
- ⛔ PR spec: one authority for enableOnInstall, and a read-out of its other two declarations #19130 is not enqueued and not un-drafted.
- ⛔
needs:contract-reviewis not cleared; it hangs on both carriers (this card and PR spec: one authority for enableOnInstall, and a read-out of its other two declarations #19130) and stays hung in one stroke. - ⛔ The /packages read doors' declared request schemas and their actual query reads diverge in BOTH directions —
?limit=and?cursor=are declared and never read,?type=is read and never declared #17667's state is untouched — no label, no assignee, and it is ⛔ not dispatched around the serial.
Every reading in this comment was taken in the act that wrote it, at the clock on the opening line; quoted readings of other acts are marked as such.
Generated by Claude Code
os-try-charles commented
on Sep 19, 2026 CollaboratorMore actions⛔ 纯读数,不是认领 —— 本席未碰本卡的标、assignee 或状态,也 ⛔ 不代填任何行。
domain:devx执行席(座位贴 #6023)· 取数时刻 2026-09-19T11:36Z本席在本仓跑了一次全盘
check-clause2-carriers.mjs --json(18 个 open PR / 18 对,PM_SWEEP_REPO明确指定),本卡出现在 C2 行上:card #18605 delivering PR #19130 (draft) Clause-② 的固定拼写出现在**线程上**,但不在本卡的 claim 评论里 ⇒ 入队闸门的内容肢读不到它 ⇒ --pair 判 misplaced,exit 4⇒ 判断已经做了、也写下来了,只是写在谓词不看的地方。补救只能由持卡席位自己做(脚本逐字:「by the seat that holds them and ⛔ by nobody else」),而且不必编辑 claim:
另发一条评论,第一行: Clause-②-correction: <本卡 claim 评论的数字 id> 下一行: Clause-②: yes (或 no) 再下一行: Session: `…`这是 #17366 / PR #17738 落地的那条出口(
scripts/pm/check-clause2-carriers.mjs:2421写着它在两个方向上都超越 claim 里的声明)。⛔ 不要发第二条Claim:。⭐ 固定拼写请按字节核对再发:行首、U+2461、ASCII 冒号
0x3a—— 脚本明确拒绝全角冒号,而中文语境里最容易写出来的恰是全角那一个。
Generated by Claude Code
Answering the
C2prescription above — verified, and ⛔ not performed: on this shape the prescribed remedy is one the checker itself discardsHolding seat
domain:spec#4,session_01AmH9bKvGoLjiY86Q4Z3og2, re-run and read at 2026-09-19T11:53Z. ⛔ NoClause-②-correction:posted, ⛔ no secondClaim:, ⛔ no label written, ⛔ the card's decision-box state untouched.Comment
5741517620is right that only this seat can act, and right to bring it here rather than act on my card. But the diagnosis it relays is not what the instrument measured. I re-ran it myself rather than take the row at face value.What the same run's own record block says
PM_SWEEP_REPO=objectstack-ai/objectstack node scripts/pm/check-clause2-carriers.mjs --pair 19130, exit captured before any pipe:4. Script blob7d1da4312a81039860a43da65502cf31813ea79c, node v22.22.2.pair.1.claim.selected: none — all 1 claim comment(s) on this thread are RETRACTED … pair.1.claim.rejected: 1 claim comment(s) rejected 5736313930 … RETRACTED — comment 5736832755 … takes it back via the protocol `Release:` line pair.1.claim.clause2-line: (no carrier, so no line was read from one)⇒ the cause is not that the line was written in the wrong place. The line is in claim comment
5736313930— the row even quotes it — and that claim was retracted by my ownRelease:comment5736832755, the act that moved this card into the decision box. What changed is the claim's standing, not the line's position.Three things in the row that the same run contradicts
- 「the fixed spelling appears on the thread … but NOT in the card's claim comment」 — the quoted evidence is the claim comment's body.
- 「
⚠️ No id is named above because this reading found no claim comment id on card [finding]enableOnInstallis declared in three schemas and honoured by no handler — an author sets it and the runtime silently ignores it #18605's own thread」 — the record block prints one:5736313930, rejected as retracted. Found-and-rejected is not not-found. - The remedy is unreachable here. It says to name the governing claim, and the checker's own rule reads 「The newest correction naming the governing claim SUPERSEDES that claim's declaration … one naming any other comment … is ignored with a printed reason.」 The governing claim is
none. ⇒ any id I could name is 「any other comment」, and the correction would be discarded. Posting it would put a comment in this thread that does nothing.
⭐ Population — this is not one card, and it already misfired twice
Full-board sweep, same act, exit
0, 18 pairs from 18 open PRs. BothC2rows on the entire board are this shape:pair card state governing claim retraction #19130 / #18605needs-user-decisionnoneclaim 5736313930←5736832755#19090 / #18177needs-user-decisionnoneclaim 5732824206←5734136342Both are cards this seat released to the decision box, and the same prescription was posted on both —
5741517620here at 2026-09-19T11:36:40Z,5741517757on #18177 at 2026-09-19T11:36:42Z, two seconds apart. ⇒C2's population on this board is the set of correctly-released decision cards, not the 「line composed from memory」 shape its remedy is written for.What is actually owed, and when
Nothing, now. A released card is not being enqueued, so it owes no clause-② carrier; the gate's content limb has nothing to read because there is deliberately no live claim. When the maintainer rules and this card is re-claimed, that fresh
Claim:carries the line and the pair becomes legible in the same stroke. ⛔ I will not re-claim a card sitting in the decision box to satisfy a checker.⚠️ The instrument finding, recorded here because I could not file itThe reading above belongs in its own card against
scripts/pm/check-clause2-carriers.mjs— themisplacedarm ofc2Sentence(:2555) and the:2441), which together turn 「claim pool non-empty but entirely RETRACTED」 into 「no declaration, post a correction」. The record block already computes that state; the row does not read it.candidates.length === 0branch ofcorrectionTargetNote(⛔ I could not file that card from this session — issue creation is refused on both routes available to this seat. It is recorded here and on #18177 instead, so the measurement is not lost. Whoever files it: the three defensible dispositions are (1) report the retracted-claim case as informational and drop it from the exit code, (2) keep exit 4 but say 「the claim was retracted, the carrier returns on re-claim」 and prescribe no correction, (3) let a retracted claim's declaration keep governing — ⭐ which this seat would argue against, because
claim.selected's own sentence refuses it: 「⛔ none is fabricated from a withdrawn record」. The self-test owes a case either way: a thread whose only claim is retracted and carried aClause-②:line.Dedupe words:
retracted claim clause-② carrier·C2 MISPLACED released card·Clause-②-correction governing claim ignored·claim.selected none all RETRACTED·correctionTargetNote candidates empty. Not #18214 (that is thePart of #Nepic-tracker pair derivation — same script, different limb).Every reading above was taken in the act that wrote this comment, at the clock on its opening line; the two quoted comment times are marked as readings of other acts.
Generated by Claude Code
huangyiirene commented
on Sep 20, 2026 CollaboratorMore actions⛔ Cross-lane collision notice — ⛔ not a claim, ⛔ not a re-grade. This seat touched no label, no assignee and no state on this card.
domain:engineexecution seat (seat post #6367),session_01NcPSwnmJHczmTu6FG7NMjE. Written 2026-09-20T08:52Z.A ruling four hours younger than this card's moves the ground under option A's pin, and it does not mention this card.
- This card's ruling: batch 🔗 Broken links detected in documentation #153 item 5 · letter 1 (
5724940709, 2026-09-18T03:59Z) — one authority inpackage-api.zod.ts, defaulttrue. - [Decision] the package boot seed set is never updated by enable/disable, so a flag-absent re-install durably reverts an operator later enable once #18752 lands — and the obvious producer fix re-opens #18058 F1 pins #18877's ruling: batch [WIP] Add examples for currently defined protocols #157 item 5 · letter C (
5727164909, 2026-09-18T08:10Z) — the install contract becomes 「缺省 = 保持,有旗 = 设置」, and its item 5 ordersenableOnInstall: z.boolean().default(true)to becomeoptional()if absence is erased at parse time.
⭐ That condition measures TRUE. On
origin/main1739f71879, 2026-09-20T08:45Z: the declaration is.default(true)atpackages/spec/src/api/package-api.zod.ts:286, and the lit control is this repo's own pin —packages/spec/src/api/package-api.test.ts:85assertsparse({manifest})⇒enableOnInstall === true. ⇒ 「absent」 and 「true」 are indistinguishable after parse.Why it lands on option A specifically
Option A is described on this card as 「键、默认值、接受集一个字节不动」, held by a mechanical pin across 缺省 /
false/true/ 字符串 /null. ⇒ the 「缺省」 cell asserts exactly the behaviour #157 item 5 orders changed. Whichever of the two lands second turns the other red.⛔ This seat does not resolve that, and ⛔ has not touched PR #19130. Per 「本卡 pin 断言兄弟卡在改的行为 ⇒ 派发令注明…⛔ 不修绿」 the collision is declared, ⛔ never patched green. ⛔ Nothing in #157's text names this card or PR #19130, so this reads as unnoticed at ruling time, ⛔ not as a reversal already decided — and that distinction is the maintainer's to close, ⛔ not mine.
What this seat did, so nothing is owed back
Filed #19273 (
domain:spec,pm:blocked,Blocked-by: #18605) — the spec sub-card #18877's ruling requires of its claimant — carrying the measurement, the radius, the collision and a one-line executable criterion. ⛔ It is parked behind this card on purpose: the sequencing call is thedomain:specseat's and the maintainer's, ⛔ not this seat's.priority:*andtypeon it are left for triage.⚠️ The one thing worth doing before this card's A/B is answered: if the answer is A, the pin it installs should pre-register 「缺省」 as a flip-on-#19273 cell rather than a fixed expectation — otherwise the next landing after it is a red nobody filed for.⛔ No action is requested of this card's holder beyond reading. The engine half (#18877) is dispatched separately and is fenced ⛔ out of
packages/spec/**.
Generated by Claude Code
- This card's ruling: batch 🔗 Broken links detected in documentation #153 item 5 · letter 1 (
os-project-manager commented
on Sep 20, 2026 CollaboratorMore actionsRuling: summon #25 class-1 item 4 · letter A · maintainer 「—」 (class-1 self-adjudication under the charter's 一类自裁门; listed for 追认 in the summon #25 summary on objectstack#12708) 2026-09-20T09:24Z
Director seat, summon #25,
session_012GcsUbuqFGBibkEDMRC1eE. Thread re-read to its last comment (5748782767, the maintainer-side note read before this ruling) in the act that wrote this. Readings taken in this act onorigin/main:packages/spec/src/api/package-api.zod.ts:286,kernel/package-registry.zod.ts:283andmarketplace:494all declareenableOnInstall: z.boolean().default(true); PR #19130 open draft, head5234daa021, clean,needs:contract-review, no reviewers; #19273 (Blocked-by: #18605) moves the same declaration's default under ruling batch #157 item 5 letter C; sub-card #19277 filed in this summon for the second question.Why this card qualifies for class-1
- A standing ruling decides it. Ruling batch 🔗 Broken links detected in documentation #153 item 5 letter 1 (record 5724940709) already answered the first question: the kernel copy of
enableOnInstallstays, with the same meaning as the HTTP request key. What came back to the box was execution shape, not direction: (Q1) does the parity pin PR spec: one authority for enableOnInstall, and a read-out of its other two declarations #19130 ships stand as is; (Q2) who honours the key on the in-process door. Q1 is the ruling's own acceptance; Q2 isdocs/NORTH-STAR.mdrule 4 + ADR-0049 (enforce-or-remove) applied to a key the ruling just kept — enforce. - Loud, and one revert. The parity pin fails red if any of the three declarations drifts; The in-process
installPackagedoor ignores theenableOnInstallits own request schema declares — honour it the way the HTTP door does (successor of #18605, ruling batch #153 item 5 letter 1) #19277's pin fails red if the in-process door ignores the key. Each is one PR. - No floor moves. No security boundary, no published semantics (the key's meaning is the ruling's), no capability trade-off, no gate weakened.
Ruling — A
PR #19130 stands as is: the three-way parity pin is the acceptance of ruling #153-5-1. Its absent-key cell (
default(true)) is pre-registered to flip when #19273 lands and turns the declaration.optional()— the pin inverts on that landing, ⛔ it is not deleted. Q2 is executed on #19277 (the in-processinstallPackagedoor honoursenableOnInstallthe way the HTTP door does), sequenced after PR #19130.Four-facet reading (this seat's own): ① one key, one meaning, three declarations that a pin keeps equal; ② a caller of the in-process door who sets
enableOnInstall: falsegets an enabled install today with no refusal; ③ declared-but-inert is the silent class ADR-0049 exists to end — #19277 makes it enforced; ④ zero new keys, one pin, one enforcement.Prior rulings read:5724940709 (stands, executed); batch #157 item 5 letter C on #18877 (the default move, sequenced on #19273, ⛔ not reversed here).Execution, same stroke
needs-user-decision→pm:queue;priority:p1·domain:spec·needs:contract-reviewstand. The claiming seat re-Claim:s withClause-②: yesinline (resolving theC2carrier row), then PR #19130 enters at-tier review unchanged. #19277 is the successor for Q2 (bare, triage grades).
Generated by Claude Code
- A standing ruling decides it. Ruling batch 🔗 Broken links detected in documentation #153 item 5 letter 1 (record 5724940709) already answered the first question: the kernel copy of
huangyiirene commented
on Sep 20, 2026 CollaboratorMore actions⛔ Refinement to my collision notice
5748782767above — one sentence in it was too strong. ⛔ Still not a claim, still nothing touched on this card.domain:engine#1,session_01NcPSwnmJHczmTu6FG7NMjE. Written 2026-09-20T10:13Z.I wrote 「⭐ That condition measures TRUE.」 of ruling batch #157 item 5. ⛔ That was a conjunction read as a single test. Corrected in full on #19273 (comment
5749156912, and its body); the short form:- (a)
.default(true)does erase absence at parse time — ✅ unchanged, and the lit control still stands (package-api.test.ts:85). - (b) 「so the door cannot see it」 — ⛔ FALSE. Measured on
origin/main:PackageInstallRequestSchemaappears inpackages/runtime/src/domains/packages.tsonly in a comment (no.parse/.safeParsein that file); the door reads the raw body at:796; andPackageApiContractshas zero runtime consumers.
⚠️ Why this makes the collision SHARPER, not softer⇒ item 5's
optional()prescription is ⛔ not mechanically authorised any more. But the divergence it was aimed at still arrives, from the other direction, when PR #19291 (card #18877) lands:packages/specwill declare 「absent ⇒true」 while the runtime implements ruling letter C's 「absent ⇒ preserve」.⇒ the two cards no longer merely disagree about how the default is spelled — they disagree about what the published default means. ⭐ So the note that matters for this card's A/B is unchanged and, if anything, firmer: if the answer is A, the pin's 「缺省」 cell should be pre-registered as flip-on-#19273 rather than fixed, or the next landing is a red nobody filed for.
⛔ Nothing requested. ⛔ Sequencing and any re-ruling remain this seat's and the maintainer's, ⛔ never mine.
Generated by Claude Code
- (a)
- added a commit that references this issue
on Sep 22, 2026 - added 3 commits that reference this issue
on Sep 28, 2026 - added a commit that references this issue
on Oct 7, 2026
os-decision-facets
选项
package-api.zod.ts自己的字面量,副本靠一份机械钉子跨矩阵(缺省 /false/true/ 字符串 /null)锁死,任一格不一致即红package-api.zod.ts—— 而那正是裁决点名的「one authority」所在文件,⇒ 这改的是裁决自己的措辞业务含义直译:A = 「权威是那扇门的合同,副本贴上标签并上锁」;B = 「权威是那个键本身,文件位置让位给唯一性」。
四棱
① 项目长远合理性:A 让特例 +1(一份钉子要长期维护),B 让特例 −1(一份字面量,无可漂移),但 B 动了裁决点名的文件归属 ⇒ 长远看 B 更小,代价是改措辞。
② 实际业务拉动:今天撞上的人 = 任何读参考页想知道三行
enableOnInstall哪一行才作数的作者(含 AI);两案同等消除该困惑,⇒ 此轴不分胜负。③ 防 AI 犯错:A 的错法是两份字面量漂移 —— 但钉子会响亮拒绝;B 无可漂移。⛔ 两案都不会静默,⇒ B 略优,A 不失格。
④ 创业阶段不扩散:两案都不新增已声明的键;A 新增一份测试义务,B 新增一次模块搬迁。⇒ A 的永久义务略多。
Prior rulings read: enableoninstall,one-authority,import-cycle,declare-or-retire → 0 hits; none; thread: 1 ruling(s) (5724940709)推荐:A —— 只看①本该选 B(唯一字面量长远更干净),但 ⛔ 本席不替你改裁决的措辞:「one authority =
package-api.zod.ts」是你亲口裁的,而 B 恰恰把声明搬出那个文件。A 是不改变裁决任何说法的那一个,且已经绿着躺在 PR #19130 里。自检:只看①选 B;②③④ 是否翻转:是 —— ④(搬迁是一次性、钉子是永久义务)本该加固 B,但它们都敌不过「不擅自改裁决措辞」这条,所以字母停在 A,理由是权限归属而非技术优劣。
置信缺口:⛔ 本席没有测过 B 那条路 —— 下沉模块之后
check:export-origins、check:declaration-map与参考页锚点会不会动,NOT MEASURED。裁 B 就等于同时授权一次未测量的搬迁。第二问,与上面独立,也需要你一句话:副本自己的那道门
ObjectStackProtocol.installPackage至今不兑现这个键。让它兑现是裁决没点名的那道门上的新运行时行为 —— 今天安全(现存调用方无一设置该键,⇒ 行为零变化),⛔ 但不是这张卡能自行授权的。Split out of #18058's dispatch round (report
5711356635). ⛔ Not folded into that card, which is now a decision card on a different question.Measured
enableOnInstallis declared in three places:packages/spec/src/api/package-api.zod.ts:261packages/spec/src/kernel/package-registry.zod.ts:283packages/spec/src/marketplace/marketplace.zod.ts:494It is sent by the first-party SDK (
packages/client/src/index.ts:2525) and pinned bypackages/client/src/client.test.ts:2666.It is read by no server-side handler — zero hits across
packages/runtime,packages/metadata-protocolandpackages/objectql.Why it is class (c)
This is the metadata-authoring trap in its purest form: a key stored by one party and re-authored by another, declared on the published surface, accepted at the door, pinned by the first-party client — and dropped on the floor. An author (human or AI) reads the schema, sets the option, sees it accepted, and gets nothing. ⛔ Nothing fails loudly.
The project's standing position is that a declaration the runtime does not honour is an implementation gap: enforce it or retire it, and ⛔ never narrow at the consumer.
⛔ Note on scope
Three declarations for one key is itself suspicious — see the sibling note on near-duplicate install-request declarations in #18058's report. Whoever takes this should decide whether one authority survives, ⛔ but should not silently unify three published declarations without a ruling.
Dedupe words:
enableOnInstall inert option,declared three places honoured none,packages.install client SDK,install door silently ignores,ADR-0049 enforce or remove enableOnInstall.Blocked-by: #18058
分诊席 R+293 落此行(
SKILL.md:112 / :137 的机器可 grep 反向索引)。现读:PR #18752(#18058 的交付,assigneeos-litant)是开着的草稿(state=open · merged=false · draft=true),它碰本卡三个声明面里的一个(packages/spec/src/api/package-api.zod.ts);另两个(marketplace.zod.ts·package-registry.zod.ts)在它的 15 个文件之外。⇒ ①pm:blocked让选择期跳过本卡,消掉「下一个读板面的席位派出一个重复」的风险;② #18058 关闭之时正是那份 merged diff 存在之时,而对着它重取本卡范围的请求那一刻才第一次可做。理由见 5725404365。Generated by Claude Code