rigorous-data-audit
Skill20 starsChanged 41 days agoMITView on GitHub
Use when: audit X, revisa a fondo, release-safe?, esto puede romper progresión, data loss, OnStoreSave/OnStoreLoad. Persistence/state-machine pre-release audit. Not cosmetic/UI: dayz-ui-development; not output-discipline: pre-output-discipline.
In this repository47 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- 3d-generation-harnessSkill
- ai-3d-to-dayzSkill
- ardy-motion-generationSkill
- blender-animationSkill
- blender-assemblySkill
- blender-visual-reviewSkill
- dayz-3d-viewerSkill
- dayz-ai-patternsSkill
- dayz-animation-pipelineSkill
- dayz-aviationSkill
- dayz-basebuildingSkill
- dayz-charactersSkill
- dayz-clothingSkill
- dayz-doorsSkill
- dayz-environment-hazardsSkill
- dayz-feature-specSkill
- dayz-mcp-verifySkill
- dayz-model-pipelineSkill
- dayz-mod-workflowSkill
- dayz-motorbikesSkill
- dayz-p3d-auditSkill
- dayz-p3d-inspectorSkill
- dayz-particlesSkill
- dayz-pbo-buildSkill
- dayz-pbo-reverse-engineeringSkill
- dayz-persistenceSkill
- dayz-physics-engineSkill
- dayz-preflightSkill
- dayz-proxy-alignSkill
- dayz-realistic-animation-directorSkill
- dayz-sound-systemSkill
- dayz-test-ingameSkill
- dayz-texture-pipelineSkill
- dayz-ui-developmentSkill
- dayz-undergroundSkill
- dayz-vehiclesSkill
- dayz-weaponsSkill
- enforce-script-referenceSkill
- mixamo-retargetSkill
- ovh-cloudSkill
- rip-vehicle-importSkill
- systematic-debuggingSkill
- task-observerSkill
- uv-clean-atlasSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
24 rules. About 0 are common, 21 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈21
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 20
Read references/why-this-skill-exists.md for the full retrospective if you want the original case study.
- Distinctive: line 33
If the change is cosmetic or UI-only, this skill is overkill — skip it.
- Distinctive: line 81
Run before spawning any agents.
- Distinctive: line 115
Use one reviewer for a bounded audit.
- Distinctive: line 159
3b — Independent verifier pass: When an independent pass is assigned, use a reviewer from another family with a fresh context that has not …
- Distinctive: line 161
If it is unavailable, declare that limitation.
- Distinctive: line 176
3c — 20% self-sample gate: Before trusting the consolidated table, pick 20% of the findings at random and verify them yourself by opening …
- Distinctive: line 178
If more than 10% of the sample is confabulated, the audit is not trustworthy — re-run step 2 with stricter prompts, or discard it.
- Distinctive: line 218
If this agent finds nothing, that is the signal that the audit is converging.
- Distinctive: line 219
If it finds a defect, reproduce it, classify its impact, and recheck the affected path within the agreed budget.
- Distinctive: line 233
After each fix, re-grep to confirm the bug pattern is gone everywhere (not just at the cited line).
- Distinctive: line 278
All sids on disk after a long session match player intent (no orphans, no ghosts)
- Distinctive: line 369
If any link is broken: the failsafe does not cover that family — a dedicated wrapper hook on the family base (with super + explicit notify) …
- Distinctive: line 389
Add to Step 1 (mechanical pre-checks) whenever the delta changes a signature to bool, introduces a "verify-before-durable" contract, or …
- Distinctive: line 408
NOT reorder the flow to gate the durable write on the newly-checked contract.
- Distinctive: line 530
Rule: before accepting a third-party test, assert, or invariant as proof of property P, locate case that DOES NOT have P and verify that …
- Distinctive: line 560
Cheap signal: if you wrote positive control and someone else found defect, check whether your control would have caught theirs.
- Distinctive: line 581
Rule: when what might be wrong is a CONVENTION (multiplication order, rows versus columns, local frame versus world, axis order, …
- Distinctive: line 588
Cheap signal: if control and instrument share function, module, or formula, it is not an independent control.
- Very specific: line 655
Use the single loop budget established before review: Follow gates-ledger §Cuándo para un bucle: executable product criteria, bounded …
- Very specific: line 672
Check the lock's scope. threading.RLock excludes threads in one process.
- Distinctive: line 675
Look for readers that discard exactly the records the loader repairs or prunes.
- Distinctive: line 706
Treat an override without that chain as a family-sized coverage hole.
- Distinctive: line 708
Treat comments such as "X and Y inherit this gate" as claims to audit, not evidence.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Rigorous Data Audit
Procedure for auditing mods where a bug equals lost player progression. Built from a real failure: six parallel Opus reasoning agents reviewed LF_VStorage 1.4.6 from independent angles and signed off as "release-safe" — an external implementer-grade audit then found 12 VULNs (P0–P3) the agents missed. This skill encodes the lessons.
A second failure refined it further: a loose application of this skill's
"parallel agents + consolidation" shape — pointed at fact-checking a corpus —
produced an audit that was ~55% confabulated, because there was no
adversarial verification step between "agents reported it" and "acting on it".
Step 3 below exists because of that. See postmortem.md for the case.
Read references/why-this-skill-exists.md for the full retrospective if you
want the original case study.
When to invoke
Trigger automatically when any of these are true:
- Mod touches persistence, save files, state machines, or async work queues
- A bug would cause silent data loss (lost items, wrong sids, money loss)
- User asks for "audit", "revisa a fondo", "release-safe?", "puede romper progresión"
- User just applied multiple fixes and wants verification before rebuild/test
- User hands you findings from an external auditor and asks you to verify
If the change is cosmetic or UI-only, this skill is overkill — skip it.
Why reasoning alone is insufficient
The reasoning agents that signed off on LF_VStorage 1.4.6 were not lazy. Each read the relevant code and produced a coherent argument. They missed bugs anyway. Looking at the 12 VULNs the implementer-grade audit caught:
| Failure mode | VULN examples | Why reasoning misses it |
| Path-helper inconsistency | VULN-003 (.tmp vs .lfv.tmp) | Bug is enumerable, not deducible — reasoning agents trace happy paths and see helpers used in isolation |
| Sidecar/marker not cleaned | VULN-008 (.restoring/.manifest.json survive DeleteContainerFiles) | Symmetric obligation — every Write needs a Delete. Reasoning agents check the writer side, not the cleanup side |
| Alternative entry point skips invariant | VULN-009 (sync path leaves stale marker), VULN-001 (kill-switch not durable) | Agent fixates on the canonical async path; the synchronous shortcut is "obviously similar" so gets a glance |
| Flag lifecycle asymmetry | VULN-010 (admin clears flag while sidecar still references stale state) | Two state stores must move together; reasoning agents check each store internally |
| Pre-super gate placement | VULN-004 (gate runs after vanilla super) | Order of operations within an EE hook is invisible from "is the gate present?" |
| Sanity caps missing | VULN-011 (LFV2 count fields uncapped) | Threat model not in scope of the agent's prompt |
Five of those are enumerable mechanically — a script + grep finds them in under a minute. Three are cross-actor — one writer + a different deleter + admin override. Reasoning across 3+ files is where Opus agents thin out.
And separately: agents report findings convincingly whether or not the findings are real. The fix is three-pronged: cheap mechanical pre-checks first, then reasoning agents specifically prompted on the gaps reasoning is bad at, then an adversarial verification pass before any finding is trusted.
Workflow
Seven steps in two phases.
- Phase A (steps 1–6) is the audit. It runs entirely from the codebase and ends with a verified findings list and fixes applied.
- Phase B (step 7) is in-game validation. A clean audit is necessary but not sufficient for "release-safe".
Skipping early steps makes later ones less effective — do not skip. Each step below carries two annotations in a quote block: Model (the model tier the step's work should run on) and Done when (the explicit exit criterion — do not advance until it holds).
Phase A — Audit (steps 1–6)
Step 1 — Mechanical pre-checks (cheap, deterministic, fast)
Assignment — run deterministic checks directly; delegate only if assigned and useful. Done when — a written list of mechanical findings exists (zero items if clean), each citing
path:line_start-line_end, ready to paste into step 2.
Run before spawning any agents. Each check is a grep + table walk; together they take ~10 minutes and catch the bookkeeping-style bugs reasoning misses.
The four reference docs give the procedures. Read them before running:
references/path-naming-matrix.md— catches path-helper drift (VULN-003 class)references/sidecar-cleanup-symmetry.md— catches missing cleanup on delete/reset (VULN-008 class)references/entry-point-audit.md— catches alternative entry points skipping invariants (VULN-009, VULN-001 class)references/flag-lifecycle-audit.md— catches flag/sidecar state-store divergence (VULN-010 class)references/crash-safe-evidence-and-bundles.md— authoritative evidence indexes and multi-root publicationreferences/authority-and-loopback.md— durable authority publication and authenticated-localhost provenancereferences/incremental-rebuild-traps.md— atomic-to-phased conversion hazards
Plus the existing structural check:
references/state-machine-matrix.md— catches illegal transitions and double-counted state- Full-ancestry super-chain walk (added 2026-07-05): whenever an invariant depends on "leaf class chains super" (physical Open/Close failsafes, EE* hook propagation, modded-base overrides), grep the override in EVERY class of the inheritance chain up to the modded base — never just the leaf. See dated section at end of this file.
This list goes into step 2's agent prompts as known-context so agents do not waste cycles re-finding.
Step 2 — Cover the relevant audit angles
Assignment — the orchestrator chooses reviewer family, effort and lane count from risk and available budget; this skill does not authorize extra agents. Done when — relevant angles are covered; every finding pastes the literal code snippet it is about (not just a line citation) plus severity. A "finding" that only describes code without pasting it is bounced back as SUSPECT, not accepted.
The eight angles below are coverage dimensions, not eight required agents or reports. Use one reviewer for a bounded audit; distribute independent angles only when delegated and useful. Bound delegated reports (≤700 words, no narrative).
Show, don't tell. A claim of the form "this code has bug X" must include a
copy-paste of the actual code, with path:line. A description without the
snippet is a hypothesis, not a finding — the next step cannot verify it and it
will be dropped. This requirement is what makes "verified" something grep-able
rather than narrative.
Coverage dimensions; mark non-applicable angles with a reason:
- Persistence & atomic flow — write barriers, fsync semantics,
.tmp/.bak1/.bak2rotation, header/footer verification, partial-write recovery - State machine — every transition, every gate, every "should never happen" branch
- Async queues & cross-tick safety — re-entry on the same sid, cancellation, queue-during-iteration, shutdown drain
- Engine hooks (EE)* — entry-point gating placement, super-call ordering, EEDelete vs EEKilled symmetry, OnStoreSave/OnStoreLoad cadence
- Admin commands — input validation, path traversal, race with running queues, sidecar ↔ in-memory consistency
- Recovery paths — what crash leaves on disk, what boot consumes, degraded modes, partial-state quarantine
- Action layer (pre-super gates) — every action handler that might fire while a container is virtualized; gates run before vanilla super
- Threat model & input bounds — sanity caps on counts, sizes, lengths from disk; bound check before allocation
Full prompts are in references/audit-prompts.md. The implementer-grade
prompt for step 4 is also there.
Step 3 — Adversarial verification + consolidate
Assignment — follow the orchestrator's review budget. Citation checking and judging whether an inference follows are different checks; neither model brand proves them. Done when — every row in the deduped table has been confirmed against the real file (by the independent verifier or by you); the 20% self-sample passed (<10% confabulation); each row is labelled defect vs improvement.
This is the step that turns "agents reported it" into "it is real". It exists
because skipping it once produced a ~55%-confabulated audit (postmortem.md).
Three sub-steps, in order:
3a — Verify every cited snippet against the real file. Open the file at the cited range and confirm it says what the agent's pasted snippet claims. Reasoning agents drift on line numbers, copy citations from sibling files, and occasionally invent plausible ranges wholesale. A finding whose snippet does not match the file is not a finding — re-derive it or drop it. Every cause in durable memory brings file+pattern+number of matches with n>0 (LL-414); without the trio it is a hypothesis, and adjudication between rival mechanisms requires a prediction that only the new mechanism compels.
3b — Independent verifier pass. When an independent pass is assigned, use a
reviewer from another family with a fresh context that has not seen the angle reports.
If it is unavailable, declare that limitation; do not silently claim independence. Hand it only the bare list of claims
(claim + location, no reasoning, no severity). Its task: for each
claim, open the cited file and return TWO separate verdicts — "does the
file actually say this" (snippet_matches_file) and "does the conclusion
follow from that code" (inference_holds, judged without seeing the
auditor's reasoning) — pasting the relevant lines (LL-270). A claim the
independent verifier cannot confirm on either verdict is NOT actionable
until the orchestrator re-reads it — dropping it silently is how a real
finding disappears. And a refutation rate of 0% is a reason to distrust the
verifier, not to trust the batch: the run that produced this rule refuted
0 of 67 claims, and TERR-2 arrived CONFIRMED on a false inheritance
premise. This is adversarial on purpose — convergence between
agents that shared context (the same spec, the same conventions doc) is
contagion, not confirmation. The verifier must not share that context.
3c — 20% self-sample gate. Before trusting the consolidated table, pick 20% of the findings at random and verify them yourself by opening the files. If more than 10% of the sample is confabulated, the audit is not trustworthy — re-run step 2 with stricter prompts, or discard it. Do not act on an audit that fails this gate.
Then build the single deduped table:
| ID | Severity | Title | File:Lines | Found by | Verified by | Defect/Improvement | Status |
- Severity is yours to assign — do not trust the agent's self-reported severity. P0 = data-loss possible. P1 = recovery required. P2 = degraded behavior. P3 = code smell.
- Defect vs improvement. Defensive coding is not a bug. An
ORbranch that accepts two input formats, a tolerant parser, a redundant guard — those are robustness, not defects. Label them "improvement" at most; do not file them as findings or inflate their severity. The 55%-confabulated audit's single biggest error class was calling tolerance a bug.
Step 4 — Implementer-grade cross-actor pass
Assignment — an independently assigned reviewer capable of cross-actor reasoning. Done when — the agreed product checks and review budget are satisfied. A new finding needs executable evidence to block. The single stop-rule owner is
gates-ledger§Cuándo para un bucle; do not create an until-clean loop here.
This is the step that, in retrospect, would have caught the 12 VULNs.
Give the assigned reviewer a fresh context — no audit history, no agent output, no priors. Hand it the codebase, the README/spec, and this single prompt: "Find every way this code can lose, corrupt, or silently misroute player data. Trace each writer to every reader, each sidecar to every cleanup site, each admin flag to every consumer. Where any of those triples is incomplete, that is a bug."
Full prompt: references/audit-prompts.md § "Implementer-grade pass".
The cross-actor framing matters. Reasoning agents prompted "audit this layer" look within the layer; they do not chase across actors. The implementer-grade prompt explicitly says "trace across actors".
If this agent finds nothing, that is the signal that the audit is converging. If it finds a defect, reproduce it, classify its impact, and recheck the affected path within the agreed budget. Escalate remaining work when that budget is exhausted.
Step 5 — Apply fixes
Assignment — use the execution route authorized by the orchestrator. Done when — every applied fix names the check or angle that caught it; a re-grep confirms the pattern is gone everywhere; no fix exceeds the minimum verified change.
Standard editing flow, with four specifics:
- For every fix, write down which mechanical check or which agent angle caught it. If a fix has no source, it is a hunch — re-verify before shipping.
- After each fix, re-grep to confirm the bug pattern is gone everywhere (not just at the cited line). VULN-003-class bugs often have siblings.
- Minimum verifiable patch. Apply only what step 3 verified. When the verified instruction is "add bands X before the else", add bands X — do not also add Y, Z, W because a sibling (unverified) finding suggested them. "While I'm here" is exactly how a patch gets bloated with confabulation-derived changes.
- Do not ship artifacts from an un-reverified audit. Packaging a
.skill, cutting a release, or handing the user a patch file based on findings that did not pass step 3 is how false confidence propagates. Applying a patch costs minutes; the bad release it enables costs hours.
Step 6 — Re-audit subset
Assignment — mechanical checks directly; targeted reasoning under the same review budget and family-independence contract. Done when — mechanical pre-checks plus the two most-changed angles run clean. A new finding loops back to step 5 once; a second reappearance stops the loop (ORCHESTRATOR_NEEDED with backlog).
Re-run mechanical pre-checks (cheap) plus the two angles whose code changed
most. If a new finding appears, loop back to step 5 once. If a finding of the same
family reappears, the defect is design, not patching: stop, file the remainder as
numbered backlog and escalate. Stop rule (owner): gates-ledger §Cuándo para un
bucle — the product gate closes the loop, a finding blocks only with an executable
repro, the budget is two rounds (rev. 2026-09-02; replaces «until zero critical/major»).
For each value crossing N layers, a test executes the two layers of each joint WITHOUT test doubles
(LL-473); the mutation to test deletes the COUPLING, and the fix is only accepted when
the RECEIVER repeats the exact mutation and sees the control die.
Phase B — In-game validation (step 7)
Step 7 — In-game test gate
Model — n/a. The user runs these; the skill cannot. Done when — all four scenarios below pass in-game. Only then is "release-safe" earned.
Audit clean ≠ release-safe. Before declaring release-safe:
- Player connects with a virtualized container, server restart, container intact (basic round-trip)
- Crash mid-virtualize (kill server) → reboot → recovery completes, no data loss, no orphan markers
- Admin reset on a virtualizing container → stable state after reset
- All sids on disk after a long session match player intent (no orphans, no ghosts)
The skill cannot run these tests for the user. The skill's contribution is to make the audit phase trustworthy enough that the in-game test phase is short.
Anti-patterns
Watching for these saves rounds:
- Declaring "release-safe" after step 2. Steps 3–7 are not optional. Phase A alone is never "release-safe" — Phase B is the gate.
- Using eight identical agents instead of eight different angles. Eight reasoning agents prompted "audit this code" produce eight redundant reports. The angles must differ.
- Skipping step 1 because "the agents will catch it". They demonstrably do not.
- Treating defensive coding as a bug. A tolerant
ORbranch, a redundant guard, a parser that accepts two formats — robustness, not defects. Calling tolerance a bug was the 55%-confabulated audit's biggest error class. - Trusting consolidated metrics without drill-down. "34 VERIFIED, 9 CONFABULATED" is smoke if it is a summed number with no per-finding click-through. Metrics without traceable findings are sums of guesses.
- Acting on an audit that has not passed step 3. The agents' report is a set of hypotheses. Adversarial verification (independent verifier + 20% self-sample) is what makes it a set of facts. No verification = do not act.
- Trusting "convergence" between agents that shared context. Four agents citing the same bug because they all read the same conventions doc is contagion, not confirmation. The step 3 verifier must have fresh context.
- Re-running the same audit after fixes. Step 6 changes the cheap checks plus the two layers most edited — full 8-angle re-runs waste budget.
- Serializing independent work after parallel delegation was authorized. If multiple lanes are assigned, dispatch them together so they run concurrently.
- Shipping a
.skill/ release / patch file from un-reverified findings. Cheap to apply, expensive to walk back. - Reading a short-circuit finding as green (LL-481). A gate skipped on PRECONDITION (dirty tree, unreadable config) wears the same face as a pass: verify the gate evaluated what changed, and count exit codes, not findings. Verification on a dirty tree is not verification.
References
references/why-this-skill-exists.md— full retrospective on the LF_VStorage 1.4.6 casepostmortem.md— the ~55%-confabulated audit and the eight lessons that hardened step 3 and step 5references/audit-prompts.md— eight angle prompts + implementer-grade pass promptreferences/path-naming-matrix.md— mechanical check #1references/sidecar-cleanup-symmetry.md— mechanical check #2references/entry-point-audit.md— mechanical check #3references/flag-lifecycle-audit.md— mechanical check #4references/state-machine-matrix.md— structural state-transition checkreferences/crash-safe-evidence-and-bundles.md— crash-safe evidence and multi-root bundle publicationreferences/authority-and-loopback.md— authority/WAL and authenticated loopback auditreferences/incremental-rebuild-traps.md— lost updates, non-idempotent retries and stuck flags
(added 2026-06-10) Engine event semantics + remediation plan completeness
Origin: LFGungame GG-01 (2026-06-10) — a respawn wiring on the wrong event passed this skill's entire pass (8 auditors + cross-actor) and 2 external reviews because everyone verified the hook's SIGNATURE and no one its SEMANTICS. And F-25 fell out of the remediation plan unclassified (groups covered 26/27 findings).
- Add to auditor prompts (all dimensions touching hooks): for each engine event override (
OnClient*Event,EE*,On*), verifying that the signature exists in vanilla is NOT enough. Verify parameter CONTRACT: (1) read the body of vanilla event handler — its internal usage reveals what it delivers (canonical example:OnClientRespawnEventkills the unconscious "choosing to respawn" → player is the OLD character; new one is born inOnClientNewEvent); (2) grep prior art across real tree mods: who hooks that event and for what purpose. If the audited mod uses an event that no prior art uses for that purpose, it is a finding (Medium confidence minimum). - Vanilla call-sites for each CONSUMED parameter (added 2026-08-15, SP-369): the handler body does not tell what caller chooses not to pass. For each parameter of an engine hook that override CONSUMES, grep vanilla call-sites of that method and verify they actually pass it. A parameter with a default value in signature is a promise caller might not keep. If any call-site omits it, override must derive the data on its own (
GetPosition(),GetOrientation()) instead of trusting the argument — or at least detect default and not make destructive decisions with it. Severity corollary: when action upon validation failure is destructive (ObjectDelete, deleting a file, dissolving a record), an unreliable parameter turns a gate into a shredder. Gates that delete must fail closed toward inaction, not toward destruction. Origin: SimpleGroup 2026-08-15 — anOnPlacementCompleteoverride validated territory withposition; vanilla call-site digging garden plot with shovel computed position and called hook with only player, override received(0,0,0)and calledObjectDelete. - Plan completeness checklist (step 2, when processing findings): if audit produced N findings and plan classifies them into groups, mechanically verify that |union of groups| == N (list of IDs, not from memory). A finding without group = lost finding (real case: F-25).
(added 2026-06-11) Production triage: deployed artifact, path attribution, lying-named gates, auditor spawn
Origin: LF_VStorage 2026-06-11 (5 production bugs; dual Claude+Codex audit; see LL-143/LL-144).
- Deployed artifact ≠ source (prelude to Step 1 when trigger is a PRODUCTION bug): if audited code is distributed packaged (PBO/build), compare artifact mtime vs relevant fix files mtime AND probe INSIDE artifact (string-probe classnames on binary, without unpacking) BEFORE root-causing against source. Declare drift as its own finding. Case: PBO 28-May without 01-Jun CodeLockBridge — 2 of 5 bugs were partially deployment drift.
- Path attribution in log evidence: a log line that "proves X works" is attributed to emitting path (synchronous shutdown vs action hook vs periodic scan) before classifying partial-vs-broken. Case: "MMG virtualizes" came ONLY from OnMissionFinish; zero runtime path activity in entire session.
- Lying-named gates (add to auditor prompts): for each trigger gate function (HasX/CanY/IsZ), paste and read BODY — do not accept name as evidence of coverage. Case:
HasCargoOrAttachmentswithout any attachments check → all slot storage invisible to all 4 triggers; missed by 9 auditors + cross-actor and uncovered by user pushback. - Auditor spawn (Step 2, operational): background agents auto-deny permission prompts outside cwd → launch auditors in FOREGROUND, all in a single turn (parallel). Case: mechanical checks agent bounced in background with PERMISSION-FAIL.
(added 2026-07-05) Super-chain verification is a FULL-ANCESTRY walk, not a leaf check
Origin: LF_VStorage F-NEW-1 (review 2026-07-05). The mod's physical Open/Close
failsafe (modded class ItemBase) only fires if every class between the leaf and
ItemBase chains super. Verification pass A-F5 checked the leaf
(rag_baseitems_container_base.Open() — chains super) and declared the invariant
satisfied. The break was one level up: RaG_ContainerBase.Open()/Close()
(RaG_Core, RaG_ContainerBase.c:142-154) set state and return WITHOUT super —
the failsafe never fires for the entire family. The miss survived TWO independent
verification passes (a prior session and a search agent) because both stopped at
the leaf.
Procedure (mechanical, ~5 min per family):
- Resolve the full chain: leaf → parents → vanilla base (
class X : Yheaders; third-party mods' extracted sources or PBO string-grep). - For EACH class in the chain, grep
override void <Method>— if present, confirm it callssuper.<Method>(). One missing link voids the invariant for every descendant. - Record the verdict per FAMILY (base class), not per leaf classname.
- If any link is broken: the failsafe does not cover that family — a dedicated wrapper hook on the family base (with super + explicit notify) is required.
Corollary: a bridge/failsafe decision justified by "handled when the leaf chains super" is UNVERIFIED until the full walk is on record. Treat such comments as claims to audit, not facts.
(added 2026-07-08) Delta-contract propagation — a Step-1 check when the trigger is "make it fail-closed"
Origin: LF_VStorage 1.5.0 pre-release audit. The change under review hardened durability
contracts (signature -> bool + gate on it; "verify sidecar before declaring persisted").
5 of ~9 real findings — including BOTH release blockers — were not the fix being wrong but
the fix MISSING at a sibling call-site: HandleRestoreFailure didn't clear the flag+sidecar
its 3 sibling terminal paths cleared; MigrateLegacyTmp got the isCanonicalTmp filter but
PromoteOrphanTmp didn't; retry/recover got the checked ClearFor gate but reset didn't;
DropQueue's success branch untracked but its 2 fail-closed branches didn't. The 8 structural
angle-auditors under-weight this — each reads its own layer's canonical path — yet the whole
point of a fail-closed delta is that it touches MANY sites.
Add to Step 1 (mechanical pre-checks) whenever the delta changes a signature to bool, introduces a "verify-before-durable" contract, or propagates a fail-closed gate:
- Grep EVERY call-site of the changed symbol AND its sibling/opposite operation that should now share the contract: the success path, EVERY failure/early-return branch, the sync/shutdown shortcut, the admin variant, the boot-reconcile variant.
- For each, confirm it consumes the new contract (checks the bool / clears the same flag+sidecar / runs the same gate). Dominant failure mode is asymmetry: N-1 of N branches updated, one missed. Enumerate the branches mechanically — do not eyeball.
- This is a DELTA check (enumerate the changed symbol's fan-out), complementary to the 5 structural checks; run it FIRST when the audit trigger is "someone hardened contracts".
Corollary (contradiction resolution): when two auditors disagree whether an orphaned on-disk
artifact (stale sidecar/marker) is dangerous or inert, the decisive question is whether the
boot/recovery scan ENUMERATES it. A sidecar whose primary enumerator glob (e.g. *.lfv) is
gone is inert even though it survives on disk — check the enumerator before rating severity.
Caveat when APPLYING the propagation (added 2026-07-08b, Step 5): if the missing call-site
transitions to a terminal/admin-blocking state (QUARANTINE, quarantine-orphaned) and its
failure branch contains a HARD-GATE (marker/payload preservation that prevents data loss), do
NOT reorder the flow to gate the durable write on the newly-checked contract. Reordering can
route the fail path into a marker-deleting / payload-purging branch and CREATE a worse
data-loss than the one you were closing. Prefer consume+retry of the contract with the durable
write kept in its ORIGINAL position. Verify the ENTIRE else/failure branch of the site you
touch, not just the happy path. Origin: a reorder of a degraded-partial handler introduced an
.lfv-deleting path at MAX failures; the adversarial reviewer caught it on the round after the
"fix" — the first apply attempt did not. Corollary: after a propagation fix, re-run the
adversarial verify pass (Step 3/4) on the CHANGED handler, because an apply can regress worse
than the finding.
Rules promoted from lessons corpus (added 2026-07-27)
Promoted from AI/20_Knowledge/lessons-learned.md so they arrive via trigger instead
of relying on someone remembering to look for them. Each rule cites its originating LL-NNN;
the complete entry (symptom, origin, evidence) lives there.
- LL-045 — Bound every claim of non-causality to the size, version, fixture, and conditions where verified. Do not promote "X does not matter" as a universal conclusion if the corpus does not cover other regimes.
- LL-139 — Make every remote fake/stub emit the same types as the real wire, not just equivalent values. Do not use
is True/is Falsewith serialized data; explicitly test0/1, bool, and missing values according to contract. The fixture composes request as producer composes it, never the most complete one "for convenience" (LL-469): facing in-game defect with green suite, first look for test that already covered case and compare inputs field by field. - LL-140 — Verify every resource exclusion with two real acquisitions on target OS and require the second to fail. Inspect socket, file-sharing, and stdlib mutex defaults; configure lock fail-closed.
- LL-190 — For every verifier asserting deleted/moved/repaired/restored, require an affected count greater than zero or an independent pre-check proving there was no work. Do not accept
{ok:true, count:0}as proof on its own.
(added 2026-07-29) Two things the audit must check and no single dimension covers alone
Origin: GameMaster IG-1 (R21 dual + this skill, 2026-07-29). The code entered with two independent UNSOUND verdicts and emerged with 19 fixes. The two most severe findings of the day were not in the code being audited: they were in the fixes written that very day. None of the 8 angles would have found them, because all 8 angles look at the system, not the patch.
1. A reused identifier is verified by its LIFECYCLE, not by its equality
G2 requires verifying that the symbol exists. LL-222 extended it to the semantics of a helper you
reuse. Missing is the third step, which is the one that bites in two-process systems: when a fix
uses an identifier emitted by ANOTHER actor, verifying that equality exists is not enough; one must
verify how long that equality lives and who resets the counter.
Real case: to delete an orphaned entity, command_id returned by enqueue was reused,
after verifying in server code that object_id == command.id — true, cited, with
path:line. What was not verified: issuer of those IDs resets its counter on every startup
(self._next_id = 1) and auto-reaps on idle at 30 min, while map indexing them on other
side is never cleared as long as host process lives. Recycled IDs ⇒ "compensatory" deletion
points to an entity from another session. A fix intended to leave no garbage could destroy work in progress.
Mandatory questions before accepting a foreign ID as key for a destructive operation:
who generates it and with which counter · does that counter reset (process, session, mission, reboot) ·
who maintains map resolving it and when is it cleared · can those two lifecycles get
desynchronized · what happens if ID no longer means what it meant. If any lacks a cited answer,
the destructive operation is not performed: log and report, never delete blindly.
A fixture never assigns ownership fields (LL-446): grep for assignments to owner_* in
helpers must yield zero; the only path to owner in tests is product operation with
real lease.
Corollary of same case: also verify execution order on other actor. There, a
spawn is always deferred to a queue and a delete of a batch without spawn is dispatched immediately, so
compensation could outrun spawn it intended to undo and create the permanent orphan
it came to prevent.
2. Step 6 looks for INTERACTIONS between fixes, not just defects in each fix
Step 6 says "re-run angles whose code changed most". Insufficient as it sounds: it invites re-auditing each fix separately, and defect appears in the product of two correct fixes.
Real case, two fixes both correct and both with proven failing test: (a) "in dry-run do not call
sweep" — correct, sweep mutated the world in a mode advertised as safe; (b) "on startup,
guarantee trailing newline on ledger" — correct, a merged append caused loss of contract
for a live entity. Together: only broken-tail repair lived INSIDE sweep, which (a) had just
disabled in dry-run, and (b) closed broken line without discarding it, so next append
fell behind it and that line ceased being last. Result: replay() always raised and
ledger remained permanently unreadable. No subsequent startup could even sweep.
Add to Step 6, explicitly: for each pair of fixes in batch, ask if one disables
a path that the other depends on. Especially when one fix adds a guard (if not X: ...) and another
touches the resource that path repaired or cleaned. Enumerate pairs mechanically if batch exceeds
four fixes; guilty pair is rarely the one suspected.
And use mutants in Step 6, not just green tests. In this case re-audit with mutants killed 12 of 14 and the 2 survivors were precisely tests that "tested" a fix without being able to distinguish it from its absence. A test that passes with and without fix is not coverage: it is decoration. The positive control of an oracle is the REAL artifact along full load→evaluate path, with mutants as files (LL-438); synthetic in-memory mocks only measure author consistency.
(SP-367, added 2026-08-07) When audited tree is OUTPUT of a generator, Step 5 does not edit the tree
Origin: LFPowerGrid F4-S2 (2026-08-07). Audit produced 3 fixes of 3 lines within a
delta of 24. Applying them seemed trivial. It was not: candidate tree was output of a
fail-closed transformer with tree manifest and contract pinned by SHA-256, and lines to
touch were its Python literals, gated by exact counts (count('"key"') != 2 -> fail).
Editing tree would have broken manifest and made fix irreproducible.
Add to Step 1 (mechanical pre-checks), as question zero: first of all, determine if
audited tree is output of a tool (transformer, codegen, build, migration) with
manifest, contract, or pinned hashes. Look for *-receipt.json, contract*.json,
*manifest*.json alongside tree, and a --verify in tool that produced it. If present, the
tree is NOT the edit surface.
Consecuencias, en orden:
- The fix is applied to generator literal, not artifact. Next: regenerate contract
and its SHA, re-run
analyze -> apply -> verifyfrom clean tree, and re-seal artifact (PBO/package). Previous artifact is preserved separately as evidence. - Re-anchoring gates is the failure mode this skill exists to prevent. A gate that is touched so it accepts your fix is a loosened gate. Rule: ALWAYS re-anchor stricter (two exact counts of 1 instead of count of 2), add a non-regression gate for each check the fix removes, and test every touched gate in red on the same day — tamper the literal, run tool, require exit != 0 with expected token, restore, and verify that restore is byte-identical.
- State cost BEFORE user approves scope of fixes. Real cost is not "editing N lines": it is contract + SHA + re-run + re-sealing + possible re-measurement. It changes which findings are worth fixing. In origin case, two of four approved fixes changed shape once cost became known, and one became inapplicable.
- A finding whose fix would require touching a hash-pinned region in contract is not fixed. It is documented, or turned into a procedural note. In origin case, relocated body was byte-identical by design and pinned: finding "debug hook was left duplicated in two files and tester may edit the one that does not compile" was closed with a line in test procedure, not code.
Corollary for Step 3a: a correct citation may not prove what is asked of it
An auditor cited an official vanilla test as proof that an API was synchronous: test measured
a counter before and after call and asserted == 1 on next statement. The citation was
literal and exact. But sibling of that API, documented as asynchronous, passed the same
assert a few lines down. Test did not discriminate, so it proved nothing about synchrony.
Rule: before accepting a third-party test, assert, or invariant as proof of property
P, locate case that DOES NOT have P and verify that same assert fails. If negative control
passes, evidence does not discriminate — it is compatible with conclusion, does not support it. It is same
axis as "a gate that cannot be turned red is not a gate", applied to third-party evidence instead of
own gates. Verifying citation exists (G2) is first rung; verifying citation
DISCRIMINATES is second, and is the one skipped.
Sibling corollary: control is calibrated to WORST real case, not a convenient one (LL-348)
Previous corollary covers control that does not discriminate. This one covers one that discriminates but in the wrong range.
A sweep of 18 files searched for a known defect — a rewritten line left alongside the
old one — measuring common prefix >= 55 characters between neighboring lines. It yielded 0. It carried positive
control, and control was planted on a pair sharing 77: passed green. The only
difficult real case shared ~32 before diverging, so probe would not have found it
ever. It was fixed because external reviewer named it, not because sweep detected it.
Lowering threshold was not answer either: at 25 there were 27 hits, nearly all legitimate repetition. Threshold was not problem; measured magnitude was. The good probe measures similarity over neighbors of lines that change ADDED — defect only exists where something landed — and its control is planted in real cases.
Rule: a positive control answers "can it find something?", and that is not the question; the question is "can it find THIS?". Plant it in worst known real case. If there is none yet, declare up to what toughness coverage is demonstrated — "0 remaining, verified up to similarity 0.60" — instead of saying "0 remaining" point-blank. And if moving threshold causes result to jump from 0 to dozens of false positives without passing through useful range, stop: you are measuring the wrong magnitude.
Cheap signal: if you wrote positive control and someone else found defect, check whether your control would have caught theirs.
Third corollary: a control that inherits the instrument's convention is born blind (LL-347)
Previous two cover control that does not discriminate and one discriminating out of range. This one covers one that discriminates perfectly inside the blind spot intended to be measured.
A gate checked that proxies were rotated 180 degrees around vertical axis. It had negative control and was well thought out: generated a model rotated 180 degrees around a horizontal axis and required gate to flag it in red. It did. Gate GREEN on good artifact, negative RED, and result in game was wrong — weapons had rotated around horizontal.
Cause: control generator applied R_new = Ry(180) * R_old, multiplying from the
LEFT, and function deriving frame returns axes as rows in world coordinates.
Multiplying from left negates rows, meaning it rotates around proxy's own axis, not around
world's. Measured: local Y axis of those proxies pointed to (1.0, -0.001, 0.006) — world's X.
The control used the same mistaken convention as the gate, so it confirmed
convention instead of testing it.
Rule: when what might be wrong is a CONVENTION (multiplication order, rows versus columns, local frame versus world, axis order, endianness, 0-based versus 1-based), control cannot be built with same code or same convention as instrument. It is built from outside: an artifact whose expected value is known via another means — a manual measurement, an external reference file, a visible asymmetrical marker — and compared against that. A control that shares gate apparatus only proves that apparatus is self-consistent.
Cheap signal: if control and instrument share function, module, or formula, it is not an independent control. And if gate comes out green and observable result comes out wrong, suspect convention before threshold.
(added 2026-07-28) Two DayZ persistence facts a Step-1 check must assume, not discover
Both were re-read against the pinned build 1.29.0.163451 during the r21 Phase 03 audit. They are engine properties, not project quirks, so any DayZ mod that persists data inherits them.
- DayZ exposes no rename and no move, so "temp -> verify -> replace" is NOT
atomic. The file primitives stop at
FileExist,OpenFile,ReadFile,CloseFile,FPrint,FGets,MakeDirectory,DeleteFileandCopyFile(VANILLA/1_core/proto/ensystem.c:397-531); a grep forRename|MoveFileover1_corereturns zero. The real replace isDeleteFile(dest)followed byCopyFile(tmp, dest), leaving a window in which the destination does not exist. Audit consequence: back up BEFORE that window, verify AFTER the copy, and delete the.tmponly once the post-copy verify passes. Treat any code or comment claiming an atomic replace as a finding, not as documentation. EntityAI.OnStoreSavewrites a runtime-dependent NUMBER of fields. With an energy component it writes nine, without it none (VANILLA/3_game/entities/entityai.c:2928-2959). Reading by fixed offset aftersuper.OnStoreLoadtherefore desynchronises only for the configurations that lack the component -- it will pass every test written against the configuration that has it. Audit consequence: any subclass that reads aftersupermust read sequentially and check each read's return; a fixed offset is a latent defect even when the current tests are green.
Both belong in the Step 1 mechanical sweep, because both are grep-able and neither is deducible by reading the happy path.
And the entry-point instance they combine into, found by this skill's own
check #3 on the Phase 03 simulator: the normal save path deleted a destination
that failed its post-copy verify, while the recovery path left the corrupt bytes
in place as the live file. Same invariant, two entry points, one of them silently
weaker -- the VULN-009 shape. When a codebase has a save and a recover, diff
their verify branches line by line; do not assume the recovery path inherited the
discipline.
(added 2026-08-14, SP-238 + SP-240) A CORRECTIVE is unaudited input: re-audit its NEW code, never delta-only
Step 3 says "re-audit until zero critical/major". It did not say that the corrective's own code must be audited as if it were a fresh round. It must.
Evidence. A corrective bundle passed its receiver, an R8 walk and the compile gate, and closed the findings of six review lanes. Re-running the multi-angle audit against its own new code then found two new criticals and one blocker, all of them defects in the corrective's design rather than its implementation: a clear-after-reapply that broke the guarantee of an alternate path, and an alias in the canonical buy/withdraw/restart flow that left the in-game ATM permanently blocked. Four of five independently re-launched auditors converged on the same alias without contact. It was the fourth instance of the same shape in one campaign, which is what makes it a rule rather than an anecdote.
Apply, appended to Step 3:
- Re-launch every applicable angle over the NEW code, not "check that the fixes landed". The round-two findings were in the corrective's design, so a delta-only check could not have seen them. Resumed agents work here and cost roughly 30% of a fresh run, provided they are told explicitly that their cached content is STALE.
- The corrective's prompt carries its own counter-scenarios -- the scenarios that would refute its design -- and the implementer verifies and documents them as part of RED->GREEN. Treat the arbitration's design as unaudited input. In the case above, the counter-scenarios that were embedded got verified; the one that was not embedded is the one the re-audit had to catch.
- Use the single loop budget established before review. Follow
gates-ledger§Cuándo para un bucle: executable product criteria, bounded rounds and an explicit escalation outcome. Do not substitute a zero-new-findings requirement.
(added 2026-08-31, SP-196 + SP-200) Repair-on-load constructors turn every reader into a writer
A store constructor that prunes, migrates, compacts, normalizes, or repairs while loading is not read-only. Every call site that constructs it can write the same file, even when the caller's help text or docstring says "read-only". Treat that claim as unverified until the constructor and its callees have been read.
Step-1 caller census:
- Grep every construction of the store class, including tests and alternate entry points.
- Classify each caller as intentional writer, required reader, or test. For each required reader, trace constructor side effects through the persistence choke point.
- Check the lock's scope.
threading.RLockexcludes threads in one process; it does not serialize two processes writing the same file. A shared file needs an inter-process lock or a design that gives only one process write authority. - Look for readers that discard exactly the records the loader repairs or prunes. That is a mechanical signal that maintenance is an unwanted side effect, not part of the read.
Read-only must be structural. A read-only mode loads without repair or checkpointing, and the persistence choke point plus every public mutator must raise if a future caller attempts to write. Pin the contract with a file that contains material the normal loader would repair, then compare its bytes before and after the read-only operation; an unchanged mtime is not enough evidence.
A pre-operation backup is not fail-closed merely because it uses O_EXCL. The path
FileExistsError -> success can reuse a stale, empty, or crash-truncated backup, and one fixed
backup name protects only the first destructive operation. Use a fresh numbered slot per
operation (.bak, .bak.2, ...), create it with O_EXCL, validate its bytes and size, never
reuse it, and fail closed when the bounded slots are exhausted.
A permanent fail-closed state must also be observable. Whenever a repair or destructive operation can stop because no valid backup slot remains, require the existing diagnostic surface to emit a finding. Always ask: how does a human learn that this brake is engaged?
(added 2026-08-31, SP-369) The super-chain walk also goes downward from a modded base
The full-ancestry walk above protects an invariant while moving from a leaf toward its bases.
A modded class <Base> needs the opposite walk too: inheriting from the base does not execute
the modded hook when a descendant overrides that method without chaining super.
Procedure:
- Enumerate every vanilla descendant of
<Base>; include indirect descendants rather than stopping at the first level. - For each method modified on
<Base>, inspect every descendant override and record whether it callssuper.<Method>()on every applicable path. - Treat an override without that chain as a family-sized coverage hole. Add a dedicated hook at the correct family boundary or document that the invariant does not cover that family.
- Treat comments such as "X and Y inherit this gate" as claims to audit, not evidence.
Record both directions separately: leaf-to-base proves that a leaf reaches the hook, while base-to-descendants proves that no overriding child bypasses it.
(added 2026-09-29, SP-447) Census the inventory before handing it to auditors; deployed ≠ source via the PBO
- [EXACT] A regex-generated inventory is closed with an independent census before auditors see it: the LFPowerGrid save/load-body table listed 11 files while 25 contained
ctx.Readorctx.Write, missing an entire hook family (LFPG_OnStore*Device, 10 classes). Auditors treat the handed table as complete. - [DESIGN] "Deployed artifact ≠ source" is checked in DayZ by extracting the PBO and comparing by content (EOL-normalized) against each candidate tag: a release tag differed from the published PBO in 51 of 144 scripts.
- [EXACT] Do not count entities by searching class names in
storage_1\data\*.bin(nor intypes.bin): the positive control returns 0 matches in a world that does contain those classes. Count them in game.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

