Repository navigation
Commit d7dd47a
docs(skills): the objectstack-platform demoStaff example teaches the manager key (#26852)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9BQB21tEjsnc9ZmSt8s8KfV)_
Fixes #26764
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:`objectstack-platform` 技能的「Demo accounts」一节,示例里给演示账号写上直属上级
`manager`(填同列表另一条目的 email),正文一句话讲清它怎么解析、哪些写法在加载时被拒、以及 `os dev` 自己写
`manager_id` 并保留手工设过的上级;eval 文件加一例(第 8 例)。两行 token 棘轮按实测重钉(SKILL.md
先削三处重述再按余额 +17,eval +221),`@objectstack/skills` patch changeset。
- 为什么改:PR #26763 给 `demoStaff` 加了 `manager` 键,但技能没教;照技能写 demo 的 AI
不知道这个键,可能自己写 seed hook 去填 `manager_id`,或拿显示名当 manager,到加载时才被拒。
- 风险与回滚:只改技能文字与 eval,不动运行时;回滚即 revert 本 PR。付账删掉的三处都是同文件里的重述,规则另有归处(见
Acceptance notes)。
- 先看:① `skills/objectstack-platform/SKILL.md` § Demo accounts(示例与新句子);②
`scripts/check-skills-token-ratchet.mjs` 两行 row 注释里的算术;③
`evals/config-plugins-ops.json` 第 8 例。
- 两分钟验证:`node scripts/check-skills-token-ratchet.mjs | grep
objectstack-platform/` 应见 `SKILL.md is 6014 tokens (ceiling 6014;
headroom 0)` 与 `config-plugins-ops.json is 1690 tokens (ceiling 1690;
headroom 0)`。
- 需要你做的:批准本 PR(`skills/**` 为 Tier H,席位不 ready / 不 arm / 不入队)。
## What changes
**`skills/objectstack-platform/SKILL.md` § Demo accounts — `demoStaff`
vs `devLogins`.** The example gains a second entry (`Legal Lead`) and
`Legal Counsel 1` names it with `manager: 'lead@example.com'`, so the
example is a stack the platform accepts (a `manager` naming no entry is
refused). The prose adds one clause, read off `origin/main` `0ea90c7a`:
> `manager` is another entry's `email` — the boot writes `manager_id`
itself once every account exists and keeps one set by hand, so no seed
hook writes it; a display name, an address no entry has, the entry
itself or a loop is refused at load
Each half has its source:
- another entry's `email`, compared without regard to case —
`packages/spec/src/system/demo-staff.zod.ts` (`manager:
z.string().email(...)`, its TSDoc) and `collectDemoStaffManagerErrors`
in `packages/spec/src/stack.zod.ts`;
- a display name is refused at the entry (`.email('A demo account's
manager is named by the email of another demoStaff entry, not by its
name')`); no entry / self / loop are refused by `defineStack` with
`STACK_CROSS_REFERENCE_INVALID` 422 (`stack-demo-staff.test.ts`, the
`manager —` describe);
- written as `manager_id` once every entry has its account, before the
seed, and a manager already set is kept — `linkDemoStaffManagers` in
`packages/plugins/plugin-auth/src/demo-staff.ts` (the second pass;
`managersKept`).
Not taught, on purpose: the alias list (`reportsTo`, `managerEmail`,
`managerId`, `supervisor` → refused naming `manager`), which the
schema's refusal already says, and the set-manager write's own refusals
(depth, cross-organization, directory-owned), which are reported with
their `code` and `reason` at boot.
**`skills/objectstack-platform/evals/config-plugins-ops.json`.** Case 8:
a demo account that reports to another; expected `manager:
'counsel1@example.com'` on the subordinate's `demoStaff` entry and
nothing else, `os dev` writing `manager_id` itself. `must_contain`:
`demoStaff`, `manager: '`, `os dev`; `must_not_contain`: `manager_id:`
(a seed row or hook writing the column), `reportsTo:`. The file is
hand-formatted (inline assertion arrays) and was spliced, not
re-serialised; `JSON.parse` reads 8 cases.
**`scripts/check-skills-token-ratchet.mjs`.** The two rows re-pinned at
the measurement, each with the arithmetic and both notes in its comment
(triage 6448202744, spec-seat note 6445537040, the standing ruling
「A:先削重复,余额按实测提高」):
| file | before (tokens / ceiling) | after | row |
|:--|:--|:--|:--|
| `SKILL.md` (priced = bytes − the 20-byte stamp line) | 23980 B → 5995
/ 5997 · 504 lines | 24055 B → 6014 / 6014 · 500 lines | 5997 → **6014**
(+17) |
| `evals/config-plugins-ops.json` | 5873 B → 1469 / 1469 · 75 lines |
6758 B → 1690 / 1690 · 85 lines | 1469 → **1690** (+221) |
| whole package, the 8 authored files of
`skills/objectstack-platform/**` (ratchet report, `_index.md`
generator-owned and excluded) | 21 010 tokens · 2 142 lines | 21 250
tokens (+240) · 2 148 lines | — |
| whole catalog, every `skills/*/SKILL.md` | 4 606 lines | 4 602 lines |
— |
| whole shipped bundle total (ratchet report's last line) | 213 518 |
213 758 (+240) | — |
Both readings are against `origin/main` `0ea90c7a` (the merge base) and
this branch's head.
The SKILL.md arithmetic, in bytes, per `git diff -U0` hunk against the
merge base: cuts 127 + 101 + 29 = **257**; additions 87 (example) + 245
(prose) = **332**; net +75 bytes, so the priced text is 23980 → 24055
bytes and the row moves 5997 → 6014: the 2 tokens of headroom absorbed
and the measured remainder (+17) raised under the standing ruling,
pinned at the measurement. The eval file's seven fixtures share no
sentence (0 bytes of duplicate), so its remainder is the whole addition,
+885 bytes.
**`.changeset/26764-demo-staff-manager-skill.md`** —
`@objectstack/skills` patch; the package's `dist` is synced from
`skills/**` (`packages/skills/scripts/sync-catalog.mjs`), so the change
publishes.
## Why
#26764: PR #26763 (`Fixes #26616`) added the optional `manager` key to a
`demoStaff` entry and recorded `Skills-docs: follow-up owed` for these
two files, both at their token ceiling. An agent writing a demo stack
from the skill was not told the key exists, so it could hand-roll a seed
hook writing `manager_id` or name the manager by display name, and
nothing catches that until load.
## Acceptance notes
**The three cuts and where each rule still lives** (every one in the
same file, read by the same reader):
1. The sample refusal output under the phantom-key sentence (§ Full
Configuration Reference) — the "Refused" posture bullet two paragraphs
down says the top level refuses an unknown key, the parse throws naming
the surface and the key, and TypeScript rejects it earlier (`TS2353`).
The sentence itself ("the top level refuses it and the stack fails to
load") stays: `scripts/check-skill-top-level-keys.mjs` quotes it as the
page's contract and its self-test pins that the page carries it (the
first gate round, on `ce024605`, caught the cut; restored in
`3f46225b`). −127 B.
2. The "A bad platform default is a default to fix" bullet (§ The App /
Platform Boundary) — the second bullet of the same list: "A missing
default, a wrong diagnostic, a shape the spec refuses — the fix is
upstream. Raise it there; do not compensate for it here." −101 B.
3. The parenthetical "(memory in dev, SQL in prod)" in § Wiring a driver
— step 4 of the Runtime Boot Sequence: `DriverPlugin (memory in dev, SQL
in prod)`, and the drivers table. −29 B (the paragraph re-wrapped;
tokens count bytes, so the re-wrap pays nothing and was not counted).
A fourth cut was made and taken back on the seat's review (`02253051`):
the `sys_metadata` clause of the config-generation sentence (§ Compile
Artifact, "and do not add `sys_metadata` objects to an environment
runtime manifest"). Its only other home is
`references/plugin-development.md`, about a plugin registering those
tables — a different reader from one generating `objectstack.config.ts`,
who reads only SKILL.md. The +74 B is in the remainder above.
No eval fixture names any cut text (`git grep` of each cut phrase over
`skills/**` and `packages/spec/scripts/**`: only the SKILL.md itself).
The `typescript` fence in § Demo accounts is a fragment, unmarked for
`check:skill-examples` (opt-in `os:check` marker; it has none, as
before).
**Triage wording.** Triage 6448202744 says "⛔ It does not raise the
ceiling"; the seat's order and spec-seat note 6445537040 say raise by
the measured remainder under ruling A, the maintainer's standing ruling
on these rows, which outranks the triage line. Read together as: room is
made inside the package first, and only the measured remainder moves a
row. The SKILL.md row rises by +17 after three cuts; the eval row rises
by exactly its addition, with no duplicate available to cut — the same
path the rows' previous re-pins took.
Forced test edits: none. No test file changed.
## Tests
No code changed; the suites that read these files are the gates below.
`node scripts/check-skills-token-ratchet.mjs --self-test`: `79 cases
pass`, exit 0.
## Verification
Gate list derived with `node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack` (no paths; the change set is 4 paths
vs merge base `0ea90c7a`): **64 commands**. Run on head `02253051` from
the worktree after the last commit, each with stdin closed and its exit
code captured before any pipe (one `COMMAND :: exit CODE` line each),
then reconciled: `dispatch-gates --ran` → ``64 derived, 64 run, 0
NOT-MEASURED, 0 UNRUN`` (a DERIVED zero). **All 64 exit 0**, among them:
<details><summary>the families that read the changed files</summary>
- `node scripts/check-skills-token-ratchet.mjs` —
`skills/objectstack-platform/SKILL.md is 6014 tokens (ceiling 6014;
headroom 0)`, `evals/config-plugins-ops.json is 1690 tokens (ceiling
1690; headroom 0)`, `81 authored bundle file(s) within their ceilings`;
`--self-test`: 79 cases pass.
- `pnpm check:skill-top-level-keys` — self-test 14 cases pass;
`SKILL.md:40 enumerates all 52 authorable top-level keys`.
- `pnpm --filter @objectstack/spec run check:skill-docs` (frontmatter
unchanged, in sync), `pnpm check:skill-compatibility`,
`check:skill-frame-sync`, `check:skill-identifier-liveness`,
`check:pm-skill-id-lint`, `check:doc-authoring`, `check:nul-bytes`,
`check:role-word`.
- `node scripts/check-empty-changeset.mjs --base origin/main`,
`check-changeset-no-major.mjs --base origin/main`,
`check-adr-0087-registration.mjs --base origin/main`, `pnpm
check:pm-changeset-deadline-census`, `check:changeset-gate-self-tests`.
- `pnpm check:ratchet-remedy-authority`, `check:scripts-symbol-anchors`,
`check:watch-hint-literal`, `check:self-test-wired`,
`check:pm-dispatch-gates` (the ratchet script's row comments).
- dist-reading families after the lock-held `turbo run build
--filter='./packages/**'` (75/75, VERDICT exit 0):
`check:dual-build-cjs-loads`, `check:dts-closure`,
`check:lean-entry-closure`, `check:published-files`,
`check:sourcemap-no-sources-content`, `@objectstack/lint
check:doc-formula-expressions`.
</details>
Round 1 (head `ce024605`) was 63 of 64 exit 0:
`check:skill-top-level-keys --self-test` red on "live tree — the real
page carries the anchor and the contract sentence the drift text
quotes", because the first version of cut 1 removed that sentence.
`3f46225b` restored it and the whole list ran green there (64/64);
`02253051` (the seat's round, the `sys_metadata` clause back) re-ran the
whole list again (above). `--tier` on this diff reads MANDATORY —
`skills/**`, clause ① (no one-line exit); the changed-line count is well
under the 3000 human-merge threshold.
Not run locally, CI's: `pnpm lint` (repo-wide), the type-check lanes,
Test Core / Test UI (no code or test file changed).
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(n/a — no schema touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (repo-wide lint is CI's
run; no `.ts`/`.mjs` logic changed, only comment rows and two ceilings)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (n/a — 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.
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01ADHkmTMombCWi6iByM4RdD
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 75abd91 commit d7dd47a
4 files changed
Lines changed: 75 additions & 20 deletions
File tree
- .changeset
- scripts
- skills/objectstack-platform
- evals
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
507 | 507 | | |
508 | 508 | | |
509 | 509 | | |
510 | | - | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
511 | 536 | | |
512 | 537 | | |
513 | 538 | | |
| |||
949 | 974 | | |
950 | 975 | | |
951 | 976 | | |
952 | | - | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
953 | 992 | | |
954 | 993 | | |
955 | 994 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
| 55 | + | |
62 | 56 | | |
63 | 57 | | |
64 | 58 | | |
| |||
174 | 168 | | |
175 | 169 | | |
176 | 170 | | |
177 | | - | |
178 | | - | |
179 | 171 | | |
180 | 172 | | |
181 | 173 | | |
| |||
258 | 250 | | |
259 | 251 | | |
260 | 252 | | |
261 | | - | |
262 | | - | |
263 | | - | |
264 | | - | |
265 | | - | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
266 | 257 | | |
267 | 258 | | |
268 | 259 | | |
| |||
450 | 441 | | |
451 | 442 | | |
452 | 443 | | |
453 | | - | |
454 | | - | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
455 | 448 | | |
456 | 449 | | |
457 | 450 | | |
458 | 451 | | |
459 | | - | |
460 | | - | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
461 | 457 | | |
462 | 458 | | |
463 | 459 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
73 | 83 | | |
74 | 84 | | |
75 | 85 | | |
0 commit comments