mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-19 13:10:03 +00:00
Ran the humanizer rules over 79 prose files in the active specs (brief, design, requirements, research and narrative docs). Removed em dashes, significance inflation, forced rule-of-three, bold-label list items and filler. Skipped tasks.md checklists and the retired specs (harnessx-*, openrouter-sast-harness, unseen-repo-evaluation). Every number, path, command, hash and identifier was preserved: checked each file against HEAD for drift in numbers, inline code and code fences, zero drift across all 79 files. Co-Authored-By: Claude Opus 4.8 <[email protected]>
289 lines
19 KiB
Markdown
289 lines
19 KiB
Markdown
# Release milestones: prove usefulness, then speed and transfer
|
||
|
||
Accepted direction: 2026-09-14. The maintainer agreed to the five-step path and asked
|
||
for it to be recorded in the roadmap as a spec. This amendment defines the order and
|
||
observable exit criteria for the remaining release work within pre-push-safety-net.
|
||
It preserves the approved requirements, completed tasks and existing owner boundaries.
|
||
It does not approve an unreviewed implementation design or enable any capability.
|
||
|
||
## Current position
|
||
|
||
**Next milestone: M3, with M4 population preparation running in parallel. M1a and M1b are met;
|
||
M2 is measured NO-GO; none of M1–M5 is verified.** The published `v1.2.0-alpha.1` is an
|
||
experimental implementation release, not a qualified advisory rollout. See
|
||
[current status](status.md) for measured evidence and limitations.
|
||
|
||
The immediate goal was one real changed-code defect with a defensible explanation and a quiet
|
||
fixed twin. That is met. Task 8.3 remains blocked.
|
||
|
||
## Strategy amendment, 2026-09-21
|
||
|
||
Accepted after the family detection census and the PHP correction. Four decisions, in the order
|
||
they should be executed. They change sequence and declared scope; they change no acceptance
|
||
threshold and no owner boundary.
|
||
|
||
1. **Close M3 at a scale that completes, before anything else.** PHP transfer is recorded as not
|
||
established, and that record came from two instrument defects rather than from the analyser:
|
||
a census verdict that checked question completion before findings, and a region budget whose
|
||
question count cannot fit any ceiling. Bounded to 25 and 100 regions, Paid Memberships Pro
|
||
completes with no timeout and establishes a true-positive SQL injection of the class its own
|
||
fact table predicted. Re-run the declared transfer replay at a completing scale and let the
|
||
result stand either way.
|
||
|
||
2. **Reserve and review the untouched M4 population now, in parallel.** M4 already permits
|
||
population preparation to proceed before the frozen candidate exists, and it is the longest
|
||
lead-time item on this path: nothing can be qualified without it however good the analyser
|
||
gets. Starting it after M2 serialises the release for no reason.
|
||
|
||
3. **M2 is the only engineering item that remains, and it cannot be scoped away.** A changed-code
|
||
transaction spends its whole budget in the build with zero query time. Graph reuse across
|
||
revisions is the accepted direction. Narrowing what a push analyses is explicitly not a way to
|
||
meet the latency gate, so the work is architectural and should have the effort that family
|
||
vocabulary work has been absorbing.
|
||
|
||
4. **Declare the v1 advisory scope as the families whose claims can be ADMITTED.** Admission
|
||
requires the entailed rung. Injection, untrusted destination and configuration entail with
|
||
witnesses; access control does not, because on any application that splits its route from its
|
||
data access the obligation is carried and a carried obligation corroborates by design. Shipping
|
||
it would ship silence. Output encoding, path, prototype and deserialization have not earned a
|
||
place either. M4 explicitly does not require every language or family to become eligible.
|
||
|
||
**Amendment to the amendment, same day.** Decision 1's re-run exposed something larger than the
|
||
runtime limit it was chasing. A repository holding two languages can never complete a question,
|
||
because a partition boundary is classified as a graph-integrity gap and such a gap demotes every
|
||
completed outcome; and a completed outcome is what admission requires. NodeGoat completes 299 of
|
||
299 and VAmPI 35 of 35 because each holds one language, while PMPro completes none of 520 and
|
||
still establishes 43 findings. The declared v0.1 target is WordPress plugins, and a plugin is PHP
|
||
plus its admin JavaScript, so on the target this tool was built for it can detect and never admit.
|
||
Task 13.4 carries it, and it now ranks with M2 rather than behind it: a narrow JavaScript-only
|
||
release can proceed without it, and the WordPress target cannot proceed at all.
|
||
|
||
**The risk this amendment does not remove.** Every number so far comes from two repositories used
|
||
to build the analyser, and one week of examining them surfaced seven false positives. On untouched
|
||
code the precision estimate will move, against a bar of 95% with zero false alerts on the fixed and
|
||
benign sides. Expect the first M4 evaluation to fail and budget for a second. That is the strongest
|
||
argument for decision 2.
|
||
|
||
## M1: One real security change works end to end
|
||
|
||
Status: **NEXT, not verified**. Dependencies: existing immutable replay and scan machinery.
|
||
M1 is split into M1a (diagnose with vetoes recorded, not applied) and M1b (repair only
|
||
the vetoes M1a showed to matter). M1 is verified only when M1b passes.
|
||
|
||
Why the split: the detector already reports the NodeGoat contribution injection. The
|
||
2026-09-14 post-census bundle carries the raw `<lambda>2` witness at contributions.js
|
||
lines 32–34, and the same bundle carries thousands of `context_incomplete`,
|
||
`graph_incomplete`, `vendor_semantics_unresolved` and `ambiguous_line_correspondence`
|
||
reasons that discard it before any developer sees it. Four independent admission vetoes
|
||
are known: no context producer for dominance/config families, vendor exclusion acting as
|
||
a global completion veto, line ambiguity inherited by every question, and query identity
|
||
differing from witness identity. Requiring all four repaired before the first visible
|
||
result is a full production pass, not one detection.
|
||
|
||
### M1a: Show the detection with every veto recorded
|
||
|
||
Status: **MET 2026-09-16**, inside its one-week box. Evidence:
|
||
[M1a record](m1a-recorded-vetoes.md) and
|
||
[measurement](../../../benchmarks/measurements/2026-09-16-nodegoat-m1a-recorded-vetoes.json).
|
||
Raw witnesses present at contributions.js lines 32–34; fixed twin analyzed and quiet with
|
||
zero rows and no deadline reason; unchanged revision analyzed and recorded `unchanged`. The
|
||
kill criterion did not trigger. Five vetoes fired and were recorded, and M1a corrected the
|
||
diagnosis: with all five lifted the detection stops at `operation_correspondence_unresolved`,
|
||
a fifth veto that was not previously named. No defect was admitted and no capability enabled.
|
||
|
||
- Use the pinned NodeGoat contribution injection case, its fixed twin and an unchanged
|
||
vulnerable revision as development data. Record exact base/head revisions, expected
|
||
operation and outcome before running. Exercise the shipped replay path, existing ranker
|
||
and physically vendor-free graph; do not substitute a hand-selected slice or hard-coded
|
||
target function.
|
||
- Run all three revisions under an explicit experimental evaluation flag that **records**
|
||
each admission and comparison veto per finding instead of applying it. The flag is
|
||
task-local, off by default, cannot enable any hook capability, and every output it
|
||
produces is labeled experimental. A longer, explicitly named development budget applies;
|
||
it cannot satisfy the hook's latency gate.
|
||
- Deliverable: the raw finding on the vulnerable revision with location and witness, the
|
||
fixed twin genuinely analyzed and quiet, the unchanged revision not reported as a new
|
||
regression, and for every finding the exact list of vetoes that fired and why. Silence
|
||
from failure is not a pass; a fixed twin that timed out or was not analyzed fails M1a.
|
||
|
||
**Exit evidence:** a replayable three-revision record under the experimental flag with
|
||
exact revision, question and operation provenance, the per-finding veto list, and readable
|
||
source and census receipts. **Kill criterion:** if the fixed twin is not quiet under the
|
||
recorded-veto run, M1 has a detector problem, and M1b does not start until that is
|
||
diagnosed and recorded.
|
||
|
||
### M1b: Repair only the vetoes M1a showed to matter
|
||
|
||
Status: **NEXT, not verified**. M1a supplied the veto list: per-family change context,
|
||
question-owned vendor relevance, operation correspondence for an operation on a changed line,
|
||
file-wide correspondence ambiguity scope, and query-to-operation provenance. The owner
|
||
diagnosis expected the first and the last two; operation correspondence is the addition M1a
|
||
measured and is the blocker that survives every other repair.
|
||
|
||
- From the M1a veto list, repair only the context/family/identity contracts this case
|
||
actually needs. The owner diagnosis expects query-to-operation provenance and question-
|
||
owned vendor relevance to be the two that fire here; M1a confirms or corrects that.
|
||
Vetoes that did not fire on this case stay as they are and their families stay
|
||
experimental. Resolve vendor and correspondence boundaries through evidence of dependency
|
||
and ownership; unknown relevance remains unresolved.
|
||
- Rerun the three revisions **without** the recorded-veto flag through the production
|
||
evidence and comparison rules. Demonstrate a developer-readable evaluation finding with a
|
||
supported security consequence, exact location, witness, change attribution and concrete
|
||
repair direction. Verify the fixed twin is analyzed and produces no actionable defect, and
|
||
the unchanged vulnerable revision is not reported as a new regression.
|
||
- Keep qualification eligibility disabled. The demonstration uses explicit experimental
|
||
evaluation output; it cannot advertise an unqualified normal hook alert.
|
||
|
||
**Exit evidence:** a replayable vulnerable/fixed/unchanged comparison record through the
|
||
production rules, exact question and operation provenance, completed required checks,
|
||
reviewed explanation, readable source and census receipts, task-local regression
|
||
verification, and a list of which vetoes were repaired and which remain. Raw findings, rank
|
||
positions, synthetic-only controls and screenshots alone do not satisfy M1b.
|
||
|
||
Owners: contributor-scan for query/operation/context evidence; pre-push-safety-net for
|
||
comparison, admission, the recorded-veto flag and reporting. Requirements: 1.1–1.4,
|
||
2.1–2.4, 3.1–3.5, 6.3, 7.1–7.3.
|
||
|
||
## M2: The same useful analysis fits the push budget
|
||
|
||
Status: **MEASURED AND UNMET, 2026-09-17.** Two attacks on engine startup were measured and
|
||
neither reaches the gate. A transaction-owned session is implemented and proven equivalent for
|
||
every shipped query kind, and it amortizes startup only across a long transaction: 326 s to 243 s
|
||
under a development budget, while under the 30-second deadline its own 9 to 13 second startup
|
||
means it usually declines to start. Removing JavaScript's redundant second engine start is a real
|
||
11.0 s against 21.0 s on identical graphs, but the attempt was reverted for an asymmetric census
|
||
gate that made 12 profile transactions pay two engine starts.
|
||
|
||
The profile names the actual cost: a changed-code transaction reaches its deadline inside the
|
||
build, head build 25.2 s of 30 s with query time 0.0 s. It is building a fresh whole-repository
|
||
graph for every pushed revision.
|
||
|
||
**Direction accepted 2026-09-17: do not rebuild a whole graph per push. Reuse the graph across
|
||
revisions instead of further optimising the rebuild.** The 30-second and 2-second gates are
|
||
unchanged; this milestone is not met, and the work is not scheduled here.
|
||
|
||
- Use the successful M1 case as a correctness baseline for a transaction-owned Joern
|
||
session within the existing backend. The measured census probe supports investigating
|
||
this design; it does not establish full-query equivalence or production readiness.
|
||
- Verify equivalent taint, dominance and configuration answers under matching semantics,
|
||
fresh request receipts, isolated graph identities, cache invalidation, crash handling
|
||
and process-group cancellation. Keep one deadline across the complete transaction.
|
||
- Rerun the frozen seven-class runtime profile with changed-code cases, cold starts,
|
||
dependency/configuration edits, growth and multi-ref transactions. Retain all timeouts
|
||
and unresolved checks. Identical-tip reuse cannot substitute for warm changed-code work.
|
||
|
||
**Exit evidence:** the M1 outcome remains correct; representative warm changed-code p95
|
||
is at most 30 seconds, cancellation/reporting at most two seconds, and supported-check
|
||
completion at least 95%, under the predeclared profile. A fast census alone does not pass.
|
||
|
||
Owner: contributor-scan runtime, with pre-push-safety-net deadline/cache integration.
|
||
Requirements: 4.1–4.4, 6.2–6.5, 7.3.
|
||
|
||
## M3: The shared design transfers across languages
|
||
|
||
Status: **PARTIAL, 2026-09-17. Not met.** Python is established and PHP is blocked by runtime.
|
||
|
||
Python: all three declared VAmPI targets detected at their declared lines with their questions
|
||
answered, 35 of 35 questions complete on every case, nothing reported new on identical revisions,
|
||
zero admitted defects. That includes the SQL injection this spec names as previously unresolved,
|
||
and both broken-object-level-authorization targets, which is the first time access control has
|
||
answered on Python at all.
|
||
|
||
PHP: not established, and the blocker is now named. All PMPro comparisons exhausted every budget
|
||
tried, up to a 4500-second deadline with a 900-second query ceiling, and produced no artifact, so
|
||
there is no target evidence. Splitting a failed batch into parts did not rescue it.
|
||
|
||
A probe narrowed the cause: the evidence pass answers all 4,425 PMPro regions in one batch in
|
||
29.7 seconds with a 681 KB response, and its cost is fixed rather than per request. Neither
|
||
request count nor response size is anywhere near a limit. What fails is the execution pass, which
|
||
runs `reachableByFlows` per candidate. The pins, receipts and declared target are correct, so the
|
||
question is being asked properly and the dataflow work is what cannot finish.
|
||
|
||
The exit asks for Node, PHP and Python together. Two of three are in hand.
|
||
|
||
- Repeat the useful vulnerable/fixed comparisons with PMPro/PHP and VAmPI/Python,
|
||
including the previously unresolved VAmPI SQLI query/path evidence. Preserve explicit
|
||
limits for authorization and other families whose evidence is still unsupported.
|
||
- Keep framework knowledge in frontends/adapters and versioned facts. Equivalent normalized
|
||
evidence must retain the same core ranking, scope and admission behavior.
|
||
- Record core and adapter changes separately. Any PMPro-driven core change must be frozen
|
||
and replayed on Node/Express before claiming transfer; the initial Node-first repair
|
||
does not remove that existing requirement.
|
||
|
||
**Exit evidence:** reviewed development/regression results for Node, PHP and Python,
|
||
including positive, fixed and unchanged controls, exact provenance, coverage and runtime.
|
||
Do not label these repeatedly inspected projects independent qualification. C/C++ bounds
|
||
remain a separate unsupported abstraction; adding a new engine is not a prerequisite here.
|
||
|
||
Owners: contributor-scan shared evidence and framework adapters; pre-push-safety-net evaluation.
|
||
Requirements: 6.2–6.4, 8.1–8.4.
|
||
|
||
## M4: Independent examples establish useful detection and low noise
|
||
|
||
Status: **PENDING M3**. Population preparation may proceed earlier, but evaluation follows
|
||
the frozen candidate. Reserve untouched cases before examining their scan results.
|
||
|
||
- Freeze reviewed vulnerable, fixed and benign changes from projects not used to develop
|
||
or tune the particular language/framework/family. Ghost remains reserved until its
|
||
actual reviewed population exists. Node evidence cannot qualify PHP or Python.
|
||
- Measure actual actionable alerts, supported recall, fixed-side silence, benign interruptions,
|
||
completed coverage and runtime together, with counts and uncertainty. Keep unlocated
|
||
targets, unanswered queries and unsupported cases visible in their declared populations.
|
||
- Apply the existing acceptance profile: at least 95% observed actionable precision,
|
||
at least 90% supported recall, at least 95% supported-check completion, the 30s/2s runtime
|
||
gates, nonzero reviewed emitted alerts and positive controls, and zero known fixed/benign
|
||
false alerts. Silence on everything fails. A core retune requires new untouched evaluation.
|
||
|
||
**Exit evidence:** reproducible, reviewed per-capability qualification with every mandatory
|
||
gate passing together. Report failures honestly and leave those capabilities experimental;
|
||
do not require every possible language or family to become eligible for a narrow release.
|
||
|
||
Owner: pre-push-safety-net task 8.3, consuming verified contributor-scan semantics.
|
||
Requirements: 6.1–6.5, 8.1–8.4 and the accepted experimental acceptance profile.
|
||
|
||
## M5: Enable a narrow advisory rollout
|
||
|
||
Status: **PENDING M4**.
|
||
|
||
- Generate eligibility bound to the exact passing runtime, query, fact, ranking and policy
|
||
identities. Enable only independently qualified capabilities; stale or missing evidence
|
||
enables none. Advisory retains the same evidence bar as blocking.
|
||
- Revalidate the packaged vulnerable/fixed/benign push experience, compact reporting,
|
||
truthful incomplete coverage, local no-model operation and preservation/removal of hooks.
|
||
- Publish the supported scope, limitations and evidence with the advisory release.
|
||
Expand capabilities only when they earn qualification. Blocking deployment is a later,
|
||
explicit decision, even though opt-in blocking plumbing already exists.
|
||
|
||
**Exit evidence:** passing packaged acceptance validation and exact eligibility for the
|
||
declared advisory scope, with the release decision recorded. Only then mark task 8.3
|
||
and release readiness complete if their mandatory criteria are satisfied.
|
||
|
||
Owner: pre-push-safety-net admission, packaging and release validation.
|
||
Requirements: 3.1–3.5, 5.1–5.5, 6.5, 7.1–7.4.
|
||
|
||
## Execution and reporting contract
|
||
|
||
Use M1a → M1b → M2 → M3 → M4 → M5 as the critical path. Preparation may overlap, but later
|
||
milestones cannot substitute for missing earlier evidence. Necessary runtime repairs
|
||
that make M1 executable are allowed; a standalone speed benchmark cannot close M1.
|
||
Keep ranker-owned scope, vendor exclusion, language-agnostic core behavior and all
|
||
acceptance thresholds unchanged. No new source IR, second detector, differential graph
|
||
mutation, learned ranker or unrelated backlog is introduced by this amendment.
|
||
|
||
Before production edits, make the required owner design/task amendment concrete and
|
||
apply the existing Kiro approval, review and verification workflow. Prior authorizations
|
||
remain valid within their scope; this milestone record does not reset them.
|
||
|
||
Progress updates shall lead with the current milestone, observed developer outcome,
|
||
remaining blocker and next concrete action. Report implementation task counts separately.
|
||
Change a milestone to verified only with linked evidence; do not infer progress from
|
||
elapsed effort or a completed experimental release tag.
|
||
|
||
Immediate next action (M3, task 13.3): re-run the declared PHP transfer replay bounded to a
|
||
region budget whose questions complete, using the corrected census verdict, and record the
|
||
outcome either way. Then task 13.4, PHP question completion, because admission reads outcomes
|
||
and M4 measures completion at 95%. Task 15.1 (M4 population reservation) runs in parallel and
|
||
blocks on nothing. Do not begin another family vocabulary campaign: the census has said which
|
||
families can speak, and the constraint has moved to runtime and to evidence from code this
|
||
project has not seen.
|