Uh oh!
There was an error while loading. Please reload this page.
test(service-settings): store decoded values in the getMany ROWS fixture, and pin the literal - #12379
Merged
os-trump merged 2 commits intoAug 25, 2026
Conversation
…ure, and pin the literal `settings-getmany.test.ts`'s `ROWS` fixture stored JSON TEXT in `value` (e.g. '"America/New_York"'), but `sys_setting.value` is a `Field.json` column and the service is verbatim in both directions: `setMany` writes `storedValue = rawValue`, and `materialiseRow`'s non-encrypted branch is `return row.value ?? null`. The DRIVER owns the JSON codec, and the fake engine here skips it -- so every fixture value resolved one JSON encoding deep. It was invisible because it lied CONSISTENTLY: every assertion in the file compares `getMany` against per-key `get`, and both sides are equally affected. Measured -- with the fixture untouched, the new literal-value pin fails `expected '"America/New_York"' to be 'America/New_York'` while the other 7 tests stay green. Re-encodes the fixture to the decoded values a real driver hands back (matching the sibling fixture in `settings-loadrows-scope.test.ts`, which already stores them plain), and lands the literal-value pin that holds the encoding depth mechanically. No existing assertion changed.
…x obsoleted The comment on the non-equivalence assertions recorded the WORKAROUND: it said the assertion sits on the cascade layer because "this fixture stores JSON text in `value`". The fixture no longer does, so the note asserted a property of the file that had just stopped being true -- the exact mislead this card exists to remove. Rewrites the reason only. The assertions on those lines are byte-identical (`git diff -U0 | grep '^[+-].*expect'` is empty across this commit).
Contributor
📓 Docs Drift CheckNothing 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): |
This was referenced Aug 25, 2026
Uh oh!
There was an error while loading. Please reload this page.
os-trump
deleted the
claude/issue-12172-settings-getmany-fixture-encoding
branch
August 25, 2026 22:13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#12172
packages/services/service-settings/src/settings-getmany.test.ts'sROWSfixture stored JSON text invalue('"America/New_York"'), so every fixture value resolved one JSON encoding deep.Premise, verified on the merged ref (
e5ce2ed03) before building on itsys_setting.valueis aField.jsoncolumnpackages/platform-objects/src/system/sys-setting.object.ts:156value: Field.json({ … 'JSON-encoded value.' })setManywrites verbatimsettings-service.ts:1667storedValue = rawValue(noJSON.stringify)materialiseRowreads verbatimsettings-service.ts:2553return row.value ?? nulldriver-sql/src/sql-driver.ts:14872-14891(write),:14929-14938(read)The codec is dialect-asymmetric but round-trips to the raw value on both: SQLite stores primitives as-is and re-parses on read (
JSON.parse('America/New_York')throws, so the string is kept); PostgresJSON.stringifys into the nativejsonbcolumn and the client parses it back. Either way a row a real driver hands back carriesAmerica/New_York— never"America/New_York". The fake engine here skips the codec entirely, so the fixture had to hold the decoded value already, and did not.Route taken: 1 — re-encode the fixture (the fake is file-local)
The card left the route open and asked for the measurement. Measured:
makeEnginein this file is file-local. The file has zeroexportstatements and no file imports from it — the only repo-wide reference is a comment insettings-loadrows-scope.test.tsnoting it hand-copied the same matcher.settings-loadrows-scope.test.ts:70,76usevalue: 'America/New_York'/'Asia/Tokyo'under the comment "Values are stored plain, as the persist path writes them."settings-getmany.test.tswas the only file spellingvalue: '"…"'in a settings fixture (3 hits, all inROWS).So Route 2 would teach a codec to a double that nobody else constructs, and would make it diverge from its own sibling copy in the same package. It is also the wrong shape on the merits: there is no single codec to teach, because the driver's behaviour is dialect-split while the observable contract at the engine boundary is "what you wrote is what you read" — which is exactly what the fake already does correctly. The defect was only ever in the fixture's input values, so that is what changed.
The acceptance criterion: a pin that asserts a literal resolved value
Landed as
[#12172] resolves the LITERAL stored value — no doubled JSON encoding, assertingmany.timezone.value === 'America/New_York'(pluslocale/currency, plus the per-keygetpath so the pin holds the encoding and not agetManyquirk).getManyagainstget, so both sides moved together and were insensitive to the defect by construction. Measured across all three states — the 7 original tests were green in every one:Dissolution verification of the new pin
Mutation re-applied the JSON-text encoding, confirmed on disk before running (3 injected
value: '"spellings, 0 remaining decoded spellings) and run under atrap … EXIT INT TERMrestore:No rebuild is involved and none is owed: the mutated symbol is the test file's own
ROWSconstant, which vitest compiles from source on every run — nodist/sits between the mutation and the assertion.Restored with
git checkout HEAD -- packages/services/service-settings/src/settings-getmany.test.ts, verified byte-identical, not merely "clean":Second-order result: none
No existing assertion changed and none broke. Nothing in this PR was adjusted to match the re-encoded fixture —
git diff -U0 | grep '^[+-].*expect'shows no removed assertion line across either commit.The second commit rewrites one comment, which the fix had made factually false: it stated the assertion sits on the cascade layer because "this fixture stores JSON text in
value" — the recorded #11680 workaround. Leaving a note asserting the defect as a standing property of the file is the precise mislead this card exists to remove. The reason changed; the assertions on those lines are byte-identical.Verification — all at the shipped head
a8c030c22Exit codes captured before any pipe (redirect-then-read), and each gate quoted from its own verdict line:
@objectstack/service-settingssuite — 29 files / 519 tests passed@objectstack/service-settingstypecheck (tsc --noEmit) — cleannode scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(self-derived change set, 1 path, merge basee5ce2ed03) — all green:check:cross-package-test-inputs,check:page-declaration-shape,check:published-files,check:slot-lookup,check:test-source-alias,check:type-source-resolution,check-ci-filter-parity,check-cross-package-test-inputs,check-plugin-teardown-shape,check-affected-docs,check-drift-comment, plus the convention-triggeredcheck:query-options-erasure,check:type-check-coverage,check:engine-double-contract,check:where-matcher, andcheck:nul-bytes.Ratchet families re-run on the shipped head, quoted:
Two declared narrowings
check:type-check-debt(--re-measure) not run locally. Its population is the DEBT ledger insidescripts/check-type-check-coverage.mjs;@objectstack/service-settingsis absent from it (the sole textual match is a prose comment at line 508). Its structural halfcheck:type-check-coverageran green here, the package's owntsc --noEmitis clean, and this diff adds no file and no package — so no ledger entry's count can move. The--re-measurehalf needs a full built workspace closure, which CI performs on every PR.pnpm lintnarrowed to the affected package, with the narrowing measured rather than assumed: ① the population came from eslint's own config resolution overpackages/services/service-settings/src, not from a guess about which files count; ② the count came from--format json— 60 files, 0 errors, 0 warnings, with the changed file confirmed present in the linted set; ③ type-aware linting is not enabled ineslint.config.*(noprojectService/project:), so no rule reads across file boundaries and a one-file diff cannot move the verdict of any untouched file.Changeset
None — this is a test fixture and a test comment; nothing ships. Carries
skip-changesetrather than an empty changeset, which stalls the release here.Generated by Claude Code