@@ -12,12 +12,12 @@ jobs:
1212 runs-on : ubuntu-latest
1313 timeout-minutes : 20
1414 env :
15- TARGET_REVISION : 73c0641af57b0ccaabcfa453c34008b2417e7678
16- VITE_SOFTWARE_REVISION : 73c0641af57b0ccaabcfa453c34008b2417e7678
15+ TARGET_REVISION : 9f27f94708cea3bf9122758b315be186d3cd7723
16+ VITE_SOFTWARE_REVISION : 9f27f94708cea3bf9122758b315be186d3cd7723
1717 steps :
1818 - uses : actions/checkout@v7
1919 with :
20- ref : 73c0641af57b0ccaabcfa453c34008b2417e7678
20+ ref : 9f27f94708cea3bf9122758b315be186d3cd7723
2121 - uses : actions/setup-node@v6
2222 with :
2323 node-version : 22
8080 const revision = process.env.TARGET_REVISION;
8181 if (!/^[0-9a-f]{40}$/.test(revision ?? '')) throw new Error('target revision is invalid');
8282 const objectLabel = 'gate a2 synthetic ceramic mug';
83+ const expectedAlgorithmVersion = 'er-dsp-2';
8384 const expectedModes = [
8485 { frequencyHz: 440, decaySeconds: 1.20 },
8586 { frequencyHz: 997, decaySeconds: 0.70 },
@@ -136,7 +137,7 @@ jobs:
136137 }
137138
138139 function assertFingerprint(fingerprint, attemptId) {
139- if (fingerprint?.algorithmVersion !== 'er-dsp-2' ) throw new Error(`attempt ${attemptId} has wrong algorithm provenance`);
140+ if (fingerprint?.algorithmVersion !== expectedAlgorithmVersion ) throw new Error(`attempt ${attemptId} has wrong algorithm provenance`);
140141 if (!Number.isFinite(fingerprint?.sampleRate) || fingerprint.sampleRate <= 0) throw new Error(`attempt ${attemptId} has invalid sample rate`);
141142 if (!Array.isArray(fingerprint?.modes) || fingerprint.modes.length !== 3) {
142143 throw new Error(`attempt ${attemptId} expected exactly 3 supported modes, got ${fingerprint?.modes?.length}`);
@@ -171,9 +172,11 @@ jobs:
171172 const snapshot = await page.evaluate(() => ({
172173 text: document.body.innerText,
173174 modeCount: document.querySelectorAll('.mode-row:not(.mode-head)').length,
175+ algorithmVersion: document.querySelector('.result-head .eyebrow')?.textContent?.trim() ?? null,
174176 }));
175177 if (!snapshot.text.includes(`${attempt} / 5`)) throw new Error(`attempt ${attempt} was not retained`);
176178 if (snapshot.modeCount !== 3) throw new Error(`attempt ${attempt} expected exactly three visible modes, got ${snapshot.modeCount}`);
179+ if (snapshot.algorithmVersion !== expectedAlgorithmVersion) throw new Error(`attempt ${attempt} displayed ${snapshot.algorithmVersion} instead of ${expectedAlgorithmVersion}`);
177180 if (attempt < 5) {
178181 await clickButton('NEW QUALIFIED ATTEMPT');
179182 await page.waitForFunction(() => document.querySelector('.status')?.textContent?.trim() !== 'success', { timeout: 3_000, polling: 50 });
@@ -183,6 +186,7 @@ jobs:
183186 const finalText = await page.evaluate(() => document.body.innerText);
184187 if (!finalText.includes('Five qualified attempts complete. Gate A2 passes')) throw new Error('Gate A2 session did not pass after five repeated strikes');
185188 if (!finalText.includes('Gate A2\nPASS')) throw new Error('Gate A2 session metric did not report PASS');
189+ const renderedAlgorithmVersion = await page.$eval('.result-head .eyebrow', node => node.textContent?.trim() ?? '');
186190
187191 await clickButton('EXPORT EVIDENCE');
188192 const evidencePath = await waitForJsonDownload();
@@ -199,6 +203,8 @@ jobs:
199203 }
200204 assertFingerprint(attempt.analysis.fingerprint, attempt.id);
201205 }
206+ const exportedAlgorithmVersion = evidence.attempts[evidence.attempts.length - 1].analysis.fingerprint.algorithmVersion;
207+ if (renderedAlgorithmVersion !== exportedAlgorithmVersion) throw new Error('rendered and exported algorithm provenance diverged');
202208 if (evidence.recurrence?.length !== 4) throw new Error('evidence does not contain four recurrence comparisons');
203209 if (evidence.recurrence.some(comparison => comparison.matchedCount < 3 || comparison.medianCents > 50)) throw new Error('recurrence comparison violates Gate A2 bounds');
204210 if (!(evidence.medianModalDriftCents <= 25)) throw new Error('session median drift violates Gate A2 bound');
@@ -235,6 +241,7 @@ jobs:
235241 const fingerprints = evidence.attempts.map(attempt => attempt.analysis.fingerprint);
236242 const report = {
237243 targetRevision: revision,
244+ renderedAlgorithmVersion,
238245 algorithmVersions: [...new Set(fingerprints.map(fingerprint => fingerprint.algorithmVersion))],
239246 attemptCount: evidence.attemptCount,
240247 modeCounts: fingerprints.map(fingerprint => fingerprint.modes.length),
0 commit comments