QEDGen Triage Guardrails#
This document records the maintenance rules from the 2026-05-24 QEDGen medium/low review. It is intentionally operational: future reviewers should use it to decide whether a new QED finding needs a code fix, a test, or a baseline update.
Probe Baseline#
The reviewed probe is stored at:
.qed/probes/qedgen-pinocchio-probe.json.qed/baselines/qedgen-medium-low-baseline-20260524.json.qed/findings/qedgen-medium-low-triage-20260524.md
QEDGen 2.29.2 non-ASCII probe limitation: direct
qedgen probe --program . --runtime pinocchio panics on non-ASCII comment
characters in this repository. Until QEDGen fixes that parser path, regenerate
the probe from a temporary copy with only src/**/*.rs ASCII-scrubbed. Do not
scrub the real source tree.
Positional Accounts#
Account count/layout validation must dominate positional account use. Pinocchio
handlers may use fixed slots such as accounts[0], but only after one of these
is true:
- the instruction account count/layout was checked by a fixed-shape parser or account-count guard;
- optional tails were validated before any tail parser can silently ignore malformed accounts;
- program-owned state slots are passed through typed loaders or an equivalent local owner, size, discriminator, and PDA prologue before later re-borrows.
Static evidence lives in:
tests/account_count_coverage.rstests/owner_discriminator_coverage.rstests/validation_inventory_guard.rs
Raw Account-Data Casts#
No new raw account-data bytemuck casts should be added in production source without a local or dominating proof of the account type. The expected proof is:
- account owner check for program-owned or SPL-owned account data;
- data length check before every fixed-size cast or offset read;
- discriminator check for Seesaw account types and Pyth
PriceUpdateV2; - PDA derivation check where the account is protocol-owned or market-owned.
Prefer adding casts inside shared loaders such as src/validation/loaders.rs,
src/state/trader_ledger.rs, or small helpers that perform their own checks.
If a cast must live in a processor, update tests/qedgen_guardrails.rs with the
file allowlist and add source evidence to tests/owner_discriminator_coverage.rs
or a focused negative test.
Offset Reads#
Fixed-offset reads are acceptable only when a nearby exact-size or minimum-size check dominates the slice. Examples:
- instruction parsers check exact serialized size before slicing;
- Pyth price parsing checks
PYTH_PRICE_UPDATE_V2_MIN_SIZEand thePriceUpdateV2discriminator; - fixed-size test helpers use local arrays with compile-time lengths.
New public parser helpers should validate the account type locally, even if
current callers validate before calling. That is why read_pyth_feed_id checks
the PriceUpdateV2 discriminator directly.
Paired Validators#
Paired-validator findings require semantic review, not mechanical normalization. Do not collapse intentionally different predicates just to make the scanner quiet.
Known valid policy differences:
bid_countandask_count: insertion uses>= MAXbecause an exactly-full book cannot accept another order; invariant/recovery checks use> MAXbecause exactly-full is a valid persisted state.emergency_status:blocks_place,blocks_user_cancel, and adminForceCancelOnlychecks intentionally model different policy surfaces.- mint, owner, feed, and program-id findings usually compare different domains such as PDA address, account owner, discriminator, and stored field equality.
vault_balancechecks compare different obligations: payout, refund, free-funds lock, and solvency.
Change code only when a shared sentinel or shared policy actually drifts across callers.
Updating The Baseline#
When QEDGen is rerun:
- save the raw probe JSON under
.qed/probes/; - compare medium/low category counts against
.qed/baselines/qedgen-medium-low-baseline-20260524.json; - investigate count drift before updating the baseline;
- fix every valid finding with a regression test or static guard;
- update the baseline rationale only after the code/test evidence exists.
The guard command is:
cargo test --test qedgen_guardrails