# Cross-review: OpenCode adapter iteration-1 refinements

- **Reviewer**: `reviewer-creator-grok-01`
- **Job**: `1484a8bf` (follow-up to `8548aab1` `[VERDICT: PASS]`)
- **Scope**: lint / behavior / loss against the iteration-1 findings and the accumulated git diff
- **Tests**: `pytest tests/test_a4_adapter_contract.py tests/test_tier1_unit.py tests/test_c1_tui_readiness.py` → **108 passed in 39.12s**

## Iteration-1 brief items

| # | Required | Status |
|---|---|---|
| 1 | SQLite columns `directory` (not `cwd`) and `time_created` in milliseconds, with fallback | **Met.** Adapter `verify_artifact` / `discover` and reconcile drift-C both `PRAGMA table_info(session)` then prefer `directory`/`time_created`, else `cwd`/`created_at`/`started_at`. `time_created` is compared as ms (`epoch * 1000` on query; `/1000` on verify when `time_col == "time_created"` or value `> 1e11`). Covered by `test_opencode_real_schema_directory_and_time_created_ms`. |
| 2 | `_resolve_db()` invokes `opencode db path` dynamically | **Met.** Adapter tries `shutil.which("opencode")` then `ctx.home_dir` / `~/.opencode/bin`, runs `[bin, "db", "path"]` with `HOME`/`HOME_DIR`/`XDG_DATA_HOME` from `DiscoveryContext`, then filesystem fallbacks. Reconcile drift-C calls `get_adapter('opencode')._resolve_db(...)` first. Covered by `test_opencode_resolve_db_cli_path`. |
| 3 | Export `OPENCODE_PERMISSION='{"*":"allow"}'` at create/resume when unset | **Met.** Both `create_session.sh` spawn `opencode)` and `resume_session.sh` use `if [ -z "${OPENCODE_PERMISSION:-}" ]; then export OPENCODE_PERMISSION='{"*":"allow"}'; fi`. Single-quoted JSON is valid; preset values are preserved. |
| 4 | `run_loop.sh` agent-type resolver and `status.sh` `resume_on_disk()` opencode branches | **Met.** Resolver adds `elif 'opencode' in segments`. `status.sh` walks name suffixes and checks `opencode_session_id_own` against a session row in SQLite. |
| 5 | Unit fixtures match real schema | **Met.** `conftest.py` mock `opencode db path` seeds `{home}/.local/share/opencode/opencode.db` with `directory`/`time_created`; a4 `_seed_opencode_session` and real-schema tests use the same columns. |

## Prior blocking items (from `be49be2b` / `8548aab1`)

| ID | Previous defect | This round |
|---|---|---|
| **F1** | `reconcile.sh` `shutil.which` with no `import shutil` | **Still fixed.** `RECON_SRC` is `import os, json, glob, subprocess, time, sqlite3, re, shutil`. Asserted in `test_opencode_shell_and_scripts_integration`. |
| **F2** | `OPENCODE_PERMISSION` default included stray single quotes (`'{"*":"allow"}'` as the *value*) | **Still fixed, quoting rewritten.** Unset-check + `export OPENCODE_PERMISSION='{"*":"allow"}'` produces a value that `json.loads` as `{"*": "allow"}`. Unset and preset (`{"*":"deny"}`) paths are covered in `tests/test_tier1_unit.py`. |

`HERDR_EPOCH=$(date +%s)` is stamped **before** `spawn` (create_session.sh:231–234), so drift-C epoch filtering is not inverted for new OpenCode sessions.

No lint, behavior, or lockstep-loss issue that would block PASS. Agent is registered (`registry.py`), own-key is wired through `atomic_yaml` / `verify_session` / `workspace_uuid`, spawn/resume specs are `--auto --agent build` / `--session {uuid} --auto --agent build`, stop captures `opencode_session_id_own`, and SKILL.md / `.mam.env.example` / integration guide storage notes were updated.

## Residual nits (do not block)

- `status.sh` `resume_on_disk` still locates the DB by `opencode.db`/`storage.db` filenames, not `opencode db path`. Read-only snapshot; pin path is reconcile via the adapter. Same nit accepted on `8548aab1`.
- `test_opencode_shell_and_scripts_integration` re-runs a duplicated bash snippet and only source-asserts the export string in `resume_session.sh` (not `create_session.sh`). The live create/resume scripts both contain the correct form; this is a test-coupling gap, not a product bug.
- TUI ready tokens `OpenCode|Chat` / input `❯` / `─{10,}` are still guessed; no live `opencode` binary in this environment to capture empirically.
- `orc_onboard.sh` `is_valid_id` remains UUID-shaped; if a live OpenCode session id is not a UUID, auto-detect from `--session`/`OPENCODE_SESSION_ID` will skip it. Create still uses pending-discovery, so this is onboard-only.

None of these require design-level rework.

No `[ESCALATE: PLANNER]`.

---

[VERDICT: PASS]
