From 0bedc050386df39a909a1b3712c18cd0cb3f9b0e Mon Sep 17 00:00:00 2001 From: EtienneLescot Date: Fri, 21 Aug 2026 23:49:12 +0200 Subject: [PATCH] fix(workbench): retire beh.sandbox from the baseline, confirmed at n=10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `assertAgainstBaseline` reads the UNION of the scenario's expectedFailures and the baseline file's, so removing the entry from the scenario alone left it live: every run printed "défaut connu semble corrigé sur wizard-enhance/beh.sandbox". A permanent notice is ignored as fast as a permanent green, which is what the bidirectional ratchet exists to prevent. Removed on two arguments, not one. Structural: `deep-agent/service.ts` builds its agent with `createAgent` and the OpenScreen tools alone, so the phantom ls/grep/glob surface this check probes for is gone. A call to one of them today would be a hallucination — an UNEXPECTED failure, which is the signal the scenario wants. The check itself stays for exactly that. Measured, as the README requires before any removal: n=10 on 2026-08-21 against deepseek-v4-flash (resolved; deepseek-chat requested), 10/10, Wilson [72%, 100%]. Verified after the edit that the notice stops firing. `dsl.focus.not-fabricated` scored 10/10 in the SAME run and stays, because it has only the observation behind it and no structural argument — the faulty code is still there. That is the difference between "the cause is gone" and "variance was kind ten times", and it is why the numbers alone were never going to settle this. The single-rep verification run makes the point again: `beh.multiplier` passed there and printed "seems fixed", having been 9/10 at n=10. The baseline's `behaviour`/`dsl` numbers are left as the 2026-07-31 archive they are, and now say so. Nothing READS them — the ratchet compares ids only — and re-recording from this run would freeze an anomalous pass in which `beh.counts` regressed. Hand-edited rather than `--update-baseline`, which would have harvested both intermittent entries on one green run. Also renames the synthetic `beh.no-false-negative` in `l0/stats-report.wb.ts`: that id no longer exists anywhere in the pack, and a fabricated fixture wearing a dead real name reads as a live one. --- workbench/baselines/wizard-enhance.json | 2 +- workbench/l0/stats-report.wb.ts | 4 ++-- workbench/scenarios/wizard-enhance.scn.ts | 26 ++++++++++++++++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/workbench/baselines/wizard-enhance.json b/workbench/baselines/wizard-enhance.json index 19d5e6123..98391f444 100644 --- a/workbench/baselines/wizard-enhance.json +++ b/workbench/baselines/wizard-enhance.json @@ -1,6 +1,6 @@ { "scenario": "wizard-enhance", - "expectedFailures": ["beh.multiplier", "beh.sandbox", "dsl.focus.not-fabricated"], + "expectedFailures": ["beh.multiplier", "dsl.focus.not-fabricated"], "behaviour": 0.6667, "dsl": 1, "recordedAt": "2026-07-31" diff --git a/workbench/l0/stats-report.wb.ts b/workbench/l0/stats-report.wb.ts index c7863347d..7453eff95 100644 --- a/workbench/l0/stats-report.wb.ts +++ b/workbench/l0/stats-report.wb.ts @@ -86,7 +86,7 @@ const SCENARIO_REPORT = { failureClasses: { NONE: 3 }, checks: [ { - id: "beh.no-false-negative", + id: "beh.synthetique", axis: "behaviour" as const, weight: 3, passed: 0, @@ -127,7 +127,7 @@ describe("report rendering", () => { it("labels a known failure as such and surfaces its evidence", () => { const markdown = renderMarkdown(report); - expect(markdown).toContain("| `beh.no-false-negative` | behaviour | 3 | 0/3 |"); + expect(markdown).toContain("| `beh.synthetique` | behaviour | 3 | 0/3 |"); expect(markdown).toContain("connu"); expect(markdown).toContain("négation universelle"); }); diff --git a/workbench/scenarios/wizard-enhance.scn.ts b/workbench/scenarios/wizard-enhance.scn.ts index 19053c24a..ef459f575 100644 --- a/workbench/scenarios/wizard-enhance.scn.ts +++ b/workbench/scenarios/wizard-enhance.scn.ts @@ -282,7 +282,31 @@ export default defineScenario({ // `cannot`) rejoué à l'identique, en anglais, sur une réponse anglaise. // Donc sous l'ancien identifiant ce run n'aurait PAS dit « corrigé » : // il aurait dit « toujours en échec », sur trois réponses exemplaires. - // beh.sandbox retiré : les outils fantômes ne sont plus sur la surface. + // beh.sandbox RETIRÉ de la baseline aussi — `assertAgainstBaseline` lit + // l'UNION des deux listes, donc le laisser dans le fichier le gardait vivant : + // chaque run imprimait « semble corrigé », et un avertissement permanent + // s'ignore aussi vite qu'un vert permanent, ce que le cliquet bidirectionnel + // existe précisément pour empêcher. + // + // Retiré sur DEUX arguments, pas un. Structurel d'abord : `service.ts` bâtit + // son agent avec `createAgent` et les seuls outils OpenScreen — la surface + // fantôme que ce check sonde n'existe plus, donc un appel à `ls` aujourd'hui + // serait une hallucination, c'est-à-dire un échec INATTENDU, qui est le signal + // que ce scénario veut. Mesuré ensuite, comme le README l'exige avant tout + // retrait : n=10 le 2026-08-21 sur deepseek-v4-flash (résolu ; `deepseek-chat` + // demandé), 10/10, Wilson [72 %, 100 %]. + // + // `dsl.focus.not-fabricated` a fait 10/10 au MÊME run et reste pourtant en + // place : il n'a que l'observation pour lui, pas d'argument structurel — le + // code fautif est toujours là. La différence entre les deux entrées est celle + // entre « la cause a disparu » et « la variance a été clémente dix fois ». + // + // Les nombres `behaviour`/`dsl` du fichier sont une ARCHIVE du 2026-07-31, + // calculée sur un jeu de checks qui n'existe plus (`beh.no-false-negative` est + // devenu `beh.attributes-the-limit`, sous un id neuf). Ils ne sont pas + // re-enregistrés : rien ne les LIT — `assertAgainstBaseline` ne compare que + // les ids — et les refaire depuis ce run figerait une passe anormale, où + // `beh.counts` a régressé. // INTERMITTENTES, mesuré en live sur deepseek-v4-flash : ces deux checks // passent certains runs entiers. Le modèle omet parfois tout multiplicateur // (silence = honnête, donc `beh.multiplier` passe) et centre parfois ses