fix(tasks): preserve refreshed GitHub credentials in sandboxes - #72540
Conversation
🦔 ReviewHog reviewed this pull requestFound 0 must fix, 0 should fix, 1 consider. Published 1 finding (view the review). |
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
products/tasks/backend/temporal/process_task/activities/provision_sandbox.py:774
**Empty Refresh Can Restore Stale State**
When neither credential is refreshed, this still performs an unlocked read-modify-write of `/tmp/agent-env`. A concurrent mid-run refresh can write a new token after this call reads the file, then have that token replaced by the stale payload, recreating the credential-loss race.
```suggestion
if fresh_env_vars:
update_sandbox_env_file(sandbox, fresh_env_vars)
```
### Issue 2 of 2
products/tasks/backend/logic/services/local_packages.py:101
**Default Catalog Alias Remains Unresolved**
Pnpm also accepts `catalog:*` for the default catalog, and that form is already used by package manifests in this repository. If an overlaid package uses it, the literal protocol reaches the generated npm manifest and dependency installation fails instead of using the workspace catalog version.
```suggestion
if version in {"catalog:", "catalog:*"}:
```
Reviews (1): Last reviewed commit: "Merge remote-tracking branch 'origin/mas..." | Re-trigger Greptile |
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
🤖 CI report
|
| File | Patch | Uncovered changed lines |
|---|---|---|
products/tasks/backend/temporal/process_task/tests/test_sandbox_credentials.py |
0.0% | 4, 62, 64, 66, 68–70, 72, 74, 76, 79–80, 82–83, 85, 87, 91, 95, 100, 102, 105, 107 |
products/tasks/backend/temporal/process_task/activities/tests/test_inject_fresh_tokens_on_resume.py |
0.0% | 8, 30, 56–57, 62, 66, 71, 102–106, 112, 142–143 |
products/tasks/backend/temporal/process_task/sandbox_credentials.py |
25.0% | 59–60, 62, 81, 87, 89–91, 103–104, 106–108, 115–116 |
products/tasks/backend/temporal/process_task/activities/provision_sandbox.py |
33.3% | 762–763, 767–768 |
products/tasks/backend/logic/services/local_packages.py |
81.5% | 111, 121, 133, 145, 150 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 29842684044 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
demo |
███████████░░░░░░░░░ 56.2% |
1,497 / 2,663 |
tasks |
█████████████░░░░░░░ 66.4% |
26,563 / 40,003 |
signals |
████████████████░░░░ 79.7% |
19,771 / 24,802 |
data_modeling |
████████████████░░░░ 80.0% |
4,834 / 6,045 |
cdp |
████████████████░░░░ 80.7% |
3,118 / 3,864 |
notebooks |
█████████████████░░░ 85.3% |
7,266 / 8,522 |
agent_platform |
█████████████████░░░ 86.4% |
3,807 / 4,405 |
actions |
█████████████████░░░ 86.6% |
717 / 828 |
cohorts |
█████████████████░░░ 87.0% |
4,303 / 4,945 |
product_tours |
██████████████████░░ 87.9% |
1,303 / 1,482 |
exports |
██████████████████░░ 88.4% |
6,943 / 7,853 |
conversations |
██████████████████░░ 89.1% |
16,431 / 18,431 |
dashboards |
██████████████████░░ 89.4% |
5,934 / 6,640 |
engineering_analytics |
██████████████████░░ 89.5% |
5,507 / 6,154 |
mcp_analytics |
██████████████████░░ 89.7% |
2,663 / 2,969 |
alerts |
██████████████████░░ 89.9% |
4,054 / 4,508 |
error_tracking |
██████████████████░░ 90.1% |
9,761 / 10,832 |
early_access_features |
██████████████████░░ 90.1% |
1,031 / 1,144 |
streamlit_apps |
██████████████████░░ 90.4% |
2,501 / 2,767 |
slack_app |
██████████████████░░ 90.6% |
8,989 / 9,926 |
marketing_analytics |
██████████████████░░ 90.8% |
11,514 / 12,684 |
stamphog |
██████████████████░░ 91.0% |
3,993 / 4,387 |
product_analytics |
██████████████████░░ 91.3% |
5,786 / 6,337 |
data_warehouse |
███████████████████░ 92.6% |
19,145 / 20,683 |
ai_observability |
███████████████████░ 92.6% |
14,671 / 15,840 |
web_analytics |
███████████████████░ 92.9% |
13,853 / 14,913 |
workflows |
███████████████████░ 92.9% |
5,648 / 6,077 |
surveys |
███████████████████░ 93.0% |
5,724 / 6,157 |
posthog_ai |
███████████████████░ 93.2% |
1,325 / 1,421 |
approvals |
███████████████████░ 93.3% |
3,395 / 3,640 |
reminders |
███████████████████░ 93.4% |
468 / 501 |
endpoints |
███████████████████░ 94.1% |
8,606 / 9,143 |
revenue_analytics |
███████████████████░ 94.5% |
3,598 / 3,809 |
skills |
███████████████████░ 94.5% |
2,893 / 3,061 |
review_hog |
███████████████████░ 94.6% |
6,808 / 7,193 |
logs |
███████████████████░ 95.4% |
9,935 / 10,416 |
experiments |
███████████████████░ 95.7% |
24,469 / 25,569 |
replay_vision |
███████████████████░ 95.8% |
13,882 / 14,491 |
annotations |
███████████████████░ 96.2% |
732 / 761 |
feature_flags |
███████████████████░ 96.3% |
16,311 / 16,940 |
user_interviews |
███████████████████░ 96.5% |
2,639 / 2,735 |
warehouse_sources |
███████████████████░ 96.7% |
291,442 / 301,346 |
customer_analytics |
███████████████████░ 97.3% |
7,780 / 7,999 |
data_catalog |
███████████████████░ 97.4% |
2,345 / 2,407 |
pulse |
████████████████████ 98.4% |
2,017 / 2,049 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
|
ReviewHog Alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏 |
There was a problem hiding this comment.
ReviewHog Report
Changes
Issues: 1 issue
Files (5)
products/tasks/backend/logic/services/agentsh.pyproducts/tasks/backend/logic/services/docker_sandbox.pyproducts/tasks/backend/logic/services/local_packages.pyproducts/tasks/backend/logic/services/modal_sandbox.pyproducts/tasks/backend/temporal/process_task/activities/provision_sandbox.py
Problem
Long-lived cloud task sandboxes receive refreshed GitHub and OAuth credentials without restarting the agent server. The background launch path used a check-then-write initializer for
/tmp/agent-env, so it could overwrite credentials that a concurrent refresh had already written. Resume refreshes also replaced the file with a partial environment.A related Code-side issue meant Codex only restored
BASH_ENVfor shells launched from the initial checkout. That half is handled by PostHog/code#3625.Changes
/tmp/agent-envwith a completed temporary file and an atomic create-if-absent link inside the existing background launch. A refresh that wins the race cannot be overwritten.Before:
flowchart LR A[Provision sandbox] --> B[Background launch] B --> C[Check then overwrite env file] D[Credential refresh] --> E[Write refreshed credentials] C --> F[agent env] E --> F F --> G[Agent shell] classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff; classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff; classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000; classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000; class B,G phBlue; class C,E phRed; class A phYellow; class F phGray;After:
flowchart LR A[Provision sandbox] --> B[Background launch] B --> C[Write temp then create if absent] D[Credential refresh] --> E[Merge credential keys] C --> F[agent env] E --> F F --> G[Agent shell] classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff; classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff; classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000; classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000; class B,G phBlue; class C,E phRed; class A phYellow; class F phGray;