Skip to content

A factory memory receipt that lands after Quit is missing from the ledger or the header (TestMemoryLateReceiptReachesFactoryHeaderAfterQuit fails ~1 in 3) #2566

Open

Description

@AbirAbbas

What happened

cmd/codeaf TestMemoryLateReceiptReachesFactoryHeaderAfterQuit fails roughly a third of the time when it runs alone, on app/v3 and on the landing candidate alike. The failure is an accounting mismatch: a memory worker's receipt that arrives after Quit is missing from the ledger, or it reaches the ledger while the factory header stays behind. Example lines from failing runs:

provider=0.0400 memory=0.0000 ledger=0.0200 header=0.0200
provider=0.0400 memory=0.0200 ledger=0.0400 header=0.0200

It first surfaced in the full check of the app/v3 → dev landing candidate (#2561), where the full suite runs under load.

Replication

Deterministic (no model). At app/v3 a687c92b2:

CODEAF_TELEMETRY=off DO_NOT_TRACK=1 go test -count=20 -run '^TestMemoryLateReceiptReachesFactoryHeaderAfterQuit$' ./cmd/codeaf/

On 2026-11-10 that run gave 13 pass / 7 fail on app/v3, and 11 pass / 9 fail on the landing candidate (land/app-v3). There were no skips. Most failures are the accounting assertion in appfactory_memory_worker_test.go; one candidate run failed earlier with memory did not start.

Field (real models). Not needed. The test drives the real public ledger and header through a scripted provider.

Where

  • The test is TestMemoryLateReceiptReachesFactoryHeaderAfterQuit in cmd/codeaf/appfactory_memory_worker_test.go; search for late receipt.
  • The boundary is where a factory job's memory-worker receipt is booked after the job's chat quits: the ledger row, then the stored factory cost and header.

The fix

A receipt that arrives after Quit is booked exactly once, and both the ledger and the factory's header show it. The test should pass 100 of 100 runs alone and under the full suite. This is not caused by the landing merge, because app/v3 fails the same way. It is filed on its own because failing 35–45% of standalone runs is a defect, not load noise.

🤖 Generated with Claude Code

Activity

  1. AbirAbbas commented on Nov 10, 2026

    @AbirAbbas
    CollaboratorAuthor

    Bisect on one machine with a focused run each time: -run '^TestMemoryLateReceiptReachesFactoryHeaderAfterQuit$', nice -n 19, -p 1, GOMAXPROCS=2. Every failure was the same line, provider=0.0400 memory=0.0000 ledger=0.0200 header=0.0200.

    Commit What it is Failed
    a29d484 land/app-v3 before dev's #2583 4 of 10
    528122a a29d484 plus dev 15d40fd (#2583) 7 of 10
    2c5e083 land/app-v3 now, which also carries #2588 and the Close fixes 12 of 15

    Combined with this issue's own counts (7 of 20 on app/v3 a687c92, and 9 of 20 on the earlier landing candidate), the failure rate is:

    The bug existed before #2583. Merging #2583 onto app/v3 makes it about twice as likely.

    Checked for the embedded engine (furrow). The first two rows were built in a worktree without internal/furrowbin/cache/furrow-linux-amd64.gz; the third was built with it. The pin is the same. Holding that constant:

    Comparison Before After
    With furrow embedded: app/v3 a687c92 against 2c5e083 4 of 10 12 of 15
    Without furrow: a29d484 against 528122a 4 of 10 7 of 10

    The first run in a fresh process fails at the same rate as later runs, so state left over by an earlier iteration in the same process is not what drives it.

    #2583 did two things that may matter here:

    • A profile's pool-errand tracker now refuses new errands once it has been stopped.
    • It added defer stopPoolErrands(...) to the run, exec and subharness roads.

    What to check next: whether a stage that ends inside the app closes the shared profile's tracker before the memory worker books its late receipt. That link is not proven.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions