Skip to content

pv discharge run: the Lean comparator arm is not memory-capped (51-72 GB RSS, OOM kills runners) #4638

Closed as not planned

Description

@noahgift

pv discharge run (the pv discharge run (build.sh, then check --strict + comparator + leanchecker) step, ci/sections.yml) caps only the leanchecker arm in systemd-run --user --scope -p MemoryMax=<N>G (crates/aprender-contracts-cli/src/commands/discharge.rs, around line 193-215). The comparator arm, lake env lean --run scripts/Comparator.lean Challenge/*.lean, has only a wall-clock timeout, no memory cap.

Measured:

  • 2026-09-27 16:14Z, gx10: one lean reached 71.6 GB RSS and OOM-hung the host (blocked rc.1's determinism job).
  • 2026-09-29 fw16: kernel OOM-killed lean at 51 GB anon RSS at 14:13Z (runner main) and 18:36Z (fw16-3); each runner sat offline for hours because its unit had no Restart= (infra fix: forjar-declared OOMPolicy=continue + Restart=always drop-in).

Wanted: run the comparator (and Axioms.lean) through the same systemd-run --user --scope -p MemoryMax=<N>G -p CPUQuota=<Q>% wrapper as leanchecker, with a test that asserts the argv (a fixture per arm, so a third arm cannot be added uncapped). Until then the job can take down any shared runner host it lands on.

Activity

  1. added this to the 0.71.0 milestone on Oct 8, 2026
  2. noahgift commented on Oct 12, 2026

    @noahgift
    MemberAuthor

    Status (owner aprender-4936), checked at main 9042f20: the defect is still present.

    In crates/aprender-contracts-cli/src/commands/discharge.rs, only the leanchecker arm goes through systemd-run --user --scope -p MemoryMax=… -p CPUQuota=… (recheck_argv). Three other Lean arms spawn through Lake::run → Lake::spawn, a bare Command::new("lake") that has a wall-clock bound and no memory cap:

    • elaborate: lake env lean Axioms.lean
    • self_test: lake env lean --run scripts/Comparator.lean --self-test
    • compare: lake env lean --run scripts/Comparator.lean Challenge/*.lean

    On the PR, merge-queue and push paths the leanchecker re-check is skipped (C312) while the comparator still runs, so the capped arm is the one that does not run there.

    Plan:

    • Give Lake an Option<Scope> that is built from the existing --leanchecker-memory-max-gib / --leanchecker-cpu-quota-pct / --leanchecker-unscoped flags, so there are no new flags.
    • Lake::spawn prefixes the same systemd-run --user --scope --slice=agent.slice -q -p MemoryMax -p CPUQuota -- argv. A --scope unit runs in the caller's process, so the pgid kill-on-timeout still holds.
    • One lake_argv builder for every arm, with one argv test per arm (Axioms, self-test, comparator, leanchecker), each asserting the scope prefix. An arm added without the scope then turns a test red.
    • When the scope cannot be created, the arm declines, as leanchecker already does. It never falls back to uncapped.

    The branch is cut from 9042f20. The PR waits for a slot.

  3. added
    P1High priority
    and removed
    P0Critical priority
    on Oct 14, 2026
  4. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    P0 to P1 (2026-10-14 P0 triage): P0 now means it blocks the next release or carries the operator's own words on it; this issue does neither, so it stays on the 0.71.0 milestone at P1.

  5. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    Folded into #4348 as a checklist row (TRIAGE-100, 2026-10-14): the open-ticket cap is 100, so this ticket is now tracked on that master and closed as not planned. Nothing is lost: reopen it when its work resumes, and an open PR for it reopens it. Pushed branch: fix/4638-lean-arms-scoped.

    Agent: aprender-clerk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions