Skip to content

Commit c5756bc

Browse files
author
DavidQ
committed
BUILD PR: extract duplicated promotion-state getState snapshot into shared helper only.
1 parent f0de25a commit c5756bc

10 files changed

Lines changed: 173 additions & 24 deletions

docs/dev/CODEX_COMMANDS.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
MODEL: GPT-5.3-codex
22
REASONING: high
33
COMMAND:
4-
Execute docs/pr/BUILD_PR_SHARED_EXTRACTION_04_AS_FINITE_NUMBER_ONLY.md exactly.
4+
Execute docs/pr/BUILD_PR_SHARED_EXTRACTION_05_GETSTATE_PROMOTION_STATE_ONLY.md exactly.
55
Edit only these files:
6-
- src/shared/utils/numberUtils.js
6+
- src/shared/state/createPromotionStateSnapshot.js
77
- src/advanced/promotion/createPromotionGate.js
88
- src/advanced/state/createWorldGameStateSystem.js
9-
- games/network_sample_c/game/ReconciliationLayerAdapter.js
109
Do not expand scope.
11-
Package the delta output to <project folder>/tmp/BUILD_PR_SHARED_EXTRACTION_04_AS_FINITE_NUMBER_ONLY_delta.zip
10+
Package the delta output to <project folder>/tmp/BUILD_PR_SHARED_EXTRACTION_05_GETSTATE_PROMOTION_STATE_ONLY_delta.zip

docs/dev/COMMIT_COMMENT.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
BUILD PR: exact asFiniteNumber extraction to shared number utils only.
1+
BUILD PR: extract duplicated promotion-state getState snapshot into shared helper only.

docs/dev/NEXT_COMMAND.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Next: if clean, produce APPLY_PR_SHARED_EXTRACTION_04_AS_FINITE_NUMBER_ONLY. If blocked, narrow further without changing PR purpose.
1+
Next: if clean, commit result and continue to the next executable BUILD. If blocked, capture the exact blocker and narrow further without changing PR purpose.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Built an execution-grade BUILD bundle for the remaining helper work by narrowing to one executable helper only: asFiniteNumber.
2-
Excluded getState because the uploaded repo snapshot did not support an exact helper-only extraction map without guessing.
1+
Built an execution-grade BUILD for the remaining getState-related work by narrowing to the only exact duplicated getState snapshot pattern identifiable without guessing.
2+
This BUILD centralizes the duplicated promotion-state snapshot logic only.

docs/dev/reports/file_tree.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
docs/
22
pr/
3-
BUILD_PR_SHARED_EXTRACTION_04_AS_FINITE_NUMBER_ONLY.md
3+
BUILD_PR_SHARED_EXTRACTION_05_GETSTATE_PROMOTION_STATE_ONLY.md
44
dev/
55
codex_commands.md
66
commit_comment.txt

docs/dev/reports/validation_checklist.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ SESSION VALIDATION GATE
22
- Bundle type: BUILD
33
- One PR purpose only: yes
44
- Exact target files listed: yes
5-
- Exact destination file listed: yes
5+
- Exact new file listed: yes
66
- Exact source edits listed: yes
7-
- Repo-wide scan avoided: yes
8-
- Start-of-day directories touched: no
7+
- Vague repo-wide scan/refactor language avoided: yes
8+
- Scope minimized: yes
9+
- Start-of-day directories untouched: yes
910
- Fake code claims avoided: yes
1011
- ZIP repo-structured and execution-ready: yes
1112

