|
6 | 6 | */ |
7 | 7 |
|
8 | 8 | /** |
9 | | - * qs-01 (DATA-1) — anchored-vs-packed GATE tests in DataManager._retrieveBucketing. |
| 9 | + * qs-01 — anchored-vs-packed GATE tests in DataManager._retrieveBucketing. |
10 | 10 | * |
11 | 11 | * Spec of record: _bmad-output/planning-artifacts/2026-07-02-convert-js-sdk/qs-01-anchored-bucketing-layout.md |
12 | 12 | * "The contract (normative)" section (the Gate paragraph + the allocation-build mapping), |
13 | 13 | * AC1, AC4, AC8, AC9. |
14 | 14 | * |
15 | | - * The gate ("run anchored iff Number(experience.version) > 8") does not exist yet in |
16 | | - * DataManager._retrieveBucketing's fresh-bucketing branch (packages/data/src/data-manager.ts:620-637) |
17 | | - * -- every experience, regardless of `version`, currently goes through the existing packed |
18 | | - * cumulative walk. The AC1 and AC4 assertions below therefore FAIL today (RED) because the |
19 | | - * disagreement they assert between "what a version-9 experience should do" (anchored) and |
20 | | - * "what it actually does" (still packed, pre-implementation) is real. AC8/AC9 protect |
21 | | - * EXISTING behavior that runs entirely before/independently of the gate (the stored-decision |
22 | | - * guard short-circuits before the version check is ever reached; the returned object's shape |
23 | | - * doesn't change with the algorithm) -- those are expected to already PASS, and are included |
24 | | - * as regression locks for after the gate lands. See this feature's decision log for why each |
25 | | - * fixture is (or isn't) expected to fail pre-implementation. |
| 15 | + * These tests lock the shipped gate in DataManager._retrieveBucketing's fresh-bucketing |
| 16 | + * branch (packages/data/src/data-manager.ts:685): `Number(experience.version) > 8` routes |
| 17 | + * fresh bucketing through the anchored layout (built by `_buildVariationAllocations`, |
| 18 | + * data-manager.ts:586, and resolved via `BucketingManager.getBucketForVisitorAnchored`); |
| 19 | + * version <= 8, missing/undefined, or non-numeric version keeps the existing packed |
| 20 | + * cumulative walk unchanged (built by `_buildPackedBuckets`, data-manager.ts:556, and |
| 21 | + * resolved via `BucketingManager.getBucketForVisitor`). AC1 asserts the gate actually |
| 22 | + * branches by exploiting a real packed-vs-anchored disagreement on the same fixture (see |
| 23 | + * below). AC4 asserts stops only zero their own width under the anchored path and never |
| 24 | + * move neighboring arms' anchors. AC8/AC9 protect existing behavior that runs entirely |
| 25 | + * before/independently of the gate: the stored-decision guard (data-manager.ts:658-665) |
| 26 | + * short-circuits before the version check is ever reached, and the returned |
| 27 | + * BucketedVariation shape is unchanged across versions. |
26 | 28 | * |
27 | 29 | * Fixture derivation methodology: every raw bucket VALUE used below (e.g. 4957, 9807, 102) |
28 | 30 | * is a real MurmurHash3 output from BucketingManager.getValueVisitorBased -- the same, |
29 | 31 | * already-implemented, already-unit-tested hash oracle the packed and anchored paths both |
30 | | - * call unmodified (packages/bucketing/src/bucketing-manager.ts:95-108; see |
| 32 | + * call unmodified (packages/bucketing/src/bucketing-manager.ts:91-112; see |
31 | 33 | * packages/bucketing/tests/bucketing-manager.tests.ts for its own tests). Values were |
32 | 34 | * derived once (for the fixed (visitorId, experienceId) string pairs used below, with the |
33 | 35 | * default hash seed) via that exact method, then frozen as literal numbers so every |
34 | 36 | * packed/anchored expectation in this file is independently re-derivable by hand from the |
35 | 37 | * spec's normative formulas (anchor = (cumWeight / totalWeight) * 10000; width = active ? |
36 | 38 | * allocation * 100 : 0) against the fixed traffic_allocation values declared alongside them, |
37 | | - * without needing to re-run any tool. This is the same class of technique BUCK-2 used to |
38 | | - * freeze its THIRDS_15/THIRDS_25 expected ranges from the spec's own pseudocode, applied one |
39 | | - * level up (the raw hash value is looked up from the hash oracle instead of hand-computed, |
40 | | - * since MurmurHash3 output cannot reasonably be hand-derived; everything downstream of that |
41 | | - * single looked-up number -- which bucket it falls into under each layout -- is plain |
42 | | - * arithmetic against the fixed weights, independently checkable inline in each fixture's |
43 | | - * comment). |
| 39 | + * without needing to re-run any tool. This is the same class of technique used in |
| 40 | + * bucketing-manager-anchored.tests.ts to freeze its THIRDS_15/THIRDS_25 expected ranges |
| 41 | + * from the spec's own pseudocode, applied one level up (the raw hash value is looked up |
| 42 | + * from the hash oracle instead of hand-computed, since MurmurHash3 output cannot reasonably |
| 43 | + * be hand-derived; everything downstream of that single looked-up number -- which bucket it |
| 44 | + * falls into under each layout -- is plain arithmetic against the fixed weights, |
| 45 | + * independently checkable inline in each fixture's comment). |
44 | 46 | */ |
45 | 47 | import 'mocha'; |
46 | 48 | import {expect} from 'chai'; |
|
0 commit comments