Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
5.5 KiB
Review 8f95cc77 — PR #62, second pass
PASS. Commit 6a37c00 fixes the five Mac failures from 6a4e385 and the two extra findings from that round. Related tests: 53 passed.
Reviewed only the snapshot /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261019T015801Z-05463c/1 (loop-20261019T015801Z-05463c). Head 6a37c0019baa31ee28b32a086e57b4c8239413c4, tree 87013e7ef7f5239f1bf6ea38a2cbda214257be3c, base 1d7b7dab58a10fe86fd747b7290d47674ca93230 is an ancestor and is the control-plane HEAD. Nine commits, 13 files, +553/−36. git diff --check is clean. Snapshot porcelain is empty and the snapshot has no .mam. Control-plane porcelain is empty. No product file was edited. The source worktree was not run.
The new commit on top of 6a4e385 is 6a37c00. It changes four files (+40/−7): opencode.py (placeholder pattern and auth_ok), status.sh, reconcile.sh, and tests/test_issue60_linux_fixes.py.
Host tools: control-plane venv Python 3.9.6, sqlite 3.51.0. bash -n accepts status.sh, reconcile.sh, create_session.sh, and stop_session.sh. The changed Python modules parse. The opencode binary was not launched. Linux was not executed here. The real database was not opened.
The round-1 blocker
On this host, closing the last WAL connection leaves opencode.db-wal at 0 bytes and opencode.db-shm at 32768 bytes, and the checkpoint has already written the rows into the main file. make("clean") now removes those two sidecars when they exist (test_issue60_linux_fixes.py:158-162). The five clean cases of test_a_query_reads_right_and_leaves_the_sidecars_alone then see a directory of exactly opencode.db, read the expected rows through mode=ro&immutable=1, and the directory is still that one file afterward. Those five cases passed. The leftover, wal-only, and live-writer cases passed again.
On Linux the close already removes the sidecars, so the new os.path.exists unlink is a no-op there. The same rows are what the immutable open reads.
Placeholder and auth
The pattern is now Ask anything(?:…|\.\.\.) "[^"]*"? (opencode.py:79). The quoted example is required, so a first line that is only Ask anything… or Ask anything... stays typed text. The wide and narrow home fixtures still read as an empty box, including the narrow line whose example has no closing quote. A first line with text after the closing quote stays, and so does a later line. test_typed_text_is_read_as_typed covers the two bare lines on both fixtures and passed. input_placeholder stays ''. The other adapters' pattern property stays None.
A first line that is exactly Ask anything… "<example>" is still cleared. That is the home-screen shape.
auth_ok accepts shutil.which("opencode"), or <home>/.opencode/bin/opencode when that path is a file and os.access(..., os.X_OK) is true (opencode.py:321-323). A mode 0644 file and a directory named opencode both fail. test_a_home_install_that_cannot_run_is_not_enough and test_adapter_auth_ok passed. Keys and auth.json still do not count. Create still asks auth-ok and does not run --version. The other agents' auth_ok bodies are outside this commit.
status and reconcile
Both copies of resume_on_disk in status.sh (:117 and :318) and the opencode drift-C open in reconcile.sh (:955) call _ro_connect(odb). sqlite3.connect(odb) is gone from both scripts. test_status_and_reconcile_open_the_database_read_only checks those counts and passed. env_python puts the skill directory on PYTHONPATH, which is the path get_adapter already uses a few lines above each open. A failed open still returns MISSING in status and is swallowed in reconcile. Hermes and codex in those scripts still open their own databases with sqlite3.connect.
Suite
Pytest used the control-plane venv, PYTHONDONTWRITEBYTECODE=1, -p no:cacheprovider, and --basetemp /tmp/mam8f95-8f95cc77-pybase. Inherited HERDR_*, MAM_*, MQTT_*, SKS_*, DELEGATE_JOB_LOGS_DIR, HOME_DIR, CLAUDE_PROJECT_DIR, CLAUDE_CONFIG_DIR, CLAUDE_CODE_TMPDIR, CODEX_HOME, PYTHONPATH, WORKSPACE_ROOT, XDG_STATE_HOME, XDG_CONFIG_HOME, XDG_CACHE_HOME, and XDG_DATA_HOME were dropped.
53 passed in 59.23 s: tests/test_issue60_linux_fixes.py and tests/test_a4_adapter_contract.py::test_adapter_auth_ok. No skip and no error.
The earlier commits are unchanged in this pass: _ro_connect still picks mode=ro when both sidecars exist, immutable=1 when there is no -wal, and a private memory copy when a -wal has no -shm. The gap between the exists check and the immutable open is still there. _DB_PATHS still keeps a path for the life of the process, and each test replaces that dict. Create still treats an executable binary as configured. Those three were left in place on purpose.
The user's background service stayed up. Its pid is 23630 and the command is opencode serve --service. The real database mtime stayed 1792367390. ~/.config/opencode/service.json stayed 1792246838 and ~/.local/state/opencode/service.json stayed 1792365227. The real opencode.log mtime stayed 1792368889 and its size stayed 2636652. The herdr config mtime stayed 1784456394.
After the report, snapshot porcelain is still empty, the snapshot still has no .mam, and control-plane porcelain is still empty at 1d7b7dab. The herdr config mtime is still 1784456394. The opencode database mtime is still 1792367390, the opencode log mtime is still 1792368889 and its size is still 2636652, and service pid 23630 is still opencode serve --service.
[VERDICT: PASS]