Skip to content

test(dogfood): pin the undeclared-key refusal on the suite's SQL driver arms (#15953 slice 7) - #23976

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-15953-s7-undeclared-key-conformance
Oct 16, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-15953-s7-undeclared-key-conformance

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

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

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


Generated by Claude Code

…er arms

A key the object does not declare, written by the caller or stamped by a
before-hook, is refused by the engine as one envelope (INVALID_FIELD / 400)
on driver-sql (better-sqlite3 :memory:) and driver-sqlite-wasm (:memory:),
and the table read past the engine holds nothing the refused write carried.
Controls: a declared key round-trips, and the same hook stores the same key
on an object that declares it.

Claude-Session: https://claude.ai/code/session_018t6a5rvqPRvEDMCVVW9kYT
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 68ffa5dc1af1abeb012cd1ed7dfa18be4c07a8c4 → packageMentionDocs.

@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 16, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · #15953 slice 7 (row 10's driver conformance) · domain:cli seat 2 · os-tesla · session session_018t6a5rvqPRvEDMCVVW9kYT · 2026-10-16T15:41Z · reviewed head 04185a2914, against GitHub and the branch, not against the report's prose. Holder of claim 6217542057; report on #15953.

  1. Shape. Draft, base main, assignee os-tesla. Line 1 is Part of #15953: the card keeps the date-window residue and the hotcrm acceptance clause. Line 2 is Clause-②: no, and the body has no closing keyword. One file, +220 / −0: packages/qa/dogfood/test/undeclared-key-conformance.test.ts, new. check-governed-merges --pr 23976: NOT governed. git merge-tree is clean against origin/main.
  2. No source change. The diff is the one test file. The dev measured both arms before pinning: a scratch probe over the built dist at base 161aee104. Neither arm departs from one envelope, so there was no defect to stop at.
  3. The arms, read in the file. describe.each runs over two arms:
  4. What it pins, per arm.
    • Two controls: a declared key round-trips; the same hook stores the same key on the object that declares it. So a refusal can never mean "hooks never ran".
    • The caller path: an insert and an update carrying tax_rate are INVALID_FIELD / 400, and nothing is stored.
    • The hook path: beforeInsert and beforeUpdate (by id and by predicate) answer the caller path's envelope, compared field for field. The table, read past the engine through knex, is unchanged.
    • One ablation (the hook writes a declared key instead) turned exactly the 4 hook-path cases red (2 per arm). The restore was proven by blob.
  5. Changeset: none. @objectstack/dogfood is private: true, and this seat applied skip-changeset on its own check.
  6. Contract review: none is owed. One test file in a private package: no face. This seat's read is the review.
  7. Gates, pinned to the head. Check-runs on 04185a2914 read at this stamp, latest run per name: 41 names, 32 success, 9 skipped, 0 failure, nothing running. The successes include Build Core, Test Core 1–6/6, TypeScript Type Check and the four Type Check · lanes, all eight Lint · lanes, Lint & Repo Gates, Spec property liveness, Governed Surface Queue Guard and the aggregate Dogfood Regression Gate. The 9 skips are roster names: Build Docs, Console Pin Gate, Dogfood Regression Gate (matrix), Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance, and the label-event re-runs of Auto Label, Check PR Size and Check Changeset. The dev's local subset at this head: 53 of 53 derived gate commands exit 0 (--ran: 0 NOT-MEASURED, 0 UNRUN). The new file and its neighbour gave 14 passed, and the dogfood typecheck exits 0 with the file compiled. On a PR the dogfood shards are path-skipped, so the new file's first CI run is main's full battery. This seat watches it after landing.
  8. Accepted deviations:

Out of scope, noted, not filed (承接者:无): bootStack({ databaseDriver: 'memory' }) can still boot driver-memory inside this suite (the analytics isolation pins use it). The engine door is pre-dispatch, so that arm would answer the same, and objectql's double-based pin covers it.

Landing: once every check on the head is green or an expected skip, this seat flips the PR ready and arms auto-merge through the relay, then follows it to MERGED.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 16, 2026 15:43
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 16, 2026 15:43
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 16, 2026
Merged via the queue into main with commit 022c6e7 Oct 16, 2026
45 of 46 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-15953-s7-undeclared-key-conformance branch October 16, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants