Commit Graph
242 Commits
Author SHA1 Message Date
Marius CiepluchandClaude Fable 5.1 81ae206978 fix(hunt): build output gets no candidate rows, a minified line is not scanned once per function, the screen checkpoints every change
The second access-control screen spun for 2h20m on one ordinary mage-ai change: a Next.js build commit whose 3 MB
one-line bundles hold 12,355 functions each. `source.ranges_from_ir` ran two regex scans of the whole line once per
function, and the screen kept its 422 finished changes in memory only, so stopping it lost them.

- `source.ranges_from_ir`: a line over MINIFIED_LINE_CHARS (2000) is not checked per function; JavaScript names on it
  stay anonymous, other languages keep the parser's name.
- `source.generated_reason`: why a changed file is build output (a directory the product walk leaves out, a minified
  name, over MAX_FILE_BYTES, a line over the cap). `hunt.producers._candidates` leaves such files out and records the
  reason on the context; the fix site of a vulnerability is always kept. The DSPy arm shares the enumeration.
- The screen writes rows.jsonl and log.jsonl per change (rows first, entry last) and resumes by skipping logged ids.

Tests: the minified line never reaches the per-function scan; generated_reason on the four shapes and two source files;
build output in an ordinary change yields no rows while a vulnerability path in a one-line file is kept.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 13:24:45 +02:00
Marius CiepluchandClaude Fable 5.1 0d7d3f0dc9 chore: format the whole tree and lint the scratch measurement scripts; CI has been red since 25ae4b4
CI runs ruff format --check and ruff check over the whole repository; 29 files had drifted from the formatter and
four measurement scripts carried lint findings, so every push since 25ae4b4 failed before pytest ran.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 02:49:44 +02:00
Marius CiepluchandClaude Fable 5.1 fbbc03f3ea measure: access-control feature table and separation screen (952 rows, 74 positive rows, 5 repositories); first ablation manifest registered
Three builds: the first two read 150 rows as empty (a producer bug, fcb43fd), the third is clean. The diff
producer was blind to removed lines (537b61e). Screen: deletion_count 0.89 is the reversed-fix construction;
on rows whose file lost lines entry_point_count 0.83 and caller_count 0.73 are the class signal; semantic covers
262 rows (TypeScript only). Repository folds assigned, leak audit recorded, manifest ac-ablation-1 registered
for decision (five arms, about 35 dollars).

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 02:45:35 +02:00
Marius CiepluchandClaude Fable 5.1 dee23c23f5 measure: both arms over the access-control training pool (2 of 5 pushes, 4 of 48 locations each); runner books real cost
DSPy baseline: 2/5 pushes, 4/48 locations, 14 of 90 ordinary pushes flagged, 25 suspicions (3 true), 11 invalid-request
failures in shopper and trigger.dev, $6.13. Pilot hunter: 2/5 pushes, 4/48 locations, 99 of 100 ordinary pushes
flagged, 594 findings (3 true). Different pushes caught; nothing in trigger.dev.

The runner booked usd 0.0 per change so --budget-usd never stopped a run; it now prices every LM call of the change
at the registered prices and writes usd into the record.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 01:14:46 +02:00
Marius CiepluchandClaude Fable 5.1 537b61e8d9 fix(hunt): diff producer records where a push removed lines; worktree checkout is proven complete
Two instrument findings from the first access-control feature table (952 rows, 74 positive rows):

1. A fix that adds a guard is, replayed base-to-head, a push that removes it. The diff producer only kept
   hunks with added lines at head, so 38 of 74 positive rows had no hunk in their file at all and 69 of 74
   were "not on a changed line", while 60% of ordinary rows were. The diff annotation separated the labels
   by construction and was blind to exactly the access-control shape. The producer (version 2) now records
   per file the head lines after which the push removed code; distance and on_changed_line count them, the
   model's hunks input renders them as removed_after_line, and diff.deletion_count is an engineered feature.