1213
BUILD-SPECIFIC CHECKS
1314
- Codex can execute without guessing: yes
14-
- Scope minimized to one helper: yes
15-
- Non-goals explicit: yes
15+
- Broad getState normalization intentionally excluded: yes
16+
- Validation steps explicit: yes
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# BUILD_PR_SHARED_EXTRACTION_05_GETSTATE_PROMOTION_STATE_ONLY
2+
3+
## Purpose
4+
Extract the duplicated promotion-state `getState` snapshot construction into one shared helper, without touching broader `getState` usages.
5+
6+
## Single PR Purpose
7+
Centralize the duplicated promotion-state snapshot logic currently embedded inside:
8+
- `src/advanced/promotion/createPromotionGate.js`
9+
- `src/advanced/state/createWorldGameStateSystem.js`
10+
11+
This BUILD does **not** attempt repo-wide `getState` normalization.
12+
13+
## Exact Files Allowed
14+
Edit only these 3 files:
15+
16+
1. `src/shared/state/createPromotionStateSnapshot.js` **(new file)**
17+
2. `src/advanced/promotion/createPromotionGate.js`
18+
3. `src/advanced/state/createWorldGameStateSystem.js`
19+
20+
Do not edit any other file.
21+
22+
## Exact New File
23+
Create:
24+
25+
`src/shared/state/createPromotionStateSnapshot.js`
26+
27+
### Required export
28+
Export exactly one named function:
29+
30+
```js
31+
export function createPromotionStateSnapshot({
32+
promoted,
33+
stableFrames,
34+
stabilityWindowFrames,
35+
lastReason,
36+
lastEvaluation,
37+
cloneLastEvaluation
38+
}) {
39+
return {
40+
promoted,
41+
stableFrames,
42+
stabilityWindowFrames,
43+
lastReason,
44+
lastEvaluation: typeof cloneLastEvaluation === 'function'
45+
? cloneLastEvaluation(lastEvaluation)
46+
: lastEvaluation ?? null
47+
};
48+
}
49+
```
50+
51+
## Exact Source Changes
52+
53+
### 1) `src/advanced/promotion/createPromotionGate.js`
54+
Add import:
55+
56+
```js
57+
import { createPromotionStateSnapshot } from '../shared/state/createPromotionStateSnapshot.js';
58+
```
59+
60+
Replace the current local `getState()` body so it returns:
61+
62+
```js
63+
return createPromotionStateSnapshot({
64+
promoted,
65+
stableFrames,
66+
stabilityWindowFrames,
67+
lastReason,
68+
lastEvaluation,
69+
cloneLastEvaluation: (value) => (value ? { ...value } : null)
70+
});
71+
```
72+
73+
Do not change the function name `getState`.
74+
Do not change `getMetrics`.
75+
Do not change evaluation logic.
76+
77+
### 2) `src/advanced/state/createWorldGameStateSystem.js`
78+
Add import:
79+
80+
```js
81+
import { createPromotionStateSnapshot } from '../../shared/state/createPromotionStateSnapshot.js';
82+
```
83+
84+
Replace the current local `getState()` body so it returns:
85+
86+
```js
87+
return createPromotionStateSnapshot({
88+
promoted,
89+
stableFrames,
90+
stabilityWindowFrames: windowFrames,
91+
lastReason,
92+
lastEvaluation,
93+
cloneLastEvaluation: (value) => (value ? cloneDeep(value) : null)
94+
});
95+
```
96+
97+
Do not change the function name `getState`.
98+
Do not change `getMetrics`.
99+
Do not change transition/evaluation logic.
100+
101+
## Hard Constraints
102+
- no repo scan
103+
- no broader `getState` cleanup
104+
- no engine API changes
105+
- no renaming of existing `getState` functions
106+
- no helper extraction beyond this promotion-state snapshot helper
107+
- no additional files
108+
- no import normalization outside the 2 exact source files above
109+
- preserve existing behavior:
110+
- `createPromotionGate.js` keeps shallow-copy behavior for `lastEvaluation`
111+
- `createWorldGameStateSystem.js` keeps `cloneDeep` behavior for `lastEvaluation`
112+
- `createWorldGameStateSystem.js` keeps `stabilityWindowFrames: windowFrames`
113+
114+
## Validation Checklist
115+
1. Confirm only the 3 listed files changed
116+
2. Confirm `src/shared/state/createPromotionStateSnapshot.js` exists and exports only `createPromotionStateSnapshot`
117+
3. Confirm `getState()` still exists in:
118+
- `src/advanced/promotion/createPromotionGate.js`
119+
- `src/advanced/state/createWorldGameStateSystem.js`
120+
4. Confirm both `getState()` functions now delegate to `createPromotionStateSnapshot(...)`
121+
5. Confirm behavior is preserved:
122+
- promotion gate uses shallow copy for `lastEvaluation`
123+
- world game state system uses `cloneDeep` for `lastEvaluation`
124+
- world game state system still uses `windowFrames` as `stabilityWindowFrames`
125+
6. Confirm no other `getState` call sites or implementations were touched
126+
127+
## Non-Goals
128+
- no repo-wide `getState` standardization
129+
- no work in `samples/shared/worldGameStateSystem.js`
130+
- no work in consumers, integration files, or engine state APIs
131+
- no alias-path migration
132+
- no refactor beyond this exact extraction

