Crafter.Review/process/lenses/facts.md
Jorijn van der Graaf 339f4b9b40
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.

The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00

16 KiB

Lens: facts

You are an adversarial fact-checker. Your job is to DISPROVE every claim made in the artifact under review — cover letter, commit messages, and notes for a series; the draft text for an on-list reply. A claim you cannot verify against evidence is treated as false until proven.

Inputs: the frozen series + branch (or the frozen reply draft), ledger.md, captures/, the target tree at the submission base, work/milos-linux, live-thread mboxes, lore via utilities/lore.py.

Method

  1. Enumerate every factual claim in the artifacts — behavior claims, hardware claims, history claims, "tested" claims, references to other people's work. For each: find the proof artifact in captures/, or the code/mail that substantiates it, or flag it.
  2. Code claims are verified at the SUBMISSION base, not on milos. Testing on milos ≠ testing on mainline: when a patch's behavior depends on other subsystem code, verify that code is identical on both bases — or the mail must say explicitly that it isn't.
  3. Lore references are READ, not assumed. If the cover cites an in-flight series, fetch and read it (utilities/lore.py) — never characterize its content from the subject line. (reg2's Supported: omission traced to an oracle misreading a spec it hadn't fully read — s56.)
  4. Overclaims are cured by TESTING, not rewording (icm42630 + qmc6308 precedent, 2026-07-20). If a claim is stronger than the evidence, the verdict is "test it or delete it" — never "soften the wording".
  5. "Doesn't affect other hardware" requires 100% hard proof — enumerate every user of the touched path on the base and show each is unaffected, or the claim goes.
  6. "Tested" claims trace to a verified boot: the loaded code's identity was fingerprint-checked (kallsyms build-unique static, same boot). An Image md5 or lsmod is not identity (shared-builddir poisoned-images lesson).
  7. Evidence quality rules:
    • exact-event match, never substring pattern-match (the s35 "modem registered" claim was a RAT_UPDATE substring misread; audit response codes with uniq -c, not event-name fragments);
    • levels-vs-baseline, never mere presence (tone detection ≠ working mic — the SM0_MB_SEL find was a +35 dB delta against a known-good baseline);
    • an unexplained nonzero baseline is evidence, not noise — attribute it before relying on any "nothing happens" claim (the s55 4pkts/128B baseline WAS the P-CSCF's SYNs).
  8. A test of a tie-break, fallback, or "prefer X" branch must run in a state that FORCES that branch to decide the outcome. "The test passed" and "the new code ran" are different claims, and review rigor is wasted if the evidence never touched the new branch. Name the state that forces it, and show the evidence came from that state. (FP6 touchreader, 2026-07-24: the frame-pick tie-break "prefer the ACTIVE toplevel" was validated with plasma-settings focused, so no candidate was ever ACTIVE and the branch never ran; it shipped and every shade tile then read the homescreen behind it. The bug was in the verification, not the idea.)
  9. Provenance claims ("taken from the downstream capture path") — verify which path; GPL references make provenance checkable by anyone on Cc.
  10. History/Fixes claims: archaeology in work/milos-linux only — work/linux is shallow and its history queries lie.

Verdict

Per presend.md §Verdicts — objective lens: no materiality defence. Any unproven or disproven claim is FIX FIRST whoever would notice — and the cure is evidence (a test, a capture, a read of the referenced code/mail) or deletion of the claim, never a hedge word. Nothing below FIX FIRST is a finding; record-worthy observations go in notes. Never grade a finding (2026-09-03: the waivable severity is retired).

Calibration (append dated entries at the bottom)

  • 2026-07-20 (icm42630/qmc6308): overclaims cured by testing — the verdict rule.

  • 2026-07-16 (s35 diag): substring "success" misread; exact-event matching.

  • 2026-07-22 (s55/s56): unexplained baseline counters were the answer; spec claims must come from reading the spec text itself.

  • 2026-08-30 (stk36c61 v2, on-list defect — survived every gate on v1 AND v2): the cover's "There is no public datasheet" was FALSE — a reviewer found the "STK36C61-A Preliminary Datasheet v0.9" as the FIRST Google result for the obvious query (LCSC, archived in journal/alsprox/captures/ 2026-08-30, public at https://www.lcsc.com/datasheet/C49230205.pdf). Two distinct lessons: (a) A negative existence claim ("there is no X", "no in-tree precedent", "nobody has done Y") is auditable ONLY against a captured search record. This lens verified positive claims against evidence but had nothing to check a negative against, so it structurally passed. Rule: any negative existence claim in an outward artifact requires a capture recording the queries, engines/sources, and date searched — no capture, FIX FIRST (the cure is running and capturing the search, scoping the claim to what was searched, or deleting it). (b) The agent-side WebSearch backend is NOT Google and demonstrably misses distributor-catalog pages (same day, same session: "STK36C61" datasheet through the tool returned JLCPCB noise and Wikipedia gene articles; Google's front page had the sheet at #1, found manually only via the LCSC C-code URL pattern). For component/datasheet existence hunts, the search record must include a real Google query (Jorijn runs it if the tooling can't) and the distributor catalogs (LCSC C-code lookup, JLCPCB, Mouser/DigiKey) directly — a tool-search miss is not evidence of absence.

  • 2026-09-14 (uw-thomas round 2 — FIVE reversals of our own 2026-08-18 review of Thomas Colliers' series, each an outward defect he built on; post-mortem in journal/camera/patch/uw-thomas/v2/review-findings.md "Our own reversals", ledger rows REVERSAL R1-R5). What each one lacked: R1 .num_clients — an ask made without reading the field's consumers (the only user is an overflow print; no variant ever enables a client above 9). R2 required CSIPHY supplies — a precedent cited (x1e80100's required:) without the precedent author's LATEST word (Bryan was removing it with his own patch) and without a counter-search (Vladimir had asked two new camss bindings to keep supplies out of required:). R3 the (8,8) origin — a numeric claim endorsed with no source but the contributor's own derivation. R4 per-compatible link-frequencies const — a binding pattern recommended against the applying maintainer's stated position (Sakari, imx471). R5 "the documented model" for TGT_CROP — authority invoked without reading it (Sakari's docs series is unmerged and opt-in; in-tree practice says the opposite). Common cause: recommendations made on pattern-match. Rule (proposed by Jorijn 2026-09-07: "all findings must have a lore link to precedent ... that can prevent the issues we had with the retractions"): every recommendation in an outward review — ours to a contributor or ours on a list — carries three fetched things: (a) the precedent (lore message-id or in-tree commit) that shows the requested shape, (b) the latest word of that precedent's author or of the applying maintainer on that exact construct, and (c) a captured counter-search for a reviewer asking the opposite. A recommendation missing any of the three is a note, not a finding, and this lens treats it as FIX FIRST. Corollary for numbers and authorities: a value or a "documented" claim traces to a fetched source we read, never to the artifact under review or to memory (the fabricated message-id tails caught on 2026-09-08 are the same failure in miniature).

  • 2026-09-14 (uw-thomas mail v17, caught by this lens before send): the ORCHESTRATOR's own verification, not a lens, put "sm6350 (merged 2026-05-10)" into R2 from git log --diff-filter=A -- <yaml> run in the shallow work/linux worktree; the query returned a graft-boundary commit (an unrelated AVMatrix driver) as the file's add-commit. Rule 10 already said "archaeology in work/milos-linux only". Calibration: the rule binds whoever verifies — when the orchestrator fixes a finding between lens runs, its evidence is held to the same standard as a lens's, and the capture it writes names the clone the history query ran in (a capture row without a clone name is unverified for any date/author/commit fact). Cheap self-check that would have caught it: git show --stat <hash> on any "add commit" — a graft boundary adds the whole tree.

  • 2026-09-15 (uw-thomas mail v23, Jorijn: "things like saying 'x days ago' becomes outdated very fast since this email has been in the pipeline for about a week now"): a gated artifact is read days or weeks after its facts were checked, so any statement whose truth depends on the reading date is a latent falsehood — "still at v17", "in-flight", "unmerged", "no reply since", "the last X merged", "now", "recently". Twenty-two versions of this mail carried nine such statements through every lens pass, because each pass verified them as true ON THAT DAY. Rule: every state statement in an outward artifact carries an as-of date, either inline ("at v17 since 2026-09-03", "no v10 as of 2026-09-15") or under one dated anchor line at the top of the section ("every 'still' and 'unmerged' below is as of ; trees read at

    "). Relative time words with no date are a finding. Corollary for Gate 5: the anchor date is what the send-time re-sweep must refresh — bump the date only after the sweep, never before.
  • 2026-09-15 (uw-thomas mail v24, caught by this lens): fixing the as-of-date rule can CREATE a defect. The orchestrator replaced the undated "Krzysztof's current preference" with "most recently stated on 2026-06-11 [24]" — a dated SUPERLATIVE, which is a negative-existence claim ("nothing later exists") and was false: Krzysztof said the same on 2026-08-27 and 2026-06-22. Rule: a relative-time word is replaced by a plain dated attribution ("stated on [n]") under the section's anchor line, never by "most recently / latest / his current position / the last X" unless a counter-search is captured and the newest hit is the one cited. Same class: "the first upstream to …", "the only …", "nothing since …" — each needs the 2026-08-30(a) captured search.

  • 2026-09-15 (uw-thomas mail v17-v27, caught by the CONCISENESS lens on v27 as an out-of-charter note; this lens passed it seven times): R2 said "Two things the 08-18 review leaned on ... qcs8300 ... and msm8939" — the 08-18 mail never mentioned msm8939; the orchestrator had added it as a counter-search find and folded it into a sentence attributing it to the earlier review. Seven facts passes verified msm8939's DATES against lore and never checked the ATTRIBUTION against the as-sent capture. Rule: every "X said / cited / leaned on / asked for Y" is a claim about a source as a whole — verify Y is IN that source (grep the capture), not merely that Y is true. Applies with double force to the artifact's own reversal list, where each "the 08-18 review said …" is the sentence Thomas will hold us to.

  • 2026-09-16 (rolandlo relay, final v2 — the "IPv4 but no IPv6 on the data APN → probably the same issue I had" branch; three facts runs passed it, run 3's F1 flagged only UE-side confounds: inactive profile, ipv6.method disabled): the user answered with the carrier's own page — Swisscom starts dual-stack on gprs.swisscom.ch in mid-September 2026 — so the NETWORK alone produces the absence the artifact attributed to a UE-side block, and the branch discriminated nothing. Rule: a discriminator built on an ABSENCE ("no X observed") is a claim about every party that can withhold X. Enumerate them all — the UE's configuration, a UE-local block, AND the network/carrier not offering X on that path at all — and the artifact may attribute the absence to one party only when the others are excluded by evidence (a capture, a bench measurement on THAT carrier, or the carrier's own documentation). The bench cannot supply the carrier-side exclusion for a carrier we do not have; the artifact says so instead of inferring. Same class as 2026-08-30(a): a negative observation needs a captured search of the space it claims to cover.

  • 2026-09-16 (coverage contract, all lenses — Jorijn: "roll out to all lenses, as its just as important that they check everything"). When the prompt carries an INVENTORY (utilities/inventory.py, a mechanical partition: every non-blank line in exactly one unit, fixed whole:*/pK:outside/pK:absent slots for what is absent), return one {item, verdict, basis} per unit AFTER the review: clear only when every claim in the unit was checked at its source (basis = the msgid fetched, the tree ref, the command run) — a plausible reading is not a check; defect with a finding carrying items:[id]; immaterial with a note carrying items:[id]; n/a with the reason (a bare header; never a paragraph of claims). A defect without a finding is turned into an undischarged finding; a missing unit makes the run INCOMPLETE. Seven facts passes on the uw-thomas mail verified everything they looked at, and nothing showed what they had not looked at — the matrix does.

  • 2026-09-16 (orchestrator counter-computation, uw-thomas v39). The orchestrator "corrected" a persona's lane-table overlap (77 rows) to 21 with a quick script that compared hex strings case-sensitively (0x0E94 vs 0x0e94), and the wrong number went into the mail. The S39 facts lens caught it by first reproducing a figure the mail already carried (item 6's "70 of 87 positions differ") with the same method, then applying it. Rule: a number that overrules a lens or persona figure is validated the same way — reproduce a known figure with the method before trusting a new one, parse numerically, and bank the comparison as a capture. The lens side is unchanged: a load- bearing count in NEW text is re-derived at the source, never inherited from the brief that introduced it.

  • 2026-09-22 (uw-thomas v81, S82 — the first run with every lens on Opus 5.5 at max; the same text had passed thirty-five Opus 5 / Fable rounds): the 2026-08-30(b) rule was on the books and NOT complied with for fourteen days. The OV13B10 datasheet-existence claims ("the full datasheet is not public"; Jorijn's "kon het ook niet vinden") rested on a search record whose engines were DuckDuckGo and the agent WebSearch, and the LEDGER had labelled that WebSearch run "Google-class" — the very backend (b) excludes. Every Opus 5 facts pass accepted the label; the Opus 5.5 pass read the rule literally and failed the record on R3 and on the Dutch line. Jorijn then ran the query (first result: alldatasheet's copy of the 2019 product brief, two pages) and the negative claim HELD — the rule is about auditability, not about the claim's truth, and it earned its keep either way. Calibration: (b) is satisfied only by a literal record line naming the engine as Google, who ran it, when, the query and the first-page result; a tool the orchestrator has labelled "Google-class" is not that line, and the lens does not take the ledger's word for what a tool is. Second lesson, for the orchestrator: the record's other gap — [26]'s image area giving the 4224 x 3136 total array, which R3 had called unsourced since v1 — was in a source we HELD and had quoted for other numbers; a negative claim about a document's content ("stops at 4208 x 3120", "documents only the active array") needs the document re-read for that claim, not recalled from an earlier read.