# Repository-Wide Validation Closure

Use this reference with `repository-wide-scan.md` to preserve repo-wide coverage through candidate-local validation, candidate-local attack-path analysis, post-dedupe reconciliation, and final reporting.

## Closure Dispositions

- Every applicable high-impact ledger row must finish as `reportable`, `suppressed`, `not_applicable`, or `deferred`. Do not claim full repository coverage while any applicable high-impact row remains `deferred`; instead state exactly what remains deferred and why.
- User/advisory/tag-seeded root-control rows remain validation input even when reachability is incomplete; validation must close them as `reportable`, `suppressed`, `not_applicable`, or `deferred` with the exact proof gap.
- Do not suppress an exact seed row only because a neighboring issue looks more dramatic or because full downstream deployment details are outside the repository; state those details as preconditions or proof gaps.
- Each in-scope row must be recorded even when no candidate is found. Candidate ids are optional links from coverage rows to findings, not the reason the row exists.
- `open_seed` is an interim disposition only; before final reporting, every row must become `reportable`, `suppressed`, `not_applicable`, or `deferred` with exact file:line evidence or a concrete proof-gap reason.

## Pre-Dedupe Candidate Requirements

- Raw repository-wide candidates should already carry the discovering file-review subagent's or parent agent's candidate-local validation evidence and attack-path facts before dedupe.
- Each raw candidate finding's candidate-ledger path from `../../../references/scan-artifacts.md` is its candidate-finding coverage artifact. Every raw candidate finding must have a stable candidate id plus candidate-ledger receipts for candidate-local validation and candidate-local attack-path analysis, or an explicit deferred reason for missing proof, before dedupe or final reporting.
- Post-dedupe validation is for reconciliation, unresolved proof gaps, cross-file confirmation, and final closure; do not let dedupe erase the earlier proof tuple or its candidate-ledger traceability.

## Validation Budget And Coverage

- Before finalizing a high-impact finding in a large repository, check whether the same inventory shard has unreviewed sibling packages, wrappers, or root controls that could be the actual broken control. If so, finish that shard's sibling checks or mark the remaining rows `deferred` explicitly.
- For query injection candidates, parser-control evidence is enough to keep the instance alive when attacker input crosses into query syntax or selector operators. Record later checks as constraints, but do not suppress the root injection until the exact query API, parser behavior, and post-query guard prove attacker input cannot change semantics or create a meaningful read/write/error side effect.
- For template and placeholder injection candidates, preserve the helper line that creates the placeholder/expression engine and the line that resolves model values through it. Recursive expansion or re-parsing of resolved values remains in scope when the resolved values are request, client, tenant, stored configuration, or error data. Suppress only with exact evidence that resolved values are constant/trusted or escaped before any second parse/evaluation.

## Suppression And Final Reporting

- Before final output, reconcile the candidate/report set against the repository coverage ledger. Every advisory-seeded or exact-anchor row must either appear as a reported finding for the same file/source/control/sink/effect tuple or be closed as `suppressed`, `not_applicable`, or `deferred` with exact counterevidence. If an anchored row is missing because a sibling issue looked cleaner, revisit that exact file/control before finalizing.
- Suppress a candidate only with exact counterevidence for that instance, such as a specific sanitizer, permission check, tenant filter, escaping context, safe parser/loader, path canonicalization check, egress allowlist, or deployment constraint that defeats the claimed source/sink path. For route auth preconditions, exact counterevidence must reflect the real deployment-default middleware plus decorator behavior; an optional or conditional login wrapper does not prove the route is authenticated.
- A safe sibling implementation is useful negative control, but it does not suppress a different default factory, resource handler, generated adapter, protected action, parser operation, or shared-helper caller.
- A surviving auth/authz, secret, or configuration issue in the same subsystem does not close a separate resource-serving, path traversal, archive extraction, export/import, backup/restore, or file copy/move row. Each row must close on its own exact control and effect.
- For advisory-seeded path/file rows that name a file-manager, builder/media, theme/archive, export/download controller, or shared `sanitize_params`-style helper, final reconciliation must revisit that exact controller/helper even if adjacent path/file/authz findings survived. A traversal in one API namespace does not close another namespace's filename/path parameter unless the same source, sanitizer, sink, and effect are proven equivalent with file:line evidence.
- Do not close a shared-sanitizer path row as only literal traversal, safe naming, or deferred parser work while the report omits the sanitizer definition and at least one caller that enables slash-preserving behavior. Adjacent cross-scope storage, script-control, or telemetry findings are not evidence that a slash-permissive filename/path parameter was closed.
- For archive extraction rows, do not close the row with generic claims about standard-library safety, UUID/manifest gates, top-level import filtering, or later recursive copies into an approved root. Closure requires exact per-entry member-path containment evidence before the extraction or write point, including any symlink, hardlink, metadata, or subtree-promotion behavior that could still materialize attacker-controlled content. Do not require escape outside the overall app/datastore root; overwriting trusted config, peer-object directories, shared roots, or imported subtrees inside that root is still sufficient file impact.
- When final report budget forces selection among multiple path/file findings, do not prefer a higher-confidence sibling download/read issue over an upload/archive-member write issue that has the exact source, broken member-path control, and write tuple. Include both when they survive; if the archive row only lacks a runtime harness, report it at lower confidence or leave it in deferred rows rather than omitting it.
- Treat lack of an in-repository write endpoint as a precondition to state, not automatic suppression, unless repository evidence proves only trusted operators can set the value in the intended deployment.
- For command/action runner command-injection rows, closure requires exact evidence that every attacker-controllable argument type reaching shell/template execution is safely typed or escaped. A partial unsafe-type denylist, a safe direct-exec sibling, or frontend widget constraints do not suppress API/webhook-controllable argument types with nil/no-op typechecks.
- Include data exposure, hardcoded secrets, weak session/cookie/security config, CSRF, rate limits, and plaintext storage only after the high-impact ledger and file list are exhausted or when they directly enable code execution, injection, privilege escalation, meaningful auth bypass, or sensitive cross-boundary impact.
- The final markdown report may group related findings for readability, but each surviving instance must remain individually addressable with its own affected location, source, broken control, sink, impact, and counterevidence.
- Include suppressed candidates and deferred rows in phase artifacts with exact file/line and counterevidence or proof-gap reasons so false-positive controls and residual coverage gaps remain auditable.
