Skip to content

Commit d4e07da

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/issue-16412-strict-env-scope-roots-dyn
2 parents 5087da6 + 44c917a commit d4e07da

7 files changed

Lines changed: 552 additions & 105 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
"@objectstack/spec": patch
3+
---
4+
5+
The error-code ledger's TSDoc stops naming a retired verdict as a live mechanism, and states the published-face rule it is actually held to.
6+
7+
`packages/spec` ships `src/**/*.zod.ts`, so `api/error-code-ledger.zod.ts`'s header is published prose — a consumer reads these sentences out of the tarball. Two of them stopped being true when `check-dispatcher-error-vocabulary`'s face refusal widened from `packages/spec/src/**` to every published package's `src/` and the dispatcher vocabulary's `boot-refusal` verdict retired with it (#16649).
8+
9+
The first said the `boot-refusal` verdict **records** reachability for codes not yet registered, and pointed at the module the verdict was being deleted from. That is a claim about where a live mechanism lives, not about a case that can no longer arise, so a reader following the pointer would have found nothing. It now records the retirement and names what replaced it: a `door: 'none'` code has no resting place short of a row in the ledger.
10+
11+
The second opened `packages/spec/src/** is held to this mechanically`. True before the widening and an understatement after it — a reader would conclude only the spec tree is guarded, which is the "guarded a part" / "guarded it" confusion this whole class of gate exists to remove. It now states the published face, the stricter spec sub-face where `pending-registration` has no allowance, and the named, dated allowance outside it owed to #8846, with both finding kinds named.
12+
13+
No schema, accept set, default or refusal moves. `ERROR_CODE_LEDGER` holds the same members before and after, and the generated reference page is regenerated from this prose rather than hand-edited.

.claude/skills/pm-dispatch/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
8686
- 收班简报是前任不再写的显式声明,是释放标记不是锁:简报即最新事件 ⇒ 立即坐席。
8787
- 滞后标题是进场顺手修的半状态,⛔ 不是阻塞;简报点名的留守尾巴作围栏。
8888
- 维护者明示召唤是仲裁:有简报径直坐席;无简报才走保守确认,确认终止即坐席。
89-
- 互斥清 ⇒ 先在座位贴留一行开轮标记(session ID + fire 时刻)再跑轮。
89+
- 互斥清 ⇒ fetch 后读三章程文件(本文、core-rules、本席章程)在 `origin/main` 的最新触碰 sha。
90+
- 异于上一开轮标记即先重读;留开轮标记(session ID + fire 时刻 + 该触碰,注明重读)再跑轮。
9091

9192
## 全体座位的不变量
9293

@@ -283,7 +284,6 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
283284
- 平台事实变化 → references 事实表改一行。
284285
- 三类以 `finding` 入 skills 车道由该席分诊;三类之外默认关 not planned。
285286
- 经验教训散文不再入技能文本;交接按收尾清单逐步走完,并 `list_triggers` 清点自设定时器。
286-
- 归档自己派出的会话是不可移交的义务。
287287
- 四段模板、状态词表、接管/退场收尾清单细则见 `references/seat-post-protocol.md`
288288
- epic 委托不入座位贴体系;`packages/spec` 恒归 spec 座位。
289289

.claude/skills/pm-dispatch/references/core-rules.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
- 自设定时器只定下次唤醒、不定轮长;新 fire 到时上一轮未清空即接续,⛔ 不重开不重排。
1818
- 分诊席跑普通直连会话,达档职责改派显式传档位的子代理;自排下次唤醒不超过 55 分钟。
1919
- 开轮互斥读四个读数:收班简报、开轮标记、本车道最新他会话认领、最新关闭卡的认领。
20-
- 未收班活动任一未满一轮即自退,总监席除外;有收班简报即坐席,坐席后先写开轮标记
20+
- 未收班活动任一未满一轮即自退,总监席除外;有简报即坐席,坐席后核章程再写开轮标记
2121
## 全体座位的不变量
2222
- 状态住 GitHub 标签、assignee、正文行与座位贴;⛔ 本地零状态;循环须能从新会话恢复。
2323
- PM ⛔ 不写文件也不写代码,唯一例外是维护者逐 PR 明示授权的 `.claude/` 内部工具 PR。

content/docs/references/api/error-code-ledger.mdx

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,32 @@ question.
110110
ONE shape, no second list: a `door: 'none'` code is a row like any other —
111111
the string under the package that stamps it, and a comment that states its
112112
`status` and the reachability reading ("no HTTP door on this tree; the
113-
thrown value is the boundary"). The dispatcher vocabulary's `boot-refusal`
114-
verdict (`packages/runtime/src/dispatcher-error-vocabulary.ts`) records
115-
that same reachability for the codes NOT yet registered, and a row here
116-
ratchets its vocabulary row out exactly as a `pending-registration`
117-
registration does. What registration changes for such a code is the face,
113+
thrown value is the boundary"). Until #16649 the dispatcher vocabulary
114+
(`packages/runtime/src/dispatcher-error-vocabulary.ts`) carried a
115+
`boot-refusal` verdict that recorded that same reachability for the codes
116+
NOT yet registered; it is RETIRED, because the gate below now refuses it —
117+
and every verdict like it — under any published package's `src/`. The one
118+
verdict that still parks a site there is `pending-registration`, and only
119+
outside `packages/spec/src/**`, under the dated allowance spelled out below.
120+
So a `door: 'none'` code has no resting place short of a row here, and the
121+
ratchet is the one `pending-registration` already had: a row here makes the
122+
site vanish from that scan. What registration changes
123+
for such a code is the face,
118124
not the wire: nothing demotes today, and if a door ever does answer with
119125
it, `error.code` carries the specific code instead of the status-derived
120126
member plus `declaredCode`. The `declaredCode` demotion (#9106) stays for
121127
genuinely unknown / third-party spellings only.
122128

123-
`packages/spec/src/**` is held to this mechanically:
124-
`check:dispatcher-error-vocabulary` refuses to classify a stamp site under
125-
that tree as anything but `foreign-vocabulary` (a different vocabulary that
126-
merely spells itself `code`) or `runtime-pinned` — a `boot-refusal` or
127-
`pending-registration` row for a spec site is a finding
128-
(`spec-face-unregistered`), and the only way out is the row here.
129+
EVERY published package's `src/**` is held to this mechanically — #16649
130+
widened the rule from `packages/spec/src/**` alone, which is all #16449
131+
could afford to measure. `check:dispatcher-error-vocabulary` refuses to
132+
classify a stamp site under one as anything but `foreign-vocabulary` (a
133+
different vocabulary that merely spells itself `code`) or `runtime-pinned`,
134+
and the only way out is the row here. Under `packages/spec/src/**` that is
135+
the whole rule, so a `pending-registration` row for a spec site is a finding
136+
(`spec-face-unregistered`); outside it, a `pending-registration` row keeps a
137+
named, dated allowance owed to #8846 and any OTHER verdict is a finding
138+
(`published-face-unregistered`).
129139

130140
A code emitted by several packages is listed once per emitting package —
131141
the union dedupes; the per-package rows are provenance, not identity.

packages/runtime/src/dispatcher-error-vocabulary.ts

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,27 @@ export type CodeStampShape =
186186
*/
187187
export type CodeDoor = 'dispatcher' | 'rest' | 'plugin-route' | 'none';
188188

189+
/**
190+
* [#16649] `'boot-refusal'` was HERE, and is retired. It named a refusal raised
191+
* before any HTTP boundary exists — the CLI rethrows it and aborts — and until
192+
* #16404 the ledger ratified that class as not owed a row
193+
* (`MONGODB_MULTI_TENANT_UNSUPPORTED` was UNregistered by #8035 on "host boot
194+
* matching is not wire vocabulary"). #16404 deleted the exemption (the ledger
195+
* is the published face, door or no door), which left the verdict meaning only
196+
* "a registration this tree still owes" — #16449 discharged nine of those,
197+
* #16649's first half the remaining fourteen, and the second half widened
198+
* `check-dispatcher-error-vocabulary`'s face refusal from `packages/spec/src/`
199+
* to every published package's `src/`, which is what makes the verdict
200+
* unwritable: a row carrying it inside that face is now a
201+
* `published-face-unregistered` finding, and the whole scan population lives
202+
* inside it. A union member no site can legally carry is a place to park work,
203+
* so it comes out with the widening that closed it.
204+
*
205+
* ⛔ Do not reintroduce it for the next pre-HTTP producer the scan finds. Its
206+
* answer under #16404 is the ledger row, and the gate's `unclassified-site`
207+
* text says so. REACHABILITY is still recorded — on the ledger row, as the
208+
* `door: 'none'` reading each of the twenty-three registrations carries.
209+
*/
189210
export type CodeVerdict =
190211
/**
191212
* Reaches a wire and the ledger does not know it. Since #9106 the door
@@ -209,28 +230,6 @@ export type CodeVerdict =
209230
* draw the same line for field-level and diagnostic codes).
210231
*/
211232
| 'foreign-vocabulary'
212-
/**
213-
* A refusal raised before any HTTP boundary exists — the CLI rethrows it
214-
* and aborts. Until #16404 the ledger's own note ratified this class as
215-
* NOT owed a row (`MONGODB_MULTI_TENANT_UNSUPPORTED` was UNregistered by
216-
* #8035 on "host boot matching is not wire vocabulary").
217-
*
218-
* [#16404] That exemption is gone: the published face is the ledger, and
219-
* every code that ships in `dist` is registered there, door or no door.
220-
* This verdict now records REACHABILITY only — no door answers with the
221-
* code, so registering it changes no HTTP body — and a row carrying it is
222-
* a registration OWED, exactly like `pending-registration`: the row
223-
* ratchets out when the ledger row lands (#16449 took the nine measured on
224-
* that card's tree; #16649 took the fourteen that remained, so on this
225-
* tree no row carries this verdict — it stays declared for the next
226-
* pre-HTTP producer the scan finds, until the gate's spec-face refusal is
227-
* widened to every published package and this verdict retires with it;
228-
* see the running log below). ⛔ Under `packages/spec/src/**` the gate refuses
229-
* this verdict outright (`spec-face-unregistered`): a spec stamp site is a
230-
* ledger member, a foreign vocabulary or a runtime-pinned template —
231-
* nothing between.
232-
*/
233-
| 'boot-refusal'
234233
/**
235234
* [#9223] The site builds its code by INTERPOLATION, so no source scan can
236235
* say which codes it produces or whether they are registered — and a named
@@ -320,10 +319,21 @@ export const UNREGISTERED_CODE_SITES: readonly UnregisteredCodeSite[] = [
320319
// `WALLED_MEMBERSHIP_POLICY_UNDECLARED` (`@objectstack/organizations`) —
321320
// were registered under their stamping packages and ratcheted out
322321
// (`stale-row`), the reachability each row recorded now carried on its
323-
// ledger row. On this tree NO row carries the `boot-refusal` verdict; a
324-
// future pre-HTTP producer the scan finds still lands here as an
325-
// `unclassified-site` and takes one, then a registration, then comes out
326-
// again. ──
322+
// ledger row.
323+
//
324+
// ── [#16649, second half] The class is now closed MECHANICALLY rather than
325+
// by having been emptied once. `check-dispatcher-error-vocabulary`'s face
326+
// refusal, which #16449 could only afford over `packages/spec/src/`, covers
327+
// every published package's `src/` — the whole of this scan's population on
328+
// this tree (52 sites: 47 published-face, 5 spec-face) — so a site here is
329+
// a ledger member, a `foreign-vocabulary` or a `runtime-pinned` template
330+
// and nothing else, and the `boot-refusal` verdict that used to park one
331+
// between is retired from `CodeVerdict` above. The single carve-out is
332+
// `pending-registration` outside `packages/spec/src/`, granted 2026-09-08
333+
// and owed to #8846; the gate's header dates it and every run prints how
334+
// many rows still stand on it. A future pre-HTTP producer the scan finds
335+
// lands here as an `unclassified-site` and its way out is the ledger row,
336+
// not a row here. ──
327337

328338
// ── runtime-pinned: an interpolated family, checked where it can be ─────
329339
{

packages/spec/src/api/error-code-ledger.zod.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,22 +106,32 @@
106106
* ONE shape, no second list: a `door: 'none'` code is a row like any other —
107107
* the string under the package that stamps it, and a comment that states its
108108
* `status` and the reachability reading ("no HTTP door on this tree; the
109-
* thrown value is the boundary"). The dispatcher vocabulary's `boot-refusal`
110-
* verdict (`packages/runtime/src/dispatcher-error-vocabulary.ts`) records
111-
* that same reachability for the codes NOT yet registered, and a row here
112-
* ratchets its vocabulary row out exactly as a `pending-registration`
113-
* registration does. What registration changes for such a code is the face,
109+
* thrown value is the boundary"). Until #16649 the dispatcher vocabulary
110+
* (`packages/runtime/src/dispatcher-error-vocabulary.ts`) carried a
111+
* `boot-refusal` verdict that recorded that same reachability for the codes
112+
* NOT yet registered; it is RETIRED, because the gate below now refuses it —
113+
* and every verdict like it — under any published package's `src/`. The one
114+
* verdict that still parks a site there is `pending-registration`, and only
115+
* outside `packages/spec/src/**`, under the dated allowance spelled out below.
116+
* So a `door: 'none'` code has no resting place short of a row here, and the
117+
* ratchet is the one `pending-registration` already had: a row here makes the
118+
* site vanish from that scan. What registration changes
119+
* for such a code is the face,
114120
* not the wire: nothing demotes today, and if a door ever does answer with
115121
* it, `error.code` carries the specific code instead of the status-derived
116122
* member plus `declaredCode`. The `declaredCode` demotion (#9106) stays for
117123
* genuinely unknown / third-party spellings only.
118124
*
119-
* `packages/spec/src/**` is held to this mechanically:
120-
* `check:dispatcher-error-vocabulary` refuses to classify a stamp site under
121-
* that tree as anything but `foreign-vocabulary` (a different vocabulary that
122-
* merely spells itself `code`) or `runtime-pinned` — a `boot-refusal` or
123-
* `pending-registration` row for a spec site is a finding
124-
* (`spec-face-unregistered`), and the only way out is the row here.
125+
* EVERY published package's `src/**` is held to this mechanically — #16649
126+
* widened the rule from `packages/spec/src/**` alone, which is all #16449
127+
* could afford to measure. `check:dispatcher-error-vocabulary` refuses to
128+
* classify a stamp site under one as anything but `foreign-vocabulary` (a
129+
* different vocabulary that merely spells itself `code`) or `runtime-pinned`,
130+
* and the only way out is the row here. Under `packages/spec/src/**` that is
131+
* the whole rule, so a `pending-registration` row for a spec site is a finding
132+
* (`spec-face-unregistered`); outside it, a `pending-registration` row keeps a
133+
* named, dated allowance owed to #8846 and any OTHER verdict is a finding
134+
* (`published-face-unregistered`).
125135
*
126136
* A code emitted by several packages is listed once per emitting package —
127137
* the union dedupes; the per-package rows are provenance, not identity.

0 commit comments

Comments
 (0)