Commit Graph
449 Commits
Author SHA1 Message Date
Marius Ciepluch 2c594b2c27 docs(benchmarks): 8.2 final gated round - dev funnel 11.9->19.2 complete, admission NO-GO #3, arm parked
Lever: unique-declaration member-call binding (dc28325). Measurement 1: zero movement
on in-family sites (0 unique-name member calls exist there; unresolved mass is framework
callee names). Screen: all 264 admission records byte-identical at dc28325. Measurement 2
(dev pool, single-lever isolation): complete-share 11.9->19.2 (+360478, exact conservation),
recall/location/FA identical, 5 ordinary none->indeterminate. Measurement 3 (ac-admission-3,
fresh freeze, criteria byte-identical): NO-GO #3, same four gates, 0/12 pairs, 264/264
fresh dc28325-stamped records. Stop condition fired: access-control arm parked permanently
(rule-11 fallback). Remaining gap: entry recognition (4/12 zero-recognition; coverage
8/12) and framework operation facts, not call resolution.
2026-10-31 09:02:59 +01:00
Marius Ciepluch dcdf04bfbc docs(benchmarks): express-pack admission provenance note for the 17 in-flight records 2026-10-31 08:48:25 +01:00
Marius Ciepluch 62c8d21667 docs(benchmarks): 8.2 admission gate - recognition doubled, NO-GO #2, stop condition fired 2026-10-30 20:55:38 +01:00
Marius Ciepluch 6024152c48 fix(benchmarks): fact_manifest_ref digests entry-pack JSON symmetrically with disk 2026-10-30 20:45:39 +01:00
Marius Ciepluch a8a28f81f3 feat(detection-core): JS handler extraction for bind(this)/arrow/class-method routes (8.2 part 3); fold in load_pack_file repairing 51971cd import 2026-10-30 20:10:22 +01:00
Marius Ciepluch 51971cda7e feat(detection-core): package-rooted entry packs wired into JS recognition; fact digest covers packs (8.2 part 2) 2026-10-30 19:25:30 +01:00
Marius Ciepluch 1d5a509424 feat(detection-core): recognition target table and first express fact pack (8.2 part 1) 2026-10-30 18:46:19 +01:00
Marius Ciepluch af400c6be4 feat(detection-core): runner migration onto core contracts, schema validation, E2E 2026-10-30 17:12:33 +01:00
Marius Ciepluch 46b4579d01 feat(detection-core): generalized admission contract with family-scope reports 2026-10-30 16:22:40 +01:00
Marius Ciepluch 92fb372498 feat(detection-core): measured per-class budget replacing the static 120s gate 2026-10-30 16:11:37 +01:00
Marius Ciepluch 1edc4790af feat(access-control-prover): 13.4 admission measurement 2026-10-30 13:25:34 +01:00
Marius Ciepluch d063167b28 feat(access-control-prover): 13.3 four-arm development regression 2026-10-30 12:37:19 +01:00
Marius Ciepluch 9c95f842f7 feat(access-control-prover): 12.6 paired scoring and admission report 2026-10-30 10:25:37 +01:00
Marius Ciepluch 494c29182d feat(access-control-prover): 12.5 admission manifest consumption 2026-10-30 10:13:09 +01:00
Marius Ciepluch ea33222bf6 feat(access-control-prover): 12.4 four-arm development comparison 2026-10-30 09:44:27 +01:00
Marius Ciepluch 282a085f77 feat(access-control-prover): 12.3 instrument and hard runtime gates 2026-10-30 08:53:05 +01:00
Marius Ciepluch eb30d0386c feat(access-control-prover): 12.2 record provenance, stage funnel and judgment transitions 2026-10-30 08:38:58 +01:00
Marius Ciepluch 733e17ed3e feat(access-control-prover): 12.1 analyzer bundles 2026-10-30 08:38:09 +01:00
Marius Ciepluch efdb66bc73 measure(ablation) gate 3: miss and false-alarm trace-component taxonomy 2026-10-28 20:06:40 +01:00
Marius Ciepluch 0b1d41d01b measure(judge) gate 2: zero-shot judge over prover findings 2026-10-28 19:43:59 +01:00
Marius Ciepluch a60e9bda9d measure(search): 2026-10-07 shiftleft sql-vuln pilot records 2026-10-28 18:59:01 +01:00
Marius Ciepluch fcf05f7755 bench(unseen): p1 pool, draft and bisect freeze artifacts 2026-10-28 18:59:01 +01:00
Marius Ciepluch c5341d79a2 measure(prover): gate 1 on the 23-repo training pool: recall 65.2% (Wilson 44.9-81.2), 15.0 FA/100, 0 instrument failures; 4/5 on the hunt overlap incl. trigger.dev 2026-10-28 18:59:01 +01:00
Marius CiepluchandClaude Fable 5.1 2f628b921b feat(prover): delivery C: the ordered trace with argument provenance for every examined pair
Codex delivery under spec access-control-prover, requirement 9. `semantic/obligations/trace.py` serialises each
(entry, operation) pair the prover examined, discharged or unguarded: the entry with its boundary, access and
parameters; each hop in order with its call line, the guards before the call and the values forwarded; the
operation with the provenance of each argument traced through the function's binds; the guards after it; the
verdict. One canonical text form and one JSON form, no language, framework, repository, size or count fields.
The prover result, the arm record and each unguarded finding carry the traces. On the ec2-plugin fix: 32
traces, 4 unguarded. Gate: 3534 tests pass; the reserved-repository guard passes on the tracked export.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 18:22:45 +02:00
Marius CiepluchandClaude Fable 5.1 7f1b820d5a style(prover-arm): format
The previous commit was gated through a pipe whose exit status was tail's, not ruff's; CI caught the
unformatted file.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 17:03:35 +02:00
Marius CiepluchandClaude Fable 5.1 5980bf8377 fix(prover-arm): the byte table holds only files that were read, so a zero-byte read stays on the record and the summary refuses it
CI failed test_unchanged_file_empty_read_refuses: the previous fix skipped failed records in the zero-byte rule.
Now the arm records a file's size only after reading it (a git-empty file is counted under empty_files and
not listed), a real zero-byte read keeps its zero and the summary refuses it on every record as the test says.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 17:00:13 +02:00
Marius CiepluchandClaude Fable 5.1 beb272a5ec feat(prover): access-control prover, delivery A: path records, Stapler and Jetty entries, Java operation rows, the prover and its scoring arm
Codex delivery under spec access-control-prover. `semantic/obligations/paths.py` builds entry-to-function path
records from the cached caller index; `mapping.py` names Stapler web methods and Jetty handlers as entries;
`check_obligations` gains the opt-in premise `assume_entries_protected` with the label `unguarded_path`;
`hunt/prover.py` proves a change with no model call and states its coverage; `benchmarks/valid/prover_arm.py`
scores it with the valid-benchmark metrics. Two fixes after the first smoke run: a product file git holds empty
is read, not unread (four changes failed on `__init__.py` and empty assets), and absent-input reasons are
counted by name.

