Skip to content

Commit d93c302

Browse files
author
DavidQ
committed
Level 11.1: State contract finalization
- Enforced normalized state structure - Prevented malformed state writes
1 parent 0afeda3 commit d93c302

6 files changed

Lines changed: 69 additions & 40 deletions

File tree

docs/dev/CODEX_COMMANDS.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,18 @@ MODEL: GPT-5.3-codex
22
REASONING: high
33

44
COMMAND:
5-
Implement BUILD_PR_LEVEL_11_1_AUTHORITATIVE_APPLY_GUARD.
5+
Implement BUILD_PR_LEVEL_11_1_STATE_CONTRACT_FINALIZATION.
66

77
Modify ONLY:
88
src/advanced/state/transitions.js
99

1010
Change:
11-
- Wrap authoritativeApply calls with:
12-
if (context && context.authoritative === true)
13-
14-
Do NOT:
15-
- change APIs
16-
- refactor unrelated logic
11+
- Enforce normalized structure for worldState mutations
12+
- Reject malformed payloads early
1713

1814
Validation:
19-
- Passive mode does not invoke authoritativeApply
20-
- Existing tests pass
15+
- No undefined state fields
16+
- Tests pass
2117

2218
Output:
23-
<project folder>/tmp/BUILD_PR_LEVEL_11_1_AUTHORITATIVE_APPLY_GUARD.zip
19+
<project folder>/tmp/BUILD_PR_LEVEL_11_1_STATE_CONTRACT_FINALIZATION.zip

docs/dev/COMMIT_COMMENT.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Level 11.1: Authoritative apply guard
1+
Level 11.1: State contract finalization
22

3-
- Restricted authoritativeApply execution
4-
- No API changes
3+
- Enforced normalized state structure
4+
- Prevented malformed state writes
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Added guard to ensure authoritativeApply executes only in authoritative context.
1+
Finalized state contract boundaries and normalization enforcement.
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
[ ] transitions.js modified only
2-
[ ] authoritativeApply guarded
3-
[ ] Passive mode safe
4-
[ ] No API changes
2+
[ ] State normalized
3+
[ ] No undefined shapes
54
[ ] Tests pass
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# BUILD PR — Level 11.1 State Contract Finalization
2+
3+
## Purpose
4+
Finalize state contract boundaries to ensure consistent shape and safe reads.
5+
6+
## Scope
7+
- Validation + contract enforcement only
8+
- No API changes
9+
10+
## File
11+
- src/advanced/state/transitions.js
12+
13+
## Change
14+
- Ensure all state writes produce normalized structure
15+
- Reject malformed state payloads at boundary
16+
17+
## Validation
18+
- No undefined state shapes
19+
- Existing tests pass

src/advanced/state/transitions.js

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,37 @@ function recalcObjectiveSummary(objectivesById) {
7979
};
8080
}
8181

82+
function ensureNormalizedWorldState(snapshot) {
83+
if (!isPlainObject(snapshot.worldState)) {
84+
snapshot.worldState = {};
85+
}
86+
87+
const worldState = snapshot.worldState;
88+
89+
if (!isPlainObject(worldState.scores)) {
90+
worldState.scores = {};
91+
}
92+
worldState.scores.total = toFiniteNumber(worldState.scores.total, 0);
93+
worldState.scores.rewardPoints = toFiniteNumber(worldState.scores.rewardPoints, 0);
94+
if (worldState.scores.rank === undefined) {
95+
worldState.scores.rank = null;
96+
}
97+
98+
if (!isPlainObject(worldState.objectives)) {
99+
worldState.objectives = {};
100+
}
101+
if (!isPlainObject(worldState.objectives.byId)) {
102+
worldState.objectives.byId = {};
103+
}
104+
worldState.objectives.summary = recalcObjectiveSummary(worldState.objectives.byId);
105+
106+
if (!isPlainObject(worldState.flags)) {
107+
worldState.flags = {};
108+
}
109+
110+
return worldState;
111+
}
112+
82113
function validateTransitionGameMode(payload) {
83114
const nextMode = payload && payload.nextMode;
84115
if (typeof nextMode !== 'string' || !nextMode.trim()) {
@@ -114,25 +145,18 @@ function validateApplyScoreDelta(payload) {
114145
if (!Number.isFinite(normalizedDelta)) {
115146
return { ok: false, reason: 'applyScoreDelta requires finite numeric payload.delta.' };
116147
}
148+
if (payload.rewardDelta !== undefined && !Number.isFinite(Number(payload.rewardDelta))) {
149+
return { ok: false, reason: 'applyScoreDelta payload.rewardDelta must be finite numeric when provided.' };
150+
}
117151
return { ok: true };
118152
}
119153

120154
function applyAuthoritativeScoreDelta(snapshot, payload, context = {}) {
121155
if (isPassiveModeContext(context)) {
122156
return { changes: [] };
123157
}
124-
if (!snapshot.worldState || !isPlainObject(snapshot.worldState)) {
125-
snapshot.worldState = {};
126-
}
127-
if (!isPlainObject(snapshot.worldState.scores)) {
128-
snapshot.worldState.scores = {
129-
total: 0,
130-
rewardPoints: 0,
131-
rank: null
132-
};
133-
}
134-
135-
const scores = snapshot.worldState.scores;
158+
const worldState = ensureNormalizedWorldState(snapshot);
159+
const scores = worldState.scores;
136160
const currentTotal = toFiniteNumber(scores.total, 0);
137161
const currentRewardPoints = toFiniteNumber(scores.rewardPoints, 0);
138162
const delta = toFiniteNumber(payload.delta, 0);
@@ -177,17 +201,8 @@ function applyAuthoritativeObjectiveProgress(snapshot, payload, context = {}) {
177201
}
178202
const now = typeof context.now === 'function' ? context.now : () => Date.now();
179203
const objectiveId = String(payload.objectiveId || '').trim();
180-
const objectives = snapshot.worldState && snapshot.worldState.objectives
181-
? snapshot.worldState.objectives
182-
: { summary: { total: 0, completed: 0, active: 0 }, byId: {} };
183-
if (!snapshot.worldState.objectives) {
184-
snapshot.worldState.objectives = objectives;
185-
}
186-
187-
if (!isPlainObject(objectives.byId)) objectives.byId = {};
188-
if (!isPlainObject(objectives.summary)) {
189-
objectives.summary = { total: 0, completed: 0, active: 0 };
190-
}
204+
const worldState = ensureNormalizedWorldState(snapshot);
205+
const objectives = worldState.objectives;
191206

192207
const existing = isPlainObject(objectives.byId[objectiveId]) ? objectives.byId[objectiveId] : {};
193208
objectives.byId[objectiveId] = {

0 commit comments

Comments
 (0)