Repository navigation
Commit ebfe658
docs(cli): say what a read-only boot's first connection writes to a SQLite file (#21779)
Fixes #21745
Clause-②: no. Documentation is made true about existing behaviour;
nothing is published.
Docs only: two files under `content/docs/`, which no package ships. No
code change, no behaviour change, no changeset.
## What changed
Triage graded #21745 option B: make the reference true, and leave the
one-rule-for-every-connect ruling closed.
`content/docs/deployment/cli.mdx` now says it once, in the
read-only-boot paragraph under **Data migrations**:
- the commands write no row and no schema;
- on a SQLite file no ObjectStack process has opened before, the first
connection converts its journal to WAL, as every ObjectStack connection
does. That changes the file's header and no row or table;
- after that, a read-only run leaves the file byte-identical.
Each other "writes nothing" sentence about a command that opens the
database now says only what is true on its own ("writes no row", "no row
and no schema"). The prose sites (secret orphans, plan/apply,
duplicates) link to that paragraph.
`content/docs/deployment/seed-tenancy-repair.mdx` made the same claim
about `os migrate duplicates`, and it gets the same qualification. The
heading "Nothing is written before you confirm" is now "Nothing is
applied before you confirm". No page under `content/docs` links to the
old anchor.
## Measured
Base: `origin/main` `d7fff21736`. Every run used the built CLI binary
`packages/cli/bin/run.js`, launched as a child process.
**The fixtures.**
- A database that `os serve` left behind for a one-object app with an
inline seed: 35 tables, WAL, auto_vacuum INCREMENTAL. Called
"configured" below.
- Legacy copies of it, made with raw better-sqlite3 (`VACUUM INTO`, then
`PRAGMA journal_mode = DELETE`), so no ObjectStack process ever opened
them:
- auto_vacuum NONE, the shape another tool leaves;
- auto_vacuum INCREMENTAL, the shape of a pre-WAL ObjectStack file;
- auto_vacuum FULL, as a control.
- Header bytes were read with `fs` only, never through a SQLite
connection.
**A1.** `os migrate duplicates --database-url file:X` on the NONE copy:
| | journal | [18] | [19] | [27] | [95] | md5 |
|---|---|---|---|---|---|---|
| before | delete | 1 | 1 | 1 | 1 | `71cdd04b096d` |
| after run 1 | wal | 2 | 2 | 2 | 2 | `02bf2c53ba03` |
| after run 2 | wal | 2 | 2 | 2 | 2 | `02bf2c53ba03` |
Run 1 changed 4 bytes in the file, all in the header (offsets 18, 19, 27
and 95). Run 2 changed none. No `-wal`, `-shm` or `-journal` file was
left after either run.
**A2.** The no-write mode of every `bootSchemaStack` caller ran twice,
each time on a fresh copy of each fixture. The callers are the family
that `schema-migrate.one-shot-family.integration.test.ts` reads off the
source.
- The modes: `migrate` `duplicates`, `plan`, `multi-value-columns`,
`unmapped-columns`, `files-to-references`, `value-shapes`,
`summary-nulls`, `meta --stored`, `recorded-by`, `resume`,
`audit-metadata-bodies` and `account-issuer`; `secret orphans`; `secret
rewrap`; `storage orphans`; `meta resync`.
| fixture | run 1 | run 2 |
|---|---|---|
| legacy NONE (16 modes) | 16 of 16 converted: header offsets 18, 19, 27
and 95 only, 4 bytes each | 16 of 16 unchanged: 0 bytes, same md5 |
| legacy INCREMENTAL (16 modes) | 16 of 16 converted, the same 4 header
offsets | 16 of 16 unchanged: 0 bytes |
| legacy FULL (`duplicates`, `plan`) | converted, and auto_vacuum went
FULL to INCREMENTAL (offset 67): 5 header bytes | 0 bytes |
| configured (16 modes) | 0 bytes | 0 bytes |
Every run exited 0 and printed parseable JSON.
**Other modes.**
- `os migrate apply` answered `n` at a real `[y/N]` prompt (a pty via
`script`), against a release one field and one object ahead: "Aborted —
no changes made.", and the legacy file converted all the same (offsets
18, 19, 27 and 95). The configured file did not change.
- Re-runs of write modes:
- `secret rewrap --apply` and `summary-nulls --apply` changed 0 bytes on
their second run (legacy and configured alike).
- `value-shapes --apply` rewrites only its flag row, `sys_migration`
`adr-0104-value-shapes`. A row diff of both runs shows nothing else.
### The sites, one row each (line numbers are `d7fff21736`'s)
| site | command | converts? | evidence | edit |
|---|---|---|---|---|
| `cli.mdx` `skip-seed-data` gloss (old :308) | a `bootSchemaStack` boot
(`skipSeedData: true` on every one) | yes | A2 | "writes nothing" to
"runs no seed" |
| :544, :547, :555 | `secret orphans` report | yes | A2 | "writes no
row"; pointer to Data migrations; code comment "writes no rows" |
| :601, :606 | `secret rewrap` dry run | yes | A2 | "writes no row";
code comment |
| :631 "a finished run writes nothing" | `secret rewrap --apply` re-run
| no: the file was already opened by the first run | 0 bytes on the
second `--apply` run | kept |
| :853, :859 "(no changes applied)" | `plan` | yes, but these sentences
are about drift changes | A2 | kept |
| :868 heading, :870, :888 | `plan` / `apply` boot, answered `n` | yes |
A2 plus the pty `n` run | heading reworded; "writes no row and no
schema"; "every table and row exactly as it was" plus pointer |
| :933 occupancy table | `plan` | yes | A2 | "writes no row and no
schema either way" |
| :1005 | `multi-value-columns` dry run | yes | A2 | "writes no row and
no schema at all" |
| :1078–:1081 | `unmapped-columns` | yes | A2 | "writes no row and no
schema" |
| :1114 | `duplicates` (table row) | yes | A1 | "writes no row and no
schema" |
| :1116–:1135 | the shared read-only-boot paragraph | yes | A2 | lead
sentence "no row and no schema"; the one qualification paragraph added
after it |
| :1150, :1203, :1255, :1349 | dry run / scan / preview code comments |
yes | A2 | "writes no rows" |
| :1185, :1239 | `files-to-references` / `value-shapes` dry runs | yes |
A2 | "writes **no row**" |
| :1215 "`--apply`'s only write is the flag row" | `value-shapes
--apply` | yes, plus the flag row | the write-mode legs above | "the
only row `--apply` writes is the flag itself" |
| :1290 "a second run … writes nothing" | `summary-nulls --apply` re-run
| no: the file was already opened by the first run | 0 bytes on the
second run | kept |
| :1438 SDK `migrateStored()` | runs inside the serving process, on its
existing connection | no new connection | route doc: it uses the
server's live engine | kept |
| :1451, :1473–:1476 | `duplicates` | yes | A1 | "writes no row and no
schema under any flag"; "changes no data in production" plus the WAL
sentence and pointer |
| :1539 "boots read-only and repairs nothing" | `duplicates` | the term
the qualified paragraph now defines | — | kept |
| :739 `os validate`, :1595/:1616/:1711/:1662/:1729 `os generate`,
:1806/:1820 `os lint --fix` | open no SQLite file | no | `git grep` of
each command for `bootSchemaStack`, `SqlDriver` and `better-sqlite3`: 0
imports | kept |
| `seed-tenancy-repair.mdx:311` | `duplicates` | yes | A1 | "writes no
row"; "its own queries are `SELECT`s only"; WAL sentence plus link |
**A4, other pages.** I ran `git grep` over `content/docs` (excluding
`releases/` and `references/`) for "writes nothing", "read-only boot",
"byte-identical", "changes nothing", and for every family command name.
Hits with no edit:
- `seed-tenancy-repair.mdx:123` is about the log, and `:251` is about a
later serving boot's repair rows.
- `ui/translations.mdx:335`: `os i18n extract --check`.
`commands/i18n/*.ts` has 0 hits for SQLite or boot imports.
- `automation/flows.mdx:1445`: "writes nothing for it" refers to the
decision nodes' rows.
- `protocol/kernel/http-protocol.mdx:1241`, `ui/actions.mdx:261` and
`concepts/metadata-lifecycle.mdx:112` are unrelated surfaces.
## Acceptance notes
- **Kept out on purpose: the journal opt-out.**
`OS_DATABASE_SQLITE_JOURNAL_MODE=delete` makes the first run on a
rollback-journal file change 0 bytes (measured on the NONE and
INCREMENTAL copies). The reference does not offer it for read-only runs,
because on a file already in WAL the same setting converts the file back
to `delete`. That is a write, to a served deployment's file.
- **Same phenomenon in runtime text.** The CLI's decline line "Aborted —
no changes made." prints after the conversion on a never-opened file.
That text speaks of the migration's changes. This card rules out any
code change. Noted, not filed; no follow-up PR is planned.
- **"After that" holds beyond the legacy files the card named.** On an
auto_vacuum FULL legacy file, the first connection also flips
auto_vacuum to INCREMENTAL. That is a header change too, and the second
run changes 0 bytes. The new paragraph says "the file's header changes"
so that this case stays true.
## Verification (head `fcc13878fa`)
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 41 families at `fcc13878fa`. All 41
ran: 41 exited 0.
- The first `check:skill-examples` run exited 3 (PREREQUISITE NOT MET:
`client-react` was not built). It exited 0 after `pnpm --filter
@objectstack/client build && pnpm --filter @objectstack/client-react
build`.
- `--ran` reconciliation: "41 derived famil(ies) accounted for — 41 run,
0 NOT-MEASURED".
- `check:doc-anchors`: "428 internal #fragment link(s) across 414 source
file(s) all resolve". Two one-time ablations through
`scripts/ablation-replace.mjs`:
- the new cross-page link `/docs/deployment/cli#data-migrations`
mutated: red, naming `seed-tenancy-repair.mdx:316`;
- a new same-page `#data-migrations` link mutated: red, naming
`cli.mdx:549`.
- Both were restored, with the blob equal to HEAD (`24ba2ab3876e`,
`385558ab3097`) and `git diff HEAD` empty.
- `pnpm lint`: eslint's population is
`**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}` (`eslint.config.mjs:971`).
`eslint --format json` on the 2 changed files reports 2 files, each
"File ignored because no matching configuration was supplied". So no
file in the lint population changed, and an `.mdx` edit cannot move a
linted file's verdict.
- No package changed, so no package build or test is owed.
- NOT MEASURED: the docs site build and the lychee link check (`Check
Documentation Links`). Reason: CI runs them over the whole site, and
lychee is not installed in this container.
---
_Generated by [Claude
Code](https://claude.ai/code/session_016GiHYRmLSNWTfbX9gVQkpz)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent d7fff21 commit ebfe658
2 files changed
Lines changed: 54 additions & 35 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
305 | 305 | | |
306 | 306 | | |
307 | 307 | | |
308 | | - | |
| 308 | + | |
309 | 309 | | |
310 | 310 | | |
311 | 311 | | |
| |||
541 | 541 | | |
542 | 542 | | |
543 | 543 | | |
544 | | - | |
| 544 | + | |
545 | 545 | | |
546 | 546 | | |
547 | 547 | | |
548 | | - | |
549 | | - | |
550 | | - | |
551 | | - | |
552 | | - | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
553 | 554 | | |
554 | 555 | | |
555 | | - | |
| 556 | + | |
556 | 557 | | |
557 | 558 | | |
558 | 559 | | |
| |||
599 | 600 | | |
600 | 601 | | |
601 | 602 | | |
602 | | - | |
| 603 | + | |
603 | 604 | | |
604 | 605 | | |
605 | 606 | | |
606 | | - | |
| 607 | + | |
607 | 608 | | |
608 | 609 | | |
609 | 610 | | |
| |||
865 | 866 | | |
866 | 867 | | |
867 | 868 | | |
868 | | - | |
| 869 | + | |
869 | 870 | | |
870 | | - | |
871 | | - | |
| 871 | + | |
| 872 | + | |
872 | 873 | | |
873 | 874 | | |
874 | 875 | | |
| |||
885 | 886 | | |
886 | 887 | | |
887 | 888 | | |
888 | | - | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
889 | 892 | | |
890 | 893 | | |
891 | 894 | | |
| |||
930 | 933 | | |
931 | 934 | | |
932 | 935 | | |
933 | | - | |
| 936 | + | |
934 | 937 | | |
935 | 938 | | |
936 | 939 | | |
| |||
1002 | 1005 | | |
1003 | 1006 | | |
1004 | 1007 | | |
1005 | | - | |
1006 | | - | |
| 1008 | + | |
| 1009 | + | |
1007 | 1010 | | |
1008 | 1011 | | |
1009 | 1012 | | |
| |||
1077 | 1080 | | |
1078 | 1081 | | |
1079 | 1082 | | |
1080 | | - | |
1081 | | - | |
| 1083 | + | |
| 1084 | + | |
1082 | 1085 | | |
1083 | 1086 | | |
1084 | 1087 | | |
| |||
1111 | 1114 | | |
1112 | 1115 | | |
1113 | 1116 | | |
1114 | | - | |
| 1117 | + | |
1115 | 1118 | | |
1116 | | - | |
| 1119 | + | |
1117 | 1120 | | |
1118 | 1121 | | |
1119 | 1122 | | |
| |||
1132 | 1135 | | |
1133 | 1136 | | |
1134 | 1137 | | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
1135 | 1148 | | |
1136 | 1149 | | |
1137 | 1150 | | |
| |||
1147 | 1160 | | |
1148 | 1161 | | |
1149 | 1162 | | |
1150 | | - | |
| 1163 | + | |
1151 | 1164 | | |
1152 | 1165 | | |
1153 | 1166 | | |
| |||
1182 | 1195 | | |
1183 | 1196 | | |
1184 | 1197 | | |
1185 | | - | |
| 1198 | + | |
1186 | 1199 | | |
1187 | 1200 | | |
1188 | 1201 | | |
| |||
1200 | 1213 | | |
1201 | 1214 | | |
1202 | 1215 | | |
1203 | | - | |
| 1216 | + | |
1204 | 1217 | | |
1205 | 1218 | | |
1206 | 1219 | | |
| |||
1212 | 1225 | | |
1213 | 1226 | | |
1214 | 1227 | | |
1215 | | - | |
1216 | | - | |
| 1228 | + | |
| 1229 | + | |
1217 | 1230 | | |
1218 | 1231 | | |
1219 | 1232 | | |
| |||
1236 | 1249 | | |
1237 | 1250 | | |
1238 | 1251 | | |
1239 | | - | |
| 1252 | + | |
1240 | 1253 | | |
1241 | 1254 | | |
1242 | 1255 | | |
| |||
1252 | 1265 | | |
1253 | 1266 | | |
1254 | 1267 | | |
1255 | | - | |
| 1268 | + | |
1256 | 1269 | | |
1257 | 1270 | | |
1258 | 1271 | | |
| |||
1346 | 1359 | | |
1347 | 1360 | | |
1348 | 1361 | | |
1349 | | - | |
| 1362 | + | |
1350 | 1363 | | |
1351 | 1364 | | |
1352 | 1365 | | |
| |||
1448 | 1461 | | |
1449 | 1462 | | |
1450 | 1463 | | |
1451 | | - | |
1452 | | - | |
| 1464 | + | |
| 1465 | + | |
1453 | 1466 | | |
1454 | 1467 | | |
1455 | 1468 | | |
| |||
1473 | 1486 | | |
1474 | 1487 | | |
1475 | 1488 | | |
1476 | | - | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
1477 | 1493 | | |
1478 | 1494 | | |
1479 | 1495 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
308 | 308 | | |
309 | 309 | | |
310 | 310 | | |
311 | | - | |
312 | | - | |
313 | | - | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
314 | 317 | | |
315 | 318 | | |
316 | 319 | | |
| |||
0 commit comments