2. 150 rows (16%, every positive of one repository) read empty files from the worktree although git holds
   the blobs; the build ran while another process checked out from the same clone. _full_checkout now
   proves the checkout: git status must be clean, a dirty tree is restored once, then InstrumentFailure
   checkout_incomplete. The table script cross-checks every unread row against the blob size and refuses
   to screen a partly unread tree, and records the diff-scoped recall ceiling (positive rows a label-blind
   enumeration would reach).

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 23:17:15 +02:00
Marius CiepluchandClaude Opus 5.5 a99579b547 measure: final push-hook arm on all 252 pilot changes (0/12, 2.1 false alarms per 100) and the combined whole-tool score
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 15:50:29 +02:00
Marius CiepluchandClaude Opus 5.5 ec40dc1c93 measure: loop parse fix recovers 2 of 7 lost hunts; DSPy baseline 20/60 with the fix
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 15:45:56 +02:00
Marius CiepluchandClaude Opus 5.5 e07ab2ac93 measure: 5 paired repeats, DSPy hunt baseline 30% vs pilot hunter 52% recall on the 12 positives
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 15:29:51 +02:00
Marius CiepluchandClaude Opus 5.5 26720ed0dc measure: pre-registered analysis for 5 paired repeats of the hunt baseline against the pilot hunter
Committed before the repeats finish. Unit is (change, repeat); paired bootstrap
over changes and exact McNemar from openultrasast.stats; failures stay in the
denominator. Dry run on the existing single runs reproduces 6/12 and 3/12.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:21:15 +02:00
Marius CiepluchandClaude Opus 5.5 3692c85d76 measure: hunt cache replay verified (zero tokens on rerun)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:16:31 +02:00
Marius CiepluchandClaude Opus 5.5 c2bfcef3df measure: hunt baseline on the 12 pilot positives
3 of 12 with the fixed answer check against the pilot hunter's 6 of 12, one
run each, not significant. The intended zero-cost replay was not a replay:
answers at temperature 0 differ between runs and the cache did not serve the
second run. Programs must be compared over repeated runs, paired by change.
About $1.10 for both runs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:15:22 +02:00
Marius CiepluchandClaude Opus 5.5 c5bf52f47d measure: Semgrep arm on the valid pilot, our rules and facts converted
0 of 12 positives; 12.6 false alarms per 100 ordinary pushes (2.1 on changed
lines only). The misses come from what the rules and facts express (access
control lives in obligations, which do not convert; sources cover request
objects only), not from the engine. Comparison arm only: a Semgrep miss is
never evidence against a hunter finding.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:10:19 +02:00
Marius CiepluchandClaude Fable 5.1 e55e44d981 research: Semgrep CE and Opengrep as the quick tier, measured
Engine LGPL-2.1, shelling out carries no obligation; the registry rules are
under the Semgrep Rules License since 2024-12-13 and cannot ship, only our
own converted rules can. Measured 4.7 s startup and 5 to 10 ms per file;
converted regex and taint rules fire for Python, PHP and JavaScript; C
propagation and Groovy do not; one sanitizer semantic we refuse on purpose
is accepted by Semgrep. Recommendation: a Semgrep arm on the valid pilot
first. Recorded in the hunter-learning-loop research note and breadth.toml.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 12:21:02 +02:00
Marius CiepluchandClaude Fable 5.1 108dc2e5f3 measure: lizard and tree-sitter-language-pack against our function-span engines
610 pair files, 570 labelled functions. lizard matches the parser engine on
C, Python and Java but loses JavaScript names and TypeScript end lines:
keep ours, take its cyclomatic complexity as a feature candidate.
tree-sitter-language-pack gives identical spans, is faster, replaces six
grammar wheels with one and adds Go, Ruby, PHP and Perl: adopt as grammar
packaging. Also found: .c files should try the c grammar before cpp.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 12:18:57 +02:00
Marius CiepluchandClaude Fable 5.1 062a7b780e refactor(p1): one source-facts module owns function ranges, callers, declaration tables and language aliases
src/openultrasast/source.py replaces the copies in semantic/functions.py,
plane/tasks/repo_facts.py, learn/features.py, learn/excerpt.py and
plane/tasks/verify.py. Two engines share one sentinel (<module>), one
DECLARATION/KEYWORDS/RESERVED set and one alias map: the parser engine
(ranges, enclosing, bounds, call_sites, callers_of, facts_for) for the
scorer, the overlay and the hunter's annotations; the line-pattern engine
(declared_functions, enclosing_at, function_span, function_bounds, the brace
matcher) that labels, features, roles, excerpts and plane facts were built
on. learn no longer imports plane.tasks. Frozen records that store the old
sentinel are mapped on read (module_function).

