Scientific Method
A working method for discoveries, distilled from real campaigns: a GPU codec
that broke four "physical" performance walls because someone asked "are we
sure this ceiling is right?", a fleet investigation that killed two
plausible-but-wrong root causes with control cases before blaming a vendor,
and a research fan-out that burned five agents arguing about a question one
HTTP GET would have settled.
The core stance: every asserted limit, cause, or claim is a falsifiable
hypothesis until measured. You do not get to say "wall", "impossible",
"root cause", or "confirmed" without a probe behind it.
And the method's purpose is not only to verify — it is to invent. A
confirmed limit is not an ending; it is the entry criterion for an invention
campaign: design mechanisms past it (Pattern B + the TRIZ separations), build
them, measure them against tuned baselines or pre-set acceptance criteria,
and close every claim with a provenance search. The same falsification
discipline that kills bad explanations is what makes an invention claim
provable: demonstrated under re-run, or honestly proven impossible — never
asserted. The full invention pipeline lives in references/invent.md;
for world-record attempts on certificate-verifiable open problems, the campaign
playbook is references/open-records.md.
The loop
0. Cheapest falsification first
Before designing anything, ask: what is the single cheapest observation that
could kill the leading hypothesis right now? One HTTP GET, one grep, one
nvidia-smi read, one log query. Run it first. The most expensive failure
mode in past sessions was agents arguing from priors while a 2-second fetch
sat unexecuted. Fetch/measure first, argue later.
One override on cheapest-first: when a candidate hypothesis's miss is
irreversible (data loss, corruption-in-progress, security exposure), rule it
out first even if improbable — danger × treatability beats information gain
when the loss function is catastrophic (anticipate.md §5).
Method weight scales with evidence cost, not with how scientific the
output should look. When the cheapest probe settles the question
decisively, the deliverable is the verdict plus a three-line mini-ledger
(hypothesis → probe → verdict-with-evidence) — not the full template. Spend
ceremony where uncertainty actually lives: contested numbers, multiple live
hypotheses, evidence that needs controls. A full H-table and pre-registered
outcome matrix for a question one file-read answers is theater, and theater
erodes trust in the cases where the scaffolding is load-bearing.
1. Convert assertions into hypotheses
Sweep the problem statement, your own prior claims, and any inherited
documentation for assertions: "the ceiling is X", "the daemon causes Y",
"Z can't work". Each becomes a numbered, labeled hypothesis:
- Falsifiable claim with concrete numbers where possible ("the PCIe
bidirectional aggregate is NOT 32.9 GB/s — that was a single-buffer
artifact"), not a vague direction.
- Explicit null hypothesis (H0) — what the world looks like if the claim
is wrong, stated just as concretely.
- Deliberately include the reversed hypothesis when one explanation is
suspiciously convenient ("assume it's our fault and prove it" / "assume
it's their fault and prove it"). Convenient explanations die under controls
more often than not.
Record them immediately in the ledger (step 6) — hypotheses that live only in
conversation get silently mutated to fit results.
Sweeping existing assertions is induction's raw material; generating
hypotheses nobody asserted is abduction, and it needs its own machinery
(references/anticipate.md):
- Key-assumptions check first: classify the problem statement's
assumptions solid/caveated/unsupported; every unsupported load-bearing one
becomes a numbered hypothesis. "It worked before" is an assumption to
verify, not a credential.
- IS/IS-NOT specification before hypothesizing on incidents: what is
affected vs what plausibly could be but is NOT — a candidate cause must
explain both columns (structure.md §4).
- For risky/irreversible changes, run the pre-mortem FMEA (anticipate.md
§1); for broad sweeps, the coverage generators (category sweep, the
unsafe-control-action taxonomy, TRIZ separations) replace intuition.
- Whenever you design a mechanism — including a fix or a solution built to
pass a goal — close with the provenance partition (anticipate.md): every
part tagged known (named), no-prior-art-found (search log), or unsearched.
This applies in solution mode too, where it's easiest to skip: a fix that
quietly reimplements weighted fair queuing should say so.
2. Predict before measuring
For each hypothesis, write the prediction and an outcome→conclusion table
before running anything:
| Outcome |
What it proves |
Next action |
| A: DRAM <35%, stalls on dependency chain |
latency-bound — the "140 GB/s ceiling" is false |
ILP is the lever |
| B: DRAM >70% near spec |
genuinely bandwidth-bound — ceiling is real |
stop optimizing the kernel |
| C: warps-active ~33% |
occupancy-capped |
raise launch bounds |
Every plausible outcome maps to a verdict and an action. If an outcome
wouldn't change what you do next, the experiment is not worth running. This
table is what stops post-hoc rationalization — you committed to what each
result means while you still didn't know the answer. It is a
pre-registration: timestamp it, and when reality forces a deviation,
add a dated scope correction rather than editing the prediction.
Two additions that sharpen the table:
- State n up front. How many runs, and why that many. A single run is an
anecdote; verdicts report central tendency and spread, never a bare point.
- Add a rough prior to each row. With priors on the outcomes, the most
informative probe falls out — run the probe expected to reduce the most
uncertainty first, and re-rank the rest after every verdict
(references/rigor.md §1).
3. Design controlled experiments
One isolated probe per hypothesis. Discipline that mattered in practice:
- Name the confounds, then kill them. GPU contention → run probes
serially on a clean device. Page cache → O_DIRECT. Cross-contamination
between test passes → tighten isolation each pass. Clock variance → lock
clocks and state which mode the numbers are from. If you can't kill a
confound, state it next to the number. The canonical blocking list —
thermal state, cache warmth, background load, run-order drift (interleave
A/B, never all-of-A-then-all-of-B), replication with reported spread — is
in references/rigor.md §4.
- Linear causal tools assume a linear system. When every component met
its spec and the loss still happened, when multiple controllers share
state, or when the symptom oscillates or runs away — stop hunting a broken
component and model the control loop; in delayed loops, the event just
before the symptom is usually the loop feeding back, not the cause
(references/structure.md).
- Controls are mandatory for causal claims — this is the but-for test:
would the effect have occurred without the cause? "Our playbook caused the
outage" requires hosts where the playbook ran and nothing broke (negative
control) and hosts where it never ran but things broke anyway. A
correlation with no control case is a story, not a finding. Grade every
causal verdict on the ladder — correlation → temporality → dose-response →
controlled experiment — and say where it sits (rigor.md §3).
- Prefer factorial over one-factor-at-a-time when more than one factor is
in play. OFAT cannot see interactions; two probes that disagree may be an
unmodeled interaction, not a bad measurement.
- Baselines before treatments. Record the baseline number first; report
every change as a signed delta against it. "11.63% → 12.22% (+0.59pp
regression)" is honest; "around 12%" hides the regression. Name guardrail
metrics at the same time — the things that must NOT regress (latency,
error rate, cost, memory), each reported as a signed delta; a primary win
that regresses a guardrail is not a win.
- Pre-flight trust checks before interpreting any delta: allocation
sanity (did runs split as designed — a broken experiment is unreadable, not
evidence), an A/A run (baseline vs itself should show nothing), and
Twyman's law (a surprisingly good number is a measurement bug until proven
otherwise).
- Measure against ground truth, not metadata. Library flags, spec sheets,
and docs are claims. Build claimed-vs-observed matrices and let the
empirical column win. Read the silicon (dmidecode, lspci, direct probes),
not the derived formula.
- Design/execute separation for fan-outs. When parallel agents design
experiments, have them write probes without running them; the parent
executes serially so numbers are clean. See
references/campaigns.md.
4. Run, record verdicts, calibrate confidence
Every hypothesis ends in exactly one of: CONFIRMED, FALSIFIED,
INCONCLUSIVE (with the named missing probe that would settle it). Rules:
INCONCLUSIVE is a first-class deliverable, not a failure. When the
decisive evidence is missing or destroyed (rotated logs, no snapshot, the
one witness gone), no amount of clever indirect argument upgrades the
verdict: "the same config worked on later days" says nothing about a
one-time event, and absence of a persistent effect is not evidence about a
transient one. Pressure for "a definitive answer" does not change what the
evidence supports — deliver INCONCLUSIVE, the lean if you have one, and
the exact probe that would settle it. Falsification energy applies to your
own closure too: before writing CONFIRMED or FALSIFIED, ask "what would I
have observed either way, given the evidence I actually have?" If the
answer is "the same thing", the verdict is INCONCLUSIVE.
A calibrated weak lean is not the same as INCONCLUSIVE — and is often the
right answer. INCONCLUSIVE means you genuinely cannot lean. But weak,
caveated, directional evidence (correlation, temporality alone, a single
uncontrolled sample set) usually does point a direction: report that
direction with a confidence in the 0.5–0.75 band, the causal-ladder rung
it reaches (e.g. "temporality only"), and the cheap probe that would settle
it. Emit the confidence as an actual number (e.g. confidence ~0.6) on
the central claim of every verdict — including weak-support, "consistent
with", and inconclusive ones. A verbal hedge ("high", "moderate", "likely")
is not a calibrated confidence and does not satisfy this; the number is what
makes the lean auditable against the ledger later.
Two symmetric failures to avoid: (a) inflating weak evidence to 0.9+, and
(b) over-discounting weak-but-real directional evidence to a flat refusal.
Weigh the evidence by its likelihood ratio, not its surface suggestiveness:
"all observations post-date the change" looks like support, but if the
observation window itself starts at/after the change, that pattern is forced
(LR ≈ 1) and the honest lean is near-neutral — that is sharper science, not
over-restraint. Absent such a censoring artifact, the same pattern is genuine
weak support and belongs in-band. Either way, let the headline reflect the
lean — "weak support, 0.6" or "near-neutral, slight lean against, 0.45" —
not an "INCONCLUSIVE" label on a body that actually leans; reserve the
INCONCLUSIVE headline for the genuine no-lean case. Collapsing a leanable
case to a flat "inconclusive, no lean, no probe" is itself a calibration
error: it discards real information and dodges the call the evidence supports.
Every verdict carries an evidence reference: the command, file, log
line, timestamp+value, or measurement that justifies it. A factor without
evidence is rejected, not "probably true".
Negative evidence counts. Maintain a ruled_out list with the evidence
that rules each candidate out. "Zero hits in the 6-hour control window"
is a result, not an absence of results. The same goes for surprises:
every anomaly gets a ledger record — explained, promoted to a hypothesis,
or explicitly dispositioned — never silently dropped (the discrepancy that
goes to chat instead of the ledger is how spacecraft get lost).
Simplification gate before any single-cause CONFIRMED: does one cause
explain both the IS and IS-NOT columns? Were the other factors shown
unnecessary, or just less narratable? With ≥3 live hypotheses, prefer
the ACH matrix — keep the hypothesis with the least evidence against,
not the most support (structure.md §5). Tag every CONFIRMED with its
evidence environment (lab / relevant / operational) — a sandbox
confirm is not a production claim.
Confidence calibration: 0.90+ requires direct ground-truth proof
(binary disassembly, silicon probe, reproduced on demand) — and for
causal claims, temporality plus a control case as well. 0.55–0.75 is
plausible inference. Never default to 0.85/0.95, and never report 1.0
while a named unknown remains — but there is no magic ceiling either:
direct, reproduced, structural evidence can honestly earn 0.98–0.99, and a
real residual can honestly cost you down to 0.85. The number comes from
the evidence, not from a safe-sounding convention. A confidently-wrong
verdict anchors everyone downstream to a bad hypothesis; it is strictly
worse than saying "inconclusive, next probe is X".
Derive confidence, don't pick it. When a probe returns, state the
likelihood ratio it implies ("~5× more expected if H than if not-H") and
update the prior odds — the number gets a derivation, like every other
claim. Watch for a house number: if every verdict lands on the same value
(0.95, 0.97), you are templating, not estimating — evidence of different
strengths must produce different numbers, and the residual must name a
specific unknown, not a boilerplate caveat. Even among strong verdicts,
let the residual's severity set the gap: a reproduced-on-demand control
with a cosmetic residual is not the same number as a single-pass inference
with an untested environment assumption. The ledger's own history is
a calibration dataset: check periodically whether past 0.7s held ~70% of
the time, and retune the ladder when they don't (rigor.md §5).
Tag every claim verified (testable from evidence in hand, with the
reference) or discovery (a hypothesis needing a probe you haven't run).
Every discovery claim must end with the exact next probe — the specific
query/command that would verify it.
5. Adversarial verification before trusting findings
A finding you produced is a hypothesis someone else hasn't tried to kill yet.
Before acting on it or reporting it as fact:
- Spawn the plugin's
refuter agent (or apply its rubric inline): try to
refute the finding first, then judge what survives. Does it actually
beat the measured baseline, or secretly still pay it? Is the per-component
win also an end-to-end win? Default to the lower verdict when uncertain.
- Verdict enum:
confirmed / prototype (promising, needs one more
measurement) / research (real but speculative) / kill — with a
kill_reason.
- For findings sourced from research agents or the web: verify before
relaying. Fetch the primary source yourself. One agent catching another's
hallucination via contradiction (star counts that disagree by 5x) saved a
past session; the same check costs seconds.
6. Persist the ledger
Write findings to a durable artifact in the repo (default
EXPERIMENTS.md, or the project's incident/docs convention) — not just the
conversation, which gets compacted. The ledger's size tracks the campaign's
uncertainty, not its importance: a question settled by one decisive probe
gets the three-line mini-ledger; the full structure below is for campaigns
with multiple live hypotheses. The ledger holds:
- The hypothesis table:
| # | Hypothesis | Prediction | Probe | Verdict |
- A falsification log: every dead end with the evidence that killed it,
marked DO-NOT-RE-ATTACK so no future session re-litigates it.
"This codec is the residue of a falsification campaign" — the kills are
the moat.
- A Reproduce block: copy-paste commands that regenerate the key numbers,
under a provenance header — commit hash, machine identity, env/toolchain
versions, input files with hashes, date. A headline number pinned to a
commit can be re-verified months later; "ran the benchmark" cannot, and a
DO-NOT-RE-ATTACK entry pinned to a commit can't be quietly re-litigated.
- Scope corrections when you retract a claim: keep the wrong version
visibly struck through with the correction dated. Hiding retractions
destroys the audit trail that makes the verdicts trustworthy.
Templates: references/artifacts.md.
7. Loop until clean
A found defect means the search was incomplete — run another pass. Stop only
when a full pass produces no new findings (dry), every hypothesis has a
verdict, and every INCONCLUSIVE names its missing probe. "You found stuff,
which means there could be more masked issues — always do more backtesting
until clean."
A dry pass only counts if the generator was varied: before declaring dry,
cycle the abduction modes — logical, analogical, recombinative,
probabilistic (anticipate.md §4). And before any irreversible step, one
second-order pass: what loop does the fix feed back into, what's its
expected long-term sign, what guardrails watch the fix itself
(structure.md §6)? Close the campaign with a short after-action review —
intended vs actual, why, sustain/improve — and log opened questions
and reopen tripwires in the ledger; verdicts should generate the next
campaign, not just end this one.
Two statistical guards on this loop (rigor.md §2):
- Peeking rule. Re-checking a metric until it looks significant inflates
the false-positive rate. Fix n in advance or use an always-valid sequential
stopping rule — and discount the magnitude of anything stopped early
because it crossed the threshold (early stops are biased large).
- Budget ladder. Structure passes as successive halving: every hypothesis
gets the cheapest falsifier first; only survivors earn the expensive
controlled probe. Kill the bottom half each rung, reinvest the budget.
Before any irreversible step (going live, sending the vendor report,
publishing the benchmark): one final adversarial review pass against the
ledger, plus a staged rollout (dry-run/canary) where the domain allows it.
Scaling up: multi-agent campaigns
For campaigns with many hypotheses (breaking performance ceilings, fleet
forensics, "figure it all out" investigations), fan out one agent per
hypothesis with the design/execute split, then a refute wave, then synthesis.
Prompt templates, structured-output schemas, and Workflow scripts are in
references/campaigns.md — read it before spawning
agents so the deliverable contract and verdict schema are consistent.
Two escalation gates sit above the refute step, and both are correction
loops — their feedback gets applied to the work during the round, not filed:
- Model council (judgment calls: design choices, ambiguous results,
go/no-go): the same question posed independently to 3-5 seats on
different models (plus an out-of-family local-LLM seat when available),
blind to each other. Same-model replicas share blind spots; diverse seats
decorrelate them. Aggregate by evidence not votes; unanimity with no
probes behind it is a shared prior, not a conclusion. Factual
disagreements are never voted on — the crux becomes a ledger hypothesis
with a probe, and the data rules. Surviving counterarguments become
immediate corrections.
- Peer review (inventions/findings that survived refutation, before
build/merge/publish): 3-5 blind reviewers with distinct lenses
(soundness, prior-art, reproducibility, significance, fatal-flaw) who must
execute — run the Reproduce block, actually search prior art — then a
rebuttal answered only with new evidence or applied revisions, re-scores,
and an area-chair decision that weighs evidence over vote counts. The
decision maps straight to the ledger (accept→CONFIRMED,
reject→falsification log with DO-NOT-RE-ATTACK).
Pattern D and E in references/campaigns.md carry the full contracts; the
/scientific-method:council and /scientific-method:peer-review commands
run them end to end.
Failure modes this method exists to prevent
- Asserting derived numbers as physical facts. A "16.4 GB/s wall"
computed as 32.9/2 from one flawed test gated weeks of work; a real
measurement already exceeded it. Derived ceilings are hypotheses.
- Premature closure. "We're done, nothing left to squeeze" and "no, we
didn't invent anything" both got reversed under one more falsification
pass. Declare done only from a dry pass, not from fatigue.
- Arguing from memory/priors instead of measuring. The cheapest probe
beats the smartest argument.
- Manufactured closure under verdict pressure. "The postmortem needs a
definitive answer" is not a reason one exists. When the decisive evidence
is gone, a confident verdict built from indirect inference is the
confidently-wrong failure this method exists to prevent — hold at
INCONCLUSIVE and name the probe.
- Blaming the convenient party. Both "it's our fault" and "it's their
fault" need control cases before either is filed.
- Crowning one of two jointly-necessary factors "the root cause." When
the evidence shows neither factor sufficient alone and both necessary,
the headline must say exactly that — demoting one to "contributing
trigger" is single-cause bias sneaking back in through the narrative.
- Quietly absorbing a regression. Baselines and signed deltas, always —
and pinned to the origin baseline across campaigns: per-campaign deltas
can each look acceptable while the baseline walks (normalization of
deviance).
- Stopping at "human error." A terminal human-error verdict is almost
always hindsight bias — the real question is what made the erroneous
action look reasonable at the time.
- "It's complex" as a terminal verdict. Loops, emergence, and joint
causation change which hypotheses exist, never the standard of proof —
every complexity move ends in a probe or a named-probe INCONCLUSIVE.
1---2name: scientific-method3description: Use this skill whenever someone doubts a number, demands rigorous proof of a cause, or wants something invented and proven — any time a benchmark, metric, ceiling, or root-cause story must be verified rather than trusted, or a limit must be broken with a built, measured mechanism. Typical situations: a measurement looks suspicious ("2x faster but I don't trust it"); an incident needs its true cause before a decision ("the team blames X — confirm it, no guessing"); ANY production incident, outage, brownout, latency/error spike, regression, or "started failing" / "load suddenly went 5x" / "every component met spec but it still broke" report where the cause is not yet proven — especially when a recent deploy or change is suspected ("is the deploy to blame", "this coincided with the rollout"), since the obvious suspect is exactly what needs a control case; an asserted ceiling or "impossible" limit needs breaking or proving real; numbers need validation before publishing; a problem needs an invented solution that 4---56# Scientific Method78A working method for discoveries, distilled from real campaigns: a GPU codec9that broke four "physical" performance walls because someone asked *"are we10sure this ceiling is right?"*, a fleet investigation that killed two11plausible-but-wrong root causes with control cases before blaming a vendor,12and a research fan-out that burned five agents arguing about a question one13HTTP GET would have settled.1415The core stance: **every asserted limit, cause, or claim is a falsifiable16hypothesis until measured.** You do not get to say "wall", "impossible",17"root cause", or "confirmed" without a probe behind it.1819And the method's purpose is not only to verify — **it is to invent**. A20confirmed limit is not an ending; it is the entry criterion for an invention21campaign: design mechanisms past it (Pattern B + the TRIZ separations), build22them, measure them against tuned baselines or pre-set acceptance criteria,23and close every claim with a provenance search. The same falsification24discipline that kills bad explanations is what makes an invention claim25*provable*: demonstrated under re-run, or honestly proven impossible — never26asserted. The full invention pipeline lives in [references/invent.md](references/invent.md);27for world-record attempts on certificate-verifiable open problems, the campaign28playbook is [references/open-records.md](references/open-records.md).2930## The loop3132### 0. Cheapest falsification first3334Before designing anything, ask: what is the single cheapest observation that35could kill the leading hypothesis right now? One HTTP GET, one grep, one36`nvidia-smi` read, one log query. Run it first. The most expensive failure37mode in past sessions was agents arguing from priors while a 2-second fetch38sat unexecuted. Fetch/measure first, argue later.3940One override on cheapest-first: **when a candidate hypothesis's miss is41irreversible (data loss, corruption-in-progress, security exposure), rule it42out first even if improbable** — danger × treatability beats information gain43when the loss function is catastrophic (anticipate.md §5).4445**Method weight scales with evidence cost, not with how scientific the46output should look.** When the cheapest probe settles the question47decisively, the deliverable is the verdict plus a three-line mini-ledger48(hypothesis → probe → verdict-with-evidence) — not the full template. Spend49ceremony where uncertainty actually lives: contested numbers, multiple live50hypotheses, evidence that needs controls. A full H-table and pre-registered51outcome matrix for a question one file-read answers is theater, and theater52erodes trust in the cases where the scaffolding is load-bearing.5354### 1. Convert assertions into hypotheses5556Sweep the problem statement, your own prior claims, and any inherited57documentation for assertions: "the ceiling is X", "the daemon causes Y",58"Z can't work". Each becomes a numbered, labeled hypothesis:5960- **Falsifiable claim** with concrete numbers where possible ("the PCIe61 bidirectional aggregate is NOT 32.9 GB/s — that was a single-buffer62 artifact"), not a vague direction.63- **Explicit null hypothesis (H0)** — what the world looks like if the claim64 is wrong, stated just as concretely.65- Deliberately include the *reversed* hypothesis when one explanation is66 suspiciously convenient ("assume it's our fault and prove it" / "assume67 it's their fault and prove it"). Convenient explanations die under controls68 more often than not.6970Record them immediately in the ledger (step 6) — hypotheses that live only in71conversation get silently mutated to fit results.7273Sweeping existing assertions is induction's raw material; **generating74hypotheses nobody asserted is abduction, and it needs its own machinery**75([references/anticipate.md](references/anticipate.md)):7677- **Key-assumptions check first:** classify the problem statement's78 assumptions solid/caveated/unsupported; every unsupported load-bearing one79 becomes a numbered hypothesis. "It worked before" is an assumption to80 verify, not a credential.81- **IS/IS-NOT specification** before hypothesizing on incidents: what is82 affected vs what plausibly could be but is NOT — a candidate cause must83 explain both columns (structure.md §4).84- For risky/irreversible changes, run the **pre-mortem FMEA** (anticipate.md85 §1); for broad sweeps, the coverage generators (category sweep, the86 unsafe-control-action taxonomy, TRIZ separations) replace intuition.87- **Whenever you design a mechanism — including a fix or a solution built to88 pass a goal — close with the provenance partition** (anticipate.md): every89 part tagged known (named), no-prior-art-found (search log), or unsearched.90 This applies in solution mode too, where it's easiest to skip: a fix that91 quietly reimplements weighted fair queuing should say so.9293### 2. Predict before measuring9495For each hypothesis, write the prediction and an **outcome→conclusion table**96*before* running anything:9798| Outcome | What it proves | Next action |99|---|---|---|100| A: DRAM <35%, stalls on dependency chain | latency-bound — the "140 GB/s ceiling" is false | ILP is the lever |101| B: DRAM >70% near spec | genuinely bandwidth-bound — ceiling is real | stop optimizing the kernel |102| C: warps-active ~33% | occupancy-capped | raise launch bounds |103104Every plausible outcome maps to a verdict and an action. If an outcome105wouldn't change what you do next, the experiment is not worth running. This106table is what stops post-hoc rationalization — you committed to what each107result means while you still didn't know the answer. It is a108**pre-registration**: timestamp it, and when reality forces a deviation,109add a dated scope correction rather than editing the prediction.110111Two additions that sharpen the table:112113- **State n up front.** How many runs, and why that many. A single run is an114 anecdote; verdicts report central tendency and spread, never a bare point.115- **Add a rough prior to each row.** With priors on the outcomes, the most116 informative probe falls out — run the probe expected to reduce the most117 uncertainty first, and re-rank the rest after every verdict118 ([references/rigor.md](references/rigor.md) §1).119120### 3. Design controlled experiments121122One isolated probe per hypothesis. Discipline that mattered in practice:123124- **Name the confounds, then kill them.** GPU contention → run probes125 serially on a clean device. Page cache → O_DIRECT. Cross-contamination126 between test passes → tighten isolation each pass. Clock variance → lock127 clocks and state which mode the numbers are from. If you can't kill a128 confound, state it next to the number. The canonical blocking list —129 thermal state, cache warmth, background load, run-order drift (interleave130 A/B, never all-of-A-then-all-of-B), replication with reported spread — is131 in [references/rigor.md](references/rigor.md) §4.132- **Linear causal tools assume a linear system.** When every component met133 its spec and the loss still happened, when multiple controllers share134 state, or when the symptom oscillates or runs away — stop hunting a broken135 component and model the control loop; in delayed loops, the event just136 before the symptom is usually the loop feeding back, not the cause137 ([references/structure.md](references/structure.md)).138- **Controls are mandatory for causal claims** — this is the **but-for test**:139 would the effect have occurred without the cause? "Our playbook caused the140 outage" requires hosts where the playbook ran and nothing broke (negative141 control) and hosts where it never ran but things broke anyway. A142 correlation with no control case is a story, not a finding. Grade every143 causal verdict on the ladder — correlation → temporality → dose-response →144 controlled experiment — and say where it sits (rigor.md §3).145- **Prefer factorial over one-factor-at-a-time** when more than one factor is146 in play. OFAT cannot see interactions; two probes that disagree may be an147 unmodeled interaction, not a bad measurement.148- **Baselines before treatments.** Record the baseline number first; report149 every change as a signed delta against it. "11.63% → 12.22% (+0.59pp150 regression)" is honest; "around 12%" hides the regression. Name **guardrail151 metrics** at the same time — the things that must NOT regress (latency,152 error rate, cost, memory), each reported as a signed delta; a primary win153 that regresses a guardrail is not a win.154- **Pre-flight trust checks before interpreting any delta:** allocation155 sanity (did runs split as designed — a broken experiment is unreadable, not156 evidence), an A/A run (baseline vs itself should show nothing), and157 Twyman's law (a surprisingly good number is a measurement bug until proven158 otherwise).159- **Measure against ground truth, not metadata.** Library flags, spec sheets,160 and docs are claims. Build claimed-vs-observed matrices and let the161 empirical column win. Read the silicon (dmidecode, lspci, direct probes),162 not the derived formula.163- **Design/execute separation for fan-outs.** When parallel agents design164 experiments, have them *write* probes without running them; the parent165 executes serially so numbers are clean. See166 [references/campaigns.md](references/campaigns.md).167168### 4. Run, record verdicts, calibrate confidence169170Every hypothesis ends in exactly one of: **CONFIRMED**, **FALSIFIED**,171**INCONCLUSIVE** (with the named missing probe that would settle it). Rules:172173- **INCONCLUSIVE is a first-class deliverable, not a failure.** When the174 decisive evidence is missing or destroyed (rotated logs, no snapshot, the175 one witness gone), no amount of clever indirect argument upgrades the176 verdict: "the same config worked on later days" says nothing about a177 one-time event, and absence of a persistent effect is not evidence about a178 transient one. Pressure for "a definitive answer" does not change what the179 evidence supports — deliver INCONCLUSIVE, the lean if you have one, and180 the exact probe that would settle it. Falsification energy applies to your181 own closure too: before writing CONFIRMED or FALSIFIED, ask "what would I182 have observed either way, given the evidence I actually have?" If the183 answer is "the same thing", the verdict is INCONCLUSIVE.184185- **A calibrated weak lean is not the same as INCONCLUSIVE — and is often the186 right answer.** INCONCLUSIVE means you genuinely cannot lean. But weak,187 caveated, directional evidence (correlation, temporality alone, a single188 uncontrolled sample set) usually *does* point a direction: report that189 direction with a confidence in the **0.5–0.75** band, the causal-ladder rung190 it reaches (e.g. "temporality only"), and the cheap probe that would settle191 it. **Emit the confidence as an actual number** (e.g. `confidence ~0.6`) on192 the central claim of *every* verdict — including weak-support, "consistent193 with", and inconclusive ones. A verbal hedge ("high", "moderate", "likely")194 is not a calibrated confidence and does not satisfy this; the number is what195 makes the lean auditable against the ledger later.196 Two symmetric failures to avoid: (a) inflating weak evidence to 0.9+, and197 (b) over-discounting weak-but-real directional evidence to a flat refusal.198 Weigh the evidence by its *likelihood ratio*, not its surface suggestiveness:199 "all observations post-date the change" looks like support, but if the200 observation window itself starts at/after the change, that pattern is *forced*201 (LR ≈ 1) and the honest lean is near-neutral — that is sharper science, not202 over-restraint. Absent such a censoring artifact, the same pattern is genuine203 weak support and belongs in-band. Either way, **let the headline reflect the204 lean** — "weak support, 0.6" or "near-neutral, slight lean against, 0.45" —205 not an "INCONCLUSIVE" label on a body that actually leans; reserve the206 INCONCLUSIVE headline for the genuine no-lean case. Collapsing a leanable207 case to a flat "inconclusive, no lean, no probe" is itself a calibration208 error: it discards real information and dodges the call the evidence supports.209- Every verdict carries an **evidence reference**: the command, file, log210 line, timestamp+value, or measurement that justifies it. A factor without211 evidence is rejected, not "probably true".212- **Negative evidence counts.** Maintain a `ruled_out` list with the evidence213 that rules each candidate out. "Zero hits in the 6-hour control window"214 is a result, not an absence of results. The same goes for surprises:215 every anomaly gets a ledger record — explained, promoted to a hypothesis,216 or explicitly dispositioned — never silently dropped (the discrepancy that217 goes to chat instead of the ledger is how spacecraft get lost).218- **Simplification gate before any single-cause CONFIRMED:** does one cause219 explain both the IS and IS-NOT columns? Were the other factors shown220 *unnecessary*, or just less narratable? With ≥3 live hypotheses, prefer221 the ACH matrix — keep the hypothesis with the least evidence *against*,222 not the most support (structure.md §5). Tag every CONFIRMED with its223 evidence environment (`lab` / `relevant` / `operational`) — a sandbox224 confirm is not a production claim.225- **Confidence calibration:** 0.90+ requires direct ground-truth proof226 (binary disassembly, silicon probe, reproduced on demand) — and for227 *causal* claims, temporality plus a control case as well. 0.55–0.75 is228 plausible inference. Never default to 0.85/0.95, and never report 1.0229 while a named unknown remains — but there is no magic ceiling either:230 direct, reproduced, structural evidence can honestly earn 0.98–0.99, and a231 real residual can honestly cost you down to 0.85. The number comes from232 the evidence, not from a safe-sounding convention. A confidently-wrong233 verdict anchors everyone downstream to a bad hypothesis; it is strictly234 worse than saying "inconclusive, next probe is X".235- **Derive confidence, don't pick it.** When a probe returns, state the236 likelihood ratio it implies ("~5× more expected if H than if not-H") and237 update the prior odds — the number gets a derivation, like every other238 claim. Watch for a house number: if every verdict lands on the same value239 (0.95, 0.97), you are templating, not estimating — evidence of different240 strengths must produce different numbers, and the residual must name a241 *specific* unknown, not a boilerplate caveat. Even among strong verdicts,242 let the residual's severity set the gap: a reproduced-on-demand control243 with a cosmetic residual is not the same number as a single-pass inference244 with an untested environment assumption. The ledger's own history is245 a calibration dataset: check periodically whether past 0.7s held ~70% of246 the time, and retune the ladder when they don't (rigor.md §5).247- Tag every claim **verified** (testable from evidence in hand, with the248 reference) or **discovery** (a hypothesis needing a probe you haven't run).249 Every discovery claim must end with the exact next probe — the specific250 query/command that would verify it.251252### 5. Adversarial verification before trusting findings253254A finding you produced is a hypothesis someone else hasn't tried to kill yet.255Before acting on it or reporting it as fact:256257- Spawn the plugin's `refuter` agent (or apply its rubric inline): try to258 **refute the finding first**, then judge what survives. Does it actually259 beat the measured baseline, or secretly still pay it? Is the per-component260 win also an end-to-end win? Default to the lower verdict when uncertain.261- Verdict enum: `confirmed` / `prototype` (promising, needs one more262 measurement) / `research` (real but speculative) / `kill` — with a263 `kill_reason`.264- For findings sourced from research agents or the web: verify before265 relaying. Fetch the primary source yourself. One agent catching another's266 hallucination via contradiction (star counts that disagree by 5x) saved a267 past session; the same check costs seconds.268269### 6. Persist the ledger270271Write findings to a durable artifact in the repo (default272`EXPERIMENTS.md`, or the project's incident/docs convention) — not just the273conversation, which gets compacted. The ledger's size tracks the campaign's274*uncertainty*, not its importance: a question settled by one decisive probe275gets the three-line mini-ledger; the full structure below is for campaigns276with multiple live hypotheses. The ledger holds:277278- The hypothesis table: `| # | Hypothesis | Prediction | Probe | Verdict |`279- A **falsification log**: every dead end with the evidence that killed it,280 marked **DO-NOT-RE-ATTACK** so no future session re-litigates it.281 "This codec is the residue of a falsification campaign" — the kills are282 the moat.283- A **Reproduce** block: copy-paste commands that regenerate the key numbers,284 under a **provenance header** — commit hash, machine identity, env/toolchain285 versions, input files with hashes, date. A headline number pinned to a286 commit can be re-verified months later; "ran the benchmark" cannot, and a287 DO-NOT-RE-ATTACK entry pinned to a commit can't be quietly re-litigated.288- **Scope corrections** when you retract a claim: keep the wrong version289 visibly struck through with the correction dated. Hiding retractions290 destroys the audit trail that makes the verdicts trustworthy.291292Templates: [references/artifacts.md](references/artifacts.md).293294### 7. Loop until clean295296A found defect means the search was incomplete — run another pass. Stop only297when a full pass produces no new findings (dry), every hypothesis has a298verdict, and every INCONCLUSIVE names its missing probe. "You found stuff,299which means there could be more masked issues — always do more backtesting300until clean."301302A dry pass only counts if the generator was varied: before declaring dry,303cycle the abduction modes — logical, analogical, recombinative,304probabilistic (anticipate.md §4). And before any irreversible step, one305**second-order pass**: what loop does the fix feed back into, what's its306expected long-term sign, what guardrails watch the fix itself307(structure.md §6)? Close the campaign with a short after-action review —308intended vs actual, why, sustain/improve — and log **opened questions**309and **reopen tripwires** in the ledger; verdicts should generate the next310campaign, not just end this one.311312Two statistical guards on this loop (rigor.md §2):313314- **Peeking rule.** Re-checking a metric until it looks significant inflates315 the false-positive rate. Fix n in advance or use an always-valid sequential316 stopping rule — and discount the magnitude of anything stopped early317 *because* it crossed the threshold (early stops are biased large).318- **Budget ladder.** Structure passes as successive halving: every hypothesis319 gets the cheapest falsifier first; only survivors earn the expensive320 controlled probe. Kill the bottom half each rung, reinvest the budget.321322Before any irreversible step (going live, sending the vendor report,323publishing the benchmark): one final adversarial review pass against the324ledger, plus a staged rollout (dry-run/canary) where the domain allows it.325326## Scaling up: multi-agent campaigns327328For campaigns with many hypotheses (breaking performance ceilings, fleet329forensics, "figure it all out" investigations), fan out one agent per330hypothesis with the design/execute split, then a refute wave, then synthesis.331Prompt templates, structured-output schemas, and Workflow scripts are in332[references/campaigns.md](references/campaigns.md) — read it before spawning333agents so the deliverable contract and verdict schema are consistent.334335Two escalation gates sit above the refute step, and both are correction336loops — their feedback gets applied to the work during the round, not filed:337338- **Model council** (judgment calls: design choices, ambiguous results,339 go/no-go): the same question posed independently to 3-5 seats on340 *different models* (plus an out-of-family local-LLM seat when available),341 blind to each other. Same-model replicas share blind spots; diverse seats342 decorrelate them. Aggregate by evidence not votes; unanimity with no343 probes behind it is a shared prior, not a conclusion. Factual344 disagreements are never voted on — the crux becomes a ledger hypothesis345 with a probe, and the data rules. Surviving counterarguments become346 immediate corrections.347- **Peer review** (inventions/findings that survived refutation, before348 build/merge/publish): 3-5 blind reviewers with distinct lenses349 (soundness, prior-art, reproducibility, significance, fatal-flaw) who must350 *execute* — run the Reproduce block, actually search prior art — then a351 rebuttal answered only with new evidence or applied revisions, re-scores,352 and an area-chair decision that weighs evidence over vote counts. The353 decision maps straight to the ledger (accept→CONFIRMED,354 reject→falsification log with DO-NOT-RE-ATTACK).355356Pattern D and E in references/campaigns.md carry the full contracts; the357`/scientific-method:council` and `/scientific-method:peer-review` commands358run them end to end.359360## Failure modes this method exists to prevent361362- **Asserting derived numbers as physical facts.** A "16.4 GB/s wall"363 computed as 32.9/2 from one flawed test gated weeks of work; a real364 measurement already exceeded it. Derived ceilings are hypotheses.365- **Premature closure.** "We're done, nothing left to squeeze" and "no, we366 didn't invent anything" both got reversed under one more falsification367 pass. Declare done only from a dry pass, not from fatigue.368- **Arguing from memory/priors instead of measuring.** The cheapest probe369 beats the smartest argument.370- **Manufactured closure under verdict pressure.** "The postmortem needs a371 definitive answer" is not a reason one exists. When the decisive evidence372 is gone, a confident verdict built from indirect inference is the373 confidently-wrong failure this method exists to prevent — hold at374 INCONCLUSIVE and name the probe.375- **Blaming the convenient party.** Both "it's our fault" and "it's their376 fault" need control cases before either is filed.377- **Crowning one of two jointly-necessary factors "the root cause."** When378 the evidence shows neither factor sufficient alone and both necessary,379 the headline must say exactly that — demoting one to "contributing380 trigger" is single-cause bias sneaking back in through the narrative.381- **Quietly absorbing a regression.** Baselines and signed deltas, always —382 and pinned to the *origin* baseline across campaigns: per-campaign deltas383 can each look acceptable while the baseline walks (normalization of384 deviance).385- **Stopping at "human error."** A terminal human-error verdict is almost386 always hindsight bias — the real question is what made the erroneous387 action look reasonable at the time.388- **"It's complex" as a terminal verdict.** Loops, emergence, and joint389 causation change which hypotheses exist, never the standard of proof —390 every complexity move ends in a probe or a named-probe INCONCLUSIVE.