Skip to content

Fix automatic review cost accounting stalls - #47

Merged
Pimpmuckl merged 1 commit into
mainfrom
fix/delta-cost-refresh
Aug 3, 2026
Merged

Fix automatic review cost accounting stalls#47
Pimpmuckl merged 1 commit into
mainfrom
fix/delta-cost-refresh

Conversation

@Pimpmuckl

@Pimpmuckl Pimpmuckl commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Incident

Automatic review cost refresh detached review_suite_arena.py costs --cd ... after many lifecycle actions. That command took the crash-prone directory cost-reports.lock for up to 600 seconds, then rescanned all round files and the Codex SQLite database. A stale lock directory made every detached job wait ten minutes even though Arena is disabled by default.

Fix

  • Return before any automatic cost lock/cache/metadata work when arena.enabled=false.
  • When Arena is enabled, apply the finalized reviewer/gate runs already in memory as one synchronous target-row delta after the canonical record is persisted.
  • Deduplicate by stable thread/session/rollout identity with a deterministic fallback; reroll survivors and repeated completion handling are not charged again.
  • Preserve implementation aggregates as manual/legacy data and mark them stale after new review spend. costs --cd is cache-only and points stale/absent rows to costs --all.
  • Use the existing OS file lock under review-cost-accounting.lock; remove the detached launcher and non-spend refreshes from grade, signoff close, and GitHub anchoring.
  • Keep Markdown ledger rendering explicit. Automatic completions update only their atomic cache row.

Recovery

Canonical review and gate records remain the source of truth. costs --all remains the explicit full-history repair path and refreshes implementation estimates. The derived cache is best effort across process crashes or a busy accounting lock; the automatic path never waits behind a rebuild. costs --all repairs any skipped delta. The PR does not claim exactly-once cache semantics.

Performance evidence

All mutations used disposable temp state. Live state was passed only to collect_review_cost_rows in read-only measurements. GitHub PR lookup was disabled in collector timings with REVIEW_SUITE_COST_SKIP_GH_PR_VIEW=1.

  • Base 7a2f087: disposable stale cost-reports.lock + real detached launcher returned in 6.720 ms, spawned one child, and the child was still blocked after 2 s; source timeout is 600 s. The child was terminated after observation.
  • Base scoped collector on live state, 5 runs: 3.957, 4.359, 4.214, 4.105, 4.802 s; median 4.214 s.
  • New Arena-disabled automatic path, 1,000 temp-state calls: median 0.3028 ms, p95 0.6127 ms; no lock/cache entry was created.
  • New Arena-enabled one-run delta, 50 calls on representative temp state: median 55.541 ms, p95 155.317 ms; 50 sessions/5,000 tokens persisted exactly once.
  • New full-history collector (costs --all collection phase) on live read-only state: 37.317 s for 2,919 rows/24,946 reviewer sessions. It intentionally remains the slow recovery command.

Validation

  • Touched-file Ruff format/check: passed.
  • pytest -n 0 on cost, Arena, gate, GitHub, and orchestrator canonical suites: 243 passed.
  • Review Suite normal: rvw_2e59d994, complete with clean local and anchored GitHub verdicts on 15e91ca.
  • Repository-wide xdist suite intentionally not run; the requested proportional owning suites cover the changed persistence/lifecycle boundary.

@Pimpmuckl

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e498e8937d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1346 to +1349
with orchestrator_store_lock(
state_dir=state_dir,
name=REVIEW_COSTS_LOCK_NAME,
timeout_seconds=REVIEW_COSTS_LOCK_TIMEOUT_SECONDS,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make the automatic delta lock non-blocking

When a review finishes while costs --all is running, this synchronous completion path waits on the same global review-cost-accounting lock that cmd_costs holds throughout the full history and SQLite scan. Because the timeout is 600 seconds, an otherwise completed review can appear stalled for up to ten minutes; the best-effort delta should use a short/non-blocking acquisition and rely on the canonical-history rebuild when the lock is busy.

Useful? React with 👍 / 👎.

Comment on lines +828 to +829
raw = json.dumps(stable, sort_keys=True, separators=(",", ":"), default=str)
return f"fallback:{blake2s(raw.encode('utf-8'), digest_size=16).hexdigest()}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist a unique fallback contribution ID

When two independent finalized runs lack all four preferred identifiers and happen to have the same selected fields—such as repeated gate failures with identical slot, variant, empty usage, elapsed time, and output—this content hash assigns them the same ID. After the first record stores that ID, _add_record and the incremental delta discard the second run, undercounting sessions and any matching token/cost contribution; the fallback needs a persisted per-run or per-attempt identity rather than only run contents.

Useful? React with 👍 / 👎.

@Pimpmuckl
Pimpmuckl force-pushed the fix/delta-cost-refresh branch 2 times, most recently from b8672e0 to 2c250c5 Compare August 3, 2026 15:11
@Pimpmuckl

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2c250c548b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

metadata,
normalized_cwd,
is_legacy,
) = _cached_review_cost_row(state_dir=state_dir, review_cwd=review_cwd)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject deltas from a different checked-out branch

When an asynchronous or resumed review started for branch A finishes after the worktree has switched to branch B, the record still identifies A through task_id/task_id_hint, but this lookup selects or creates the cache row using B's current Git metadata and never applies the branch predicate used by collect_review_cost_rows. The delta consequently charges B even though a canonical collection excludes that record from B, corrupting the cached ledger; skip records whose task ID differs from the current branch or derive the target row from the recorded branch.

Useful? React with 👍 / 👎.

@Pimpmuckl
Pimpmuckl force-pushed the fix/delta-cost-refresh branch from 2c250c5 to 5935acc Compare August 3, 2026 15:24
@Pimpmuckl

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5935acc73f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

*, state_dir: Path, review_cwd: Path
) -> tuple[ReviewCostRow | None, Path, Path, dict[str, str], str, bool]:
normalized_cwd = str(normalize_review_cwd_value(review_cwd) or "")
metadata = _metadata_for_cwd(normalized_cwd)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep PR lookup out of the completion lock

When Arena is enabled and gh pr view is slow or unreachable, this metadata lookup runs synchronously while apply_review_cost_delta_best_effort holds the global accounting lock, and _current_pr_number can wait for its 10-second subprocess timeout. The completed review therefore still stalls, while every concurrent automatic delta uses a zero-second lock timeout and is silently dropped until a manual costs --all rebuild. Preserve the cached PR number or defer GitHub metadata refresh to the explicit rebuild path.

Useful? React with 👍 / 👎.

@Pimpmuckl
Pimpmuckl force-pushed the fix/delta-cost-refresh branch from 5935acc to 15e91ca Compare August 3, 2026 15:37
@Pimpmuckl

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 15e91ca7f7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Pimpmuckl
Pimpmuckl merged commit bbb8dc7 into main Aug 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant