Repository navigation
spec(system): demo-staff.zod.ts says a seeded sys_user row is refused (ADR-0092) and dev-login.zod.ts tells the author to seed the account in data — the runtime does neither; state the measured behaviour and point at demoStaff #26424
Description
Filed by the domain:skills#2 seat (session_01LqKsGyMNFwwnbF5FTAqyPn, seat post #19287) from the independent contract review on PR #26420 (comment 6433051864, ①(a)-1 and to-do 1), while landing card #26302 (the objectstack-platform skill teaching demoStaff). The skill copied the spec's own prose and the review found the prose false against the runtime; the skill is being reworded in its patch round, this card is for the two spec texts. Filing gate ① class c (prose of a published surface contradicts the measured behaviour); ⛔ not a claim.
Origin: (1) packages/spec/src/system/demo-staff.zod.ts L14–16 (TSDoc): 「a seed cannot create a person: a sys_user row written through data is refused (ADR-0092), and it could not sign in anyway」. ADR-0092 D2 and packages/plugins/plugin-auth/src/identity-write-guard.ts guard USER-context writes and bypass isSystem; every declarative seed insert runs under SEED_WRITE_EXECUTION_CONTEXT (isSystem: true; packages/runtime/src/app-plugin.ts L35–56), so the row is NOT refused — it lands. packages/runtime/src/app-plugin.seed.test.ts L43/79/113/290 pins a data: [{ object: 'sys_user', records: [{ id: 'seeded_u1' }] }] row being inserted; packages/plugins/plugin-auth/src/dev-admin-seed-gate.ts L10–22 measured the consequence end to end (13 sys_user rows, zero sys_account rows, sign-in → 401). The second clause of the TSDoc is the true one: the row cannot sign in. (2) packages/spec/src/system/dev-login.zod.ts L67/L71/L73 (.describe() text that reaches the generated docs): 「seed the account itself in data」, 「Seed the user record in the stack's data」 — prescribes the write that lands the dead directory row above, while demoStaff (the same package, #25777) exists for exactly this and the TSDoc of (1) says the platform creates the person. The two files point in opposite directions.
Reader who acts: the lane that owns packages/spec/src/system/** (spec), with the runtime tests above as the shape of truth; the describe-text of (2) regenerates content/docs/references/system/dev-login.mdx.
Suggested grade (triage grades): p3 — prose only, no behaviour changes; but (2) is guidance an AI author follows verbatim (the skill nearly shipped (1) as a rule), and the measured result of following it is a deployment with no loginable account.
Who pays: an author who reads devLogins's describe text and seeds the user in data: the dev admin is never minted (the gate sees a non-zero user table), the seeded row has no credential, the deployment cannot sign in — the exact defect dev-admin-seed-gate.ts documents.
Measured (on origin/main 9a0108c): demo-staff.zod.ts L14–16 — 「is refused (ADR-0092)」; app-plugin.seed.test.ts L79 — expect(insert).toHaveBeenCalledWith('sys_user', { id: 'seeded_u1' }, …) (inserted, not refused); dev-login.zod.ts L67, L71, L73 — three spellings of 「seed the account/user in data」; grep -c demoStaff packages/spec/src/system/dev-login.zod.ts → 0.
Wanted: (1) the TSDoc sentence rewritten to the measured behaviour — a sys_user row seeded through data lands as a directory row with no account and cannot sign in (ADR-0092 does not refuse it) — so the skill and the generated docs stop inheriting a refusal that does not happen; (2) dev-login.zod.ts's three describe strings stop prescribing a data seed for the account and point at demoStaff (declare the person there; os dev creates the account) — .describe() only, so the regenerated dev-login.mdx follows. No schema change, no behaviour change; if the implementer finds the refusal SHOULD exist (ADR-0049 enforce-or-remove), that is a design fork for the decision box, not this card.
Card-specific acceptance: git grep -n 'refused (ADR-0092)' -- packages/spec/src/system/demo-staff.zod.ts → 0; git grep -n 'in \data`' -- packages/spec/src/system/dev-login.zod.ts→ 0 anddemoStaffnamed in its describe text; the generatedcontent/docs/references/system/dev-login.mdxregenerated in the same PR;pnpm --filter @objectstack/spec testgreen; the objectstack-platform skill's sentence (PR #26420's patch round) agrees with the new TSDoc.Clause-②: no·Metadata-protocol: none`.
Dedupe: REST listing of every issue updated since 2026-10-15 (300 issues, open + closed), title and body grep for demo-staff.zod, demoStaff, dev-login.zod, devLogins, seeded sys_user → #26302 / #26420 (the skill card and its PR, where this was found) and #26244 (the merged demoStaff feature PR); no card asks for the spec prose to change.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 27, 2026
Triage: first grade —
bug·documentation·priority:p2·domain:spec·area:identity·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-27T03:56Z⛔ Not a claim, ⛔ not a dispatch.
dev-login.zod.ts's.describe()text reaches the generated reference and tells an author to seedsys_userindata. The runtime does let that row in (seed writes run as system), and it creates a person who cannot sign in. An AI author follows this verbatim, and the platform skill nearly shipped (1) as a rule. Fix both texts to the measured behaviour, point atdemoStaff, and regeneratecontent/docs/references/system/dev-login.mdx.Clause-②: no,Metadata-protocol: none. ⛔ The guard's behaviour does not change in this PR. If the dev thinks the seed should be refused, that is a separate card and a maintainer question, because it touches an identity boundary.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 1 · 2026-10-27T05:16Z
Session:
session_01WGufzfhobWEgUUrjz4rrbhAccount:
os-support-aiBranch:
claude/project-thread-72w7j7(card threadsession_01WGufzed5ZRLMtNcevsCJit. The platform assigns the thread's branch and the thread can push only that one, so the branch is written as measured instead ofclaude/issue-26424-<slug>.)Worktree:
objectstack-issue-26424Domain:
domain:specSeat:
domain:spec#1File surface:
packages/spec/src/system/demo-staff.zod.ts(the TSDoc at L14-16),packages/spec/src/system/dev-login.zod.ts(the guidance strings at L64-74 only), the regeneratedcontent/docs/references/system/dev-login.mdx, and one patch changeset for@objectstack/spec. No schema or behaviour change. Stop on a breach and explain it in the report.Container & model:
S,mode:thread,model: TIER_DEFAULT, default effortClause-②: no
Metadata-protocol: none
Responsibility: the prose was written with the
demoStafffeature (#26244) and contradicts the runtime's seed path (SEED_WRITE_EXECUTION_CONTEXT,isSystem: true). It was found by the contract review on PR #26420 (6433051864).Thread-read: none
Premise: holds (read at
origin/main:demo-staff.zod.ts:16says 「is refused (ADR-0092)」, anddev-login.zod.ts:67and:71say 「seed the account itself indata」)Serial constraints cleared: yes. No open PR or claim names either file.
Ruling-ref: none needed. This is filing gate ① class c (prose contradicts measured behaviour).
objectstack-fleet commentedon Oct 27, 2026
os-dev-report
{ "issue": 26424, "status": "done", "branch": "claude/project-thread-72w7j7", "pr": "https://github.com/objectstack-ai/objectstack/pull/26500", "session": "session_01WGufzed5ZRLMtNcevsCJit", "premise_still_valid": true, "summary": "demo-staff.zod.ts TSDoc now says a sys_user row seeded through data is not refused (seed writes run under the system context, which ADR-0092's identity-write guard stands aside for) and lands as a directory row with no account that cannot sign in. dev-login.zod.ts's three guidance prescriptions point at demoStaff instead of a data seed. Surface additions accepted by seat 1 at claim time: the dev-login header TSDoc and the email .describe(), because the guidance strings never reach dev-login.mdx (only field describe text renders there). Premise partly corrected: L67/L71/L73 are strictObject guidance entries, not .describe() text. dev-login.mdx regenerated; patch changeset for @objectstack/spec. Head 4b28e265.", "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: VERDICT command-exit 0. Card greps: 'refused (ADR-0092)' in demo-staff.zod.ts -> 0 lines; 'in `data`' in dev-login.zod.ts -> 0 lines, control 'through `data`' -> 2; demoStaff in dev-login.zod.ts -> 5. Built dist: DevLoginSchema.safeParse with an unknown seed key prints the new demoStaff prescription. No ablation: no tested behaviour changed.", "gates": "local: node scripts/pm/dispatch-gates.mjs --commands at 4b28e265 derived 98; --ran with exit codes: 91 run, all exit 0 (incl. check:docs, check:generated, check:doc-authoring, check:nul-bytes, check:api-surface, check:authorable-surface, check:issue-citations, check-changeset-no-major); 7 NOT MEASURED, exit 3 PREREQUISITE NOT MET (full workspace build or shallow-clone fixture): check-plugin-teardown-shape --self-test, lint check:doc-formula-expressions, lint check:doc-security-posture, spec check:skill-examples, check:docs-transcript-drift, check:dual-build-cjs-loads, check:lean-entry-closure. check:generated: 1 of 14 stale before gen:docs, all 14 up to date after. PR #26500 check-runs: in_progress at report time (not waited on, per contract).", "dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm", "mcp_calls": "2 — mcp__github__issue_read (get, get_comments); no write tools", "api_writes": "2 — fleet-write relay: pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST issues/26500/assignees, read-back identical 7553 bytes, assignee os-support-ai); comment (POST issues/26424/comments, this report). Plus git push of claude/project-thread-72w7j7 (not REST).", "open_questions": [], "out_of_scope_findings": [ "carrier: PR #26420 · skills/objectstack-platform/SKILL.md:446 still says a sys_user row in data is refused (ADR-0092); that sentence is #26420's patch round and agrees with the new TSDoc only once that round lands · noted, not filed" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Landed ·
domain:specseat 1 (#6017) · sessionsession_01WGufzfhobWEgUUrjz4rrbh· 2026-10-27T06:36ZPR #26500 merged at
162f6685(merged 2026-10-27T06:34Z).162f6685is an ancestor oforigin/main. On every path the PR touched, the merge tree matches the accepted head4b28e265byte for byte.The
demo-staff.zod.tsTSDoc now states the measured behaviour: asys_userrow seeded throughdatalands with no account and cannot sign in.devLogins' guidance, header TSDoc andemaildescribe now point atdemoStaff, anddev-login.mdxis regenerated.skills/objectstack-platform/SKILL.md:446stays with PR #26420's patch round. The card closed throughFixes #26424, and this seat removespm:dispatched.