Skip to content

Commit c67f244

Browse files
docs(qa): a checklist item drives the fresh-install order (os migrate apply, then the first os serve), and validation-rule-type-matrix drops its red-until-#24782 text (#25075)
Fixes #25054 Clause-②: no Two items in `docs/qa/platform-checklist/areas/` and nothing else: no product code, test, pin, changeset or `RUNNER.md`. `areas/integration-system.json` (open in PR #25045) is untouched. ## 1. New item `cli.fresh-install-migrate-apply-first` (`areas/cli.json`, revision 1) - **What it drives:** an empty file database, `os migrate apply --yes` first, then the first `os serve`, in one environment, as a deploy script runs them. - **Oracle:** the boot (acceptance[1]). The serve reaches `✓ Server is ready` (not DEGRADED), `/api/v1/health` answers 200, and the output has no organization-ownership refusal. The marker is read at its own layer (acceptance[0]): the `sys_migration` row `adr-0131-organization-ownership`, read through SQLite after the apply and before any boot, then again after the boot, where it must be unchanged. - **Release:** `since: "v18.1"`. The change for #24827 is `.changeset/24827-migrate-apply-birth-marker.md`, a `minor` changeset pending on `main`, so it ships in 18.1.0. `fixtures.knownGaps[0]` says a run against 18.0.0 records the refusal as 18.0.0's known behaviour, not as a FAIL of the item. Measured: the fix commit `19484af538` is not an ancestor of the `@objectstack/cli@18.0.0` tag commit `06cab4849a` (exit 1). Control leg, the commit 50 behind that tag: exit 0. The checkout is not shallow. - **Pins:** `fixtures.knownGaps[1]` says why the fix's two pins score no clause (RUNNER rule 6). `apply.organization-ownership-birth.integration.test.ts` runs `MigrateApply` in-process, and `schema-migrate.birth-after-flush.test.ts` runs with no kernel. Neither spawns the CLI or boots `os serve`. So the item has no `automated` ref, and both clauses are driven live. - **Why a new item.** No existing item's scope covers this order. I read the titles and scopes of `platform-core.json` and `cli.json` at `688052e147`: | item | its scope | why the order does not belong there | |---|---|---| | `platform-core.v18-boot-refusals` | a 17.x-shaped database | its revision 6 says the order "is not added here" | | `cli.organization-ownership-ceremony` | upgrading a database that 17.x or an 18.0 pre-release created | it never uses an empty database | | `cli.migrate-plan-apply-json` | plan and apply on a database a prior `os dev` boot synced (its `fixtures.requires[0]`) | it never uses an empty database and never boots after the apply | | `platform-core.boot-health`, `cli.dev-boot-contract` | the `os dev` boot | that boot creates the tables and writes the birth marker itself, so the order cannot arise | | `cli.scaffold-first-run` | the published scaffold, booted by `os start --artifact` | it has no `os migrate apply` | ## 2. `records-forms.validation-rule-type-matrix` (`areas/records-forms.json`, revision 6 to 7) - `fixtures.knownGaps[1]` is removed, and the closing "Red until #24782 lands" is removed from `acceptance[5].clause`. `knownGaps[1]` itself asked for both edits once the change for #24782 merged. It merged as PR #25051 (`72518d20f5`), per the `domain:engine` pointer 6308955528 on seat post #6023. No other field changed. Each edited item gets one `revision` bump and one `history` row. The new item starts at revision 1 with one row. A scripted editor made the edits: text edits inside each target item's own span, then a re-parse asserting that every other item, every top-level key, and the bytes outside the spans are unchanged, and that the target matches the intended edit exactly. The history rows carry the placeholder ref `#PENDING-25054`, because this PR had no number yet. The next commit on this branch replaces it with this PR's number and changes nothing else. ## Live readings on `main` (base `688052e147`, CLI built from this worktree) ### Fresh-install order: first evidence for the new item The showcase was run from this PR's worktree. Run directory under the session scratchpad: `fresh.db` absent before the run (`test ! -e` on it and on its `-wal` and `-shm`). Environment for both commands: `OS_DATABASE_URL=file:RUN/fresh.db`, `OS_HOME=RUN/home`, and `OS_AUTH_SECRET` and `OS_SECRET_KEY` set to fresh random values. The boot also had `OS_PORT=41873`. 1. `os migrate apply --yes`: exit **0**. It printed `✓ Created/extended 107 table(s): 107 table(s) to create, 0 column(s) to add.` and `[organization-ownership] a datastore created from empty: birth marker written (shape generation 1, platform 18.0.0).` 2. The marker row, read through `node:sqlite` before any boot: `id adr-0131-organization-ownership`, `verified_at 2026-10-21T06:54:23.840Z`, `applied_at null`, `blocking 0`, `advisory 0`, `details {"birth":{"shapeGeneration":1,"platformVersion":"18.0.0","createdAt":"2026-10-21T06:54:23.840Z"}}`. This is the only row with that id. 3. `os serve -p 41873` (started with `setsid`): it printed `✓ Server is ready` with `Mode: production` and `OrganizationOwnershipBootGuard` among the plugins. `GET /api/v1/health` answered 200 10 s after the start, and `GET /api/v1/ready` answered 200. Refusal greps over the output: `carries no organization-ownership marker` 0, `refuses to start` 0, `os migrate organization-ownership` 0. 4. The marker row after the boot: one row, identical to step 2. The process group was stopped and port 41873 is free. | item (revision) | clause | verdict | evidence | |---|---|---|---| | `cli.fresh-install-migrate-apply-first` (1) | acceptance[0] | pass | apply exit 0, created-tables line, the row in steps 2 and 4 | | `cli.fresh-install-migrate-apply-first` (1) | acceptance[1] | pass | `✓ Server is ready`, health 200, 0/0/0 refusal greps | Item verdict: **pass**. ### Verification re-run of `records-forms.validation-rule-type-matrix` acceptance[5] The boot was the canonical checklist boot: `pnpm -C WORKTREE/examples/app-showcase exec objectstack dev --ui --seed-admin -p 41874 -d file:SCRATCH/data.db` with `OS_PORT=41874` exported. The run signed in as the seeded admin and authored the two scratch objects of `fixtures.requires[2]` with `PUT /api/v1/meta/object/qa_vr_probe` and `PUT /api/v1/meta/object/qa_vr_probe_err`, which both answered 200. Then it followed steps[6]: - `POST /api/v1/data/qa_vr_probe {"title":"abc"}` answered **201**, and the re-read found 1 row (`title abc`). - Exactly **one** server-log line names `qa_unevaluable_warn`, across the whole log: `Validation rule 'qa_unevaluable_warn' (warning): the rule could not be evaluated (runtime: int() type error: cannot convert to int) — write proceeded: the rule is advisory, so it was not applied to this write`. Lines naming the rule that contain `write rejected`: 0. Lines that contain `fails closed`: 0. - Control: `POST /api/v1/data/qa_vr_probe_err {"title":"abc"}` answered **400** `VALIDATION_FAILED`, with `fields[0].constraint` `{rule: qa_unevaluable_err, reason: unevaluable}`. The re-read found 0 rows. Its log lines say `— write rejected: a rule that cannot be evaluated fails closed, it is never skipped`, which is true here. | item (revision run) | clause | verdict | evidence | |---|---|---|---| | `records-forms.validation-rule-type-matrix` (6) | acceptance[5] | pass | 201 + re-read, the single log line quoted above, control 400 + empty re-read | | `records-forms.validation-rule-type-matrix` (6) | acceptance[0] to [4] | skipped | outside this verification re-run | This is a verification re-run, so it files no run record (RUNNER, Run records). Both servers were stopped by process group, and `examples/app-showcase/.objectstack`, which the boots wrote into the worktree, was deleted. ## Gates Local, derived by `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` from the merge base. All 13 ran at `7b35265616`, and each exit code was captured before any pipe: | command | exit | |---|---| | `node scripts/check-ci-filter-parity.mjs` | 0 | | `node scripts/check-closing-keyword-parity.mjs` | 0 | | `node scripts/check-closing-keyword-parity.mjs --self-test` | 0 | | `node scripts/check-comment-mask-corpus.mjs` | 0 | | `pnpm --filter @objectstack/lint run check:doc-formula-expressions` | 0 | | `pnpm check:cross-package-test-inputs` | 0 | | `pnpm check:doc-authoring` | 0 | | `pnpm check:driver-memory-census` | 0 | | `pnpm check:gitlink-declared` | 0 | | `pnpm check:nul-bytes` | 0 | | `pnpm check:platform-checklist` | 0 | | `pnpm check:refd-timer-probe` | 0 | | `pnpm check:watch-hint-literal` | 0 | - `--ran` reconciliation: `✓ dispatch-gates --ran: 13 derived famil(ies) accounted for — 13 run, 0 NOT-MEASURED`. - `pnpm check:platform-checklist` runs in no per-PR CI. - At BASE `688052e147`: `OK — 16 areas, 328 items (323 active, 1 planned); coverage: 39 kinds mapped, 2 waived; … symbol anchors: 979/989 resolved … 18 file floors held`. - At `7b35265616`: `OK — 16 areas, 329 items (324 active, 1 planned); coverage: 39 kinds mapped, 2 waived; … symbol anchors: 985/995 resolved … 18 file floors held`. - `scripts/checklist-select.mjs`: `since:v18.1` and `file:packages/cli/src/utils/schema-migrate.ts` each resolve the new item. - `git merge-tree --write-tree` against `origin/main` (`2b1382a5b3`) and against PR #25045's head (`4a595ed439`): both exit 0 with a tree id and no conflicts. The one commit that landed on `main` since BASE touches nothing under `docs/qa/platform-checklist/`. - No package is touched, so no package build or test is owed. `skip-changeset` was re-measured: the changed paths sit in the private repo root, outside every package directory. No public package's `files[]` names `docs`, `qa` or a parent path. Positive control: 73 public packages name `dist`. - CI families: the PR's check-runs are cited in the report on #25054. ## Acceptance notes - Observed, not in scope: the stock showcase's `os migrate apply` prints an ERROR-level line, `2 federated (external) object(s) are NOT bound to their remote table, yet stay registered and served: …` (from `packages/objectql/src/plugin.ts`). It comes right after the same boot's `datasource 'showcase_external': connect denied by policy (schemaMode 'external': …)`. A migrate run serves nothing, so the line's consequence does not describe this run. This is passed to the seat through the report on #25054. --- _Generated by [Claude Code](https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent d96f618 commit c67f244

