12 Commits
Author SHA1 Message Date
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 17194b3df9 ci: pytest runs with the hunt and semantic extras kept; sandbox tests skip by cause where no bwrap exists
CI's first full pytest run since 2836b78 showed 65 failures in three classes. uv run re-synced the environment
to the lockfile's default extras before pytest, removing dspy again (UV_NO_SYNC=1 now). The learn slice, pair
corpus and hunt producer tests need tree-sitter (semantic extra installed). Thirty-two tests need bubblewrap
isolation, which CI's container cannot provide: they carry a sandbox marker and skip where the isolation
preflight fails, with the cause's type in the reason; proven locally by hiding bwrap (7 skipped, 23 passed).
The partial-clone extraction test now probes one lazy fetch through git itself first, so git's own stderr
reaches the next CI log instead of git_exit_128.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-14 07:54:09 +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 4.8 e49c150316 test(infra): fix the 3 stale/flaky infra tests to the current contracts
- test_engine_image_and_rustfs_policy: root Dockerfile was refactored to the
  digest-pinned ousast-task-base (carries semantic+s3 deps) + a joern-build stage,
  installing the package --no-deps. Updated the stale `COPY benchmarks` (now
  --chown=1000) and `.[semantic,s3]` (now --no-deps + joern-cli copy + pinned base)
  assertions to the new contract.
- test_image_stages: plane/Dockerfile.engine-task refactored the same way; the
  split marker is now `FROM ${ENGINE_REF} AS replay`, base is ousast-task-base
  (not ax-task-runner:v0.3.1), and the replay stage no longer installs git (base
  provides it). Re-pinned the engine-stage SHA and updated the markers/assertions.
- test_partial_clone_lazy_fetch: passed alone but failed mid-suite — a leaked
  GIT_DIR/GIT_OBJECT_DIRECTORY/alternates from an earlier test changed the
  missing-blob count. Added an autouse fixture that neutralises inherited git
  control vars so every test in the file is self-contained (reproduced + verified).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-12 15:58:11 +02:00
Marius CiepluchandClaude Opus 4.8 a49b15b720 unseen: bound the per-repo Python parse phase (--parse-deadline)
Git subprocess calls were deadline-bounded (Git.command_timeout uses the
remaining per-repo budget), but a pure-Python parse between git calls
(repository_changes -> history/blame/diff on a giant file) had no
deadline: when it hung, no further git call fired the git deadline, so
the worker stalled indefinitely (observed >720s with zero git
processes). An external watchdog was papering over it at ~20 min/stall.

Add extract.process_deadline(seconds): a SIGALRM/setitimer wall-clock
alarm installed on the worker's main thread that raises
ExtractionTimeout("wallclock_timeout"), with no-op guards (None/<=0, off
the main thread, or no SIGALRM support) and strict timer-cancel +
handler-restore in finally. Wrap the whole extract_repository body in it
so the timeout propagates to the existing `except source.Rejected` and
journals as a clean rejection, not a worker failure.

Budget = --extract-deadline (git, 240s) + --parse-deadline (new, 120s)
= 360s total ceiling, so git-bound repos keep their full budget (yield
unchanged) while a hung parse is rejected well before any external
watchdog. Record parse_deadline_seconds in the report.

295 unseen tests pass (incl. timeout + handler-restore + no-op cases),
ruff clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-10 14:46:18 +02:00
Marius CiepluchandClaude Opus 4.8 0023f61ff8 unseen: revert the batched-blob materialize (it failed git fetch on ~half of repos)
Git.materialize enumerated every object reachable from HEAD and tried to
`git fetch --no-filter` them by SHA. Git rejects that for real repos
("did not send all necessary objects" / "bad revision"), exiting 1 ->
InstrumentFailure(git_exit_1) that failed the whole repository. Measured
in a live draw: 326/670 attempts, ~49% of all failures, which froze the
accepted pool at 44/300. Reproduced on pallets/flask (26221 reachable,
9287 missing, fetch exit 1).

