Skip to content

Commit b697e1b

Browse files
author
DavidQ
committed
Finalize promotion gate validation and closeout
1 parent 32ce0e7 commit b697e1b

6 files changed

Lines changed: 54 additions & 8 deletions

File tree

docs/dev/CODEX_COMMANDS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
MODEL: GPT-5.4-codex
22
REASONING: high
33
COMMAND:
4-
Execute docs/pr/BUILD_PR_PROMOTION_GATE_57_OBSERVABILITY_ABORT.md exactly.
5-
Package to <project folder>/tmp/BUILD_PR_PROMOTION_GATE_57_OBSERVABILITY_ABORT_delta.zip
4+
Execute docs/pr/BUILD_PR_PROMOTION_GATE_58_VALIDATION_CLOSEOUT.md exactly.
5+
Package to <project folder>/tmp/BUILD_PR_PROMOTION_GATE_58_VALIDATION_CLOSEOUT_delta.zip

docs/dev/COMMIT_COMMENT.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Add promotion gate observability and abort visibility
1+
Finalize promotion gate validation and closeout

docs/dev/NEXT_COMMAND.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Next: validation closeout
1+
End of promotion-gate lane

docs/dev/reports/file_tree.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
src/advanced/promotion/createPromotionGate.js
2-
src/engine/debug/panels/PromotionGatePanel.js
32
src/shared/state/createPromotionStateSnapshot.js

src/advanced/promotion/createPromotionGate.js

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,38 @@ function resolveGateMode({ promoted }) {
5353
}
5454

5555
function createAbortVisibility({ rollbackTriggered, promoted, reason }) {
56-
const aborted = Boolean(rollbackTriggered) && !promoted;
56+
const aborted = Boolean(rollbackTriggered);
5757
return {
5858
decisionPath: 'PROMOTION_GATE_ABORT_VISIBILITY',
5959
rollbackTriggered: Boolean(rollbackTriggered),
6060
aborted,
61-
reason: aborted ? 'ROLLBACK_ABORTED_PROMOTION' : String(reason || '')
61+
reason: aborted
62+
? (promoted ? 'ROLLBACK_ABORT_VISIBLE' : 'ROLLBACK_ABORTED_PROMOTION')
63+
: String(reason || '')
64+
};
65+
}
66+
67+
function createValidationChecklist(evaluation, cycleState) {
68+
const modeVisible = typeof evaluation?.mode === 'string' && evaluation.mode.length > 0;
69+
const handoffVisible = isPlainObject(evaluation?.handoff)
70+
&& evaluation.handoff.decisionPath === 'PROMOTION_GATE_HANDOFF';
71+
const abortVisible = isPlainObject(evaluation?.abort)
72+
&& evaluation.abort.decisionPath === 'PROMOTION_GATE_ABORT_VISIBILITY';
73+
74+
cycleState.passiveSeen = cycleState.passiveSeen || evaluation.mode === 'passive';
75+
cycleState.authoritativeSeen = cycleState.authoritativeSeen || evaluation.mode === 'authoritative';
76+
cycleState.abortSeen = cycleState.abortSeen || evaluation.abort?.aborted === true;
77+
cycleState.fullCycleReached = cycleState.passiveSeen && cycleState.authoritativeSeen && cycleState.abortSeen;
78+
79+
return {
80+
checklistPath: 'PROMOTION_GATE_VALIDATION_CLOSEOUT',
81+
modeVisible,
82+
handoffVisible,
83+
abortVisible,
84+
passiveSeen: cycleState.passiveSeen,
85+
authoritativeSeen: cycleState.authoritativeSeen,
86+
abortSeen: cycleState.abortSeen,
87+
fullCycleReached: cycleState.fullCycleReached
6288
};
6389
}
6490

@@ -68,6 +94,7 @@ function createPromotionGate(options = {}) {
6894
const stabilityWindowFrames = asPositiveInteger(options.stabilityWindowFrames, 3);
6995
const logger = typeof options.logger === 'function' ? options.logger : null;
7096
const onEvaluation = typeof options.onEvaluation === 'function' ? options.onEvaluation : null;
97+
const onValidation = typeof options.onValidation === 'function' ? options.onValidation : null;
7198

7299
let promoted = Boolean(options.initiallyPromoted);
73100
let stableFrames = promoted ? stabilityWindowFrames : 0;
@@ -83,6 +110,12 @@ function createPromotionGate(options = {}) {
83110
lastEvaluationAtMs: null,
84111
lastPromotionAtMs: promoted ? Number(now()) : null
85112
};
113+
const validationCycle = {
114+
passiveSeen: !promoted,
115+
authoritativeSeen: promoted,
116+
abortSeen: false,
117+
fullCycleReached: false
118+
};
86119

87120
function getMetrics() {
88121
return {
@@ -180,6 +213,7 @@ function createPromotionGate(options = {}) {
180213
reason: lastReason,
181214
metrics: getMetrics()
182215
};
216+
evaluation.validation = createValidationChecklist(evaluation, validationCycle);
183217

184218
lastEvaluation = evaluation;
185219

@@ -192,6 +226,9 @@ function createPromotionGate(options = {}) {
192226
if (onEvaluation) {
193227
onEvaluation(evaluation);
194228
}
229+
if (onValidation) {
230+
onValidation(evaluation.validation, evaluation);
231+
}
195232

196233
return evaluation;
197234
}

src/shared/state/createPromotionStateSnapshot.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ function cloneAbort(value) {
1212
return { ...value };
1313
}
1414

15+
function cloneValidation(value) {
16+
if (!value || typeof value !== 'object') return null;
17+
return { ...value };
18+
}
19+
1520
function resolveStatusMode({ promoted, lastEvaluation }) {
1621
const fromEvaluation = lastEvaluation && typeof lastEvaluation.mode === 'string'
1722
? lastEvaluation.mode
@@ -29,6 +34,10 @@ function resolveStatusAbort({ lastEvaluation }) {
2934
return cloneAbort(lastEvaluation?.abort);
3035
}
3136

37+
function resolveStatusValidation({ lastEvaluation }) {
38+
return cloneValidation(lastEvaluation?.validation);
39+
}
40+
3241
export function createPromotionStateSnapshot({
3342
promoted,
3443
stableFrames,
@@ -52,7 +61,8 @@ export function createPromotionStateSnapshot({
5261
snapshot.status = {
5362
mode: resolveStatusMode({ promoted, lastEvaluation: snapshot.lastEvaluation }),
5463
handoff: resolvedHandoff,
55-
abort: resolveStatusAbort({ lastEvaluation: snapshot.lastEvaluation })
64+
abort: resolveStatusAbort({ lastEvaluation: snapshot.lastEvaluation }),
65+
validation: resolveStatusValidation({ lastEvaluation: snapshot.lastEvaluation })
5666
};
5767
return snapshot;
5868
}

0 commit comments

Comments
 (0)