2 files changed

Lines changed: 79 additions & 4 deletions

File tree

‎docs/qa/platform-checklist/areas/cli.json‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,6 +2273,76 @@
22732273
"ref": "#24850"
22742274
}
22752275
]
2276+
},
2277+
{
2278+
"id": "cli.fresh-install-migrate-apply-first",
2279+
"title": "A fresh install whose first command is `os migrate apply` boots on its first `os serve` (18.1.0): the apply creates the tables on an empty database and writes the organization-ownership birth marker (the sys_migration row `adr-0131-organization-ownership`), so the serve reaches its serving line with no ownership refusal",
2280+
"since": "v18.1",
2281+
"status": "active",
2282+
"revision": 1,
2283+
"priority": "P1",
2284+
"surface": "cli",
2285+
"personas": [
2286+
"operator (local shell) whose deploy script runs `os migrate apply` before the first `os serve` of a fresh install"
2287+
],
2288+
"fixtures": {
2289+
"app": "showcase",
2290+
"requires": [
2291+
"an EMPTY database: a file DB path under /tmp/RUN/ that does not exist yet — `test ! -e` on it and on its `-wal` and `-shm` before steps[0]. ⛔ Never a file an earlier command touched: `os dev`, `os serve` and `os migrate plan` each create tables in it, and a database that held a declared table before the apply was not created from empty, so it gets no birth marker by design",
2292+
"one environment for both commands, as a deploy script has: OS_DATABASE_URL=file:/tmp/RUN/fresh.db and OS_HOME=/tmp/RUN/home, plus OS_AUTH_SECRET and OS_SECRET_KEY (32-byte hex), because a production `os serve` composes the auth family only when an auth secret resolves and refuses to boot with no stable encryption key (RUNNER environment facts, the walled-boot entry). `os migrate apply` composes what `serve` mounts (packages/cli/src/utils/schema-migrate.ts header), so it gets the same environment. Add OS_PORT=PORT for the boot (RUNNER environment facts: the showcase's self-pinging connectors read it, `-p` alone does not set it)",
2293+
"a showcase directory no other runner boots: your own worktree, or a scratch copy. Both commands load its objectstack.config.ts and its compiled dist/objectstack.json, and both write .objectstack/data/ (the showcase_external fixture, local uploads) into the directory they run in. Delete that .objectstack after the run"
2294+
],
2295+
"knownGaps": [
2296+
"18.0.0 does not carry the fix. There `os migrate apply` on an empty database creates the tables and writes no birth marker, and the first `os serve` refuses the database as one 17.x or an 18.0 pre-release created: the refusal platform-core.v18-boot-refusals acceptance[1] reads, opening \"This database carries no organization-ownership marker\". A run whose subject is 18.0.0 records that refusal as 18.0.0's known behaviour, never as a FAIL of this item. The fix (#24827) is .changeset/24827-migrate-apply-birth-marker.md, a minor changeset pending on main, so it ships in 18.1.0. Read at base 688052e147: the fix commit 19484af538 is not an ancestor of the @objectstack/cli@18.0.0 tag commit 06cab4849a (exit 1; control leg, a commit 50 behind the tag, exit 0)",
2297+
"the fix's pins score no clause here (RUNNER rule 6, a pin scores only the layer it drives): packages/cli/src/commands/migrate/apply.organization-ownership-birth.integration.test.ts runs `MigrateApply` in-process and judges the guard through `assertOrganizationOwnershipMigrated` on a boot that creates nothing, and packages/cli/src/utils/schema-migrate.birth-after-flush.test.ts holds the failed-write refusal with no kernel at all. Neither spawns the CLI, so neither answers acceptance[0]'s exit code, and neither boots `os serve`, so neither reaches acceptance[1]'s serving line. The item carries no automated ref and both clauses are driven live",
2298+
"a Turso remote (`libsql://`) primary is outside this item: `os migrate apply` creates no tables there (its schema sync is skipped), so the first serving boot creates them and writes the birth marker itself, as it did before the fix"
2299+
]
2300+
},
2301+
"steps": [
2302+
"in the showcase directory, with the environment of fixtures.requires[1] exported and the DB path absent: `os migrate apply --yes; echo $?`. Keep the full output and the exit code",
2303+
"before any boot, read the marker through SQLite (node:sqlite, so a `-wal` is read too; there is no sqlite3 CLI here): `SELECT id, verified_at, applied_at, blocking, advisory, details FROM sys_migration WHERE id = 'adr-0131-organization-ownership'`",
2304+
"the first boot, in the same environment: `os serve -p PORT`, started with `setsid` and its output kept in a file (RUNNER environment facts: stop its process group, never the pnpm pid). Poll GET /api/v1/health until it answers 200 or the process exits, then read the output",
2305+
"read the marker row again with the steps[1] query, then stop the server's process group and confirm the port is free"
2306+
],
2307+
"acceptance": [
2308+
{
2309+
"clause": "`os migrate apply --yes` on an empty database creates the tables, exits 0, and writes the organization-ownership birth marker: exactly one sys_migration row `adr-0131-organization-ownership`, verified, whose details carry the birth at this release's ownership shape generation. The apply wrote it, before any boot",
2310+
"oracle": "build",
2311+
"verify": "steps[0] exits 0 and its output reports the tables it created. steps[1] returns exactly one row with verified_at set, applied_at null, blocking 0, and details.birth.shapeGeneration equal to ORGANIZATION_OWNERSHIP_SHAPE_GENERATION (packages/spec/src/system/migration.zod.ts#ORGANIZATION_OWNERSHIP_SHAPE_GENERATION, 1 at base 688052e147). The apply's output also prints `[organization-ownership] a datastore created from empty: birth marker written (shape generation N, platform V).` (packages/runtime/src/organization-ownership-boot-guard.ts#recordOrganizationOwnershipBirth); that line is supporting evidence only, the row is the oracle. steps[3] reads the same single row unchanged, so the boot found the apply's marker and wrote none of its own",
2312+
"evidence": "the apply's exit code and its created-tables line, and both reads of the marker row"
2313+
},
2314+
{
2315+
"clause": "the first `os serve` over that database boots: it reaches its serving line, with no organization-ownership refusal",
2316+
"oracle": "log",
2317+
"verify": "steps[2]'s output carries `✓ Server is ready` (packages/cli/src/utils/format.ts#printServerReady), not its DEGRADED variant, and GET /api/v1/health answers 200 while the process runs. The output has 0 hits for `carries no organization-ownership marker`, for `refuses to start` and for `os migrate organization-ownership`. A boot that exits 1 with that refusal is a FAIL on 18.1.0 or later, and 18.0.0's known behaviour (fixtures.knownGaps[0])",
2318+
"evidence": "the serving line and the boot's Mode row, the health status, and the three refusal greps with their counts"
2319+
}
2320+
],
2321+
"negative": [
2322+
"on a release that carries the fix, a fresh install whose first `os serve` after `os migrate apply` is refused as an earlier release's database is the defect #24827 fixed: FAIL",
2323+
"the other side of the birth decision, a database the apply did not create from empty, must get NO marker and stay refused until the ceremony runs. It is not this item's fixture: the fix's pin holds it (apply.organization-ownership-birth.integration.test.ts, case b), and the refusal itself is platform-core.v18-boot-refusals"
2324+
],
2325+
"traps": [
2326+
"destructive-in-place",
2327+
"first-boot-cold-start"
2328+
],
2329+
"source": [
2330+
".changeset/24827-migrate-apply-birth-marker.md (minor, pending on main at base 688052e147: ships in 18.1.0)",
2331+
"packages/cli/src/utils/schema-migrate.ts#recordBirthOfFlushedStore",
2332+
"packages/runtime/src/organization-ownership-boot-guard.ts#recordOrganizationOwnershipBirth",
2333+
"packages/runtime/src/organization-ownership-boot-guard.ts#ORGANIZATION_OWNERSHIP_BOOT_REFUSAL_CODE",
2334+
"packages/cli/src/commands/migrate/apply.organization-ownership-birth.integration.test.ts",
2335+
"docs/adr/0131-total-organization-ownership-no-null-organization-id.md",
2336+
"#24827 (the fixed p1), #25054 (the checklist gap: QA run #24838, round 16 of wave anchor #24579)"
2337+
],
2338+
"history": [
2339+
{
2340+
"revision": 1,
2341+
"date": "2026-10-21",
2342+
"change": "initial, for #25054: no checklist clause drove the fresh-install order #24827 fixed (QA run #24838, 18.0 sweep round 4; confirmed in round 16 of wave anchor #24579). A new item, because no existing item's scope covers a fresh install's first `os serve` after `os migrate apply`: platform-core.v18-boot-refusals scopes a 17.x-shaped database (its revision 6 says the order is not added there), cli.organization-ownership-ceremony the upgrade of a database 17.x or an 18.0 pre-release created, cli.migrate-plan-apply-json an apply on a database a prior `os dev` boot already synced (its fixtures.requires[0]), platform-core.boot-health and cli.dev-boot-contract the `os dev` boot, which creates the tables and writes the birth marker itself, and cli.scaffold-first-run the published scaffold booted by `os start --artifact`, with no `os migrate apply` in it. First evidence, driven live at base 688052e147 (the showcase in this PR's worktree, its own file DB, OS_PORT 41873): `os migrate apply --yes` exited 0, printed '✓ Created/extended 107 table(s)' and '[organization-ownership] a datastore created from empty: birth marker written (shape generation 1, platform 18.0.0).'; the marker row read verified_at 2026-10-21T06:54:23.840Z, applied_at null, blocking 0, advisory 0, details birth shapeGeneration 1, platformVersion 18.0.0; the first `os serve -p 41873` printed '✓ Server is ready' with Mode production, /api/v1/health and /api/v1/ready answered 200 (health 10 s after the start), the three refusal greps counted 0, and the row read back unchanged after the boot",
2343+
"ref": "#25075"
2344+
}
2345+
]
22762346
}
22772347
]
22782348
}

