Commit Graph
2 Commits
Author SHA1 Message Date
Marius Ciepluch 7e3b3bbc8b docs(pre-push-safety-net): record approved design and implementation plan 2026-09-12 18:27:14 +02:00
Marius CiepluchandClaude Opus 5 7e397beca6 docs(flow-aware-ranking): brief -- rank pairs by evidence, in phases that each must prove themselves
A taint request costs 6.63s, a 637-file plugin yields 4,463 regions, and 83.8%
of them share one rank ordered alphabetically. The ranker is not weak, it is
looking at the wrong thing.

The evidence that this is tractable, from one plugin:

    getMemberOrderByCode  (holds CVE-2023-23488)  rank 0.30
        $wpdb->get_var("... WHERE code = '" . $code . "' LIMIT 1")
    getMemberOrderByID    (sibling)               rank 0.30
        $wpdb->get_row("... WHERE id = '$id' LIMIT 1")
    pmpro_rest_api_get_membership_level           rank 0.80
        no SQL sink at all

A region with no sink outranks two holding raw concatenated SQL. The signal is
in the sink call's own text -- interpolated versus bound -- and nothing in the
ranker reads it.

And the detail that decides whether a keyword rule suffices: `esc_sql` IS in
scope for the CVE's function, applied to a different statement. "A sanitizer is
present, rank it lower" demotes exactly the right answer. Knowing which call it
wraps is reading, not matching -- which is the case for a model rather than a
table.

Unit: (region, family) PAIRS, tiered by cheap evidence. Tier 0 (no sink of that
family in scope) is the only tier that excludes rather than orders, so it alone
must be exact; above it, being wrong costs position rather than the finding.
That bound is what makes a model safe here -- a ranker cannot manufacture a
finding.

Six phases, each shipping only if it beats the previous one on a repository it
was not developed against: baseline, exact pruning (the phase that makes a scan
finish), heuristic tiers, the LLM ranker, breaking the closed loop, then prompt
optimisation. Phase 2 carries an explicit possibility that the model is not
needed for tiering -- and knowing that is worth more than assuming it. Phase 5
comes last because an optimiser run against a censored metric optimises the
censorship.

Records what the prompt must carry, and that the question is never "is this
vulnerable" -- that is the arbiter's job and the one thing a ranker must not be
asked.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-10 16:06:55 +02:00