Files
multi-agent-mux/.agents/reports/reviewer-grok-01/report-4709b38f.md
T

7.1 KiB
Raw Blame History

Review 4709b38f — Issue #60, opencode 2.x

Reviewed only the snapshot /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261018T055915Z-abe16e/1 (loop-20261018T055915Z-abe16e). Head 6b4b96fa1875862ef3bed830fe7b04166b1fad58, tree 9cfb2106081eba96b58cc6b7573031de0acba399, base 74333f87d0c02888c2b5b281e912d97e74348c01 is an ancestor. Three commits, 13 files, +460/−275. git diff --check is clean. Snapshot porcelain is empty and the snapshot has no .mam. Control-plane main is 74333f87d0c02888c2b5b281e912d97e74348c01, porcelain empty. No product file was edited.

Host tools: /usr/bin/python3 3.9.6, the control-plane venv the same 3.9.6, /bin/bash 3.2.57. bash -n accepts create_session.sh, resume_session.sh, update_yaml_resumed.sh, reconcile.sh, and status.sh. opencode --version in a temporary home, with XDG_DATA_HOME, XDG_STATE_HOME, XDG_CONFIG_HOME, and XDG_CACHE_HOME unset, printed opencode v2.0.32.

The user's background service stayed up for the whole review. Its pid is 86524, the command is opencode serve --service, and the service file mtime stayed 1792246838. The real database mtime stayed 1792247140. Nothing in this review called session delete, service stop, or an API against that database. After the tests the only opencode binary still running was that service.

What this Mac's database already stores

A read-only open of ~/.local/share/opencode/opencode.db shows a migrated database. session_v2 and session each have 4 rows. Every session_v2 row has parent_id NULL, and every id matches [A-Za-z0-9_]. The 2.x tables present are session_v2, session_message, session_inbox, session_pending, event, and event_sequence. The 1.x tables a migration keeps are also present: session, message, part, todo, and session_share. todo and session_share are keyed by session_id. Column names only were read. No row body was printed.

That matches the adapter. discover reads session_v2 where parent_id IS NULL (opencode.py:220). A child shares the workspace directory and can be newer than the TUI session, so drift C in reconcile.sh:966-968 uses the same filter. verify_artifact still accepts a known child id (opencode.py:115). status.sh checks session_v2 in both copies of resume_on_disk.

Purge scope

purge_artifacts calls opencode session delete --standalone -- <id> only when session_v2 contains that id (opencode.py:136-141). The fake CLI, and the real 2.0.32 contract below, delete that id and its children from the 2.x tables and leave the other session alone. A missing id does not invoke the CLI (test_purge_does_not_run_opencode_for_a_session_it_does_not_hold). A missing binary or a non-zero delete writes a WARN and leaves the session_v2 row for residual_artifacts (opencode.py:143-149, test_a_failed_delete_is_warned_and_reported).

The SQL that follows deletes message, part, and session (and the plural names) for that same id. It does not delete todo or session_share. db_rows_naming reports any remaining session_id or aggregate_id rows, so a migrated todo stays visible: test_opencode_residual_reports_event_rows expects residual [<db> (todo.session_id: 1 rows)] and eight entries for the other session. session_share.session_id is on that same report path. The append of sqlite rows for session happens when one of those 1.x tables exists (opencode.py:172-173), including when the delete matched no row. A fresh 2.x database has none of those tables, and the real contract asserts the purged list is only the session-delete line.

Spawn, resume, and the real binary

spawn_spec is opencode --auto --standalone. resume_spec with a materialized id is opencode --session <id> --auto --standalone (opencode.py:198-204). The same strings are the opencode arms in create_session.sh, resume_session.sh, and update_yaml_resumed.sh. test_spawn_and_resume_never_pass_agent_and_run_standalone reads those three scripts and rejects a line that still contains --agent. Live skill files and docs/ have no opencode db path and no --agent build. VERSIONS.md, bug-report/, and .agents/reports/ still describe the 1.x command; the brief leaves those historical notes in place. create_session.sh still treats auth.json or a provider key as enough, and otherwise accepts opencode --version. That check was left as it was, and --version exits 0 on this install.

_run points HOME and XDG_DATA_HOME at the discovery home before debug paths or session delete (opencode.py:80-87). _resolve_db reads the db line. The fallback is <home>/.local/share/opencode/opencode.db.

The opt-in contract test_real_opencode_2x_contract ran here, because 2.0.32 is installed. It used a pytest temporary home and tmp, unset the four XDG_* variables, and called only --help, api --standalone, and session delete --standalone. --help contains --standalone and --session. Discover returned the parent id. verify_artifact on the child was true. Purge of the parent cleared parent and child residuals. A second delete exited 1 with Session not found. No model prompt was sent.

This review did not start a herdr pane, so it did not drive create, a first TUI message, drift C, stop, and resume as one live chain. The pieces of that chain are the command lines above, drift C's session_v2 query, and verify_session_uuid, which calls the adapter. Stop's graceful /exit then kill-session then SIGKILL path is unchanged. --standalone is what makes the server a child of that TUI. The id charset on this database has no shell metacharacters, so the unquoted $UUID in resume_session.sh is safe for the ids stored here.

The new code uses HOME, XDG_DATA_HOME, sqlite, and subprocess. Nothing in it is macOS-only. This host is macOS, so Linux was not executed here.

Tests

Pytest used the control-plane venv, PYTHONDONTWRITEBYTECODE=1, -p no:cacheprovider, and --basetemp /tmp/mam4709-4709b38f-pybase. Inherited HERDR_*, MAM_*, MQTT_*, SKS_*, WORKSPACE_ROOT, DELEGATE_JOB_LOGS_DIR, HOME_DIR, CLAUDE_PROJECT_DIR, CLAUDE_CONFIG_DIR, CLAUDE_CODE_TMPDIR, CODEX_HOME, and PYTHONPATH were dropped.

On the snapshot, 44 tests passed in 7.56 s: tests/test_issue60_opencode_v2.py (including the real-binary contract), tests/test_a4_adapter_contract.py, and tests/test_issue31_purge_residual.py::test_opencode_residual_reports_event_rows. No skip and no error.

A separate clone whose discover query read session instead of session_v2 failed both test_discover_and_verify_read_session_v2_and_skip_child_sessions and test_a_fresh_2x_database_has_no_session_table_and_still_works (assert [] == ['ses_main']), in 1.07 s. A fresh 2.x database has no session table, the query raises, and discover returns []. The clone was discarded. Snapshot porcelain stayed empty.

After the report, snapshot porcelain is still empty, the snapshot still has no .mam, and control-plane porcelain is still empty at 74333f87. The herdr config mtime is still 1784456394. The opencode database mtime is still 1792247140 and service pid 86524 is still opencode serve --service.

[VERDICT: PASS]