src/advanced/promotion/createPromotionGate.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ createPromotionGate.js
77

88
import { asFiniteNumber } from '../../shared/utils/numberUtils.js';
99
import { isPlainObject } from '../../shared/utils/objectUtils.js';
10+
import { createPromotionStateSnapshot } from '../../shared/state/createPromotionStateSnapshot.js';
1011

1112
function asPositiveInteger(value, fallback = 1) {
1213
const numeric = Math.floor(asFiniteNumber(value, fallback));
@@ -75,13 +76,14 @@ function createPromotionGate(options = {}) {
7576
}
7677

7778
function getState() {
78-
return {
79+
return createPromotionStateSnapshot({
7980
promoted,
8081
stableFrames,
8182
stabilityWindowFrames,
8283
lastReason,
83-
lastEvaluation: lastEvaluation ? { ...lastEvaluation } : null
84-
};
84+
lastEvaluation,
85+
cloneLastEvaluation: (value) => (value ? { ...value } : null)
86+
});
8587
}
8688

8789
function evaluate({

src/advanced/state/createWorldGameStateSystem.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
createTransitionAppliedEvent,
1919
createTransitionRejectedEvent
2020
} from './events.js';
21-
import { getState as getSharedState } from '../../shared/state/getState.js';
21+
import { createPromotionStateSnapshot } from '../../shared/state/createPromotionStateSnapshot.js';
2222
import { asFiniteNumber } from '../../shared/utils/numberUtils.js';
2323
import {
2424
cloneDeep,
@@ -226,17 +226,14 @@ function createInlinePromotionGate({
226226
evaluate,
227227
getMetrics,
228228
getState() {
229-
const state = getSharedState({
229+
return createPromotionStateSnapshot({
230230
promoted,
231231
stableFrames,
232232
stabilityWindowFrames: windowFrames,
233233
lastReason,
234-
lastEvaluation
234+
lastEvaluation,
235+
cloneLastEvaluation: (value) => (value ? cloneDeep(value) : null)
235236
});
236-
return {
237-
...state,
238-
lastEvaluation: state.lastEvaluation ? cloneDeep(state.lastEvaluation) : null
239-
};
240237
}
241238
};
242239
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export function createPromotionStateSnapshot({
2+
promoted,
3+
stableFrames,
4+
stabilityWindowFrames,
5+
lastReason,
6+
lastEvaluation,
7+
cloneLastEvaluation
8+
}) {
9+
return {
10+
promoted,
11+
stableFrames,
12+
stabilityWindowFrames,
13+
lastReason,
14+
lastEvaluation: typeof cloneLastEvaluation === 'function'
15+
? cloneLastEvaluation(lastEvaluation)
16+
: lastEvaluation ?? null
17+
};
18+
}

0 commit comments

Comments
 (0)