Git cannot batch-fetch arbitrary tree/blob objects by SHA, so remove
materialize and restore the original lazy path: the blob:none clone keeps
the commit graph and the introducing/blame/ordinary-history reads fetch
their blobs on demand through Git's promisor. The per-fix tolerant fetch
loop, the process-pool parallelism, the 25-with-zero-entries guard, the
per-repo deadline and resume are unchanged. Extraction content is
byte-identical (only the prefetch is gone).

217 unseen tests pass, ruff clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-10 05:06:24 +02:00
Marius CiepluchandClaude Opus 4.8 65714405eb unseen: parallelize extraction + batch per-repo blob fetch
Serial extraction at ~147s/repo made a 300-repo pool take days, and
~626 lazy per-file blob faults per clone pushed slow repos past the
240s deadline (a draw reached 21 entries from 347 attempts, 160 of them
extraction_timeout). Both fixed.

Parallel: a bounded ThreadPoolExecutor (--extract-workers, default 6)
runs clones concurrently, each into its own clone with a private counter.
The main thread alone owns the journal, REST (license via finish_license),
counters, and acceptance. Entries are accepted in STRICT SEED ORDER with
the fork-network dedup applied at acceptance, so the pool is byte-
identical to the serial draw (tested: workers=6 == workers=1, including
fork collisions, out-of-order completion, and resume). The systemic guard
and resilient skips are unchanged; a graceful stop drains started work to
the journal for resume.

Batched blobs: repository_changes fetches the fixes together and
Git.materialize fetches all missing blobs for the read revisions in one
`fetch --no-filter --stdin` (rev-list --missing=print), instead of per-
file promisor faults. Content is byte-identical (tested; >=12 fetches
collapsed to 1).

202 unseen tests pass, ruff clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-09 17:37:05 +02:00
Marius CiepluchandClaude Opus 4.8 b074cf7f89 unseen: bound per-repo extraction time; a slow repo skips, never aborts
A pathologically slow repository (observed: tensorzero, 183s to clone,
then `git blame -C` past the 180s command limit) raised
subprocess.TimeoutExpired, which Git.run mislabeled as a fatal
InstrumentFailure("git_launch_failed") and aborted the whole 300-repo
draft. The same slowness stalled throughput (a 54-minute no-progress
gap).

Give each clone a per-repo wall-clock budget (--extract-deadline,
default 240s, plumbed Clones -> Git, counting the initial clone). A
timeout -- a command exceeding the remaining budget, or the budget
elapsing -- raises ExtractionTimeout(Rejected), which the existing
rejection handler turns into an "extraction_timeout" skip so the draw
moves to the next candidate. Genuine launch failures and non-zero git
exits stay fatal; timeouts and launch failures are now distinct. The
deadline is recorded on the report only, not the journal inputs, so
changing it does not refuse resume.

181 unseen tests pass, ruff clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-08 13:22:22 +02:00
Marius CiepluchandClaude Opus 4.8 f4c7143525 unseen: make clone disk-size guard tolerate git's mid-walk churn
disk_bytes() summed the clone tree with rglob + stat() as a size cap
before every git command. On a blob:none clone, `git show` triggers an
on-demand blob fetch that writes and deletes transient
.git/objects/pack/*.rev files, so a path rglob had just listed could be
gone by the stat() call -> FileNotFoundError aborted the whole draft as
an instrument_failure. The race can hit any candidate, so it was a
non-deterministic draft-killer (observed extracting a real npm repo).

Skip a file that raises OSError mid-walk; the size cap is unaffected.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-10-08 11:16:13 +02:00
Marius CiepluchandClaude Opus 5.5 48ae918dec unseen-eval group 2 (2.1-2.4): advisory sourcing, vulnerability-introducing ranges, ordinary-commit draw, draft manifest and slices; journal with resume
Implemented with Codex. Sourcing run (2.5) next, by the coordinator.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 19:51:30 +02:00