‎docs/qa/platform-checklist/areas/records-forms.json‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,7 +1919,7 @@
19191919
"title": "All six validation-rule types enforce on the write path with their exact per-type error codes — and advisory severities flag without blocking",
19201920
"since": "v15",
19211921
"status": "active",
1922-
"revision": 6,
1922+
"revision": 7,
19231923
"priority": "P1",
19241924
"surface": "api",
19251925
"personas": [
@@ -1933,8 +1933,7 @@
19331933
"for the UNEVALUABLE legs (negative[0], negative[1], acceptance[5]): two runtime-authored scratch objects, each carrying one script rule whose condition `int(record.title) > 1` cannot be evaluated over a non-numeric title — no seeded rule is unevaluable, so the stock doors author them. As admin: PUT /api/v1/meta/object/qa_vr_probe {name: qa_vr_probe, label: QA, sharingModel: public_read_write, fields: {title: {type: text}}, validations: [{type: script, name: qa_unevaluable_warn, severity: warning, message: x, condition: \"int(record.title) > 1\"}]} → 200, and the same body as qa_vr_probe_err with the rule named qa_unevaluable_err at severity: error → 200 (the recipe of QA run #24779 / #24782). A write with title \"abc\" then drives each rule"
19341934
],
19351935
"knownGaps": [
1936-
"no showcase rule declares severity:'info' — it shares the identical non-error branch with 'warning' (rule-validator.ts tests `severity === 'error'` and logs everything else), so the warning leg is the driven proof; author a scratch info rule only if a distinct observation is wanted, and record which severities were actually driven",
1937-
"acceptance[5] stays red until #24782 lands: the unevaluable warning rule's write answers 201 and persists (correct), but the server log prints two lines naming the rule that both say \"write rejected\" — the predicate evaluator's fail-closed sentence, emitted before severity is consulted, and the advisory branch's warn, which embeds that violation message (packages/objectql/src/validation/rule-validator.ts). Measured at 580fd4ed (QA run #24779) and again at a43405d596 (#24802). When #24782's fix merges, re-run the clause and drop this line"
1936+
"no showcase rule declares severity:'info' — it shares the identical non-error branch with 'warning' (rule-validator.ts tests `severity === 'error'` and logs everything else), so the warning leg is the driven proof; author a scratch info rule only if a distinct observation is wanted, and record which severities were actually driven"
19381937
]
19391938
},
19401939
"variants": [
@@ -1987,7 +1986,7 @@
19871986
"evidence": "response + re-read + the captured log line"
19881987
},
19891988
{
1990-
"clause": "an UNEVALUABLE severity:'warning' rule lets the write land, and no log line beside it reports a rejection: the write answers 2xx, the row persists, and no server-log line naming the rule says the write was rejected or that the rule failed closed — the log must not state the opposite of what the server did. Red until #24782 lands",
1989+
"clause": "an UNEVALUABLE severity:'warning' rule lets the write land, and no log line beside it reports a rejection: the write answers 2xx, the row persists, and no server-log line naming the rule says the write was rejected or that the rule failed closed — the log must not state the opposite of what the server did.",
19911990
"oracle": "log",
19921991
"verify": "step-7 qa_vr_probe write: status 201 and a re-read finding the row; then every log entry naming qa_unevaluable_warn, read to its end — the predicate evaluator's entry spans lines (it embeds the CEL source with a caret) and its verdict sits after the caret — none may contain \"write rejected\" or \"fails closed\" (the fail-closed sentence belongs to the error-severity path; rule-validator.ts header: an unevaluable warning/info rule is logged, never thrown). Score the absence of the rejection wording, not whichever replacement sentence #24782 picks; a line saying the rule could not be evaluated is expected and passes. Control: the qa_vr_probe_err write answers 400 VALIDATION_FAILED naming qa_unevaluable_err and persists nothing — there the rejection wording is true",
19931992
"evidence": "both responses + both re-reads + every log line naming either rule, quoted"
@@ -2045,6 +2044,12 @@
20452044
"date": "2026-10-20",
20462045
"change": "steps[0] respelled: 'boot showcase isolated' → 'boot the showcase on its own port and DB'. Round 12's out-of-scope finding (landing record 6287983829 on wave anchor #24579): the phrase 'showcase isolated' named the dogfood §0 own-port boot, and a runner read it as the `isolated` tenancy posture (OS_TENANCY_POSTURE=isolated). The new spelling names that boot by what it is, in RUNNER.md's own words for it (the trap table's counter: own port/DB, skill §0), and names no posture. Read at base e4d604efd3. No clause changed",
20472046
"ref": "#25003"
2047+
},
2048+
{
2049+
"revision": 7,
2050+
"date": "2026-10-21",
2051+
"change": "fixtures.knownGaps[1] removed and acceptance[5].clause's closing 'Red until #24782 lands' dropped, as knownGaps[1] said to do once #24782's fix merged: PR #25051 (72518d20f5), named by the domain:engine pointer 6308955528 on seat post #6023. Verification re-run of acceptance[5] at base 688052e147, steps[6] on the canonical own-port boot (`objectstack dev --ui --seed-admin -p 41874 -d file:SCRATCH/data.db`, OS_PORT exported): the qa_vr_probe write {title: \"abc\"} answered 201 and the re-read found its one row; exactly one server-log line names qa_unevaluable_warn, \"Validation rule 'qa_unevaluable_warn' (warning): the rule could not be evaluated (runtime: int() type error: cannot convert to int) — write proceeded: the rule is advisory, so it was not applied to this write\", and it carries neither 'write rejected' nor 'fails closed'. Control: the qa_vr_probe_err write answered 400 VALIDATION_FAILED, fields[0].constraint {rule: qa_unevaluable_err, reason: unevaluable}, its re-read found no row, and its log lines say the write was rejected. No other clause changed",
2052+
"ref": "#25075"
20482053
}
20492054
]
20502055
},

0 commit comments

Comments
 (0)