Skip to content

Commit 162f668

Browse files
docs(spec): demo-staff and dev-login prose state the measured seed behaviour and point at demoStaff (#26500)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} --> _Requested by **Yibo Wang** · [project thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwBD535BtxqcqchrhyxX7HFcR)_ Fixes #26424 Clause-②: no Metadata-protocol: none ## 维护者速读 - **改了什么:** 只改文字。`demoStaff` 的 TSDoc 不再说种子写入的 `sys_user` 行会被拒(ADR-0092);`devLogins` 的三条拒收提示、文件头 TSDoc 和 `email` 描述不再教作者在 `data` 里种账号,改为指向 `demoStaff`。 - **为什么改:** 运行时实测:种子写入以系统上下文执行,身份写守卫让行,这行会落库,但没有凭据、登录不了。旧文字一处说"会被拒",一处教人去种它,两处都和实际不符,AI 作者会照抄。 - **风险与回滚:** 无 schema、键或行为变化;只有 prose 和一条拒收提示的措辞变了。回滚即 revert 本 PR。 - **先看:** `packages/spec/src/system/dev-login.zod.ts`(guidance 三条 + email 描述)、`packages/spec/src/system/demo-staff.zod.ts`(L14-20)、`content/docs/references/system/dev-login.mdx`(重生成)。 - **两分钟验证:** `git grep -n 'in \`data\`' -- packages/spec/src/system/dev-login.zod.ts` 应无输出;`git grep -n 'refused (ADR-0092)' -- packages/spec/src/system/demo-staff.zod.ts` 应无输出。 - **需要你做的:** 无,席位落地。 ## What changes - `packages/spec/src/system/demo-staff.zod.ts`: the TSDoc sentence that said a `sys_user` row written through `data` "is refused (ADR-0092)" now states the measured behaviour. Every seed write runs under the system execution context, which ADR-0092's identity-write guard stands aside for, so the row lands. It lands as a directory row with no account and cannot sign in. - `packages/spec/src/system/dev-login.zod.ts`: the three `guidance` prescriptions (`permissions`, `capabilities`, `seed`) stop telling the author to seed the account in `data`. They tell the author to declare the person in `demoStaff`, so that `os dev` creates the account. - **Surface additions, accepted by seat 1 at claim time:** the same file's header TSDoc ("What it is NOT", which listed "`data` fixtures" as the way to have the account) and the `email` field's `.describe()` ("an account this application seeds") now point at `demoStaff` too. These were added because the `guidance` strings do not reach the generated reference. Only field `.describe()` text renders there, so without the `email` change the regenerated `dev-login.mdx` would not have moved. - `content/docs/references/system/dev-login.mdx`: regenerated (`gen:docs`). Its `email` row now names `demoStaff`. - `.changeset/26424-demo-staff-dev-login-seed-prose.md`: `patch` for `@objectstack/spec`, with both declaration lines. No schema, key or behaviour change. ## Why The two files pointed in opposite directions, and both were wrong about what happens. `packages/runtime/src/app-plugin.ts` writes every seed insert with `SEED_WRITE_EXECUTION_CONTEXT` (`isSystem: true`). `packages/plugins/plugin-auth/src/identity-write-guard.ts` bypasses `isSystem` writes. `packages/runtime/src/app-plugin.seed.test.ts` pins a `sys_user` seed row being inserted. `packages/plugins/plugin-auth/src/dev-admin-seed-gate.ts` records the consequence end to end: 13 `sys_user` rows, zero `sys_account` rows, and sign-in answering 401. An author who follows the old `devLogins` text gets a person who cannot sign in. `demoStaff` exists for this case. ## Tests - `pnpm --filter @objectstack/spec test` at `4b28e265`, under `os-verify-lock`: `VERDICT command-exit 0`, Test Files 728 passed (728), Tests 22040 passed, 1 todo. - `pnpm --filter @objectstack/spec build` at `4b28e265`: `VERDICT command-exit 0`. - No ablation: the diff changes no tested behaviour. It changes prose and one refusal prescription's wording, and no test pins that wording. ## Acceptance notes - Card acceptance: `git grep -n 'refused (ADR-0092)' -- packages/spec/src/system/demo-staff.zod.ts` gives 0 lines. `git grep -n 'in \`data\`' -- packages/spec/src/system/dev-login.zod.ts` gives 0 lines. Control leg: `git grep -c 'through \`data\`'` on the same file gives 2, so the grep reads the file. `git grep -c demoStaff` on `dev-login.zod.ts` gives 5. - Premise correction: the card says the three strings at L67/L71/L73 are `.describe()` text that reaches `dev-login.mdx`. They are `strictObject` `guidance` entries, which are shown in an unknown-key refusal and not in the generated reference. The text that reached the reference was the `email` description, which is why it joined the surface. - `skills/objectstack-platform/SKILL.md:446` still says the row "is refused (ADR-0092)". That sentence belongs to PR #26420's patch round and is left untouched here. ## Verification <details><summary>Refusal prescription as an author sees it (built dist)</summary> `DevLoginSchema.safeParse({ email: 'a@b.co', seed: true })` now answers: ```text Unrecognized key(s) on a `devLogins` entry: `seed`. • a `devLogins` entry creates no account. Declare the person in `demoStaff` — `os dev` creates the account so it can sign in — and name it here so the banner can print it. A `sys_user` row seeded through `data` has no credential and cannot sign in. This key is new in @objectstack/spec 17.5 and strict from birth — an unknown key here was never accepted. ``` </details> <details><summary>Generated artifacts</summary> `pnpm --filter @objectstack/spec check:generated` first reported 1 of 14 stale (`content/docs/references/**`). After `gen:docs`: "All 14 generated artifacts are up to date". </details> <details><summary>Derived gates at 4b28e26 (node scripts/pm/dispatch-gates.mjs --commands, then --ran)</summary> `dispatch-gates --ran`: 98 derived, 91 run, 7 NOT MEASURED, 0 unrun. All 91 that ran exited 0, including `check:docs`, `check:generated`, `check:doc-authoring`, `check:nul-bytes`, `check:api-surface`, `check:authorable-surface`, `check:issue-citations` and `check-changeset-no-major`. The 7 that exited 3 (PREREQUISITE NOT MET) need a full workspace build or a fixture commit that this shallow clone lacks. CI runs them: - `node scripts/check-plugin-teardown-shape.mjs --self-test` (pinned fixture commit not in the shallow clone) - `pnpm --filter @objectstack/lint run check:doc-formula-expressions` (`@objectstack/formula` not built) - `pnpm --filter @objectstack/lint run check:doc-security-posture` (`@objectstack/lint` not built) - `pnpm --filter @objectstack/spec run check:skill-examples` - `pnpm check:docs-transcript-drift` - `pnpm check:dual-build-cjs-loads` - `pnpm check:lean-entry-closure` </details> ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. - [x] 2. Every name I added uses the casing for its kind. (No names were added.) - [x] 3. No formatter ran; `pnpm lint` passes. (`pnpm lint` is left to CI.) - [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. - [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_01WGufzed5ZRLMtNcevsCJit --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent b7f2b0c commit 162f668

4 files changed

Lines changed: 33 additions & 14 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
docs(spec): `demoStaff` and `devLogins` prose state what a seeded `sys_user` row really does, and `devLogins` points at `demoStaff`
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
- **Before.** `DemoStaffSchema`'s TSDoc said a `sys_user` row written through `data` is refused (ADR-0092). It is not: every seed write runs under the system execution context, which the identity-write guard stands aside for, so the row lands. `DevLoginSchema` told the author to "seed the account itself in `data`" in its prescriptions for the `permissions`, `capabilities` and `seed` keys, and its header and `email` description assumed the application seeds the account. Following that lands a directory row with no credential, which cannot sign in.
11+
- **Now.** The `demoStaff` TSDoc says the row lands as a directory row with no account and cannot sign in. The `devLogins` prescriptions, header and `email` description tell the author to declare the person in `demoStaff`, so that `os dev` creates an account that can sign in. The regenerated `references/system/dev-login.mdx` carries the new `email` description.
12+
- No schema, key or behaviour changes. Only prose and a refusal prescription's wording change.

‎content/docs/references/system/dev-login.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const result = DevLoginSchema.parse(data);
2828

2929
| Property | Type | Required | Description |
3030
| :--- | :--- | :--- | :--- |
31-
| **email** | `string` | ✅ | Email of an account this application seeds — printed by the development boot banner |
31+
| **email** | `string` | ✅ | Email of an account that can sign in, such as one declared in `demoStaff` — printed by the development boot banner |
3232
| **password** | `string` | optional | Development-fixture password printed beside the address; omit when the account signs in another way |
3333
| **label** | `string` | optional | The audience this account belongs to (e.g. `Hiring admin`) — printed before the address |
3434

‎packages/spec/src/system/demo-staff.zod.ts‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ import { strictObject } from '../shared/strict-object';
1212
* ## Why the platform creates it and the application only declares it
1313
*
1414
* A metadata app's demo seed hands records to named people (`owner_id:
15-
* 'Legal Counsel 1'`), and a seed cannot create a person: a `sys_user` row
16-
* written through `data` is refused (ADR-0092), and it could not sign in
17-
* anyway — signing in needs a hashed credential the auth pipeline mints. So
15+
* 'Legal Counsel 1'`), and a seed cannot create a person who can sign in. A
16+
* `sys_user` row written through `data` is not refused — every seed write runs
17+
* under the system execution context, which ADR-0092's identity-write guard
18+
* stands aside for — but it lands as a directory row with no account, and it
19+
* cannot sign in: signing in needs a hashed credential the auth pipeline mints,
20+
* and a seed row carries none. So
1821
* every application used to carry its own script that created the accounts
1922
* through the auth door, assigned their positions and permission sets, and
2023
* re-ran the seed so the deferred owners resolved. The maintainer ruled the

