---
name: discriminator-question
description: "An assertion both right and wrong code satisfy proves nothing — ask \"what arrangement makes right and wrong answer DIFFERENTLY\" instead of re-reading the test; six instances on 2026-08-01, incl. a vacuous row written into a REQ gate at mint and an argument that only gates WHETHER there is an output"
metadata: 
  node_type: memory
  type: feedback
  originSessionId: b34cabf6-2098-41af-b492-dc8e22aa8675
  modified: 2026-08-03T06:09:52.555Z
---

An assertion that the intended behavior satisfies — but the bug satisfies too — was never evidence. Four instances in one session (HANDRAIL, 2026-08-01):

1. BTreeMap exact-match-wins fixture queried the UPPERCASE key with both spellings present — ASCII uppercase sorts first, so exact-match and scan-first answered identically; only the lowercase query discriminates.
2. Claim-inertness row compared claim-absent vs claim-forged over an AMBIENT store — empty store admits everyone, both sides agreed for an unrelated reason; needed a CONTROLLED store (claimed admitted, proven refused).
3. Delete-source refusal asserted exit-1 — but the invocation failed anyway further along for an unrelated reason (no dialable address); exit codes are SHARED outcomes; assert the refusal outcome itself plus that the same call WITHOUT the flag is not that refusal.
4. (Cousin) uniform-table blindness — [[uniform-table-blindness-sweep]].

5. **The gate clause of a REQUIREMENT, at mint** (DOORBELL W2, 2026-08-01) — doyle ruled a unit row into a REQ text: "a walk over every named site's rendered help asserts no internal code appears." Green-by-default twice: every shipped site is already clean, so it passes even if the walk enumerated ZERO sites, and passes whether or not the predicate can detect a code at all. He named it himself on acceptance — the setup-suppresses-failing-arm class **wearing a gate row**. Repair: pin the enumeration (assert it visited exactly the named set) AND prove the predicate can fail against a fixture carrying the thing. Without the first it proves nothing about coverage; without the second, nothing about detection.

6. **An argument that only changes WHETHER THERE IS AN OUTPUT** (DOORBELL W4, 2643317) — the inert-rule repair set `authority` and `admit_node`, but both are inputs to `apply_mutation`'s PERMISSION check, not to the rule bytes it writes; the widening gate fires only under `OwnerAgent`, so on a fixture where the write succeeds either way, defect and repair emit BYTE-IDENTICAL rules. A discriminator comparing OUTPUTS can never see an argument that only changes whether an output exists. Repair: arrange the answer to DEPEND on the argument — ROW A a policy-FORBIDDEN widening with the ack given (refused under the mint-recorded owner seat, waved through by the node-sovereign seat), ROW B a record saying no ack given; both directions, plus a non-vacuity row (ack given AND policy allowing → redeems/writes/spends) so the refusals are not a verb that refuses everything.

7. **A COVERAGE-STAGE ACTIVATION** (v0.51.0 doc respin, 235fe5a) — activating `doc` on a REQ to guard a page that had drifted unwatched. `traceable-reqs` reports the stage satisfied from ANY tag anywhere in the tree, so if that REQ already carried a `doc->` tag in some other file, the activation goes green while the page it was meant to guard stays exactly as unguarded as before — paperwork wearing a guard's clothes. Discriminator: grep that the new tag is the SOLE evidence for that REQ, then delete that one line and require exit 1. Both halves — sole-source and can-fail — or the activation proves nothing.

8. **EVIDENCE I AUTHORED, while auditing everyone else's instruments** (IR-18, 2026-08-03) — "the daemon wrote NOTHING to stderr, so it was killed; silent death with an empty log is TerminateProcess, not a slow box." hertz's negative arm killed it: on a PASSING run that rig's daemon stderr is empty too, so the observation is present in both arms and carries zero information either way. I had spent the same night refusing other people's absence-proxies (a blind KILL_REFUSED zero, a blanket zero-REFUSED gate) and did not turn the rule on a sentence I was writing into the register — where it reached SIX sites, including a triage instrument telling a future reader to discriminate two entries by it. Tell: an ABSENCE offered as positive evidence, with no negative arm run. Related cousin: a category error rode along — "bare exit 1 and no panic" (a victim TEST PROCESS dying) was mapped onto "empty daemon.stderr.log" (a log), two different processes and two different artifacts read as one observation.

9. **A DISCRIMINATOR THAT READS THE FAILURE PATH'S OWN OUTPUT** (golden r2, FIELD-SEAL, 2026-08-25) — doyle proposed a clean one-grep test for a red: if the strike line `manifest declares no [session.psyche_resume] role` appears in the previous GREEN run too, it is a standing benign diagnostic; if absent, it is new box behaviour and IS the lead. I ran it: absent, 0 occurrences, plus 0 strike lines and 0 bare `psyche_resume` in the whole green log. That reads as a clean decisive answer — and it is worthless, because **that sentence is printed BY the strike path**. A green run takes no strike, so it prints no strike line, whether or not the manifest lacks the role. The probe is confounded with the outcome it is being used to explain, so BOTH hypotheses predict the same reading. The sound version does not read logs at all: the fixture manifest AT SOURCE (`er_brief_once_per_session_e2e.rs:140-147`) declares `[session.self]` + `[session.psyche_init]` and NOT `[session.psyche_resume]`, in a file untouched across the range — so the sentence was equally TRUE in the green run and simply never printed. Hypothesis A, benign, not the lead; I had been leaning the other way and retracted it. **The distinguishing feature from instance 8: there the absence was MY OWN evidence; here it was a PEER'S proposed instrument, arriving with the authority of the person who owns the triage — and a well-formed one-command test is exactly what you execute without auditing.** Tell: before running a peer's discriminator, ask WHICH CODE PATH EMITS the thing being grepped; if only the failing path emits it, absence in a passing run is a tautology, not a measurement.

**Why:** passing is only evidence when failure was reachable; the discriminator question is not answerable by reading the test — it needs the arrangement analyzed against BOTH readings. A "compare the outputs" test is blind to any input that gates whether the output is PRODUCED — check the argument's real consumer (a permission check, an early return) before trusting an equality assertion.

**How to apply:** for every mutation-survival, and for every fixture pinning a precedence/priority/ordering property, ask what arrangement makes the two readings disagree and build THAT. A mutant surviving usually means the test is wrong, not the mutant weak. **Apply the same audit to REQ gate clauses when they are MINTED, not only to the tests that later satisfy them** — a vacuous row written into a requirement is worse than a vacuous test, because it reads as the standard and every later test is measured against it. A row over an "everything is clean" property is the tell. **Turn it on your OWN evidence before writing it into a durable record** — an absence ("nothing in the log", "no lines matched") is never positive evidence until a passing run is checked for the same absence, and a claim in a register propagates into triage instruments where it silently stops discriminating.

Related: [[instrument-soundness-guards]], [[stacked-defects-mask-each-other]].
