Skip to content

Commit 223ae93

Browse files
docs(releases): the 18.0.0 notes and upgrade checklist, walked from 17.7.0; Upgrading's table gains 18.0.0 and 17.5–17.7 (#24922)
Fixes #24905 Clause-②: no The v18 line gets its curated 18.0.0 page, `content/docs/releases/v18/18-0.mdx`, beside `index.mdx` as the v17 line does it, with a `## Upgrade checklist` walked from 17.7.0 on the published 18.0.0 packages. `index.mdx` drops the "curated notes … are not written yet" sentence and links the page; `meta.json` lists it. Upgrading's per-release table gains a v18.0.0 row and the 17.5.0, 17.6.0 and 17.7.0 rows, and its stale v17.4.0 row now links the checklist `17-4.mdx` carries. The first downstream reader is objectstack-ai/hotcrm#2202 (HotCRM's upgrade to 18.0.0); this PR does not claim to have walked it. ## The CHANGELOG filter - **Read.** The `## 18.0.0` sections of every package CHANGELOG at the version commit `06cab4849a`: 53 packages, 1,115 distinct entries (`@objectstack/spec` alone: 341), 340 of them marked BREAKING or carrying a `(narrowing)` Clause-② arm. The 340 were read in body (their FROM → TO tables and one-line fixes); the other 775 were screened by title, and the 253 whose title says refuse / retire / remove / default / rename were read further. - **Kept: 129 changeset commits cited on the page** (153 of the 1,115 entries; 137 of the 340 flagged). - **The rule.** An entry is kept when an application must edit something for 18.0.0 (its metadata, its code against the published packages, its REST or SDK client, its tests on `@objectstack/verify`, or its deployment configuration) **and** the change could be measured on the 18.0.0 artifact. Left out: platform internals and tooling, the Console refresh entries, rules that bind only a walled operator, entries a later entry undoes, surfaces that shipped only in a prerelease (`record:json`), and two app-relevant behaviours that could not be measured here (`1b40780` approvals resume as the decider; `f05649f` / `3f0b6f2` hook `readonly` and `onError: 'abort'` rollback). - **Deviation from the named corpus:** the dispatch named `packages/spec/CHANGELOG.md`; it holds 132 of the 340 flagged entries, so the other packages' sections were read too (decided on the business-need axis: the CLI, runtime and plugin breaks an upgrader meets live there). ## Checklist steps, as measured on 18.0.0 | Step | What it says | How it was measured on 18.0.0 | | :--- | :--- | :--- | | 1 · pins | every `@objectstack/*` to 18.0.0 together, lockfile | walk: `pnpm install` moved the seven ranges to 18.0.0, no peer warning | | 1 · protocol | `engines.protocol: '^18'`, `specVersion: '^18.0.0'`; `migrate meta --from 17 --write` rewrites the first | walk: on `'^17'` validate warns and the boot exits 1 `✗ package … targets protocol ^17 … Run: objectstack migrate meta --from 17`; `--write` printed `manifest.engines.protocol: '^17' → '^18'` | | 1 · migrate meta | read its list as a search list | walk: `406 manual change(s)` on a one-object app | | 1 · skills | remove the `skills add` skills, add `@objectstack/skills` with the project's manager, sync | walk: `Skipped … installed with skills add` ×10 + `Nothing to sync.` exit 0 before; `Synced 10 skills` after; `npm install --save-dev` exit 1 `edgesOut` in the pnpm project | | 1 · validate/build | run both | walk: both exit 0 | | 2 · overlays | `os migrate security-catalog-overlays` before the first boot | walk 2: exit 0, `✓ No environment-wide permission-set or position row is stored over a package-held name` | | 2 · refused boot | boot once; quoted refusal, code `ORGANIZATION_OWNERSHIP_MIGRATION_REQUIRED` | walk: `objectstack start` exit 1, port never bound; code read off `@objectstack/runtime` `dist/index.js` | | 2 · not apply first | `os migrate apply --allow-destructive` is not the remedy | walk, on a DB copy: `os migrate plan` 28 destructive, apply exit 1 `✗ Refusing to drop sys_comment.reactions …` | | 2 · backup / plan / apply | `--out plan.json`, then `--apply --plan-file plan.json --backup-taken` | walks 1 and 2: 81 tables planned (77 before the refused boot), `unattributableRows: 0`; apply attributed 32 rows, rewrote 2 grants, deleted 49 mirrors, dropped 14 columns, NOT NULL on 32, `✓ The ceremony is complete` | | 2 · serve | the server serves the upgraded DB | walk: admin signs in, keeps `platform_admin` / `admin_full_access`, 3 notes read, a 4th written, the 17.7.0 API key answers 200 | | 2 · drift | `comment-reactions` preview + `--apply --yes`, then `migrate apply --allow-destructive --yes` | walk 2: `Converted 1 reaction(s)`, 3 columns dropped, next boot 0 drift lines, reaction reads back | | 3 · flows | value slots CEL, text slots `{{ }}`, bound roots, `$` names, node contracts, aliases, edges, retry | probes: `os validate` (rule `expression-invalid`, exit 1) and `defineStack` (`STACK_SCHEMA_INVALID` 422) on the installed 18.0.0 spec, each position the tag names | | 3 · pages, views, actions | props are errors, `dataSource` binding, retired keys, layout, list views, `editInline`, url schemes | probes as above; save door measured: `PUT /api/v1/meta/page/NAME` → `422 INVALID_METADATA` for an undeclared prop and `kind: 'jsx'` | | 3 · objects, fields | `externalSharingModel`, `unique: true`, `controlled_by_parent`, stage `kind`, one-hop formulas, option `visibleWhen`, metadata-table lookups, duplicates, `defineSeed` | probes (`defineStack`, `os validate`, `defineSeed`) | | 3 · security | `permissionSets`, retired permission-set keys, `packageId`, `'.FIELD'`, one name per holder, sharing rules, manifest `permissions` | probes; `NAMESPACE_CONFLICT` read off `@objectstack/objectql` `dist/core.js`; declared-rule text read off `@objectstack/plugin-sharing` | | 3 · datasources, templates, webhooks, inbound hooks | `mongo`, template keys and registry, declared webhooks, timestamped signature | probe + walk (`os serve` with `OS_DATABASE_DRIVER=mongo` exit 1); tarball: `plugin-email`, `DeclaredWebhookNameConflictError` (`plugin-webhooks`), `signature-body-only` (`trigger-api`) | | 3 · hooks and code | hook-body lowering, engine context, removed exports, `allowEnvironmentOverlay`, hand-built kernels, `os meta resync`, verify | tarball: `cli/dist/utils/extract-hook-body.js`, `plugin-security` (`carries no principal`, `AUTHZ_STORE_IDENTITY_OBJECTS`), `service-i18n` d.ts, `verify`; exports probed absent; walk: `os meta resync` exit 2 `command meta:resync not found` | | 3 · REST, SDK, keys | key lifecycle, CORS, anonymous docs and i18n, body validation, catalog rows gone, upload scopes, reactions, form submit, imports, search | walk 2 against the served 18.0.0: new key `expires_at` +90 d, 2-year key `400 API_KEY_EXPIRY_TOO_LONG`, 17.x key stamped +1 y; no `access-control-allow-origin` for a foreign origin (GET and preflight); `401 UNAUTHENTICATED` on `/api/v1/openapi.json` and `/api/v1/i18n/locales`; `400 INVALID_REQUEST` for `text/plain`; `400 VALIDATION_FAILED` for `null`, `[1,2]` and `expectedVersion: 3`; 404 on the four catalog objects; grants carry `permission_set`, no `permission_set_id`; `scope: 'public'` → `400 INVALID_REQUEST`; `403` codes, `PAYLOAD_TOO_LARGE`, the submit and import doors read off the tarballs | | 4 · not carried / unlisted | at `a7199ef974`: 20 pending changesets, six `minor` ⇒ 18.1.0; 8 shipped in 18.0.0 unlisted; 12 not in it; 7a-2 an open PR — **re-read at `71696121a6` in [Merge with #24912](#merge-with-24912): 26 / 10 minor / 8 / 18, 7a-2 merged after the cut** | `git merge-base --is-ancestor` of each changeset's adding commit against `06cab4849a` in a full clone (`--is-shallow-repository` false): 8 exit 0, 12 exit 1, the exit-0 rows of the same run being the control leg; tarball: `deploymentWide` in `plugin-sharing`, `codeInviteRoleNotFound` in `plugin-auth`, adopt-orphans guard absent from `runtime`; walk: `os serve` with no auth secret exit 1 with the quoted refusal | | 4 · walled postures | `group` / `isolated` boot on a fresh DB with their prerequisites | walk: three refusals in order (organizations runtime, `OS_PLATFORM_OWNER_EMAIL`, membership policy), then `✓ Server is ready` with `Tenancy: group` and `Tenancy: isolated` | | 5 · tags | `latest` 18.0.0, `next` 18.0.0-next.5 (older), `rc` 17.0.0-rc.6; never `@next` | `npm view … dist-tags` on spec, cli, runtime, core, objectql, skills, organizations, create-objectstack; `npm view … time` / `versions` (no `next.4`) | ## The walk - **Fixture.** `create-objectstack@17.7.0` blank scaffold (`v17app`, pnpm 10.28, Node 22.22), its ten skills installed by `skills add`, booted once on 17.7.0 with `objectstack start` into `.objectstack/data/objectstack.db`. Walk 1 seeded an admin and three notes; walk 2, on a fresh scaffold that followed the written steps 1 and 2 verbatim, also seeded an API key and a comment carrying a stored emoji reaction. Everything ran under the session scratchpad, never in the repo. - **Outcomes.** Every step in the table above ran as the page says; walks 1 and 2 printed the same ceremony numbers. Extra measurements: the walled postures on a fresh database, `OS_DATABASE_DRIVER=mongo`, a production boot with no auth secret, and the save door. - **What the walk changed in the page.** 1. The skills step: `npm install --save-dev` exits 1 (`npm error Cannot read properties of null (reading 'edgesOut')`) in the pnpm project `create-objectstack` makes, so the page (and `index.mdx`) adds the package with the project's manager. 2. `specVersion` is a hand edit: `--write` rewrites `engines.protocol` only, and nothing on the boot path reads `specVersion`. 3. The order in step 2: overlays first, then a boot that is refused on purpose (its schema sync creates the tables the ceremony needs: 77 planned before it, 81 after), and ⛔ not `os migrate apply --allow-destructive`, which the drift lines recommend and which refuses. 4. The tail of step 2: a served boot still logs three orphaned columns; `comment-reactions` then `apply --allow-destructive` clears them. 5. Step 4: the "not carried yet" premise split in two once the tarballs were read (below). ## The PM's hypotheses, measured 1. **Falsified.** `walledPostureRefusal` is in `@objectstack/cli@18.0.0-next.5` (`dist/commands/serve.js`) and absent from `@objectstack/cli@18.0.0`; history: added by `ae6bd1a696` (#24480), removed by `fc34d000fc` (#24667). `os serve` 18.0.0 boots `group` and `isolated` once the organizations runtime, the owner email and a membership policy are present; point 4 states that posture with the measured refusals. 2. **Confirmed.** The boot is refused before the port binds, exit 1, by the `com.objectstack.organization-ownership-boot-guard` plugin; the error code is `ORGANIZATION_OWNERSHIP_MIGRATION_REQUIRED` (on the error object, not in the printed line), and the remedy names `os migrate organization-ownership --out PLAN` then `--apply --plan-file PLAN --backup-taken`. 3. **Confirmed.** `17-4.mdx` carries `## Upgrade checklist` (line 606) and `### 17.4.0`; 17.5–17.7 each carry one (lines 1671, 1524, 1259) and had no row. **The card's own premise, measured** (at `a7199ef974`; 7a-2 has since merged after the cut — see the merge section). "The 18.x steps that landed after the cut (for example 7a-2, PR #24872) ship in 18.1.0" does not hold as written: #24872 is an open PR, not on `main`; and 7a-3 (#24828) and 7b-3 (#24845) landed **before** the version commit, so their code is in the 18.0.0 packages while their changesets are still pending. Step 4 says so. ## Choices settled here - **The corpus**: all 53 package CHANGELOGs, not spec's alone — the business-need axis (above). - **Measurement tags per line** (measured in the walk / probed on 18.0.0 / read off the tarball) instead of the v17 pages' single "not exercised" tag — the guard-against-AI-error axis: a reader can tell a run step from a probed refusal, and nothing unmeasured is presented as a step. - **Two unmeasurable behaviours left out** rather than tagged "not measured" — the dispatch's ruling that every step is measured on the artifact. ## Deviations, named - **File surface breach: `scripts/docs-audit/handwritten-docs.json`, one line.** `pnpm check:docs-audit-scope` reds when a hand-written page exists that the roster does not list; the line was written by `node scripts/docs-audit/check-audit-scope.mjs --write` (`+1 added, -0 removed`). The dispatch both bounds the surface to `content/docs/releases/v18/**` and `content/docs/upgrading.mdx` and requires the docs gates to stay green; the ruled page shape needs the roster line, so this PR keeps the gate green and names the breach here rather than choosing silently. - **One sentence of Upgrading's prose changed beside the rows.** "Only the v17 line is broken out per release. Each of its three minors …" is false once the v18.0.0 row links a per-release page (and "three" was already wrong), so it reads "The v17 and v18 lines are broken out per release. Each v17 minor …". The page's rules are untouched; Upgrading's step-4 skills command is untouched (see the acceptance notes). ## Acceptance notes - **18.0.0's CHANGELOG omits eight changesets whose code shipped in 18.0.0.** *(Downgraded after the epic seat's note `6294471945`: the #23818 ruling's `annotate-shipped` step carries such entries into the next CHANGELOG with a "Shipped in …" lead line — the 18.0.0 CHANGELOG already holds entries headed `**Shipped in 18.0.0-next.2**, whose CHANGELOG missed this entry` — so this is the release lane working as ruled, not a defect.)* At `a7199ef974`, `.changeset/24583-7a3-…`, `24583-7b3-…`, `24750-…`, `24751-…`, `24767-…`, `24772-…`, `24773-…` and `24785-…` belong to commits that are ancestors of the version commit `06cab4849a`, and the 18.0.0 tarballs carry their code (`deploymentWide`, the no-auth-secret refusal measured with `os serve`, `codeInviteRoleNotFound`); their entries will first appear in 18.1.0's CHANGELOG. Reported to the PM for filing. - **Before the ceremony, the `[schema-drift]` lines and `os migrate plan` prescribe `os migrate apply --allow-destructive` for the `organization_id` columns without naming the ceremony** (28 destructive changes on the walk's database), and that apply then refuses on `sys_comment.reactions`. Reported to the PM for filing. - **`npm install --save-dev "@objectstack/skills@…"` fails in a pnpm-installed project** and is still the command in `content/docs/upgrading.mdx` step 4, `content/docs/ai/skills.mdx`, `content/docs/ai/skills-reference.mdx`, `skills/README.md` and `skills/objectstack-upgrade/SKILL.md`. Reported to the PM for filing. - `18.0.0-next.4` was never published, while every CHANGELOG carries a `## 18.0.0-next.4` section. Observation only. - `os migrate security-catalog-overlays`'s preview printed "Raw execute() called … FORWARDED, not refused — if it wrote, this boot wrote"; the database file's mtime did not move. Observation only. ## Merge with #24912 #24912 (card #24904, `71696121a6`) edited `content/docs/upgrading.mdx` and `content/docs/releases/v18/index.mdx` and amended `packages/cli/CHANGELOG.md` in place. `git merge origin/main` (no rebase, no force) stopped on one conflict: both sides added a `v18.0.0` row to Upgrading's "Per-release specifics" table, and #24912's side still carried the stale `v17.4.0 — ⛔ checklist not written` row. Resolution: **one `v18.0.0` row** linking `/docs/releases/v18/18-0#upgrade-checklist`, `#upgrading-to-180` and `/docs/releases/v18`, and this PR's 17.4–17.7 rows. `index.mdx` merged clean; `packages/cli/CHANGELOG.md` is #24912's and untouched here. Merge commit `b6917f0b72`; `git merge-tree --write-tree origin/main HEAD` exit 0 before the push and again after it (main `71696121a6`). New measurements for the reconciliation (all on npm 18.0.0, under the session scratchpad): - **Walk 3, walled:** a `create-objectstack@17.7.0` app with `@objectstack/organizations@17.7.0`, booted under `OS_TENANCY_POSTURE=group`, an owner and two records, moved to 18.0.0 (the exact `"17.7.0"` organizations pin moved by hand): `os migrate security-catalog-overlays` exit 0; refused boot exit 1; plan `posture group`, 81 tables, `unattributableRows: 0`; apply `✓ The ceremony is complete`; served `Tenancy: group`, both records in their organization. - **Walk 3, development database:** a 17.7.0 `os dev` database moved to 18.0.0. `OS_DATABASE_URL=file:… os serve --dev` exit 1 naming `Run 'os migrate organization-ownership --dev --out PLAN' …`. `os dev` with the artifact 17.7.0's `os start` had compiled still in `dist/`: `✗ The upgrade plan was refused, and nothing was changed.` (the plan refused protocol `^17` although `objectstack.config.ts` read `'^18'`). After `os build`: `✓ Upgraded the development database to the v18 organization ownership` and `✓ server started on the upgraded database`. - **`os start` with no secret:** a fresh `--home`, no `AUTH_SECRET` / `OS_AUTH_SECRET`: it wrote `HOME/auth-secret` (mode `0600`), served, sign-up `200`. - **The CHANGELOG copies:** the `@objectstack/cli@18.0.0` tarball's `CHANGELOG.md` line 162 still reads `ae6bd1a: feat(cli)!: 18.0 supports fresh 'single' installs only — …`; the repository's `packages/cli/CHANGELOG.md` at `71696121a6` line 162 reads `ae6bd1a: feat(cli)!: the 18.0 pre-release refusals of … both lifted in 18.0.0`, and its `fc34d00` headline adds "and on databases the ownership ceremony upgraded". | # | File | Old → new | Measurement | | :--- | :--- | :--- | :--- | | 1 | `upgrading.mdx` table | two `v18.0.0` rows + #24912's stale `v17.4.0` row → one `v18.0.0` row (checklist · Upgrading to 18.0 · v18) + this PR's 17.4–17.7 rows | hypothesis 3 (17-4.mdx carries its checklist) | | 2 | `upgrading.mdx` "Upgrading to 18.0" | a 6-step sequence → 8 steps in the walk's order: `os migrate security-catalog-overlays` first, the drift tail (`comment-reactions --apply --yes`, then `apply --allow-destructive --yes`) last, and one link to `/docs/releases/v18/18-0#2-upgrade-the-database` for each step's output; the rest of #24912's prose unchanged | walks 2 and 3 (overlays exit 0); walk 2 (`Converted 1 reaction(s)`, `Applied 3 change(s)`, next boot 0 drift lines) | | 3 | `upgrading.mdx` `--dev` paragraph | "`os dev` runs the whole sequence itself" → + "Run `os build` before it: while `dist/objectstack.json` was still the artifact 17.x compiled, `os dev`'s in-place upgrade refused its plan and changed nothing." | walk 3, development database | | 4 | `upgrading.mdx` walled bullet | + the declared membership policy, `OS_AUTH_MEMBERSHIP_POLICY=invite-only` (or `auto`), with its refusal `✖ FATAL: tenancy posture 'group' is walled, but this deployment never declared a membership policy.` | fresh-DB walk (refusal); walk 3 (upgraded DB served with it set) | | 5 | `v18/index.mdx` `--dev` bullet | + the same `os build` caveat | walk 3, development database | | 6 | `v18/index.mdx` walled bullet | + "18.0.0 also refuses a walled boot until a membership policy is declared …" with the refusal; #24912's "same prerequisites as 17.x" sentence kept as written | as 4 | | 7 | `v18/index.mdx` "Upgrading a database to 18.0.0" | closing sentence + one link to the walked 18.0.0 checklist; `## Per-release notes` kept; nothing of #24912's removed | — | | 8 | `18-0.mdx` "How to read the 18.0.0 CHANGELOG" | the `ae6bd1a` caution → says it reads the tarball's copy (what `node_modules` holds), names #24912 and quotes the amended repository text | the two CHANGELOG copies | | 9 | `18-0.mdx` step 2 intro | + the overview link to `/docs/upgrading#upgrading-to-180` | — | | 10 | `18-0.mdx` step 2, `os dev` | "according to the CLI reference … did not exercise that path" → the measured `os serve --dev` refusal, `os dev`'s in-place upgrade, and the `os build`-first caveat | walk 3, development database | | 11 | `18-0.mdx` step 4, auth secret | "A production server boot …" → "A production `os serve` boot …" + "`os start` is not refused: it wrote `HOME_DIR/auth-secret` (mode `0600`) … and served sign-up" — now agrees with #24912 | `os start` with no secret | | 12 | `18-0.mdx` Callout and step 4, walled | "a walled database … not walked" → walked under `group` (an `isolated` database not walked) — now agrees with #24912's "on a database the ceremony upgraded" for `group` | walk 3, walled | | 13 | `18-0.mdx` step 4, pending changesets | read at `a7199ef974` (20, six `minor`; "7a-2 is an open PR") → read at `71696121a6`: 26, ten `minor`; 8 shipped in 18.0.0 unlisted; 18 not in it, six `minor`, 7a-2 (#24872, merged 2026-10-20 15:26 UTC, after the cut) first among them | `git merge-base --is-ancestor` per changeset against `06cab4849a`; `gh api pulls/24872` (`merged: true`) | Point 13 is not one of #24912's: it is named because the merge brought `.changeset/24583-7a2-…` into this branch's tree, which made "7a-2 is not on `main`" false. Already in agreement, re-measured: #24912's "start 18.0 against the database once (`os serve` / `os start`)" (the walks used `os start`); "the refusal `os serve --dev` prints names the command with `--dev`" (walk 3). ## Round 3 Two sites told a reader to run a destructive apply without reading its plan first; `os migrate apply --allow-destructive` applies **every** destructive change in the plan, and `--yes` skipped its confirmation. - **Measured on 18.0.0 first** (on a copy of the `group` walk's post-ceremony database): `os migrate plan` listed 4 destructive changes (`sys_comment.reactions`, `sys_sso_provider.created_by` / `updated_by`, index `idx_sys_sso_provider_organization_id`). `os migrate comment-reactions --apply` without `--yes`, non-TTY: exit 1, `⚠ Apply mode writes sys_comment_reaction rows. Re-run with --yes to confirm …`. `os migrate apply --allow-destructive` without `--yes`, non-TTY (stdin `/dev/null`): applied nothing, printed `⚠ Confirmation required. Re-run with --yes to apply, or use "os migrate plan" to preview.`, **exit 0** (the plan still listed 4). On a TTY (a pty): it listed the changes and asked `Apply 4 change(s) to DATABASE? [y/N]`; `n` → `ℹ Aborted — no changes made.` exit 0 (plan still 4); `y` → `✓ Applied 4 change(s).` exit 0, then `✓ Physical schema is in sync with metadata`. - **`content/docs/upgrading.mdx`, "Upgrading to 18.0" step 8:** "`os migrate comment-reactions --apply --yes`, then `os migrate apply --allow-destructive --yes`" → preview `os migrate comment-reactions`, then `--apply --yes`; run `os migrate plan` and check its destructive entries are only the ceremony's leftovers (in the walk: the three columns); any other entry is the app's own and decided separately; then `os migrate apply --allow-destructive` in a terminal, answering its `[y/N]` prompt after reading the list; in a non-interactive shell it applies nothing and still exits `0`. - **`content/docs/releases/v18/18-0.mdx`, step 2 "Then clear the drift …":** "then `os migrate apply --allow-destructive --yes`, which dropped the three columns" → the same plan check, the `[y/N]` prompt and the non-TTY behaviour, each quoted from the measurement; the walk's own `--yes` run stays recorded as a fact of the walk; the `group` walk's extra index entry is named. - **Rule 4 sweep, found and fixed the same way:** `npx skills remove --all` (`-y` implied, removes every installed skill) in `upgrading.mdx` step 4 and `v18/index.mdx` → "run `npx skills list` first", and `18-0.mdx` step 1 names `npx skills list` before the named `skills remove … -y` (measured: it listed the ten `objectstack-*` skills with their source). **Reviewed, not changed:** the ceremony's `--apply --plan-file … --backup-taken` (ruled out of scope); `os migrate security-catalog-overlays` (its bare run is the preview, `--apply` follows it); `os migrate comment-reactions --apply --yes` in `18-0.mdx` (already after its preview); `os migrate meta --from 17 --write` (writes only the source edits it can prove, re-runs the chain and restores on a mismatch; not destructive); `skills experimental_sync --copy -y` (copies the package's skills into the agent directory, skipping `skills add` ones); Upgrading's `os migrate apply --allow-destructive # … once you have read the plan` (already after `os migrate plan`). ## Gates At head `9da4c8d328` (merge base `71696121a6`), the re-derived list (62 commands, the same 62 as rounds 1 and 2) ran locally, every one exit 0, after `pnpm --filter '@objectstack/lint...' --filter '@objectstack/client-react...' build` under the verify lock (VERDICT command-exit 0); `--ran` with recorded exit codes: `62 derived, 62 run, 0 NOT-MEASURED, 0 UNRUN`. `git merge-tree --write-tree origin/main HEAD` exit 0 just before the push. Earlier heads `5019f5152f` and `b6917f0b72` were green on the same 62. CI's own check-runs are the record for everything outside that list. **Changeset:** none. Measured: all 73 published `package.json` manifests declare `files[]` (control: all 73 name `dist`), none names `content/`, a docs path or `scripts/`, and the root package is private, so `skip-changeset`. --- _Generated by [Claude Code](https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent b9a79ef commit 223ae93

5 files changed

Lines changed: 780 additions & 22 deletions

File tree

0 commit comments

Comments
 (0)