Gate: labels rebuilt before and after are identical, 7,921 rows, after
sentinel normalisation (benchmarks/measurements/2026-10-13-source-module-
label-diff/record.json). 490 targeted tests pass; 3,312 collect. Net: 657
lines deleted, 212 added. benchmarks/unseen keeps <global> for its own
frozen manifests.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 12:00:37 +02:00
Marius CiepluchandClaude Fable 5.1 ad20405fc2 docs(benchmark): where the hunter's false alarms come from
Sweep over the pilot's hunter records: most 'vulnerable' suspicions on ordinary
pushes sit far from the diff. Scope to the change, then confidence, then the
config_secrets family; 5/12 recall kept at 8.8 false alarms per 100 (in-sample).

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 08:35:04 +02:00
Marius CiepluchandClaude Fable 5.1 af7d3e49b1 docs(benchmark): pilot numbers, hunter arm final and push hook interim
Arm (b) hunter over all 252 changes: recall 6/12 raw, 5/12 with the classifier
filter; false alarms 92.5 and 54.4 per 100 ordinary pushes. Arm (a) push hook at
163/252: recall 0/12, 0.7 false alarms per 100. Per-positive table, classifier
stats, the one hook false alarm, and the disk fix for the replay output.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 08:13:02 +02:00
Marius CiepluchandClaude Fable 5.1 7a636d60fb feat(benchmark): freeze the valid-benchmark pilot, 12 verified positives + 240 negatives
First live run of the valid detection benchmark. Labels come from the fix
site (fix^1), never SZZ.

- 32 held-out Python/JS advisories sourced from the public pool-p1 set,
  CWE + text from OSV. 133 candidate locations -> 125 after dropping
  tests/minified.
- 125 DeepSeek verification calls: 31 locations passed all three checks
  (vulnerable pre-fix, fix addresses it, reachable in-repo) across 12 repos.
- Maintainer spot-check accepted all 12.
- 20 ordinary negatives per positive change from the same repos, 240 total.
- Held-out guard: 0 dropped against the training-only used set.
- Frozen manifest at benchmarks/valid/pilot/ (252 changes), provenance and
  NOTES under benchmarks/measurements/2026-10-12-valid-benchmark-pilot/.

Three fixes found by the live run:
- catalog.py: skip a site the fix renamed or removed instead of aborting.
- assemble.py: negative ratio counts positive changes, not accepted
  functions (malla would have demanded 260 negatives). Test updated.
- held-out guard: run against training sources only; build_used() also
  scans measurements/populations, which flagged the 12 repos via my own
  SZZ-pool analysis outputs (circular).

Replay and metrics not yet run; see NOTES.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-12 19:42:45 +02:00
Marius CiepluchandClaude Opus 4.8 a024656da0 fix(cpg): single-query path drops params the script does not declare
taint.request_params emits guards/fixedOrigin/originAnchors/quotedSanitizers/
fieldParameterSources, which taint.sc reads from per-request JSON in its BATCH
branch but does NOT declare on `@main def exec` and does NOT consume in its
single-request branch (it defaults them). The single-query path passed them as
`--param guards=...` (disposable) or named args (session), so joern errored
`Unknown arguments` and every cpg.run("taint", ...) failed -- a silent zero of
the shape AGENTS.md warns about. scan_region->taint_verdict->_usable_flows and
the pair-path verdict()/verdicts() were dead; the push/scan batch route was
unaffected (it carries the extras as JSON the script parses itself).

Fix: parse the script's `@main def exec(...)` signature once (_declared_exec_params
+ memoised _declared_params) and, in query(), filter params to the declared set
before building either route. Faithful, not lossy -- the single-request branch
could never use those 5 fields. No-op for config/dominance (their request_params
emit only declared params; verified). Only taint sheds the 5 extras.

Verified end-to-end on banks (patched backend in the replay image): single-query
path now runs; baseline 0 findings, annotated search 2 path/model_entailed
findings (prompt->write_text). Regression test asserts no undeclared param
reaches the command line and the query parses, with a fake runner (no Joern).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-12 14:16:36 +02:00
Marius CiepluchandClaude Opus 4.8 8f7fc4ae83 measure(g2): banks fixed-search MVP -- "no wrong targets, only wrong searching" demonstrated
Same CPG, only the search changes. Baseline (shipped path spec) resolves 0
prompt->write_text flows on banks; injecting the two annotations an LLM steer
would supply (parameter_sources=True + write_text/read_text path sinks) makes the
engine resolve prompt -> path-join -> prompt_file.write_text(prompt.raw). First
measured instance of "#2 guided by #1" closing on an unseen target; fix needed
exactly the param-source + file-write-sink annotations.

