Core concepts
The distinction between a candidate, proof, finding, and every non-proof state.
Candidate
A candidate is a per-scan hypothesis that changed code may contain an exploitable
source-to-sink path. The contract in
src/core/contracts/deton-candidate.ts records its family, rule, file and line
range, entry point, source, sink, supporting evidence, confidence, missing
context, and proofability.
Candidate confidence describes the static detector's confidence in its match. It is not confidence that exploitation succeeded. Candidate creation alone cannot produce a PR finding comment or a persisted evidence artifact.
Finding
In the current pure contracts, a “finding” is an in-memory issue value eligible only after the evaluator accepts a supplied identity-matching record and the builder's configured checks accept its fields. The label does not establish live execution, record authenticity, independent custody, persistence, delivery, or canonical publication. It is not a synonym for candidate.
The intended persisted deton_findings model gives the issue a stable identity
across scan runs, while candidates belong to individual runs. The table exists
in src/models/schema/deton/evidence.ts; the current scan job does not yet write
that table. Do not infer a complete cross-run finding lifecycle from the current
production path.
src/core/deton/security-issue-builder.ts enforces the public boundary: it
returns no in-memory security-issue value unless the pure evaluator accepted the
supplied identity-matching record and the candidate, plan, oracle identifiers,
and eligibility fields satisfy the configured checks. The current production
scan path does not persist that value as a standalone evidence artifact. An
eligible result may be formatted and submitted to GitHub, but construction
alone does not establish delivery success.
Proof plan and oracle result
A proof plan is a bounded contract derived from the candidate's attack family. Its
deterministic field is a schema enum value, not statistical confidence, not certainty, and
not repeatability, provenance, or attestation. The plan declares:
- the expected oracle and marker;
- minimum prospective replay instructions or sample limits;
- seed and identity requirements;
- forbidden observations;
- egress and data-extraction policy;
- a family-specific safety ceiling.
For an eligible configured run, the isolated runner returns an observation
record and the pure evaluator judges the supplied fields. The runner cannot set
confirmed itself, and a stored or illustrative record does not by itself
establish live execution, authenticated provenance, or custody. This separation
is encoded by src/libs/deton/runner/types.ts and
src/core/deton/oracle-evaluator.ts.
What confirmed requires
src/core/deton/verdict-engine.ts can emit confirmed only when all of these
conditions hold:
- The candidate has a proof plan and a supplied oracle-result record.
- Candidate ID, attack family, and oracle kind match across the records.
- Redaction is not blocked and the evidence contains no sensitive finding.
- Noise controls accept the observation.
- No forbidden observation appears.
- The observed marker exactly matches both the expected marker and the plan.
- The sample count meets the plan and the record carries
deterministicas a schema enum value. - Reproduction, fix guidance, bad-fix warning, prospective retest criteria, impact, affected location, and redacted proof are all present.
- The family is allowed to publish.
Today the registry marks only sqli and command_injection as
proof_enabled with first_pack_publishable. A contract entry for another
family does not make that family confirmable.
For the current evaluator, confirmed means that the evaluator accepted a
supplied, identity-matching record through the configured gates. It does not
prove live execution, record authenticity, or independent custody.
The deterministic label is a schema enum value. It is not statistical confidence, it is
not certainty, and it is not repeatability, provenance, or attestation.
Verdict states
The canonical verdict contract in src/core/contracts/deton-verdict.ts defines
six outcomes.
| State | Narrow meaning | What it does not mean |
|---|---|---|
confirmed | The pure evaluator accepted a supplied identity-matching oracle record whose deterministic field is a schema enum value. | Live execution, record authenticity, independent custody, statistical confidence or certainty, persisted evidence, GitHub delivery, canonical publication, or safety of unrelated paths and families. |
not_exploitable | A schema-compatible state reserved for a separately admitted bounded-refutation contract, which the current evaluator does not provide. | A conclusion derived from a missing observation, or a general proof that the code or repository is safe. |
inconclusive | For the current evaluator, observed: false yields inconclusive with reason oracle_not_observed; other incomplete or rejected evidence also remains inconclusive. | Safe, fixed, passed, or not exploitable. |
unsupported | No enabled proof contract is available for this candidate, or the family is deferred. | Absent or harmless. |
out_of_scope | The family is excluded from this proof scope. The dashboard collapses this to the neutral unsupported presentation. | Safe. |
error | Validation failed. The dashboard presents this as inconclusive. | Evidence for or against exploitability. |
The dashboard also has presentation states that are not canonical verdicts:
candidate— detected, without a proof plan currently in flight;proof_pending— a plan exists and the run is still active;stale— the scan was superseded before the candidate received a verdict.
Silence is not a safety guarantee
The current detector deliberately skips syntax it cannot classify confidently. It analyzes a bounded set of changed-file and source-to-sink shapes rather than the whole program. A run with no candidate means only that these heuristics did not raise one in the analyzed diff. An unsupported, inconclusive, stale, error, or empty outcome must not be translated into "no vulnerability."