Repository navigation
Commit 022c6e7
Part of #15953
Clause-②: no
## What this is
Slice 7 of the card: row 10 of the classification table (comment
`6115219467`), the per-driver half, as the slice-7 claim (`6217542057`)
scopes it. It is one new test file,
`packages/qa/dogfood/test/undeclared-key-conformance.test.ts`, beside
`read-coercion-conformance.test.ts` and in its style.
On every SQL driver arm the dogfood conformance files run, it pins that
a key the object does not declare is refused by the ENGINE as one
envelope, whether the caller wrote it or a before-hook stamped it. The
table, read straight past the engine through knex, holds nothing the
refused write carried. This is the platform's own pin for what hotcrm's
`test/undeclared-key-probe.test.ts` asserted, so
objectstack-ai/hotcrm#1583 can retire that file.
- No source change anywhere.
- `@objectstack/dogfood` is `private: true`, so there is no changeset.
The seat applies `skip-changeset`.
- The card stays open for the date-window family's residue and the
acceptance clause "runs from `os verify` on hotcrm's metadata".
## The arms
- **`driver-sql` on better-sqlite3 `:memory:`.** This arm is the table's
"memory", read as the claim rules: the driver-memory arm left the
conformance files in #5704, and this is the arm
`read-coercion-conformance.test.ts` runs. It is also the table's
"sqlite".
- **`driver-sqlite-wasm` `:memory:`.** Covered by measurement. The suite
already runs this arm (`date-bucket-parity-conformance.test.ts`,
`group-key-read-shape-parity.test.ts`), and here it boots under
`ObjectQL` and syncs its schema.
## What each arm answers today, measured before anything was pinned
The setup is `ObjectQL` over each real driver with a system context.
`probe_quote` declares `tax_rate` and `probe_quote_line` does not
(hotcrm's declared/undeclared pair). The reading was taken on the built
engine and drivers at base `161aee104`, and the pinned file re-ran green
at the final head.
| write carrying `tax_rate` onto `probe_quote_line` | driver-sql |
sqlite-wasm |
|:--|:--|:--|
| caller insert, caller update | refused: `Error`, `code`
`INVALID_FIELD`, `status` 400, `field` `tax_rate`, `object`
`probe_quote_line` | the same |
| `beforeInsert` hook stamps it | the same envelope | the same |
| `beforeUpdate` hook, by id | the same envelope | the same |
| `beforeUpdate` hook, by predicate (`multi: true`) | the same envelope
| the same |
| the table after each refusal | unchanged | unchanged |
| the same hook on `probe_quote`, which declares the key | stored `7` |
stored `7` |
No arm departs from one envelope, so there was no defect to stop at. The
objectql pins (`engine-post-hook-undeclared-field.test.ts`,
`engine-undeclared-key-caller-path.test.ts`) prove the door against
driver doubles only, and say so. This file is the half on the shipped
drivers.
## The cases (six per arm, twelve in all)
1. **Control:** a declared key round-trips through insert, update,
`findOne` and the knex read.
2. **Control:** the same hook stores the same key on the object that
declares it. So a refusal can never mean "hooks never ran on this arm".
3. **Caller insert:** `INVALID_FIELD` / 400, naming the field and the
object. The table is empty.
4. **Caller update:** the same envelope, and the row is unchanged.
5. **Hook insert:** `code` and `status` as above, and the same envelope,
field for field, as the caller path's answer on that arm. The table is
empty.
6. **Hook update, by id and by predicate:** the same, and both rows are
unchanged.
The envelope is projected from the engine's own error (`code`, `status`,
`field`, `object`) and never rebuilt in the test. The hook path is
compared with the caller path's measured answer. No message text is
pinned.
## Ablation (one, on the fixture)
- **Mutation:** the probe hook on `probe_quote_line` writes a DECLARED
key instead. `const LINE_HOOK_WRITES = { [KEY]: 7 };` becomes `{
unit_price: 7 }`, through `scripts/ablation-replace.mjs`: anchor x1 to
x0, replacement x0 to x1, blob `878a1b97a7cc` to `8c606255f1ce`. A trap
in the ablation script restores on exit.
- **Reading:** predicted `4 failed | 8 passed`, read `4 failed | 8
passed`. Both hook-path cases failed on both arms, each with "expected
the engine to refuse, and it answered". The controls and the caller path
stayed green.
- **Restore:** the blob is back to `878a1b97a7cc`, equal to HEAD's; `git
diff HEAD` and `git status --porcelain` are both empty.
- **No build leg:** the mutated file is the test itself, which vitest
loads from source, so there was no build or dist leg to run.
## Tests and gates, at `04185a291`
- `pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2
--reporter=verbose test/undeclared-key-conformance.test.ts
test/read-coercion-conformance.test.ts`: 2 files, 14 passed.
- `pnpm --filter @objectstack/dogfood typecheck`: exit 0, after a build
of the whole `@objectstack/dogfood^...` closure. `tsc --listFiles`
includes the new file.
- `pnpm exec eslint --no-inline-config
packages/qa/dogfood/test/undeclared-key-conformance.test.ts`: exit 0
with 0 messages, and the file was linted, not ignored. The repo-wide
lint is CI's `Lint & Repo Gates`.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` (no paths): 53 derived, 53 run, all exit 0.
`--ran` reconciles 53 / 53 / 0 NOT-MEASURED / 0 UNRUN.
- `check:dual-build-cjs-loads` first exited 3 (PREREQUISITE NOT MET: 8
packages outside the dogfood closure had no `dist/`). It exited 0 after
those were built.
- **Declared to CI, not run locally:** the rest of the dogfood suite
(the Dogfood Regression Gate, three shards) and `test:repo` (Test Core).
## Acceptance notes
- **Wall time.** The twelve cases take about 200 ms. The file's local
wall (15 s on a shared box) is module import of the built objectql and
drivers. Dogfood is excluded from Test Core, whose per-file captures
feed the 10 s line, so this file is outside that reading.
- **A driver-memory arm was not added.** `bootStack({ databaseDriver:
'memory' })` can still boot driver-memory in this suite; the analytics
isolation pins use it as a two-driver equivalence arm. This slice
follows the claim's reading of "memory". Noted, not filed; carrier:
none.
- **`origin/main` moved after the merge.** This branch merged
`6d1660dc3`, and `origin/main` then moved to `68ffa5dc1`. That is one
commit (PR #23959), touching other dogfood files
(`authz-conformance.test.ts` and its census) and `packages/rest`.
Neither reads this file or anything it imports, so the branch was not
re-merged.
- **Left alone, as the claim says:**
- the objectql write-path half of row 10 (it landed with #23603);
- the date-window family's residue;
- `packages/verify`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_018t6a5rvqPRvEDMCVVW9kYT)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2e0e451 commit 022c6e7
1 file changed
Lines changed: 220 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
0 commit comments