2026-09-12 18:45:54 +02:00
|
|
|
# Reproducible push evaluation inputs
|
|
|
|
|
|
|
|
|
|
`inputs.json` schema 1 declares 11 cases and 9 snapshots before any new scanner run.
|
|
|
|
|
Run `.venv/bin/python -m openultrasast.push_inputs benchmarks/push/inputs.json`.
|
|
|
|
|
It is offline by default, even if the ordinary repository network environment variable is set.
|
|
|
|
|
`--fetch` explicitly permits the existing repository resolver to fetch missing pinned commits.
|
|
|
|
|
No project scripts, npm installation, or scanner are executed. Nonzero exit means at least one
|
|
|
|
|
case has invalid input or an explicit missing prerequisite; the complete population stays in JSON.
|
|
|
|
|
|
|
|
|
|
Each snapshot references an existing repository recipe (with an optional full commit override),
|
|
|
|
|
plus a census of readable witness/context/license blobs. The commit identifies the whole tree;
|
|
|
|
|
the file list is provenance evidence, **not an analysis scope or graph allowlist**. Future replay
|
|
|
|
|
must materialize the pinned tree and apply declared authored edits before the ranker chooses scope.
|
|
|
|
|
Bytes come from `git cat-file` at the full SHA rather than the mutable cached working tree.
|
|
|
|
|
SHA-256 and byte length are checked for every listed blob. An authored replacement must match
|
|
|
|
|
exactly once, declare provenance, and verify both the original and resulting identity.
|
|
|
|
|
|
|
|
|
|
PMPro uses upstream 2.9.7 and 2.9.8. Its SQL query changes from interpolation to `$wpdb->prepare`.
|
|
|
|
|
The introducing replay reverses the reviewed pair; it does not claim that 2.9.7 historically
|
|
|
|
|
introduced the CVE. NodeGoat's contribution handler evaluates three request fields before numeric
|
|
|
|
|
validation. Its authored repair replaces these eval calls with `Number`, eliminating JavaScript
|
|
|
|
|
execution; it is not represented as an upstream security fix or a comprehensive numeric-validation
|
|
|
|
|
repair. Its commented tutorial repair remains unchanged. Existing injection facts include JavaScript
|
|
|
|
|
`eval`; actual frontend, ranker and arbiter behavior remains to be measured.
|
|
|
|
|
|
|
|
|
|
Both benign variants change only a comment on the **vulnerable** base. They mean no new defect,
|
|
|
|
|
not repository-clean, and deliberately retain backlog to test whether the hook becomes a nag.
|
|
|
|
|
The PMPro source pair is GPL-2.0; NodeGoat is Apache-2.0. Only hashes and small authored edit
|
|
|
|
|
instructions are stored here; repository source stays in the external opt-in cache.
|
|
|
|
|
|
|
|
|
|
Ghost is reserved independently for its production Node API, CommonJS module boundaries and async
|
|
|
|
|
endpoint methods, with public reviewable history at
|
|
|
|
|
https://github.com/TryGhost/Ghost/security/advisories. The pin declares Ghost 6.64.0-rc.0 and
|
|
|
|
|
Express 4.22.2. It does not establish ESM or Express 5 coverage. Selection inspected only the
|
|
|
|
|
manifest, license and endpoint shape, not scanner results. Their source bytes were read at the
|
|
|
|
|
pinned raw GitHub URLs and hashed; the offline validator still requires Git object availability.
|
|
|
|
|
Its supported-family positive/fixed/benign population must be independently reviewed and frozen
|
|
|
|
|
before scanning. If inspected results inform tuning, retire its holdout status. No reserved
|
|
|
|
|
security case is silently inferred from the existence of an advisory.
|
|
|
|
|
|
|
|
|
|
All capabilities remain experimental: NodeGoat is inspected transfer/development data and cannot
|
|
|
|
|
qualify production Node support; Node evidence cannot qualify PHP or Python. Independent PHP and
|
|
|
|
|
Python populations are explicitly missing in `capability_prerequisites`. VAmPI retains all three
|
|
|
|
|
known targets (including SQLI), with `vulnerable=1`; these snapshot regressions are not paired pushes.
|
|
|
|
|
Libpng is an envelope/unsupported-arithmetic control, not a detection success or a supported miss.
|
|
|
|
|
The validator makes no finding, precision, recall, silence, latency or admission claim.
|
2026-09-12 19:04:20 +02:00
|
|
|
|
|
|
|
|
## Frozen diagnostic scoring (task 1.3)
|
|
|
|
|
|
|
|
|
|
`push_scoring` consumes recorded execution evidence; it does not run the scanner or
|
|
|
|
|
implement push delta/admission policy. Freeze the workload and expected configuration
|
|
|
|
|
**before** executing it:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
.venv/bin/python -m openultrasast.push_scoring freeze benchmarks/push/inputs.json benchmarks/push/diagnostic-config-v1.json > /tmp/profile.json
|
|
|
|
|
.venv/bin/python -m openultrasast.push_scoring score /tmp/profile.json benchmarks/push/input-validation.json benchmarks/push/unmeasured-run-v1.json
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The committed v1 profile reserves the 11 declared cases and exact tip target locations.
|
|
|
|
|
It is a proposed 30-second evidence-mode experiment, not measured performance. The
|
|
|
|
|
`unmeasured-run-v1.json` deliberately contains no executions: scoring it exits **1**,
|
|
|
|
|
retains all 11 unresolved cases, and earns no recall, coverage or admission. An invalid
|
|
|
|
|
profile/runtime identity exits **2**. A fully resolved diagnostic score exits **0**;
|
|
|
|
|
that exit status is not capability admission. Freeze a new version when configuration,
|
|
|
|
|
source manifest, core, facts, query semantics or scope changes; do not edit a measured
|
|
|
|
|
profile to match later execution. Runtime `context` must record the actual values,
|
|
|
|
|
not merely copy an expected profile hash. Profiles are content identities, not signatures.
|
|
|
|
|
|
|
|
|
|
Each `records` entry supplies `case_id`, actual `ranking_mode`, `rank` (or null), exact
|
|
|
|
|
`selected`/`deferred` question IDs, `queries`, `alerts`, `delta`, `coverage`, `cache_state`
|
|
|
|
|
and nonnegative elapsed `timings` including `total`. Cache states distinguish `cold`,
|
|
|
|
|
`warm_changed` and `identical_tip`; stage costs remain beside each outcome. Queries
|
|
|
|
|
supply `id`, `status` and `outcome`. A positive needs a finding with the exact frozen
|
|
|
|
|
`site` and `family`, a supported `rung`, and a nonempty actual `witness`. A transitive
|
|
|
|
|
claim additionally needs a recorded `origin` and ordered `flow` from that region to
|
|
|
|
|
the frozen target's path/function. Missing rank never proves transitivity. Negative
|
|
|
|
|
answers require the exact `target` and a witnessed discharge; empty/failed queries
|
|
|
|
|
cannot earn fixed-side silence. These checks establish evidence association, not the
|
|
|
|
|
truth of an arbitrary supplied witness: use engine output and review the attribution.
|
|
|
|
|
|
|
|
|
|
Alerts are separate from raw findings. Only reviewed `actionable_true` alerts with
|
|
|
|
|
`review_evidence`, `question_id` and exact `site` association can contribute precision;
|
|
|
|
|
unreviewed/wrong-target alerts remain in its denominator. Benign comment changes retain
|
|
|
|
|
vulnerable backlog, so a raw positive is not automatically a new alert. The scorer
|
|
|
|
|
consumes a recorded delta; task 5.1 supplies replay, and the policy tasks establish it.
|
|
|
|
|
|
|
|
|
|
Reports retain unresolved cases, sample counts, Wilson intervals, separate regression
|
|
|
|
|
results, per-capability metrics, coverage and cold/warm latency. Missing benign runs
|
|
|
|
|
have unknown interruption rate. VAmPI's readable regression may be measured while
|
|
|
|
|
independent admission prerequisites remain missing. Unsupported/unreviewed populations
|
|
|
|
|
stay visible. All results remain experimental pending the later joint admission gate.
|
2026-09-13 15:24:06 +02:00
|
|
|
|
|
|
|
|
## First full replay experiment (task 5.2)
|
|
|
|
|
|
|
|
|
|
`measure.py` runs the six prepared PMPro/NodeGoat security, fixed and benign cases
|
|
|
|
|
through the production `ousast pre-push` CLI. It does not supply a hand-selected
|
|
|
|
|
source slice or regions. The complete 11-case population remains in the scorer;
|
|
|
|
|
Ghost is not scanned, and the separate VAmPI/libpng populations are retained as
|
|
|
|
|
unexecuted regression/envelope evidence rather than being silently dropped.
|
|
|
|
|
|
|
|
|
|
Build the local image first, then run with a writable output parent and the existing
|
|
|
|
|
repository-object cache mounted read-only:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
docker run --rm --network none --memory 3g --entrypoint python \
|
|
|
|
|
-v "$PWD:/context:ro" \
|
|
|
|
|
-v "$HOME/.cache/openultrasast/repos:/cache:ro" \
|
|
|
|
|
-v /path/to/output-parent:/results \
|
|
|
|
|
openultrasast:dev /context/benchmarks/push/measure.py \
|
|
|
|
|
--manifest /context/benchmarks/push/inputs.json --cache /cache --out /results/new-run
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The output directory must not already exist. Input validation opens and verifies
|
|
|
|
|
pinned source/license blobs before any measurement. A private bare Git repository
|
|
|
|
|
reads the existing objects and creates reproducible authored commits using only the
|
|
|
|
|
specified edits. Every other tracked blob remains in the tree; the cache's files,
|
|
|
|
|
index and refs are unchanged. No project code, package installation or network is used.
|
|
|
|
|
|
|
|
|
|
`profile.json` is written before the first replay. PMPro runs first, followed by an
|
|
|
|
|
explicit `freeze-after-pmpro.json` checkpoint and Node with identical installed core,
|
|
|
|
|
facts, queries and policy. Both analysis and cancellation allowances stay 30 and 2
|
|
|
|
|
seconds. Whole CLI elapsed time, separate available stage costs, exact input pins,
|
|
|
|
|
source byte counts, selected/deferred identities, raw artifacts, process exits and
|
|
|
|
|
terminal output remain available. `rank` denotes an observed selected-question position;
|
|
|
|
|
an unlocated/unselected target retains null. A completed empty query cannot earn a
|
|
|
|
|
witnessed negative or fixed-side silence. No transitive path is fabricated from rank.
|
|
|
|
|
|
|
|
|
|
`scorecard.json` uses the existing frozen-population scorer. `decision.json` explicitly
|
|
|
|
|
returns NO-GO because this initial cold diagnostic does not qualify independent
|
|
|
|
|
capabilities or prove joint quality and warm latency. Exit **1** with a completed
|
|
|
|
|
`decision.json` means measured NO-GO; a traceback without that completion record is a
|
|
|
|
|
failed instrument. Zero CLI exit means advisory allow, never complete analysis.
|
|
|
|
|
Missing artifacts and unanswered questions remain errors/unresolved, not clean results.
|
|
|
|
|
|
|
|
|
|
Cold here means no persisted graph/query/comparison reuse; filesystem caches are not
|
|
|
|
|
flushed. Six one-shot runs are diagnostic samples, not representative warm p95 evidence.
|
|
|
|
|
Normal capabilities remain disabled, so zero alerts do not establish precision or useful
|
|
|
|
|
recall. A separately named longer lab run may obtain witnesses, but cannot replace the
|
|
|
|
|
30-second measurements or satisfy the hook's latency gate.
|