Skip to content

Commit 9997b65

Browse files
chore: pin the suite-adequacy figures and record the study
check_manuscript pins the coverage, the mutation score, the gap and its interval, and the per-operator kill rates, and the reproduction guide and changelog record the new scripts and how they differ from the decision-blindness study.
1 parent 1165259 commit 9997b65

3 files changed

Lines changed: 94 additions & 0 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ All notable changes to TrustWeave are documented in this file. The project follo
4040
(`docs/cedar-suite-strategy-study-v1.json`, deviations recorded in it). Of 43 real
4141
earlier-version edits, 24 change a decision and 21 of those weaken one
4242
(`docs/cedar-real-edits-v1.json`).
43+
- `scripts/rego_suite_study.py` and `scripts/rego_source_mutation.py` measure what a real
44+
policy suite's line coverage is worth, under `docs/SUITE_ADEQUACY_PROTOCOL_REGO.md` (hash
45+
fixed in the script): on the 49 OPA Gatekeeper modules that ship an author-written suite, the
46+
line coverage `opa test --coverage` reports against the fraction of the module's mutants the
47+
same suite kills, every number from the engine. The suites reach 93.8% mean line coverage but
48+
kill 70.6% of mutants, a 23.2-point gap concentrated in value-level faults
49+
(`docs/rego-suite-adequacy-v1.json`). `rego_source_mutation.py` locates each edit through
50+
`opa parse`, a distinct and richer operator set than `rego_mutation.py`'s fixed-text one
51+
(it adds deleted rules, dropped conditions and replaced literals, and never edits inside a
52+
string literal); the two studies measure different things and are reported separately.
4353
- `third_party_sample.py oracle-rego` checks the sampled Rego modules against `opa deps`, each
4454
compiled with its whole repository: 150 agree, the 6 that do not all share their package with
4555
other files (the engine answers for a package, the adapter for a file), and for 144 the

‎docs/REPRODUCING_THE_STUDY.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,24 @@ python scripts/cedar_exact_study.py edits --cache /tmp/cedar-cache \
195195
`repos/{owner}/{repo}/commits?path=` returns them; `docs/cedar-real-edits-v1.json` pins every
196196
pair it measured by commit and SHA-256, so re-deriving the pairs does not depend on it.
197197

198+
### 4d. What a real suite's line coverage is worth (Gatekeeper Rego)
199+
200+
Runs under [`SUITE_ADEQUACY_PROTOCOL_REGO.md`](SUITE_ADEQUACY_PROTOCOL_REGO.md). Needs `opa`
201+
on `PATH` and the pinned Gatekeeper library (a cloned corpus, commit in the artifact's `corpus`
202+
block). For each module with an author-written suite it records the suite's line coverage and
203+
its mutation score, every number from `opa test`.
204+
205+
```bash
206+
python scripts/rego_suite_study.py study \
207+
--corpus /path/to/gatekeeper-library \
208+
--json docs/rego-suite-adequacy-v1.json
209+
```
210+
211+
This is a different measurement from the decision-blindness prediction of §4 above: it reports
212+
line coverage against a located-source mutation score (`scripts/rego_source_mutation.py`), where
213+
`scripts/rego_mutation.py` reports a text-search mutation score against the decision-coverage
214+
flag. The protocol states how the two operator sets differ.
215+
198216
### 5. The whole gate
199217

200218
```bash

‎scripts/check_manuscript.py‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,9 +1172,75 @@ def p_value(stratum: str) -> str:
11721172
claims += _summary_claims(docs)
11731173
claims += _cedar_claims(docs)
11741174
claims += _sample_oracle_claims(docs)
1175+
claims += _rego_suite_claims(docs)
11751176
return claims
11761177

11771178

1179+
def _rego_suite_claims(docs: Path) -> list[Claim]:
1180+
"""What a real suite's line coverage is worth against its mutation score (Gatekeeper Rego)."""
1181+
1182+
suite = _load(docs, "rego-suite-adequacy-v1")
1183+
head = suite["headline"]
1184+
operators = suite["by_operator"]
1185+
1186+
def rate(operator: str) -> str:
1187+
counts = operators[operator]
1188+
return str(round(100 * counts["killed"] / counts["total"]))
1189+
1190+
return [
1191+
(
1192+
rf"on the ({_GROUPED}) Gatekeeper modules\s+that ship an author-written suite",
1193+
(_grouped(suite["population"]["modules_with_a_suite_and_a_decision"]),),
1194+
"rego suite study: the population",
1195+
),
1196+
(
1197+
r"a mean of (\d+\.\d)\\% line coverage",
1198+
(f"{head['mean_coverage']:.1f}",),
1199+
"rego suite study: mean coverage",
1200+
),
1201+
(
1202+
r"killing\s+(\d+\.\d)\\% in the mean "
1203+
rf"\(({_GROUPED}) of ({_GROUPED}) over the ({_GROUPED}) modules",
1204+
(
1205+
_pct(head["mean_mutation_score"]),
1206+
_grouped(head["killed"]),
1207+
_grouped(head["mutants"]),
1208+
_grouped(head["modules"]),
1209+
),
1210+
"rego suite study: mean mutation score and pool",
1211+
),
1212+
(
1213+
r"a per-module gap of (\d+\.\d) points with a 95\\% bootstrap interval of "
1214+
r"\$\[(\d+\.\d), (\d+\.\d)\]\$",
1215+
(
1216+
_pct(head["mean_gap"]),
1217+
_pct(head["gap_bootstrap_95"][0]),
1218+
_pct(head["gap_bootstrap_95"][1]),
1219+
),
1220+
"rego suite study: the gap",
1221+
),
1222+
(
1223+
r"the suites kill (\d+)\\% of deleted rules and (\d+)\\% of removed negations but "
1224+
r"only (\d+)\\% of changed string literals, (\d+)\\% of changed comparisons and "
1225+
r"(\d+)\\% of changed numbers",
1226+
(
1227+
rate("delete a rule"),
1228+
rate("remove a negation"),
1229+
rate("change a string literal"),
1230+
rate("change a comparison"),
1231+
rate("change a number literal"),
1232+
),
1233+
"rego suite study: the uneven gap by operator",
1234+
),
1235+
(
1236+
r"author-written suites for real Rego policy reach (\d+\.\d)\\% line coverage yet "
1237+
r"kill only (\d+\.\d)\\% of the policies' mutants",
1238+
(f"{head['mean_coverage']:.1f}", _pct(head["mean_mutation_score"])),
1239+
"rego suite study: the figures restated in related work",
1240+
),
1241+
]
1242+
1243+
11781244
def _sample_oracle_claims(docs: Path) -> list[Claim]:
11791245
"""The sampled Rego modules against the engine's own dependency analysis."""
11801246

0 commit comments

Comments
 (0)