Skip to content

fix: guard opencode state against missing volumes and agent deletes - #23

Merged
icco merged 6 commits into
mainfrom
fix/persist-state-guard
Oct 14, 2026
Merged

icco merged 6 commits into
mainfrom
fix/persist-state-guard

Conversation

@icco

@icco icco commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Why

A host reboot surfaced the loss of OpenCode sessions and logins even though /data was bind-mounted. Files inside the volume had been deleted while both servers ran, so the loss only showed on restart.

This adds a startup check that /data is a mount, a smoke-test step that recreates the container and checks a session survives, ask rules and an AGENTS.md rule against deleting /data/.config and /data/.local, moves OpenChamber chats to /data/workspace/.chats, and documents what persists where.

Risks

The mount check would not have caught this incident. The rm asks match any command text containing .config or .local, so rm vite.config.ts also prompts. Existing chats under /data/.config/openchamber/chats stay listed.

icco and others added 2 commits October 14, 2026 14:00
…eates

The entrypoint now exits when $HOME (/data) is not a mountpoint, so sessions, credentials, and logs can never land in the container layer. The smoke test runs both servers on a named volume, then recreates the OpenCode container and checks that a session, the server log, and the config and state directories survive.

OpenChamber chats move to /data/workspace/.chats so agent sessions no longer run with a working directory inside /data/.config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Build and General now ask before rm commands that name a .config or .local path, and AGENTS.md forbids deleting /data/.config or /data/.local. The README lists what lives where under /data and how to restore it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@icco
icco requested a balanced review from Copilot October 14, 2026 14:01
@icco
icco marked this pull request as ready for review October 14, 2026 14:04
The suffix patterns missed rm -rf .config .local .cache, where neither protected directory is last or followed by a slash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI 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.

🟡 Changes recommended

Common deletion forms bypass the new permission rules, and the mount requirement masks existing password-validation tests.

2 open findings
What changed in this PR

Adds persistence safeguards for OpenCode and OpenChamber state.

Changes:

  • Requires /data to be mounted and documents persisted state.
  • Adds recreation-based persistence smoke testing.
  • Relocates chats and adds agent deletion guards.
File Description
AGENTS.md Prohibits deleting persistent state.
Dockerfile Relocates managed chats.
README.md Documents persistence and safeguards.
entrypoint.sh Enforces the /data mount.
opencode.jsonc Adds deletion confirmation rules.
scripts/​smoke-test.sh Tests mounts and persistence.
tests/​routing.test.mjs Verifies agent rules.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread opencode.jsonc Outdated
Comment thread entrypoint.sh Outdated
@icco
icco requested a balanced review from Copilot October 14, 2026 14:08
Adds ask rules for rm commands naming HOME (including XDG_*_HOME), ~, or ending in /data. The integration test now matches each rule's resource as well as its action, and checks ask/allow decisions for sample commands against the agents the server reports.

The negative password runs mount a volume, so they fail on the password check rather than the mount guard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@icco
icco requested a balanced review from Copilot and removed request for Copilot October 14, 2026 14:15
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI 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.

🟡 Changes recommended

The mount check and deletion rules still have concrete bypasses that can leave persistent state unprotected.

2 open findings
2 resolved since last review

🧠 Review effort: Balanced

Comment thread entrypoint.sh Outdated
Comment thread opencode.jsonc Outdated
The mount guard checked $HOME, which a caller can override while the XDG state paths stay hard-coded under /data. Build and General now also ask before rm commands containing /data/., which catches rm -rf /data/.*.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@icco
icco requested a balanced review from Copilot October 14, 2026 14:20

Copilot AI 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.

🟢 Approval recommended

The persistence safeguards are consistent, documented, and covered by configuration and container-level tests.

0 open findings

2 resolved since last review

🧠 Review effort: Balanced

@icco
icco merged commit 6157857 into main Oct 14, 2026
12 of 13 checks passed
@icco
icco deleted the fix/persist-state-guard branch October 14, 2026 14:30
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.

2 participants