mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-09 07:10:34 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Before a native OpenCode agent can run a task, agent setup runs a harness test. The test sends one "Respond with hello." prompt through `opencode run`. > - The native OpenCode driver gives every OpenCode process its own `HOME` and XDG data, cache, and state directories. The harness test did not. It used the host user's `HOME`, so it shared `~/.local/share/opencode/opencode.db` with every other OpenCode process on the host. > - OpenCode keeps one SQLite database for each data directory. When two OpenCode processes start at the same time on one database, one process can fail in about one second with `Error: Unexpected error / database is locked`. > - The harness test then reports `opencode_hello_probe_failed`. Three failures pause agent verification, so the agent's first task stays queued and never starts. > - This pull request gives each local native harness test its own temporary OpenCode home, the same as the native driver. > - The benefit is that a native OpenCode agent passes setup when other OpenCode processes run on the same host, and its first task starts. ## Linked Issues or Issue Description No public issue exists. This is the bug description. Refs #14393 (open, related): it isolates the OpenCode data directory for the legacy `opencode_local` execution path. This pull request covers a different path: the native runner harness test. **What happened?** Two native OpenCode runner end-to-end cells failed before any provider turn and before their planned control-plane restart: `stock-harness.runner-opencode.local.continuity-restart` ("Timed out waiting for chat turn settles to waiting") and `local-session-integrity.runner-opencode.local.structured-question-restart-resume` ("Timed out waiting for pending user question"). In both cells, the server log shows `Agent lifecycle operation failed ... phase: verifying ... failureCode: harness_test_failed` three times. The run stayed `queued` with `startedAt: null`. The second cell failed two attempts 2 seconds apart, which is shorter than one successful hello turn. **Steps to reproduce** 1. Run several native OpenCode harness tests at the same time with the host `HOME` (or run one while another OpenCode process starts). 2. Some `opencode run` processes exit 1 within about one second with `database is locked`. 3. Agent verification records `harness_test_failed`, and after three failures it pauses. **Expected behavior** The harness test uses an isolated OpenCode home, the same as the native runtime that it qualifies. Other OpenCode processes on the host do not affect it. ## What Changed - `packages/adapters/opencode-local/src/server/test.ts`: for a local `paperclip_runner` probe, create a temporary home and set `HOME`, `XDG_DATA_HOME`, `XDG_CACHE_HOME`, and `XDG_STATE_HOME` inside it. Also set `OPENCODE_DISABLE_MODELS_FETCH` and `OPENCODE_DISABLE_DEFAULT_PLUGINS`, as the native driver does, so a fresh cache does not fetch a catalog or install default plugins. Remove the directory after the probe. - The legacy `opencode_local` adapter keeps the host home, because its `opencode auth login` credentials live there. Remote (sandbox) probes do not change. - `packages/adapters/opencode-local/src/server/test.remote.test.ts`: add a regression for two concurrent native probes (each gets its own data directory, and the directory is removed), and a sibling case that the legacy adapter keeps the host home. ## Verification - Red, unit: the new concurrent-probe test failed on the unfixed code (`expected 'user' to match /^paperclip-opencode-native-probe-home-/`). It passes with the fix. `cd packages/adapters/opencode-local && npx vitest run src/server` gives 89/89 passed. `tsc --noEmit` passes. - Red, real process: the unfixed `testEnvironment` against the real pinned OpenCode 1.18.34 and OpenRouter, 12 concurrent probes, 3 rounds: 2 of 36 probes failed with `opencode_hello_probe_failed` (`database is locked`). A plain shell reproduction with 6 concurrent `opencode run` processes on the shared home: 2 of 6 failed with `database is locked`. - Green, real process: the fixed `testEnvironment`, same 12 x 3 rounds: 36 of 36 passed with `opencode_hello_probe_passed`. - End-to-end reruns of both failing cells: two rounds at this revision with the real pinned OpenCode and OpenRouter (`pnpm test:e2e:runner -- --max-automatic-retries 0 --id <cell>`). `stock-harness.runner-opencode.local.continuity-restart`: 2 of 2 passed. `local-session-integrity.runner-opencode.local.structured-question-restart-resume`: round 1 passed. Round 2 passed agent verification, asked the question, and crossed the restart. After the user answered, the continuation run failed with a different error: `runner_local_connect_failed: PRP command run.attach timed out`. That failure is after the harness test and is not changed by this pull request. It is tracked as a separate signature. In all four reruns, agent verification passed on the first attempt. ## Risks - Low risk. The change applies only to local native OpenCode harness tests. The native runtime already uses an isolated home, so the test now matches the runtime that it qualifies. - A native probe no longer reads OpenCode credentials from the host user's home. This is intended: native OpenCode agents receive provider credentials through the agent environment, and the native driver does not read the host home either. - Each probe starts with a cold cache. With the catalog fetch and default plugins disabled, a probe took 4 to 6 seconds in local tests, the same as before. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`), Anthropic, used through Claude Code with tool use (shell, file edits, test execution). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>