Repository navigation
Commit 75afeff
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ81ut4uJxWyaaick9b2LrTc1)_
Fixes #26302
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:objectstack-platform 技能包的 Seed Data 节新增一小节「Demo accounts —
`demoStaff` vs `devLogins`」:种子数据把记录分给人,但造不出人(`data` 里写 `sys_user`
行会被拒),人声明在 `demoStaff`,`os dev` 在开发管理员之后创建账号(用种子密码,条目不带
`password`;`position` / `permissionSets` 只能是本 stack 自己声明的;`os build`
不写进产物,非开发启动不创建);`devLogins` 只是启动横幅文字,不创建、不授权。配一条 eval。
- **为什么改**:审计 #26184 的 P1 行 —— 包里只在顶层键清单提到 `demoStaff`,AI 作者准备 demo
时只声明横幅登录、手写用户种子行,启动后 `owner_id` 解析不到人。
- **风险与回滚**:只改技能 markdown、eval JSON 和
`scripts/check-skills-token-ratchet.mjs` 两行天花板数字;不发版、无运行时改动,回滚 = revert
本 PR。风险在教学措辞与 spec 是否一致 —— 六个探针(合法条目、`role:` 别名、平台权限集、`password`
键、重名、未声明职位)都用构建后的 `defineStack` 跑过,结果见 Tests。
- **先看**:① `skills/objectstack-platform/SKILL.md` 新小节(Seed Data 表之后);②
同文件四处删重复(`defineStack()` 开头两句、「读源码看精确形状」段、启动序列第 6 步的括号、速查表两条端口注释);③
`scripts/check-skills-token-ratchet.mjs` 两行天花板(5828→5981、1211→1458)。
- **两分钟验证**:`node scripts/check-skills-token-ratchet.mjs` ——
全绿,objectstack-platform 的 SKILL.md 与 eval 文件 headroom 都是 0。
- **需要你做的**:Approve(Tier H,`skills/**` 是发布面),席位随后落地。
## What changes
Row P1 of the audit on #26184 (comment 6425678185, §
objectstack-platform), taught in the fewest lines an AI author needs, in
the file that names `devLogins`:
- `skills/objectstack-platform/SKILL.md` — a **Demo accounts —
`demoStaff` vs `devLogins`** subsection under *Seed Data*, next to the
mode table and the bootstrap cheat sheet: a seed deals records to people
and cannot create one (a `sys_user` row in `data` is refused, ADR-0092);
the people go in `demoStaff` and `os dev` creates each account after the
development admin, signing in with the seed password (an entry carries
no `password`); one example entry; `name` is what a seed reference
resolves by; `position` / `permissionSets` name only what this stack
declares (a platform set such as `admin_full_access` is refused); `os
build` drops the key and a non-dev boot creates nothing; `devLogins`
creates and grants nothing, it only prints an existing account on the
boot banner. The choice rule: pick `demoStaff` whenever the demo needs
an account to exist.
- `skills/objectstack-platform/evals/config-plugins-ops.json` — eval 7:
a demo whose seed names two people and should open signed in as one of
them. Expected: both in `demoStaff` with a declared position /
permission set, created by `os dev`; `must_not_contain` the `role:`
alias and `admin_full_access`.
- `scripts/check-skills-token-ratchet.mjs` — the two touched `CEILINGS`
rows, each raised by exactly the measured remainder with the arithmetic
in the row comment (below).
Every sentence of the section is read off the spec:
`packages/spec/src/system/demo-staff.zod.ts` (the schema, its `aliases`
and `guidance`), `stack.zod.ts` (`collectDemoStaffErrors`, the
`demoStaff` / `devLogins` TSDoc, the envelope-key note),
`packages/plugins/plugin-auth/src/demo-staff.ts` (the environment gate
and the provisioning order) and `packages/cli/src/commands/compile.ts`
(the artifact drops the key). Nothing was taught beyond the card's
*Wanted*.
## Why
**Who pays:** an AI author preparing a demo. The package named
`demoStaff` only in its top-level key list, so the author declared
banner logins and hand-wrote user seed rows, and the seed's `owner_id`
references resolved to nobody on the first boot.
### Line budget (`skills/**` is a published surface)
Whole-file, before → after, lines:
| File | Before | After |
|:--|--:|--:|
| `skills/objectstack-platform/SKILL.md` | 488 | 503 |
| `skills/objectstack-platform/evals/config-plugins-ops.json` | 65 | 75
|
Whole-package (`SKILL.md` + `references/**/*.md` + `rules/**/*.md`):
**2092 → 2107** (+15; the seven other `.md` files are untouched).
`references/_index.md` is generator-owned and unchanged (41).
### Token ratchet — maintainer ruling A
Both touched files sat at the ceiling (`SKILL.md` headroom 4, the eval
file 0). Paid as the maintainer ruled on the seat thread's decision card
「skills 修复卡的教学和 eval 都撞 token 天花板,怎么付?」 (2026-10-27T01:21Z), his tap
verbatim and untranslated: 「A:先削重复,余额按实测提高」.
**Cut first** — four genuine restatements in `SKILL.md`, each with its
surviving home in the same file:
| Cut | Surviving home |
|:--|:--|
| The two-sentence intro under `## defineStack() — The Core
Configuration` ("`objectstack.config.ts` is the single entry point …
calls `defineStack()`") | the opening paragraph (one `defineStack()`
surface over `objectstack.config.ts`) and the project-tree comment `←
THE entry point — defineStack()` |
| The five-line "For the exact Zod shape … read `stack.zod.ts` …"
paragraph, compacted to one pointer line | `## References` ("Always
`Read` the source for exact field shapes"); the
`ObjectStackDefinitionSchema` pointer stays |
| Boot sequence step 6's aside `(see "Ports & networking" in Part 3)` |
the **Port resolution** paragraph three lines below, which links the
same section |
| The cheat-sheet comments `(auto-hops port if taken)` and `(see Ports &
networking)` | the same **Port resolution** paragraph (dev hops,
production fails loudly, link) |
**Then raised by the measured remainder** (bytes, because `ceil(utf8
bytes / 4)` is the convention; the `SKILL.md` count excludes its 20-byte
release-stamp line):
| Row | Before | Cuts | Added | After | Ceiling |
|:--|--:|--:|--:|--:|:--|
| `SKILL.md` | 23294 B = 5824 tok (ceiling 5828) | −309 B | +939 B |
23924 B = 5981 tok | 5828 → **5981** (+153) |
| `evals/config-plugins-ops.json` | 4842 B = 1211 tok (ceiling 1211) | 0
(six fixtures share no sentence) | +989 B | 5831 B = 1458 tok | 1211 →
**1458** (+247) |
Both rows are pinned AT the measurement (headroom 0). No other row of
the script is touched.
## Tests
<details><summary>Spec parse probe — the six shapes the section
describes, against the built `@objectstack/spec` (`dist/index.mjs`),
exit 0</summary>
```
valid: ACCEPTED
role_alias: REFUSED — demoStaff.0: Unrecognized key(s) on a `demoStaff` entry: `role`. Did you mean `role` → `position`? …
platform_set: REFUSED — Demo account 'Legal Counsel 1' (stack.demoStaff[0]) is granted permission set 'admin_full_access', which this stack does not declare in permissions. A demo account can hold only a permission set its application declares, never a platform set; …
password_key: REFUSED — demoStaff.0: Unrecognized key(s) on a `demoStaff` entry: `password`. | a `demoStaff` entry carries no password: every demo account signs in with the development seed password (`os dev --admin-password`, default `admin123`) …
duplicate_name: REFUSED — Demo account name 'Legal Counsel 1' is declared twice in `demoStaff` … Seed data deals a record to a person by name …
undeclared_position: REFUSED — Demo account 'Paralegal 1' (stack.demoStaff[0]) is assigned position 'paralegal', which this stack does not declare in positions. …
```
</details>
No TypeScript changed, so no package `test` / `typecheck` is owed; the
new `typescript` block is a fragment (not `os:check`-marked), and
`check:skill-examples` still type-checks the package's marked blocks
(below). Dogfood battery: n/a — no `!` in the title and no `(narrowing)`
arm.
## Acceptance notes
- The section lives in `SKILL.md` (the routing file, loaded first)
rather than `references/bootstrap.md`: the failure the card names
happens while writing seed data, and `SKILL.md` is where the package's
Seed Data section and its only `devLogins` mention sit. The dispatch
order allowed either.
- `references/_index.md` is generator-owned; `check:skill-refs` reports
it in sync, so it is not touched.
- `Metadata-protocol: none` ⇒ no `Skills-docs:` line is owed.
- Noted, not fixed (out of scope):
`packages/spec/src/system/dev-login.zod.ts` carries three `guidance`
strings telling the author to "seed the account itself in `data`" /
"Seed the user record in the stack's `data` fixtures", while
`demo-staff.zod.ts` says a `sys_user` row written through `data` is
refused (ADR-0092) — the refusal prescription points at a write the
runtime refuses. Reported to the seat in the os-dev report; not
reproduced with a boot here.
- Commit author: the commit was made with an explicit `os-warren` author
override instead of the clone's configured `Claude` identity; the branch
is a harness-owned thread branch, so it was not rewritten. Reported as a
deviation.
## Verification
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` on the branch tree (54 families; the derived
set is identical before and after the merge of `origin/main` at
`5507225e`), each command run locally with its exit code captured before
any pipe, then reconciled.
`dispatch-gates --ran` at head `f0926209`: **54 derived families
accounted for — 53 run (exit 0), 1 NOT-MEASURED, 0 UNRUN.** The one
NOT-MEASURED is `pnpm check:dual-build-cjs-loads`, recorded exit 3
(PREREQUISITE NOT MET: it needs every package's `dist`), so CI's run is
its reading.
<details><summary>Readings</summary>
- Ratchet family on the merged head `f0926209`: `node
scripts/check-skills-token-ratchet.mjs` exit 0 — "81 authored bundle
file(s) within their ceilings"; `objectstack-platform/SKILL.md` 5981 /
5981 (headroom 0), `evals/config-plugins-ops.json` 1458 / 1458 (headroom
0); `--self-test` exit 0 (79 cases).
- The card's three acceptance gates on the merged head: `pnpm --filter
@objectstack/spec check:skill-docs` exit 0 ("Skill docs in sync");
`check:skill-refs` exit 0 ("9 generated files in sync with
packages/spec"); `check:skill-examples` exit 0 ("264 prose examples
type-check across 3 surface(s)"). The latter two sit outside the derived
set and were run for the card's acceptance line.
- The other 50 derived commands ran at `01d2b0f8`, whose diff against
`main` is byte-identical to the merged head's (the merge brought other
packages' ratchet rows and unrelated files): every exit 0, including
`pnpm check:pm-dispatch-gates` (run detached), `pnpm --filter
@objectstack/lint run check:doc-formula-expressions` and `pnpm
check:lean-entry-closure`.
- Builds under `scripts/pm/os-verify-lock.sh` (slot `issue-26302`):
`pnpm --filter '@objectstack/client-react...' build` VERDICT
command-exit 0 (265 s held), which is what lets `check:skill-examples`
type-check the client blocks.
- Not owed locally: no package `test` / `typecheck` (no TypeScript
changed); `test:repo`, `pnpm lint` and the whole-tree scans are CI's.
- CI on the PR: not waited for (the order forbids it); the seat reads
the check-runs.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(no schema touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` is CI's whole-tree run.
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. Publishes nothing (`skills/**` has no `package.json`;
`skip-changeset`); both declaration lines are above.
- [x] 6. `packages/spec` not touched.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English (the 维护者速读 block and
the quoted ruling are Chinese by the repo's own rule).
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbX1XjSzpntF9n85TgB)_
Co-authored-by: os-warren <warren@objectstack.ai>
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 08ed7e2 commit 75afeff
3 files changed
Lines changed: 68 additions & 13 deletions
File tree
- scripts
- skills/objectstack-platform
- evals
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
431 | 431 | | |
432 | 432 | | |
433 | 433 | | |
434 | | - | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
435 | 455 | | |
436 | 456 | | |
437 | 457 | | |
| |||
740 | 760 | | |
741 | 761 | | |
742 | 762 | | |
743 | | - | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
744 | 774 | | |
745 | 775 | | |
746 | 776 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | 36 | | |
40 | 37 | | |
41 | 38 | | |
| |||
78 | 75 | | |
79 | 76 | | |
80 | 77 | | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
86 | 81 | | |
87 | 82 | | |
88 | 83 | | |
| |||
348 | 343 | | |
349 | 344 | | |
350 | 345 | | |
351 | | - | |
| 346 | + | |
352 | 347 | | |
353 | 348 | | |
354 | 349 | | |
| |||
445 | 440 | | |
446 | 441 | | |
447 | 442 | | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
448 | 463 | | |
449 | 464 | | |
450 | 465 | | |
| |||
455 | 470 | | |
456 | 471 | | |
457 | 472 | | |
458 | | - | |
| 473 | + | |
459 | 474 | | |
460 | 475 | | |
461 | 476 | | |
462 | 477 | | |
463 | | - | |
| 478 | + | |
464 | 479 | | |
465 | 480 | | |
466 | 481 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
63 | 73 | | |
64 | 74 | | |
65 | 75 | | |
0 commit comments