mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-17 20:19:29 +00:00
**Amendments approved and folded into the numbered requirements** rather than left as a proposal appended to the file: - Req 5.5 — a report proportionate to the evidence behind a finding. A rule whose only evidence is a text match is summarised past a stated number of sites; a finding a proposer reasoned about keeps its detail whatever its rung; nothing leaves findings.json, which is the record a baseline is compared against. - Req 5.6 — a family that cannot decide a class states the limit, and no scan presents an absence of findings as evidence of absence. - Req 4.6 — at least one pinned checkout carries a vulnerability a family can decide in principle, so a scan producing nothing is distinguishable from an engine that cannot see. Each carries the evidence that produced it, and the amendment record keeps what group 2 confirmed rather than changed: Req 8's overfitting warning earned its place twice, Req 3.3's honesty counters made an invisible failure visible, and Req 11.2's gates held through all nine defect fixes. Req 5.5 is half implemented. Task 2.11 made pattern matches proportionate; task 2.17 now carries the model layer's own suspicion band, which is 38 of vampi's 60 findings and is an enumerated candidate the graph could NOT decide with a judge's opinion attached -- a pattern match with an opinion, not a reasoned claim, and weaker evidence than the obligations checker's structural output. **finding-feedback-loop requirements generated**, seven of them: a dismissal file the developer owns and the tool never writes, rejecting one without a reason because a suppression list without reasons is a graveyard nobody can audit; a counter-example ledger whose entries are runnable regression cases, grouped by shared cause so a recurring bug is visible as one; a model that proposes a cause into a review queue and decides nothing, validated by reverting the three known matcher fixes and measuring what it recovers; dismissals plus a recipe's known vulnerabilities as one split evaluation set with the holdout unread and asserted; evolution scoped to the judge and residual questions with the fact tables off limits to any automated means; an adoption that reports what it traded and reverts itself when net-negative; and the loop inheriting the corpus blind spot, so its evidence base is repositories and it states how few it has. Phase: requirements, generated, not approved. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
137 lines
7.7 KiB
Markdown
137 lines
7.7 KiB
Markdown
# Requirements Document: finding-feedback-loop
|
||
|
||
## Introduction
|
||
|
||
Nine engine defects were found in one session against two repositories. **Three were the same bug in three
|
||
matchers** — a spec token matched as a substring rather than a word: `resolve` inside `resolveUrl` in the
|
||
sanitizer matcher, `user` inside `users` in the discharger matcher, `gets` inside `fgets` in the sink matcher.
|
||
Each was found by a measurement, fixed locally, and left no trace; the third survived until an 89k-line C
|
||
library made it visible as 26 identical false positives.
|
||
|
||
Nothing in the system remembers that a finding was wrong. There is no artifact saying *this site, at this
|
||
rung, is not a defect, and here is why* — so a class recurs, and each recurrence costs another measurement.
|
||
|
||
Two audiences want that artifact for different reasons. A maintainer wants the *propagation* automated: two of
|
||
the three matcher bugs needed no judgement at all, only the fix carried across. A developer wants to dismiss a
|
||
finding in their own repository, have it stay dismissed, and have the reason reviewable beside the code — a
|
||
tool that cannot be told it is wrong is one they stop running.
|
||
|
||
This feature is bounded by a rule the project has held from the start and a leak that shows why. An optimiser
|
||
may evolve **the question** — the judge and residual prompts, which are how we ask. It may never author **the
|
||
facts** — tables, rulesets, the declared policy file, which are what we claim. On 2026-09-05 the improve lever
|
||
admitted candidate shapes because they "recover a currently missed holdout pair"; five of eleven were taught by
|
||
the holdout pairs they then recovered, and a holdout Youden of **−0.059 was reported as +0.059**.
|
||
|
||
Context: `brief.md`, `.kiro/specs/contributor-scan/` (Req 8 on overfitting, Req 10 on baselines), the memory
|
||
`closed-loop-train-on-test-leak`, and the measurements
|
||
`2026-09-09-repo-vampi-authz-precision.json` and `2026-09-09-repo-libpng-bounds.json`.
|
||
|
||
## Requirements
|
||
|
||
### Requirement 1: A dismissal the developer owns
|
||
|
||
**Objective:** As a developer, I want to record that a finding is not a defect in my repository, so it stays
|
||
recorded and my colleagues can see why.
|
||
|
||
#### Acceptance Criteria
|
||
|
||
1. The system shall read dismissals from a declarative file in the **target** repository, and shall never
|
||
write to it — the same rule the declared policy file already follows.
|
||
2. A dismissal shall carry the site it concerns, the rung it was dismissed at, a reason, and an author.
|
||
3. The system shall reject a dismissal that carries no reason, because a suppression list without reasons is
|
||
a graveyard nobody can audit.
|
||
4. The system shall report a dismissed finding as dismissed, with its reason, rather than omitting it — so a
|
||
stale dismissal is visible rather than silent.
|
||
5. When a dismissal no longer matches any finding, the system shall say so, because a dismissal that has
|
||
stopped applying is either a fixed bug or a moved target and both are worth knowing.
|
||
|
||
### Requirement 2: A counter-example ledger the maintainer can group
|
||
|
||
**Objective:** As a maintainer, I want every rejected finding recorded with what produced it, so a recurring
|
||
cause is visible as a cause rather than as five separate bugs.
|
||
|
||
#### Acceptance Criteria
|
||
|
||
1. When a finding is contradicted — by a dismissal, by the judge with coverage, or by a declared contract —
|
||
the system shall record the site, the rung, the witness, the spec tokens that produced it, and the commit.
|
||
2. Each ledger entry shall be runnable as a regression case: this site, at this commit, shall not be reported
|
||
at that rung.
|
||
3. The ledger's regression cases shall run offline in CI, so that re-introducing a fixed cause fails a test
|
||
rather than a repository scan four weeks later.
|
||
4. The system shall group ledger entries by what they share — spec token, matcher clause, family, witness
|
||
shape — and report the groups by size.
|
||
5. The ledger shall be committed evidence, not a local artifact.
|
||
|
||
### Requirement 3: A model may propose a cause, and only propose it
|
||
|
||
**Objective:** As a maintainer, I want the model to do the part that needs judgement — naming what a group of
|
||
counter-examples has in common — without it deciding anything.
|
||
|
||
#### Acceptance Criteria
|
||
|
||
1. Given a group of counter-examples, the system shall ask a model for a hypothesis: what these share, and
|
||
what change would remove all of them.
|
||
2. The model's output shall be written to a review queue, and shall never be written to a fact table, a
|
||
ruleset, or the declared policy file.
|
||
3. An adoption shall require a human commit, exactly as any other change to those files does.
|
||
4. The system shall be validated by reverting the three known matcher fixes and measuring how many of their
|
||
groups it recovers and what it proposes. A model that cannot rediscover a cause already known shall not be
|
||
trusted to propose one that is not.
|
||
|
||
### Requirement 4: Dismissals are a labelled evaluation set
|
||
|
||
**Objective:** As a maintainer, I want a repository's dismissals and its known vulnerabilities to form one
|
||
evaluation set, so an optimiser has both classes rather than only the negatives.
|
||
|
||
#### Acceptance Criteria
|
||
|
||
1. The system shall build a per-repository evaluation set from a `benchmarks/repos/` recipe's known
|
||
vulnerabilities and that repository's dismissals.
|
||
2. The evaluation set shall declare a train/holdout split.
|
||
3. The system shall not read the holdout during optimisation, and a test shall assert it.
|
||
4. The system shall report the size of both classes, because an evaluation set of negatives alone can only
|
||
teach silence.
|
||
|
||
### Requirement 5: Evolution targets the question, never the facts
|
||
|
||
**Objective:** As a maintainer, I want the prompts to improve against real rejections without the fact tables
|
||
ever being authored by a model.
|
||
|
||
#### Acceptance Criteria
|
||
|
||
1. The system shall support reflective evolution over the judge and residual questions only.
|
||
2. The system shall not modify sources, sinks, sanitizers, obligations, dischargers, rulesets or the declared
|
||
policy file by any automated means.
|
||
3. An evolved prompt shall be scored on the train split alone.
|
||
4. An evolved prompt shall be adopted only when it affirms fewer dismissed sites **and** loses no known
|
||
vulnerability.
|
||
5. The three gates shall stay byte-identical across an adoption, or the adoption is a regression wearing a
|
||
fix's clothes.
|
||
|
||
### Requirement 6: An adoption reports what it cost
|
||
|
||
**Objective:** As a maintainer, I want to see what an adoption traded, because a false-positive reducer that
|
||
quietly loses recall is worse than none.
|
||
|
||
#### Acceptance Criteria
|
||
|
||
1. Every adoption shall record precision and recall before and after, on the pinned repositories and on the
|
||
pair corpus.
|
||
2. Every adoption shall record which counter-examples it removed and which it did not.
|
||
3. A net-negative adoption shall be reverted automatically rather than argued about.
|
||
4. The system shall record what a target repository's evolved state learned and what it was measured against,
|
||
so per-repository tuning is legible rather than a black box.
|
||
|
||
### Requirement 7: The loop inherits the corpus's blind spot
|
||
|
||
**Objective:** As a maintainer, I want this loop measured on the evidence that can actually see its failures.
|
||
|
||
#### Acceptance Criteria
|
||
|
||
1. The evaluation set shall include whole repositories, not pairs alone: the pair corpus could not see any of
|
||
the nine defects that motivate this feature, and the gates stayed byte-identical through every fix.
|
||
2. The system shall state how many repositories its evidence base contains, because two — one of which has
|
||
never produced a true positive — is very little to tune against.
|
||
3. Where an adoption is measured on one repository only, the system shall label it as such rather than
|
||
reporting it as a general improvement.
|