Skip to content

Commit ab8b10f

Browse files
hotlongclaude
andauthored
test(driver-sql): attribute each legacyUniqueReplacements guard to exactly one case (#8557) (#8768)
* test(driver-sql): attribute each legacyUniqueReplacements guard to one case (#8557) * test(driver-sql): note the cross-arm effect on the #3955 field-arm case, add changeset (#8557) --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent a675b4d commit ab8b10f

2 files changed

Lines changed: 495 additions & 0 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
"@objectstack/driver-sql": patch
3+
---
4+
5+
test(driver-sql): attribute each `legacyUniqueReplacements` guard to exactly one case (#8557)
6+
7+
**`patch`, and deliberately not `none`.** This adds no runtime code and changes
8+
no behaviour — every assertion is green on `main` before the change. The bump is
9+
the floor rather than a skipped changeset because the file it protects is
10+
release-relevant: what lands is the pin that makes a future single-guard
11+
deletion visible, and the release notes for the version that first carries it
12+
are the place a maintainer looks to learn the pin exists. A `minor` would claim
13+
a capability; `none` would leave the protection undocumented at the only moment
14+
anyone reads for it.
15+
16+
The declared-index replacement arm's guards were **individually unpinned**:
17+
measured on #8468, deleting the ADR-0120 S6 name-identity guard, or admitting a
18+
declared bare `unique: true` through the scope filter, left the entire suite
19+
green — including the two tests whose names say they cover exactly those cases.
20+
The protection was real but collective, so no test attributed it to a line, and
21+
a refactor could remove any single guard and be told nothing.
22+
23+
`schema-drift.legacy-unique-guard-attribution.test.ts` adds that attribution.
24+
The existing object-level suites are untouched — they are broader than any one
25+
guard, which is why they could not do this job.
26+
27+
- **Nine guards are individually attributable.** One input per guard,
28+
constructed so only that guard can reject it, each paired with a **twin**
29+
the same input with the single property that guard reads changed, which must
30+
produce exactly one replacement. The twin is the reachability witness: without
31+
it a case would still pass while some earlier guard swallowed the input, which
32+
is the failure mode being fixed, one level up. Measured: deleting any one of
33+
the nine turns **exactly one** test red, and its name says which line went.
34+
- **Five guards cannot be attributed at all**, because another guard rejects a
35+
superset of their inputs — deleting one is behaviour-preserving for every
36+
possible argument, so a test claiming to pin it would be lying. For those,
37+
what is pinned is the **fact the domination rests on**, so the day it breaks
38+
and the guard becomes load-bearing alone, something goes red.
39+
40+
Behind the dominated S6 guard are the hand-written organization composites on
41+
`sys_team`, `sys_business_unit` and `sys_member` — three shipped platform
42+
objects on a spelling valid indefinitely. Those composites are now pinned
43+
directly, in both the shipped bare-`true` spelling and the respelled
44+
`'organization'` form.
45+
46+
The bare-spelling case is the test-side half of a pair whose first half already
47+
shipped: #8463 (PR #8512) put the same divergence into prose on
48+
`isOrganizationScopedUnique`'s JSDoc, in this same file, with no test attributing
49+
it. Routing the declared branch through the field predicate remains the rejected
50+
option 1 of #8323 (maintainer ruling 2026-08-13), and is now refused by a test
51+
rather than only by a comment.

0 commit comments

Comments
 (0)