Smoke on the 23 fix changes of the training pool: 7 pushes caught (30 percent, Wilson 16 to 51), 28 of 93
locations, precision 7 of 8 flagged, no instrument failure; three changes over the 120 second bound. Twelve of
the 17 Jenkins fixes reach the fixed method but check no operation because the method is the operation;
the spec now carries handler-named operations for delivery B.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 16:50:04 +02:00
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 6fe46c3062 data: access-control training pool refrozen (e6a67487): 23 fix changes, 93 accepted locations, 23 repositories, 20 ordinary pushes per fix, floor 20, walk cap 1500; 11 repositories left out for short history
Batch 1 and the spot-checked batch 2 combined. The walk and freeze record are in the training work directory.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 09:31:56 +02:00
Marius CiepluchandClaude Fable 5.1 30ad197d3f fix(bench): an unparsable file in one ordinary commit no longer ends a repository's history walk
The combined access-control freeze stopped at its 31st repository: one ordinary commit of a PHP tree touched a
Python file that does not parse, functions() raised Rejected, and ordinary_history let it end the walk. The
file is now marked parse_failed on its row and such a commit is rejected as an ordinary push (reason
function_parse), which keeps the draw conservative without losing the repository.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 08:42:25 +02:00
Marius CiepluchandClaude Fable 5.1 436e83de5e data: access-control batch 2 spot-checked; all 69 passing locations accepted (27 changes, reviewer mc)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 07:36:16 +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 c01e61c4dd fix(bench): the pilot hunter arm undoes an inherited sparse checkout before it reads a hotspot
The training clones are sparse-checkout and a worktree inherits it; without this the hunter arm raises
unreadable_hotspot on every change of the access-control pool. Same helper and checkout proof as the hunt runner.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 23:18:44 +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 Fable 5.1 60cbefec9b data: access-control batch verified, awaiting spot-check: 57 of 78 cloned (6 GB disk guard), 148 catalog sites, 69 pass all three checks in 27 changes
Java 63 of 69 sites. verify: 148 records, 701 deepseek-flash calls, no provider errors. The 21
uncloned sources are in sources_access_control_dropped.json for a later clone pass.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 22:07:39 +02:00
Marius CiepluchandClaude Fable 5.1 6a9e4093fe data: 78 access-control advisories sourced from the OSV dumps (maven 48, npm 12, pip 11, composer 7), 237 candidate repositories after exclusions
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 21:53:00 +02:00
Marius CiepluchandClaude Fable 5.1 3d08d692ff bench(train): class-targeted sourcing, --family, from the public OSV dumps
sources --family <family> keeps only advisories whose CWE the taxonomy maps to that family, writes
sources_<family>.json beside the training set, and excludes the pilot, every repository the
benchmarks already name, the strict used set and every earlier batch; --prefilter-only runs the
dump pass without GitHub. Implemented by Codex (gpt-6-astra), gated here: names normalize rejects
exclude nothing instead of aborting, and the strict used set is in the exclusions.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 21:46:45 +02:00
Marius CiepluchandClaude Fable 5.1 30921a12b9 data: access-control training pool frozen (53f9f364): 5 fix changes, 48 accepted locations, 20 ordinary pushes per fix, floor 20, history limit 1500
mcp-documentation-server (8 ordinary commits) and line-desktop-mcp (13) are left out of this freeze;
their locations stay accepted for a later one.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 21:30:04 +02:00
Marius CiepluchandClaude Fable 5.1 1d1c87f63b bench(valid): a training freeze may cap the history walk at the newest N first-parent commits
ordinary_history(limit=) walks only the newest commits; assemble.freeze(history_limit=) and
--history-limit pass it through and the record carries it. The held-out benchmark passes none.
Reason: trigger.dev's 7,109-commit walk runs for hours at the per-commit cost of the function
and generated checks; the training freeze now walks its newest 1,500.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 20:47:23 +02:00
Marius CiepluchandClaude Fable 5.1 47d0f0fac1 bench(unseen): per-commit history cache for ordinary_history; assemble.freeze --history-cache
One append-only JSONL per clone (named by the sha256 of its top-level path), one line per commit
with the row as the walk built it and HISTORY_CACHE_VERSION, flushed after every commit so a
killed run keeps its progress. A cached row is reused only when its parents match the current log;
other versions and torn lines are recomputed. With no cache directory nothing changes. The
7,400-commit trigger.dev walk that took over an hour per freeze becomes a one-time cost.
Implemented by Codex (gpt-6-astra), gated here.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 19:40:34 +02:00
Marius CiepluchandClaude Fable 5.1 bbbb0f397e bench(valid): a training freeze may lower the ordinary floor to the ratio; the draw takes a size
The held-out benchmark keeps the 40-commit floor and the union of twelve-commit stratified draws.
A training freeze passes floor=20 (never below the ratio) and the record carries ordinary_floor.
When the union of twelve-commit draws cannot reach the count (small cells stay unallocated on
every draw), one stratified draw of the full count is used; with count equal to the eligible
commits that is every one of them.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-13 18:33:10 +02:00
Marius CiepluchandClaude Opus 5.5 f29b3a3df2 data: maintainer spot-check, 51 access control locations accepted (7 changes)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 18:09:10 +02:00
Marius CiepluchandClaude Opus 5.5 2b65680d5d data: hunt training-set candidates (task 4.1), not frozen: 99 verified locations in 28 changes, awaiting spot-check
Sourced apart from the 12 pilot repositories: 212 candidates (pool-fresh, pool-retry, OSV for PyPI,
npm, Maven and Packagist), 49 dropped because the benchmarks already name their repository, 413
catalog locations, 99 passing all three verifier checks in 28 repositories. Short of the 40-positive
target. catalog.py now reads .java and .php. Freeze waits on the maintainer's spot-check
(CANDIDATES.md, SOURCING.md).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 16:48:41 +02:00
Marius CiepluchandClaude Opus 5.5 25ae4b489c fix(p1,p0): restore the pre-P1 range contract for two callers; docs link and maintainer paths
The full suite after the replay found regressions from 062a7b7 and 94e96c6:
- catalog_gen and candidates.labeled_spans still unpacked 3-tuples and expected None on a parser
  rejection; source.ranges returns FunctionRange (4 fields, module entry first) and raises ValueError.
- ranges_from_ir passed the language to declarator_name, so the repo-facts declaration table named a
  callback call (exec(..., function () {) as a function; the pre-P1 call had no language.
- the catalog_gen fail-loud test blocked the old module name.
- docs: a renumbered examples anchor, and two .kiro paths in the public threat model.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 16:15:32 +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