Files
Open_Ultra_SAST/.kiro/specs/contributor-scan/brief.md
T
Marius CiepluchandClaude Opus 5 41266ce472 docs(contributor-scan): brief -- the model layer is complete and unshipped
Asked what the spec state was and whether anything was forgotten. It was, and
it is the largest thing outstanding: model-grounded-detection is 16/16 tasks
complete and its arbiter measures 86.7% pair-correct at 6.7% leak, but the
model layer has ZERO production callers. `ousast scan` still runs
preprocess -> map -> overlay -> obligations -> regress -> report and touches
none of it. Every number quoted today came from a measurement harness in a
scratch directory.

That is a scope gap in the predecessor spec rather than a slip in executing it:
there was never a task saying "make this reachable", and its Req 11.2 (gates
stay byte-identical) is satisfied PRECISELY BECAUSE nothing is wired. The spec
is complete and the feature is unshipped, both at once.

A new spec rather than an amendment, because the predecessor is coherent and
closed -- it built an arbiter and measured it -- while this is a different
question: making it something a developer runs on a repository they are about
to contribute to.

What it covers, in the order it bites: scan integration; whole-repo scanning
(entry-point region selection, ranking across thousands of candidates, a budget
policy -- the enumerator caps at 8 per region, meaningless at repo scale -- and
a performance envelope never measured); running against a known-vulnerable
checkout, since the 176 real-world CVE pairs are single-function excerpts that
exercise none of it; the deferred memory decision, with 173 of those pairs idle
behind a stub tier; and retiring evidence_level.

It also records what was built outside any spec: the pipeline itself, the ops
work (one image, compose, shell wrappers, pyinfra -- with the Docker image
never actually built), and the corpus additions.

And it carries the known limits forward rather than losing them: the flat
permissive_values list that cannot tell debug=True from httponly=True,
interprocedural resolution as the most repeated miss cause, and the five bugs
that shared one shape -- a taint-specific assumption applied to every family,
each caught by a measurement rather than a check.

Not approved.

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

69 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Brief: contributor-scan — make the model layer a tool someone runs
**Status:** brief only, unapproved. Successor to `model-grounded-detection`, which is complete (16/16 tasks)
and is not reopened by this.
## The gap this exists to close
`model-grounded-detection` built and measured an arbiter. It works: 41.3% of the corpus reaches
`model_entailed` against the flat IR's 2.2%, and the wired pipeline scores 86.7% pair-correct at 6.7% leak
against the LLM hunter's 76.7% / 12.3%, at a fifth of the model calls and ~100× cheaper.
**And none of it is reachable by a user.** `ousast scan` still runs
`preprocess → map → overlay → obligations → regress → report` and touches the model layer nowhere;
`model/pipeline`, `judge`, `config_value`, `report`, `calibrate` and `execution` have zero production callers
outside `model/`. Every number quoted above came from a measurement harness in a scratch directory.
That is a scope gap in the predecessor spec, not an oversight in its execution: it had no task saying *make
this reachable*, and its Req 11.2 (the gates stay byte-identical) is satisfied precisely **because** nothing
is wired. The spec is complete and the feature is unshipped, both at once.
## What the goal actually is
> "a real world tool that helps developers when they want to contribute"
That reframes the work. A contributor does not have a labelled function and a known weakness class — they
have a repository they are about to touch and a question about what is risky in it. Everything measured so
far is function-level pairs: a labelled function, a declared family, a known target. None of it exercises the
questions a whole repository asks.
## What is missing, in the order it bites
1. **Scan integration.** Wire `model/pipeline` into `ousast scan` so a finding with a rung reaches a report.
Without this nothing else matters.
2. **Whole-repo scanning.** Region selection from entry points instead of a labelled function; ranking across
thousands of candidates rather than one; a budget policy (the enumerator caps at 8 candidates per region,
which is meaningless at repo scale); and the performance envelope — a CPG build on a 100k-line tree, not a
40-line excerpt. **This has never been run.**
3. **A known-vulnerable repository as the target.** The 176 real-world CVE pairs already in the corpus are
single-function excerpts and do not exercise any of the above. Running against a real checkout — curl,
libpng, a WordPress plugin — is the only way to find what breaks at scale.
4. **The memory decision.** 173 of those 176 pairs are `memory` family, routed to a deferred execution tier
that is a stub. Either adopt Clearwing for them or scope C memory-safety out explicitly. Right now it is
neither, and a sixth of the corpus sits idle.
5. **Retire `evidence_level`.** It duplicates `rung` in intent; noted as a follow-up in group 3 and never
tracked.
## Already built and unrecorded
These were delivered during `model-grounded-detection` without being in any spec. They belong here so the
record is not scattered:
- **The pipeline itself** (`model/pipeline.py`) — Req 8 existed, task 3.2 built `judge()`, and nothing ever
said to connect an enumerator to it. Built, tested, measured, unspecified.
- **Ops** — a single image carrying tool and engine, a compose file with read-only target and tmpfs scratch,
bash/zsh/PowerShell wrappers that make the container invisible, and a pyinfra deploy for host installs.
The Docker path is written and syntax-validated but **the image has never been built**.
- **Corpus** — the `owasp` slice (40 validated xss pairs; `output_encoding` went from 1 pair to 41) and
authored sink/sanitizer facts for Java and JavaScript.
## Known limits to carry forward
- `permissive_values` is a flat literal list with no keyword association, so it holds both `True` and `False`.
`debug=True` is dangerous where `httponly=True` is safe and the model cannot tell them apart.
- Interprocedural resolution is the most repeated miss cause across every experiment: OWASP's helper classes,
`angular-http-server`'s `resolveUrl`. Joern supports it; our queries may not be configured for it.
- Five bugs in `model-grounded-detection` shared one shape — a taint-specific assumption applied to every
family, each found by a measurement rather than a check. Any new family-specific path should be audited for
siblings before it is measured, not after.