Commit 9a40257
perf(d-3 followup): harden compare.exs against schema drift (standards#99)
Phase D-3 follow-up under the single-lane HCG tier-2 channel
(standards#91). PR #26 (D-4 bootstrap) deferred this as a "separate
defensive D-3 follow-up, not coupled to D-4 collection": when
bench/baseline.json `_status` is flipped to `active`, a scenario
present in results.json but absent from baseline.json (a new harness
scenario landed without rebaseline) silently passed the gate, and a
scenario present in baseline.json but absent from results.json (the
harness dropped a scenario without rebaselining) was never even
checked. Both directions of schema drift now fail-closed in active
mode and surface as informational "scaffold (would fail: ...)" rows
in scaffold-placeholder mode so a rebaseline PR previews the
active-mode verdict before the gate is armed.
The comparator now iterates the union of scenario names across
results and baseline rather than the results map alone, and uses a
single `enforce: bool` opt to pivot between scaffold and active mode
(replaces the previous `nil` sentinel). check_regression/5 also has
a latent crash fixed in the process — when baseline values are TODO
sentinels (or any non-number), num/1 returns nil and the `or` chain
raises BadBooleanError; the inner `&&` short-circuit already returns
nil for unknowns, so the outer joins are switched from `or` to `||`
to match. Previously this was masked by scaffold mode never reaching
check_regression at all (the `nil` sentinel skipped it); the new
flow exposes that path in scaffold mode too.
docs/perf-contract.md gains a "Schema drift" section explaining the
two directions, the active vs scaffold display difference, and the
fail-closed semantic. The behaviour pivots on `_status` in
bench/baseline.json — no code change is needed to arm the schema
checks once Phase D-4 maintainer-only rebaseline + active flip lands.
Smoke-tested locally against synthetic results/baseline fixtures
(four cases: active+drift→regressed, scaffold+drift→ok-with-warnings,
active+clean→ok, active+TODO-sentinels→ok-no-crash). Build is not
verified end-to-end — the session environment has Elixir 1.14 only,
no Elixir 1.19 / OTP 28 toolchain — but Code.format_string!/1 reports
the file is already formatted and Code.string_to_quoted!/1 round-trips
under 1.14. Repo CI (`Perf Regression`, governance, hypatia-scan,
dogfood-gate, codeql, scorecard) is the verification gate.
Refs hyperpolymath/standards#91
Refs hyperpolymath/standards#99
NOT Closes #99: joint-close is owner-only; D-4 baseline collection
plus the `_status` flip to active still pend under #99 after this
lands. Same posture as PRs #14, #22, #26.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>1 parent 430ef58 commit 9a40257
2 files changed
Lines changed: 85 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
| |||
59 | 60 | | |
60 | 61 | | |
61 | 62 | | |
62 | | - | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
63 | 67 | | |
64 | 68 | | |
65 | 69 | | |
66 | | - | |
| 70 | + | |
67 | 71 | | |
68 | 72 | | |
69 | 73 | | |
70 | | - | |
| 74 | + | |
71 | 75 | | |
72 | 76 | | |
73 | 77 | | |
| |||
80 | 84 | | |
81 | 85 | | |
82 | 86 | | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
83 | 100 | | |
84 | | - | |
85 | 101 | | |
86 | 102 | | |
87 | 103 | | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
88 | 108 | | |
89 | 109 | | |
90 | 110 | | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
95 | 132 | | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
100 | 138 | | |
101 | | - | |
102 | | - | |
103 | | - | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
104 | 144 | | |
105 | 145 | | |
106 | | - | |
| 146 | + | |
107 | 147 | | |
108 | 148 | | |
109 | 149 | | |
110 | | - | |
| 150 | + | |
111 | 151 | | |
112 | 152 | | |
113 | 153 | | |
| |||
126 | 166 | | |
127 | 167 | | |
128 | 168 | | |
129 | | - | |
130 | | - | |
131 | 169 | | |
132 | 170 | | |
133 | 171 | | |
| |||
138 | 176 | | |
139 | 177 | | |
140 | 178 | | |
141 | | - | |
142 | | - | |
| 179 | + | |
| 180 | + | |
143 | 181 | | |
144 | 182 | | |
145 | 183 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
84 | 110 | | |
85 | 111 | | |
86 | 112 | | |
| |||
0 commit comments