Skip to main content

max / quasi

9.3 KB · 240 lines History Blame Raw
1 #!/usr/bin/env python3
2 """Draw a stratified, reproducible probe sample from the shape population.
3
4 A probe is a full re-authoring of a real shape function into the `declare!`
5 form, checked production by production against the grammar in wiki
6 `quasi-declare-form`. Round 1 ran 15 probes over 26 functions (5.1% of 514) and
7 found one new blocking class per 1.4 probes without the rate flattening, which
8 is why the form is not closed. Round 2 has to be big enough that coming back
9 clean means something, and aimed at the holes round 1 left rather than at
10 another uniform draw.
11
12 This script is the sampling frame, written down so a round can be re-run and
13 argued with. It reads the population from `population.py`, so the two cannot
14 drift.
15
16 THE STRATA, each one a hole section 7 of the record names by hand:
17
18 conceded The three goingson forms conceded to the `Field::refilled`
19 deferral and never re-authored. The concession covers 4 sites
20 while the closure weight in those functions is far larger, so the
21 concession itself is untested. Always drawn, never sampled.
22 af-cold audiofiles outside the five files round 1 touched. That tree
23 carries 43 of the 66 carried containers, 89 of the owned
24 parameters and 22 of the 25 `Type::Variant.method()` sites, so it
25 is where the twelve amendments have the most to prove.
26 fallible Shapes returning `Result<_, RouteError>`. Amendment 1 (`take`) is
27 the highest-site-count gap in the record: 54 fallible shapes, 106
28 `?`, 13 of them mixing converted and bare reads. Its failure mode
29 is a 404 rendered as a 500, so it is the amendment worth the most
30 evidence.
31 rest Everything else, drawn uniformly, so the round is not purely
32 adversarial and a clean result can speak for the population
33 rather than only for its hard corners.
34
35 Round 1's targets are excluded by (file, function) rather than by line, since
36 lines have moved. `project_content.rs` is excluded whole: its probe covered a
37 five-function cluster the record does not name.
38
39 python3 scripts/probe-sample.py # the default round-2 draw
40 python3 scripts/probe-sample.py --json # machine-readable batches
41 python3 scripts/probe-sample.py --seed 8 --probes 20
42 python3 scripts/probe-sample.py --show-frame # strata sizes, no draw
43
44 The seed is printed with every draw. Record it on the task: it is what makes a
45 round reproducible, and a round nobody can re-run is not evidence.
46 """
47
48 from __future__ import annotations
49
50 import argparse
51 import importlib.util
52 import json
53 import random
54 import sys
55 from pathlib import Path
56
57 HERE = Path(__file__).resolve().parent
58
59
60 def load_population():
61 """Import `population.py` as a module, so the predicate has one home."""
62 spec = importlib.util.spec_from_file_location("population", HERE / "population.py")
63 mod = importlib.util.module_from_spec(spec)
64 spec.loader.exec_module(mod)
65 return mod
66
67
68 # Round 1, from the evidence table of wiki `quasi-declare-form` section 7.
69 # By path and function name, never by line: the lines have moved since
70 # 2026-09-02, and a stem alone would exclude a same-named function in another
71 # tree that round 1 never touched.
72 M = "MNW/server/src/quasi"
73 G = "Apps/goingson/src-tauri/src/quasi"
74 A = "Apps/audiofiles/crates/audiofiles-browser/src/quasi"
75
76 PROBED = {
77 (f"{G}/tasks.rs", "screen"),
78 (f"{G}/data.rs", "confirm_form"),
79 (f"{G}/data.rs", "import_form"),
80 (f"{G}/settings.rs", "setting"),
81 (f"{G}/settings.rs", "screen"),
82 (f"{G}/sharing.rs", "invitation_rows"),
83 (f"{A}/importing.rs", "flow"),
84 (f"{A}/export.rs", "naming_field"),
85 (f"{A}/export.rs", "setting_route"),
86 (f"{A}/export.rs", "picker"),
87 (f"{A}/sync.rs", "screen"),
88 (f"{A}/files.rs", "row"),
89 (f"{M}/git_nav.rs", "region"),
90 (f"{M}/git_nav.rs", "breadcrumb"),
91 (f"{M}/project.rs", "screen"),
92 (f"{M}/feeds.rs", "row"),
93 (f"{M}/git_commit.rs", "body_field"),
94 (f"{M}/git_commit.rs", "signature"),
95 (f"{M}/auth_pages.rs", "forgot_password"),
96 (f"{M}/user.rs", "screen"),
97 }
98
99 # Probe 9 covered an unnamed five-function cluster in this file.
100 PROBED_FILES = {"MNW/server/src/quasi/project_content.rs"}
101
102 # Read in round 1 and conceded to the `Field::refilled` deferral without being
103 # re-authored. The concession is what round 2 has to test, so these are drawn
104 # rather than sampled.
105 CONCEDED = [
106 (f"{G}/events.rs", "form_fields"),
107 (f"{G}/settings/email.rs", "fields"),
108 (f"{G}/tasks.rs", "edit_fields"),
109 ]
110
111 AF_TREE = A
112 # The five audiofiles files round 1 reached.
113 AF_WARM = {"sync.rs", "files.rs", "export.rs", "importing.rs", "toolbar.rs"}
114
115 # How the draw is split, after the conceded three. Weighted at the holes.
116 WEIGHTS = {"af-cold": 0.30, "fallible": 0.30, "rest": 0.40}
117
118
119 def stratify(shapes: list[dict]) -> dict[str, list[dict]]:
120 conceded_keys = set(CONCEDED)
121 strata: dict[str, list[dict]] = {"conceded": [], "af-cold": [], "fallible": [], "rest": []}
122 for s in shapes:
123 key = (s["file"], s["fn"])
124 stem = Path(s["file"]).name
125 if key in conceded_keys:
126 strata["conceded"].append(s)
127 continue
128 if s["file"] in PROBED_FILES or key in PROBED:
129 continue # round 1 covered it
130 if s["file"].startswith(AF_TREE) and stem not in AF_WARM:
131 strata["af-cold"].append(s)
132 elif "Result" in s["returns"]:
133 strata["fallible"].append(s)
134 else:
135 strata["rest"].append(s)
136 return strata
137
138
139 def draw(strata: dict[str, list[dict]], want: int, rng: random.Random) -> list[dict]:
140 """Draw `want` shapes beyond the conceded three, per WEIGHTS."""
141 picked = list(strata["conceded"])
142 remaining = max(0, want - len(picked))
143 for name, weight in WEIGHTS.items():
144 pool = strata[name]
145 n = min(round(remaining * weight), len(pool))
146 picked.extend(rng.sample(pool, n))
147 # Weight rounding can leave the draw a shape or two short; top up from the
148 # largest untouched pool so the requested size is the size delivered.
149 chosen = {(s["file"], s["fn"]) for s in picked}
150 if len(picked) < want:
151 spare = [s for name in WEIGHTS for s in strata[name]
152 if (s["file"], s["fn"]) not in chosen]
153 rng.shuffle(spare)
154 picked.extend(spare[: want - len(picked)])
155 return picked
156
157
158 def batch(picked: list[dict], per: int) -> list[list[dict]]:
159 """Group into probes, keeping same-file shapes together where possible.
160
161 A probe that re-authors two functions from one file re-reads one context
162 rather than two, and round 1's clean probes 3 and 4 were both clusters.
163 """
164 by_file: dict[str, list[dict]] = {}
165 for s in picked:
166 by_file.setdefault(s["file"], []).append(s)
167 ordered = [s for _, group in sorted(by_file.items()) for s in group]
168 return [ordered[i : i + per] for i in range(0, len(ordered), per)]
169
170
171 def main() -> int:
172 ap = argparse.ArgumentParser(
173 description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
174 )
175 ap.add_argument("--root", default=str(Path.home() / "Code"))
176 ap.add_argument("--seed", type=int, default=2, help="the round's seed; printed with the draw")
177 ap.add_argument("--probes", type=int, default=14, help="number of probe batches")
178 ap.add_argument("--per-probe", type=int, default=3, help="shapes per batch")
179 ap.add_argument("--json", action="store_true")
180 ap.add_argument("--show-frame", action="store_true", help="strata sizes only, no draw")
181 args = ap.parse_args()
182
183 pop = load_population()
184 root = Path(args.root)
185 shapes: list[dict] = []
186 for rel in pop.SHAPE_DIRS:
187 d = root / rel
188 if not d.is_dir():
189 print(f"missing: {rel}", file=sys.stderr)
190 return 1
191 for f in sorted(d.rglob("*.rs")):
192 parts = f.relative_to(root).parts
193 if f.name in ("tests.rs", "parity.rs") or "tests" in parts:
194 continue
195 for h in pop.shapes_in(f):
196 h["file"] = str(Path(h["file"]).relative_to(root))
197 shapes.append(h)
198
199 strata = stratify(shapes)
200 if args.show_frame:
201 print(f"population {len(shapes)}")
202 for name, pool in strata.items():
203 print(f"{len(pool):5} {name}")
204 print(f"{len(shapes) - sum(len(v) for v in strata.values()):5} excluded (round 1)")
205 return 0
206
207 want = args.probes * args.per_probe
208 picked = draw(strata, want, random.Random(args.seed))
209 batches = batch(picked, args.per_probe)
210 coverage = 100.0 * len(picked) / len(shapes)
211
212 if args.json:
213 json.dump(
214 {
215 "seed": args.seed,
216 "population": len(shapes),
217 "sampled": len(picked),
218 "coverage_pct": round(coverage, 1),
219 "batches": [
220 {"probe": i + 1, "targets": b} for i, b in enumerate(batches)
221 ],
222 },
223 sys.stdout,
224 indent=1,
225 )
226 print()
227 return 0
228
229 print(f"seed {args.seed}: {len(picked)} shapes of {len(shapes)} ({coverage:.1f}%), "
230 f"{len(batches)} probes")
231 for i, b in enumerate(batches, 1):
232 print(f"\nprobe {i}")
233 for s in b:
234 print(f" {s['file']}:{s['line']} {s['fn']} -> {s['returns']} ({s['lines']} lines)")
235 return 0
236
237
238 if __name__ == "__main__":
239 raise SystemExit(main())
240