‎packages/spec/src/system/dev-login.zod.ts‎

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ import { strictObject } from '../shared/strict-object';
2828
* ## What it is NOT
2929
*
3030
* ⛔ Not an identity, not a seed, and not an authorization: declaring an entry
31-
* here CREATES NOTHING. It is presentation — the application naming accounts it
32-
* seeds by some other means (`data` fixtures, an `onEnable` hook, its own
33-
* script) so the banner can point the operator at one that shows something.
34-
* An entry naming an account nothing seeds prints a credential that does not
35-
* work, exactly as a README line would.
31+
* here CREATES NOTHING. It is presentation — the application naming accounts
32+
* that exist by some other means so the banner can point the operator at one
33+
* that shows something. The way to have a demo account is to declare the person
34+
* in `demoStaff`: `os dev` creates the account through the auth door, so it can
35+
* sign in. A `sys_user` row seeded through `data` is not that — it lands as a
36+
* directory row with no credential and cannot sign in. An entry naming an
37+
* account nothing created prints a credential that does not work, exactly as a
38+
* README line would.
3639
*
3740
* ## Read only in development
3841
*
@@ -64,14 +67,15 @@ export const DevLoginSchema = lazySchema(() => strictObject(
6467
permissions:
6568
'a `devLogins` entry grants nothing — it only names an account for the boot banner to '
6669
+ 'print. Grant capabilities with a permission set (`permissions`) or a position '
67-
+ '(`positions`), and seed the account itself in `data`.',
70+
+ '(`positions`), and declare the person in `demoStaff` so `os dev` creates the account.',
6871
capabilities:
6972
'a `devLogins` entry grants nothing — it only names an account for the boot banner to '
7073
+ 'print. Declare capabilities in `capabilities` and distribute them with `positions` / '
71-
+ '`permissions`; seed the account itself in `data`.',
74+
+ '`permissions`; declare the person in `demoStaff` so `os dev` creates the account.',
7275
seed:
73-
'a `devLogins` entry creates no account. Seed the user record in the stack\'s `data` '
74-
+ 'fixtures (or in `onEnable`) and name it here so the banner can print it.',
76+
'a `devLogins` entry creates no account. Declare the person in `demoStaff` — `os dev` '
77+
+ 'creates the account so it can sign in — and name it here so the banner can print it. '
78+
+ 'A `sys_user` row seeded through `data` has no credential and cannot sign in.',
7579
},
7680
},
7781
{
@@ -84,7 +88,7 @@ export const DevLoginSchema = lazySchema(() => strictObject(
8488
* sign-in form and every seeded fixture key on, so a value that is not one
8589
* names an account the operator cannot reach.
8690
*/
87-
email: z.string().email().describe('Email of an account this application seeds — printed by the development boot banner'),
91+
email: z.string().email().describe('Email of an account that can sign in, such as one declared in `demoStaff` — printed by the development boot banner'),
8892

8993
/**
9094
* The password to print beside {@link DevLogin.email}.

0 commit comments

Comments
 (0)