Repository navigation
Commit 019f26e
docs(qa): cli 18.0.0-next.5 pre-release database recipe scores organization-ownership-ceremony acceptance[5] (#26818)
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8X9pGRYcwLf7ufCFxseXuXT)_
Fixes #26624
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:`areas/cli.json` 新增区级配方
`cli-18-prerelease-db`,`organization-ownership-ceremony` 的 acceptance[5]
引用它(revision 5 → 6);`packages/qa/dogfood` 里提交一份由 18.0.0-next.5 自己的 `os
dev` 生成的数据库文本快照(约 400 KB)和它的生成脚本。
- 为什么改:acceptance[5] 需要「18.0 预发布版创建并服务过的数据库」,每次都得在 tag commit 上单独构建,两轮
18.2.0 都只能记 blocked(fixture);现在一条命令恢复即可。
- 风险与回滚:只动 QA 台账 JSON 和私有包 `@objectstack/dogfood` 的 test
目录(不进测试套件、不发布),不碰产品代码;回滚即 revert。
- 先看:`docs/qa/platform-checklist/areas/cli.json` 顶部 `fixtures`
块;`packages/qa/dogfood/test/upgrade-harness/cli-prerelease-fixture.ts` 的
`useTheRelease` 与 `census`;history revision 6。
- 两分钟验证:`pnpm --filter @objectstack/dogfood exec tsx
test/upgrade-harness/cli-prerelease-fixture.ts restore --to
/tmp/n5check/n5.db`,预期打印 restored … born under
@objectstack/cli@18.0.0-next.5 (820fd5a)。
- 需要你做的:无,席位落地。
## What changes
- `docs/qa/platform-checklist/areas/cli.json` gains an area-level
`fixtures` block with one recipe, `cli-18-prerelease-db`, in the
README's "Area-level `fixtures`" shape. Its `sequence` is what a runner
replays: restore the committed dump into two new SQLite files (the
primary and the telemetry sibling `os dev` keeps beside a file primary),
then read the census it should hold. A `regenerate` entry names how the
dump is remade from the tag.
- `cli.organization-ownership-ceremony` (revision 5 → 6) opts in with
`fixtures.provisioning.use` + `why`; `fixtures.requires[2]` names the
recipe first and keeps the by-hand tag build as its fallback;
`knownGaps[2]` is rewritten as CLOSED-by-recipe; `steps[5]` names the
restored pair and that the delivery row lands in the telemetry sibling
under `--dev`; `history` records the re-drive and its verdict. No clause
sentence, verify or evidence changed.
- `packages/qa/dogfood/test/upgrade-harness/cli-prerelease-fixture.ts`
(new, not a test; vitest never collects it): `restore` loads the dump;
`generate` builds or takes a worktree of the
`@objectstack/cli@18.0.0-next.5` tag commit, boots that commit's own `os
dev --seed-admin` over a fresh file DB, drives its HTTP doors
(`useTheRelease`), stops it, takes a census that refuses a database
missing anything acceptance[5] reads, and writes the dump. It reuses
`sqlite-text-dump.ts` from the same harness.
- `packages/qa/dogfood/test/upgrade-harness/fixture-18.0.0-next.5/`
(new): `database.sql` (198,531 B), `telemetry.sql` (202,762 B),
`manifest.json` (5,573 B, ref, sha `820fd5aef0`, census, people).
## Why
acceptance[5] (P0) scored `blocked(fixture)` in waves 1 and 2 (QA runs
#25812, #26481): it needs a database an 18.0 pre-release created and
served, which took a tag-commit build each run, and an npm install of
the published pre-release CLI is no substitute (it resolves 18.1
dependencies). The card asked for one choice and its size: **a committed
fixture**, as SQLite text (406,866 bytes in all, well under the ~1 MB
line where the card preferred a script), so a run needs no build at all;
the generator is committed beside it so the dump is only ever made by
repo tooling and can be remade from the tag.
The doors the generator drives are the ones fixtures.requires[2] lists
(QA run #24838's by-hand sequence): admin sign-in, the global `mail`
settings written twice, member A invited + signed up + accepted, member
B by admin create-user, a password reset and a verification resend, a
second pending invitation, the declared webhook's mirror row activated,
an admin task and a member task. The mail settings point SMTP at a
closed local port with queued delivery and `OS_EMAIL_RETRIES=10` on the
boot, so each queued mail fails fast and waits as a `pending`
`email.send.async` job: the jobs the ceremony re-points exist without
planting a row by hand.
## Tests
No product code changed. The generator and the restore were run, and the
clause was re-driven once on the restore.
<details><summary>generate, over a built worktree of the tag commit
820fd5a (its own os dev)</summary>
```text
cli-prerelease-fixture: @objectstack/cli@18.0.0-next.5 os dev serving on http://localhost:34935
POST /api/v1/auth/sign-in/email → 200
GET /api/v1/auth/organization/list → 200
POST /api/v1/auth/organization/set-active → 200
PUT /api/settings/mail → 200
PUT /api/settings/mail → 200
POST /api/v1/auth/organization/invite-member → 200
POST /api/v1/auth/sign-up/email → 200
POST /api/v1/auth/organization/accept-invitation → 200
POST /api/v1/auth/admin/create-user → 200
POST /api/v1/auth/request-password-reset → 200
POST /api/v1/auth/send-verification-email → 200
POST /api/v1/auth/organization/invite-member → 200
GET /api/v1/data/sys_webhook?name=showcase_task_changed → 200
PATCH /api/v1/data/sys_webhook/whk_2775de4f-… → 200
GET /api/v1/data/showcase_project → 200
POST /api/v1/data/showcase_task → 201
POST /api/v1/auth/organization/set-active → 200
POST /api/v1/data/showcase_task → 201
cli-prerelease-fixture: wrote …/fixture-18.0.0-next.5 from @objectstack/cli@18.0.0-next.5 (820fd5a): 4 mails, 4 mail jobs (pending, pending, pending, pending), 8 global setting-audit rows
```
</details>
<details><summary>Re-drive of acceptance[5] on the restore, run subject
main 8b27638 (os serve --dev, ceremony --dev)</summary>
```text
restore → n5.db + n5.telemetry.db, born under @objectstack/cli@18.0.0-next.5 (820fd5a)
boot 1 (os serve --dev): exit 1, never listened
✗ This database carries no organization-ownership marker: 17.x or an 18.0 pre-release (18.0.0-next.*) created it, …
sys_flow_credential, sys_secret still carry a physical organization_id column its object no longer declares. …
rows written: 0 (only empty tables created by schema sync: sys_identity_email, sys_platform_setting_audit, …)
plan: exit 0, file checksum before == after (e2a40557ae1f5002)
--apply without --plan-file: exit 1 "Refused: --apply executes only a plan you reviewed …"
apply --plan-file --backup-taken --json: exit 0, complete true, blocking 0
sibling-moves moved 10 (2 identity mails, 8 global audit rows), jobsRewritten 2, activityRepointed 14
declared-webhooks mirrorsDeleted 1, activationRows 1 · column-drops dropped 2 · not-null 64/65 (1 rotation shard unsupported)
marker adr-0131-organization-ownership verified, checkpoint shapeGeneration 1
boot 2: "✓ Server is ready", exit 0 on SIGTERM
rows (before the plan vs after the apply):
identity mails 3a6bc605, 5297ac0f: in sys_identity_email under their ids, 24 shared columns, 0 diffs; gone from sys_email
invitation mails 89172e91, bad94ef3: still in sys_email
global sys_setting_audit 8/8 in sys_platform_setting_audit, 0 diffs, gone from sys_setting_audit
email.send.async jobs naming moved mails: payload.object = metadata.object = sys_identity_email; invitation jobs unchanged
count changes across the apply: sys_email 4→2, sys_identity_email →2, sys_setting_audit 9→1,
sys_platform_setting_audit →8, sys_webhook 1→0, sys_metadata_activation 0→1, sys_migration 4→5 — each a step in the report
after boot 2 and the doors: only additions (sys_session +4, audit/activity rows), plus sys_verification 1→0 (the reset consumed it);
the moved mails' attempt_count 2→3 (boot 2 retried the re-pointed sends at the closed port)
doors: admin / member A / member B sign in 200 with their 18.0 passwords, 401 wrong
token read from the moved reset mail → POST /auth/reset-password 200; new password signs in 200
PATCH showcase_task 200 → exactly one sys_http_delivery (telemetry sibling), ref_id declared:showcase_task_changed
member A reads its own task 200 (1 row)
verdict acceptance[5]: pass
```
</details>
## Acceptance notes
- The recipe is a restore, not a runtime provisioning on a live boot
like this ledger's other recipes; its `$comment` says so, and the item's
own steps then boot the run subject's stock showcase over the restored
pair.
- Reads the recipe's `knownGaps` keep: no magic-link mail and no
`email.attachment.reclaim` job (18.0.0-next.5's served composition
mounts no magic-link door; identity mail carries no attachment), so
those clause arms read nothing; every mail job is `pending`, none
`completed`. The second boot retries the re-pointed sends, so the moved
rows' `attempt_count`/`updated_at` advance after it: compare at the
apply for byte-equality. No `sys_http_delivery` exists before the
upgrade (on 18.0.0-next.5 the organization-less declared webhook refuses
to fan out), so `deliveriesResourced` is 0 and the delivery leg is the
post-upgrade PATCH.
- A production `os serve` boot over the restored pair is NOT MEASURED;
the recipe requires `--dev` throughout, because the telemetry sibling is
part of the `os dev` composition the database was born in.
- `scripts/gen-upgrade-harness-fixture.mjs`'s header still says two
fixtures live in that directory; this third one has its own generator.
Not touched (outside this card's paths).
## Verification
Gates at head 884054f (branch merged with origin/main c8583f8): `node
scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 49 commands; all 49 exit 0, and
`--ran` reconciles 49 derived, 49 run, 0 NOT-MEASURED. Three needed this
container's build state first, none of them for this diff:
`check-plugin-teardown-shape.mjs --self-test` (exit 3 on the shallow
clone until its pinned positive-control commit was fetched),
`check:dts-closure` (exit 1) and `check:dual-build-cjs-loads` (exit 3,
PREREQUISITE NOT MET) until a full `turbo run build`. `pnpm
check:platform-checklist`: OK, 7 area recipes, 12 item references
resolved, 7/7 recipes referenced, symbol anchors 1004/1014 resolved (10
on the named residual). The new script: eslint exit 0, and `tsc
--noEmit` over it with the dogfood tsconfig's compiler options exit 0
(the package's whole typecheck is CI's `Type Check · workspace` lane).
No dogfood test file changed and the new script is not collected, so no
dogfood battery ran. No changeset: `docs/qa/**` and the private
`@objectstack/dogfood` publish nothing (`skip-changeset`).
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (eslint on the new file:
exit 0; CI runs the repo scan)
- [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. (publishes
nothing: `docs/qa/**` and the private `@objectstack/dogfood`)
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (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 by [Claude
Code](https://claude.ai/code/session_01JQwxbWtVJeUNymRQZCEe8t)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 4b59358 commit 019f26e
5 files changed
Lines changed: 1354 additions & 4 deletions
File tree
- docs/qa/platform-checklist/areas
- packages/qa/dogfood/test/upgrade-harness
- fixture-18.0.0-next.5
0 commit comments