Files the instrument bug the first MVP hit: single-query cpg.run("taint",
request_params(...)) is dead -- request_params emits 5 keys (guards/fixedOrigin/
originAnchors/quotedSanitizers/fieldParameterSources) absent from taint.sc's exec
signature; both single-query sub-routes reject them (silent None). Batch path
(run_batch->requestsFile JSON) unaffected; push/scan route uses batch.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-12 14:02:41 +02:00
Marius CiepluchandClaude Opus 4.8 04667c815e measure(g0): fair-target deep scan -- detection 3/5 on app-shaped+sound vs ~0 library-heavy
Ran ousast scan --mode deep on the 5 app-shaped + sound pool targets (the fair change-scoped
eval set from the shape classification). Detection 3/5: graphiti (hunter, Cypher injection),
mcp-remote (hunter, url-scheme injection), dcmcp (ENGINE overlay -- 'outbound.request reached
from parameter' on readFileFromUrl; parameter-as-source fired because an entry point is present).
2/5 missed: malla (DOM/template XSS) and dms (Jinja SSTI), both in families families.toml
documents as limited.

This validates the strategic pivot: the near-zero catch was substantially a TARGET MISMATCH --
on app-shaped repos the engine itself detects (0 -> 3/5). But all hits stop at suspicion/
static_corroboration; release-grade BLOCK still needs proof-arm elevation + family coverage +
the DSPy hint loop. Cost ~$0.007/repo. So bet #1 (fix eval target) is necessary and material
but not sufficient.

Next: recompute a floor on an app-shaped sound subset / real app corpus (VAmPI, NodeGoat,
DjanGoat, vibe-py); measure proof-arm suspicion->proven lift.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-12 11:16:35 +02:00
Marius CiepluchandClaude Opus 4.8 e15ed680a9 spec(g0): strategic pivot -- core problem is unprovable reachability; fix the eval target first
Named the core problem with the maintainer: the tool spots dangerous ops but cannot prove
attacker-reachability -- the trust boundary lives outside the changed library code. Chosen
strategic bet (of three): FIX THE EVALUATION TARGET FIRST.

LLM shape classification of the 49 public pool vulns ($0.033): reachability_in_repo only
24% (12/49); 76% are pure libraries. A legitimate change-scoped catch needs sound label AND
reachability in-repo -> just 5/49 (~10%): graphiti, desktopcommandermcp, malla,
document-merge-service, mcp-remote. Shape predicted the hunter outcome (graphiti app-shaped ->
caught; bedrock library -> missed). So record-07's 3/92 is scored against a ~90%-illegitimate
denominator -- the near-zero catch is largely a target mismatch.

Next: deep scan on the 5 fair targets for a per-tier catch rate; then an app-shaped eval set
from known-vulnerable apps. Artifacts: 2026-10-12-pool-p1-shape-classification/ (+ earlier
label-audit, hunter-sound-targets). Memory: evaluation-target-mismatch.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-12 10:49:56 +02:00
Marius CiepluchandClaude Opus 4.8 27a7c12ca1 measure(g2): model hunter on sound targets -- first LLM catch the static tiers missed (1/2)
ousast scan --mode deep (DeepSeek deepseek-flash, model layer + tool_hunter, 60-call bound) on
bedrock + graphiti, the two sound pilot targets the static engine missed:
- graphiti: HIT -- falkordb_driver.py:207, tag family:cypher-injection; rationale traces
  build_fulltext_query concatenating user input into a Cypher string at line 278 (inside the
  labelled function, location-matches). The static engine produced zero findings here.
- bedrock: miss -- 12 suspicions on adjacent concerns (network-PUBLIC, download_file), never
  named the install_packages -> pip command injection.
Cost is a non-issue: ~$0.007/repo, 64 model calls for a whole-repo deep scan. BUT everything
stopped at suspicion rung -- the proof arm did not elevate to proven; release-grade BLOCK needs
proven findings.

Direction (maintainer): prompt evolution is a core lever -- a DSPy-based loop (GEPA/MIPRO,
pluggable; evolving field) whose objective is to learn what hints/annotations steer the model
to the real sink, sourced from the framework knowledge already shipped (no new user
annotation), with LLM-proposed boundaries graduating into the facts.

Next: measure proof-arm lift on graphiti; stand up the DSPy hint loop + re-run bedrock; widen
the hunter to the 23 sound targets for a catch rate; then a change-scoped + proven run.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-12 10:37:10 +02:00
Marius CiepluchandClaude Opus 4.8 a43e6293f5 measure(g0/g2): LLM corpus-label audit -- only 47% of public pool labels are sound
Widened the banks label-mislocation finding across all 49 public pool vulns via DeepSeek
(advisory + head code + pool label -> sound/unsound), $0.038 total. Result: 23/49 (47%)
sound; 53% unsound (25 pre-exist in base, 16 sink outside the changed lines) -- a change-scoped
hook correctly stays quiet there. Systematic by family: injection 10/13 sound, but path 1/7,
output_encoding 1/8, config_secrets 1/4.

Implications: record-07's floor (catch 3/92) is scored against a corpus ~half unfair to a delta
hook; the honest catchable denominator is the sound subset (caveat added to record 07 NOTES).
Fair pilot re-score: only bedrock + graphiti (injection) of the 5 are sound and the engine
missed both = the real detection gaps for the LLM-guided hunter.

Also: GEPA-style reflective-retry (future spec) + GLM cyber model (future spec) noted; DeepSeek
is the working default. Artifact: benchmarks/measurements/2026-10-12-pool-p1-label-audit/.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-12 10:09:32 +02:00
Marius CiepluchandClaude Opus 4.8 e901640f3f measure(g0): record 07 — slice-1 unseen-repo baseline (G0 exit)
First honest, measured unseen-repo baseline on 100 frozen never-seen repos
(1300 changes, DEFAULT arm, docker lane). This is the quick pattern-rule FLOOR
(no LLM: model=disabled, 0 calls; engine_covered=0, the ~200s wall) — the release
gate is now a measurement, not an assertion.

- catch 3/92 = 3.3% (Wilson95 1.1–9.2%); false_alarm 3.1% (cluster95 1.6–5.4%,
  icc 0.25); alerts_only 0%; instrument_failure 4.2% (<5%); engine_covered 0.
- by family: deser 1/4, injection 2/20, rest 0.
- baseline row appended to usage-p1.jsonl (freeze_digest 3371c67d) = G0 exit.

Caveats in NOTES.md: machine-label (SZZ, 100 unchecked), regex-only floor (NOT the
>=90%/<10% gate), docker lane, slice-1 sizing (~±10% overall, per-family too thin).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-11 22:30:58 +02:00
Marius CiepluchandClaude Opus 4.8 8de0c2732b spec+docs(search-with-proof): record first cluster demonstration + fixed-side negative [skip ci]
Feed the milestone back into the spec and steering. HANDOFF: the open "first demonstrated"
question is RESOLVED -- xiaomusic (path, prefix-check-bypass) demonstrated on the vulnerable
side (3/3 affected, 0/3 safe) and the blind fixed-side search produced 0 false proofs; pair
total $1.22. Records the six-fix chain that enabled it (parity, verify-time-only, fair-share
budget, served-root guidance, oracle prefix-bypass coverage, control-signal feedback) plus the
keystone. tasks.md: implementation note; pilot (6.2/6.3) in progress. spec.json: pilot status.
safety-net steering: proof-based BLOCK mechanism reached first execution-backed demonstration
(feasibility-pilot scope, not release readiness; pilot exit + 73-negative qualification open;
classifier stays triage). search README: status note. Payload-free; demos/boards stay gitignored.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-07 13:25:52 +02:00
Marius CiepluchandClaude Opus 4.8 ecd1372568 measurements: FIRST cluster demonstration (xiaomusic prefix-bypass path traversal) [skip ci]
search-with-proof produced its first demonstrated finding on a real CVE fix-pair end to
end on kube-ax: vuln observes, fixed does not, 0 false proofs, $0.37, 55 calls. Enabled
by the full session fix chain (parity, verify-time-only, fair-share budget, served-root
guidance, oracle prefix-bypass coverage, control-signal feedback). Payload-free record.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-07 12:41:01 +02:00
Marius CiepluchandClaude Opus 4.8 d1fe78987b measurements: xiaomusic vuln search -- oracle fix landed (agent targets prefix-sibling) but served-dir wiring missed this run [skip ci]
Oracle broadening works in the agent: demo now targets the prefix-sibling vector. Still
inconclusive (0 false proofs, $0.29): the agent set the served-dir env var to its own
value, not ${served_root}, so the sibling canary was outside the served tree. Served-root
wiring is nondeterministic (a prior run wired it). Last-mile agent-reliability gap.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-07 11:52:19 +02:00
Marius CiepluchandClaude Opus 4.8 4c356caa21 measurements: py re-validation 2 -- served-root fix works (demo now wires ${served_root}); still inconclusive, budget-bound [skip ci]
Served-root guidance validated: authored demo now references ${served_root}. Still
inconclusive (0 false proofs); agent spread budget across vectors and hit run_ceiling
(164 calls, $1.47/$1.50) without converging, and the committed traversal did not
differential. Remaining = per-app exploit-authoring + convergence (the layer the $0 local
glance proof did by hand).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-07 11:05:07 +02:00
Marius CiepluchandClaude Opus 4.8 e387ca16a2 measurements: py re-validation -- budget fix works (18 verify tasks, 0 before); demo didn't wire served_root [skip ci]
Fair-share budget validated: the Python agent completed the full loop and verified 18
demos within $0.74 of $1.50 (0 verify tasks before). Still inconclusive, 0 false proofs.
Root cause of no-differential: the authored demo never references ${served_root}; the
agent pointed the app's served dir at its own value, so the observable was outside the
served tree. Next: guidance to wire the served dir to ${served_root} for the path oracle.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-07 09:23:33 +02:00
Marius CiepluchandClaude Opus 4.8 e01fb513f2 measurements: validation of explore-trap fix (ts now authors a demo; py analysis complete but out of budget) [skip ci]
2 path searches (ts/py), vulnerable, cluster, $1.95 of $2. The trap fix is validated
behaviourally: ts pair 9 now authors a demo (verify_tasks 0->2; fails could_not_build on
entrypoint), py pair 13 drops 118->36 calls and its board shows a complete route-to-sink
+ entrypoint trace but hits the per-run budget ceiling before authoring/verifying. Still
0 demonstrations, 0 false proofs. Payload-free aggregate; raw stays gitignored. Next
levers: per-run budget/step allocation for demo-write+verify after analysis; demo
entrypoint/build (start.path) for compiled/served apps.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-07 08:28:37 +02:00
Marius CiepluchandClaude Opus 4.8 7c220307d4 measurements: path-family pilot after keystone + target-parity (0 demos, parity validated) [skip ci]
3 path searches (php/ts/py), vulnerable side, cluster verify lane, $2.95 of $3.
Payload-free aggregate; raw boards/demos stay gitignored. Finding: the parity fix
produced directed, target-aware search (the agent reasons about reaching the named
observable and inspects the app's serving guard), but no demonstration landed -- all
three spent their per-pair allowance before a differential, and two wrote zero verify
demos (budget consumed in reason/explore). Next levers: allowance/budget split toward
demo-writing, entrypoint discovery for php, and the explore-vs-verify path layout the
py agent flagged.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-06 19:35:42 +02:00
Marius CiepluchandClaude Fable 5.1 70553cb7c6 measurements: first search-with-proof demonstrated (glance ceiling proof, $0 local) [skip ci]
Outcome-only record of the first end-to-end demonstrated verdict and the two
masking defects (regenerated npm lock pinning an incompatible mime; agent demo
targeting the wrong file). Payloads stay in the gitignored private area.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-06 17:54:47 +02:00
Marius CiepluchandClaude Fable 5.1 263be30979 search-with-proof 3.2: oracle probe passes on kube-ax in task-boundary mode [skip ci]
All five oracles demonstrated, gaming demos inconclusive, 38 s, ~500 MB RSS.
The probe dispatcher accepts a skipped isolation check in task-boundary mode.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-06 00:14:51 +02:00
Marius CiepluchandClaude Opus 5.5 1d67412e2b search-with-proof: executor smoke driver and pilot selection (6.1)
20 development pairs, one per repository, 4 per language, 5 per family; identities
in a gitignored manifest, counts and digest committed. Executor smoke drives one
executor task end to end without a model and fails loudly on an unread clone.
kube-ax operator constraints as steering.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 17:26:06 +02:00
Marius CiepluchandClaude Opus 5.5 85f4f0b3d4 search-with-proof: declarative demos, brain/executor split, kube-ax constraints
Demos are data the verifier executes (fixed build recipes, runtime+path start,
HTTP/CLI steps with captures; the canary is never referable). The agent loop with
the key never runs repository code: executor tasks without a key exchange commands
and results through presigned objects. AX capacity errors are back-pressure with at
most 2 tasks in flight; caches and builds under /workspace with a 2 GiB guard;
verifiers take one presigned archive per side. Launcher fix: private /dev in bwrap.
190 tests on the host; probe 5/5 demonstrated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 17:12:46 +02:00
Marius CiepluchandClaude Opus 5.5 0f74767db9 search-with-proof: probe harness (3.2) and agent worker (group 5)
Probe runs each oracle toy pair with a real demo and two gaming demos, records
image facts, RSS and disk, fails loudly if isolation is unavailable; dispatchable
as an AX task. Worker: reason step without tools, explore tool loop whose run tool
goes through the sandbox with a scrubbed env (model key absent), spend reserved
before each call. Host probe: 5/5 real demos demonstrated, 10/10 gaming demos
inconclusive. 89 tests.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 14:45:48 +02:00
Marius CiepluchandClaude Opus 5.5 4b38239f68 search-with-proof group 4 + image: board, spend reservation, coordinator, search-task image
Board as immutable versioned blobs (coordinator sole writer); budget reserve/settle
before model calls; per-task and run caps; coordinator loop over an injected
executor; batch.py accepts a fixed allow-list of search variables; XSS browser
oracle; ousast-search-task image (Python, Node/TypeScript, PHP, Java 17, sqlite,
bwrap, chromium) built by CI. 103 tests on the host.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 14:26:43 +02:00
Marius CiepluchandClaude Opus 5.5 742469d671 search-with-proof group 2: verifier with owned oracles and differential
The verifier, not the artefact, observes the effect: SQL, path, command and SSRF
oracles owned by the verifier (XSS needs a browser executor, else no_oracle);
artefact exit code and output ignored; immutable checkout and dependencies;
3 runs per side; one-sided build or readiness failure is inconclusive. An
isolation failure raises IsolationUnavailable instead of reading as
could_not_build (the NPROC limit now applies inside the user namespace).
35 tests, including gaming attempts and 300 host processes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 14:09:48 +02:00
Marius CiepluchandClaude Opus 5.5 6d27c9bfcf unseen-eval: calibrated replay deadline + native agreement check, docker-lane diagnostics, proof 4.4 record; engine runner cleans up fetched sources
gVisor replays exhausted the hook's 30 s deadline in the snapshot step on a
1,725-file repository; cluster replays now use 30 s x a measured slowdown
factor, verified on a native sample. The engine runner deletes each pin's fetched
source (1.8 GB had accumulated), caps the cache at 500 MB and refuses below
1.5 GB free. Proof 4.4: two engine pins via the generic dispatcher match the VM
baseline exactly. Implemented with Codex.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 08:14:57 +02:00
Marius CiepluchandClaude Opus 5.5 c6e87a8517 unseen-eval groups 4-6: generic AX batch dispatcher (engine_trace on it), replay task and image stage, scorer with adoption gate
Implemented with Codex.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 20:19:14 +02:00
Marius CiepluchandClaude Opus 5.5 8213d3baad unseen-eval group 1: used set (1,029 repositories, every source read), extended guard, usage ledger; record 01
Implemented with Codex; task 1.5 run by the coordinator against the real
sources (S3 memory read-only).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 19:17:35 +02:00
Marius CiepluchandClaude Opus 5.5 afff080874 merge(engine): Kubernetes engine workers (Deployment from the image, S3 queue); leak-audit records carry digests, not repository names
The Joern leak-audit record named spent population v1/v2 repositories, which
the reserved-repository guard forbids outside benchmarks/independent/ (no v3
repository was involved: 0 matches). Records now carry counts and SHA-256
digests. With Codex.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 14:39:36 +02:00
Marius CiepluchandClaude Opus 5.5 298bd17780 learn: Joern-slice leak audit on the completed trace run -- no leak; paths differ between pair sides in 2 of 105 both-asked pairs
Coverage 72 path, 231 asked-nothing, 9 failed, 189 unsupported. The engine
almost never distinguishes a vulnerable function from its fix, so a Joern-slice
prompt experiment is not funded; the lever is the engine's knowledge of fix
mechanisms.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 14:08:26 +02:00
Marius CiepluchandClaude Opus 5.5 cbc252553a learn: 251 more advisory-fix pairs whose function survives the fix (advisory-fixes-3)
Batch 3 of real (vulnerable function, fixed function) pointer pairs, mined at
zero model cost from reviewed GHSA advisories (pip, npm, maven, composer,
published since 2023, newest first). Same rules as batch 2, widened three
ways: a merged PR's single commit when the advisory links no commit, commits
up to 6 files / 240 lines, and two-family advisories with the family read
from the diff. Every candidate's function diff was read: 412 reviewed, 255
kept, 3 one-per-repository, 2 withheld by the reserved-population guard
(bisected with output discarded). Permissive licences only; no repository
named elsewhere under benchmarks/; no WordPress plugin.

Kept 251: injection 56, untrusted_destination 26, path 71, output_encoding
69, access_control 20, deserialization 9; python 83, typescript 48, php 46,
java 37, javascript 37. Only 12 post-cutoff: batch 2 had used up the
post-2026-06-01 pool. Memory 1133 -> 1635 static examples; complete pairs in
the whole memory 459 -> 710. Embeddings: 15 calls, $0.0030. No chat-model
call, no Docker, no Joern. Record:
benchmarks/measurements/2026-10-04-decision-engine-harvest-3.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 11:57:34 +02:00
Marius CiepluchandClaude Opus 5.5 20777d8863 chore(audit): module audit gains learn.slice
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 17:04:33 +02:00
Marius CiepluchandClaude Opus 5.5 1b2c7993a7 learn: in-function def-use slice from the tree-sitter layer + leak audit (\$0)
slice.py renders source -> step -> sink lines with fixed wording for flow,
no-flow and not-analysable; the prompt option is default-off (byte-identical
default prompt). semantic IR: JS/C declarations count as assignments, augmented
assignment keeps its target (gate, map_gate, pair_gate outputs unchanged).
Audit over exp-004's 501 units: 59 flow, 161 no-flow, 281 not analysable;
has-flow within-pair accuracy 0.52, pooled AUC 0.55 -- no leak. Fixes a
numbering bug that rejected every excerpt with a blank line. With Codex.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 14:56:52 +02:00
Marius CiepluchandClaude Opus 5.5 8aeca972c0 learn: freeze exp-004 units (501 units, 390 paired, 220 groups) after the negatives harvest; audit gains learn.fill
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 12:36:02 +02:00
Marius CiepluchandClaude Opus 5.5 5b2bd9bb91 merge(learn): negatives harvest -- 98 real fix pairs with surviving functions (79 post-cutoff), paired groups 151 -> 249
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-10-03 08:29:32 +02:00
Marius CiepluchandClaude Opus 5.5 50c93edfb8 learn: 98 advisory-fix pairs whose function survives the fix (advisory-fixes-2)
Real (vulnerable function, fixed function) pointer pairs for the six compiled
families, mined at zero model cost from reviewed GHSA advisories (pip, npm,
maven, composer), newest first: 79 of 98 published after 2026-06-01
(post_cutoff = true). Each pair: one linked one-parent fix commit, <= 4 source
files / 120 lines, the function holding the changed code lines declared once on
both sides with a changed body; every function diff read and kept only when the
named function holds the fix (145 reviewed, 100 kept); 2 dropped by the
reserved-population test; permissive licences only, no repository named
elsewhere under benchmarks/.

New label source advisory-fixes-2; the advisory-fix tests run over both
batches. Memory 937 -> 1133 static examples (98 paired groups added);
positives-only groups stay 99 (vibe-py/dev-php/v2 data gaps), their share of
positive groups in the six families 0.40 -> 0.29. Embeddings: 7 calls,
$0.0014. No chat-model call. Record:
benchmarks/measurements/2026-10-03-decision-engine-negatives-harvest.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-10-03 08:23:42 +02:00