Repository navigation
fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) - #460
Conversation
review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time.
$$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$`
sidecar collided between the two concurrent tier-2 calls — one engine's usage could
overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID
doesn't work either: it differs between the chain's pipe subshell and the reader.)
Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path
(unique by construction) and inherited by the engine's pipeline subshell, so writer
and reader agree while concurrent calls never share a file. $$ remains a fallback for
non-concurrent direct callers.
- token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT.
- engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key.
- tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key
and fallback assertions; correct the misleading "$$ isolates parallel" test.
- token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on
NUL bytes; use truncated JSON, which jq rejects across versions).
Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 49 minutes and 43 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughEngine invocations now export a unique ChangesConcurrent token-usage sidecar isolation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
There was a problem hiding this comment.
Code Review
This pull request introduces a per-call usage-sidecar key (_ENGINE_USAGE_OUT) using unique mktemp paths across several runner functions in scripts/engine.sh and scripts/lib/token-metrics.sh. This change ensures that concurrent engine calls remain isolated and do not collide on a shared $$-keyed sidecar file. Additionally, a flaky test in tests/token_report.bats was fixed by replacing binary input with truncated JSON. The review feedback correctly points out that exporting _ENGINE_USAGE_OUT without declaring it local pollutes the calling shell's environment, and suggests using local -x to safely scope the variable to the respective functions while still exporting it to subshells.
There was a problem hiding this comment.
Pull request overview
This PR fixes a concurrency bug in token-usage capture where the “usage sidecar” file was keyed by $$, causing collisions when tier-2 engines run concurrently (as in scripts/review-one-pr.sh). It switches to a per-call key derived from a unique mktemp path and shared between the pipeline subshell (writer) and the parent shell (reader) via an exported env var, and updates tests to validate isolation and remove a flaky jq-version-dependent fixture.
Changes:
- Key engine usage sidecar files per call via exported
_ENGINE_USAGE_OUT(mktemp-derived) with a$$fallback. - Add/adjust unit tests to validate per-call keying and concurrent isolation, and fix an incorrect prior assertion about
$$. - Make a malformed-JSONL test deterministic by using truncated JSON instead of NUL bytes.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
scripts/lib/token-metrics.sh |
Updates _engine_usage_sidecar to prefer _ENGINE_USAGE_OUT for per-call concurrency-safe keying, with $$ fallback. |
scripts/engine.sh |
Exports per-call _ENGINE_USAGE_OUT in each run_* entrypoint based on a unique mktemp path. |
tests/dev-lead/unit/test_token_metrics.bats |
Adds tests for per-call keying and concurrent isolation; corrects the prior $$ behavior explanation. |
tests/token_report.bats |
Replaces flaky NUL-byte fixture with truncated JSON to ensure jq failure is deterministic across versions. |
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: LOW
Reviewed commit: aebff67372c5adfb5412d5362c69939d3d7cb896
Review mode: triage-approved (single reviewer)
Summary
Focused follow-up to #456 that fixes a real concurrency bug in the token-usage sidecar. scripts/review-one-pr.sh backgrounds run_agentic & and (run_duck) & simultaneously; in bash, $$ stays the parent PID in both subshells, so the prior ${TOKEN_LOG_FILE}.last-usage.$$ key collided. The fix keys the sidecar to a per-call mktemp path exported via _ENGINE_USAGE_OUT — unique by construction per call, and inherited by the engine's cmd | tee pipeline subshell so writer (subshell) and reader (calling shell) agree. The $$ form is retained as a fallback for non-concurrent direct callers. The PR body and updated _engine_usage_sidecar header comment correctly explain why neither $$ nor BASHPID alone solves both requirements.
Linked issue analysis
No linked issue; PR resolves the open chatgpt-codex-connector P2 review thread on #456 ("key usage sidecars by BASHPID"). The fix matches the substance of that feedback while documenting why BASHPID alone is insufficient.
Findings
- Correctness: The mechanism is sound.
export _ENGINE_USAGE_OUTin eachrun_*is inherited by the immediately-following pipeline subshell whereparse_engine_usagewrites the sidecar, and the same exported value is visible to the parent when it later calls_record_engine_tokens. The new bats test (concurrent calls sharing $$ stay isolated) reproduces the failure mode with a widened race window (sleep 0.3) and asserts the 111/222 values do not cross-contaminate. - Test hygiene: Good correction — the prior
path includes shell PID to isolate parallel invocationstest was asserting a false invariant; it's rightly renamed to a fallback assertion and the doc now points to the concurrency test for the real guarantee. The jq 1.7 / NUL-byte fix intoken_report.batsis a sensible portability tightening. - Maintainability (non-blocking):
gemini-code-assistflagged four sites (scripts/engine.sh:503,578,703,860) suggestinglocal -x _ENGINE_USAGE_OUT=...instead ofexport _ENGINE_USAGE_OUT=.... The current code is functionally correct because everyrun_*re-exports a fresh path before the engine pipeline runs and_record_engine_tokensis invoked synchronously inside the samerun_*call. However,local -xwould prevent the variable from leaking into the parent shell's environment after the function returns (where it would point at a stale temp path that any other future caller of_engine_usage_sidecarwould pick up instead of the$$fallback). Worth considering in a follow-up; not blocking this PR. - Security: No security surface — bash test/CI tooling, no secrets, no auth, no CodeQL/Gitleaks/AgentShield findings.
CI status
All required checks green: CodeQL, ShellCheck, bats, Lint (validate-agent-profiles, gh-aw-compile, Compile agentic workflows), Secret scan (gitleaks), Agent Security Scan, AgentShield, SonarCloud (Quality Gate passed, 0 new issues), unit-tests, Tests, Dependency audit (ecosystems detected, no audits required). The in-progress Dev-Lead Agent / dispatch is this review run itself.
Reviewed automatically by the PR-review agent (single-reviewer mode: opus 4.7). Reply if you need a human review.
Dev-Lead — fix-reviews (applied)Changes committed and pushed. |
7a60dd7
Dev-Lead — review-changes (applied)Changes committed and pushed. |
… key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dev-Lead — rate-limited (intent: review-changes)PR: #460 |
|
Note @don-petry I received your request but all AI engines are currently rate-limited. I'll retry automatically once the rate limit clears. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/engine.sh`:
- Around line 499-505: The conditional guards that export the mktemp-derived
sidecar use the POSIX [ -n "$_tok_tmp" ] test; update each occurrence in the
functions run_triage, run_agentic, run_duck, and run_writer to use Bash's [[ -n
"$_tok_tmp" ]] form when deciding to export _ENGINE_USAGE_OUT (the mktemp result
stored in _tok_tmp) so the guard matches the repo's required Bash conditional
style and avoids subtle word-splitting/regex differences.
In `@scripts/lib/token-metrics.sh`:
- Around line 149-153: In _engine_usage_sidecar replace the POSIX test [ -n
"${_ENGINE_USAGE_OUT:-}" ] with the Bash conditional [[ -n
"${_ENGINE_USAGE_OUT:-}" ]] so the script follows the repo's Bash guideline;
update the conditional that decides between printing "$_ENGINE_USAGE_OUT" and
printing "${TOKEN_LOG_FILE}.last-usage.$$" to use [[ ... ]] (refer to the
_ENGINE_USAGE_OUT variable and TOKEN_LOG_FILE in the existing if/else block).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 1d34f9e1-7465-44f3-a7f7-6a5e548783c9
📒 Files selected for processing (4)
scripts/engine.shscripts/lib/token-metrics.shtests/dev-lead/unit/test_token_metrics.batstests/token_report.bats
Dev-Lead — fix-reviews (applied)Changes committed and pushed. |
|
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
|
@donpetry-bot please review |
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…y) (#460) * fix(token-metrics): key usage sidecar per-call, not by $$ (concurrency) review-one-pr.sh backgrounds `run_agentic &` and `(run_duck) &` at the same time. $$ stays the parent PID inside both subshells, so the `${TOKEN_LOG_FILE}.last-usage.$$` sidecar collided between the two concurrent tier-2 calls — one engine's usage could overwrite or be read by the other before _record_engine_tokens logged it. (BASHPID doesn't work either: it differs between the chain's pipe subshell and the reader.) Fix: each run_* exports _ENGINE_USAGE_OUT, derived from its own per-call mktemp path (unique by construction) and inherited by the engine's pipeline subshell, so writer and reader agree while concurrent calls never share a file. $$ remains a fallback for non-concurrent direct callers. - token-metrics.sh: _engine_usage_sidecar prefers _ENGINE_USAGE_OUT. - engine.sh: run_triage/run_agentic/run_duck/run_writer export the per-call key. - tests: concurrency-isolation test (two jobs sharing $$ stay separate), per-call-key and fallback assertions; correct the misleading "$$ isolates parallel" test. - token_report.bats: make the malformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes; use truncated JSON, which jq rejects across versions). Addresses PR #456 review (chatgpt-codex-connector P2: key usage sidecars by BASHPID). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] * chore: apply manual instructions [skip ci-relay] * test(token-metrics): cover mktemp-failure fallback for per-call usage key Adds regression coverage for the fix that clears _ENGINE_USAGE_OUT before mktemp (PR #460 review, copilot-pull-request-reviewer ×3): - unit: a set-but-empty per-call key falls back to the $$-keyed sidecar (the mktemp-failure state), so it never reuses a prior/inherited key. - engine: a stale exported _ENGINE_USAGE_OUT + a forced mktemp failure does NOT reuse the stale sidecar — run_triage logs an estimate, not the planted 999/9/9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reviews): address review comments [skip ci-relay] --------- Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>



Why
Follow-up to #456. The merged token-usage capture keys its sidecar file by
$$:${TOKEN_LOG_FILE}.last-usage.$$. Butscripts/review-one-pr.shruns the tier-2 engines concurrently:In bash,
$$stays the parent shell PID inside both background subshells, so the two concurrent calls collide on the same sidecar — one engine's usage can overwrite, or be read by, the other before_record_engine_tokenslogs it. This was flagged bychatgpt-codex-connector(P2) on #456.BASHPIDalone doesn't fix it either: the writer runs in the chain'scmd | teepipe subshell (oneBASHPID) while the reader runs in the calling shell (a differentBASHPID) — they'd never agree on the path.Fix
Key the sidecar to the per-call
mktemptemp — unique per concurrent call, and shared writer↔reader via an exported env var:run_*exports_ENGINE_USAGE_OUT="${per_call_tmp}.usage"after creating its temp. It's inherited by the engine's pipeline subshell, so writer and reader agree; it's unique per call, so concurrentrun_agentic/run_ducknever share a file._engine_usage_sidecarprefers_ENGINE_USAGE_OUT; the$$form remains only as a fallback for non-concurrent direct callers.Tests
$$(the exact failure mode) each read back their own usage (111vs222), with a widened race window._engine_usage_sidecar; corrected the previous test that wrongly claimed$$"isolates parallel invocations".collect_org_jsonlmalformed-JSONL test deterministic (jq 1.7 exits 0 on NUL bytes — switched to truncated JSON, which jq rejects across versions).Test plan
shellcheck --severity=warningon all touched scriptsbats— token_metrics (41), engine_writer (37), token_report (17), model_pricing (13), fleet_report (40): 0 failuresResolves the open review thread on #456.
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests