Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
511 changes: 511 additions & 0 deletions docs/devflow/opencode-port/02-proposal.md

Large diffs are not rendered by default.

506 changes: 506 additions & 0 deletions docs/devflow/opencode-port/03-plan.md

Large diffs are not rendered by default.

152 changes: 152 additions & 0 deletions docs/devflow/opencode-port/build-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Build and Test Commands

Use this file as the command reference for OpenCode fork work. Update it when a
new verification command is discovered or when a command has an important
environment requirement.

## Environment

Required tools:

```bash
node --version
npm --version
bun --version
```

Current local setup:
- Bun installed with `brew install oven-sh/bun/bun`.
- Verified Bun version: `1.3.13`.
- OpenCode root: `/Users/jvanzyl/js/jopen/hojo-opencode`.

## Dependency Install

Run from the OpenCode root:

```bash
bun install
```

Known behavior:
- `bun install` can update `bun.lock` even when no source change is intended.
- After switching among OpenCode PR branches, stale `node_modules` can resolve an
older `effect` version than `bun.lock`; rerun `bun install` before treating
Effect import/type errors as code failures.
- On `devflow/pr-15224-session-start`, it added missing lock entries for the
PR's demo workspace package.
- On `devflow/pr-16598-session-stopping`, it changed the `ghostty-web` resolved
Git SHA.
- Treat lockfile drift as a separate review item. Do not silently include it in
PR absorption unless it is required and documented.

## Narrow Package Checks

Run from package directories, not with `bun --cwd`; Bun 1.3.13 did not accept
the attempted `bun --cwd "packages/opencode" run typecheck` command form.

Plugin package:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode/packages/plugin
bun run typecheck
bun run build
```

OpenCode package:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode/packages/opencode
bun run typecheck
bun run build
```

Observed results:
- `packages/plugin`: `bun run typecheck` runs `tsgo --noEmit`.
- `packages/plugin`: `bun run build` runs `tsc`.
- `packages/opencode`: `bun run typecheck` runs `tsgo --noEmit`.
- `packages/opencode`: `bun run build` runs `bun run script/build.ts` and builds
target binaries.

## PR-Specific Tests

Session stopping PR `#16598`:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode/packages/opencode
bun test test/plugin/session-stopping.test.ts
```

Observed result on 2026-05-03:
- 4 pass, 0 fail, 10 assertions.
- On `devflow/hojo`, the adapted Effect-path hook test has 2 pass, 0 fail,
4 assertions.

Session start PR `#15224`:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode/packages/opencode
bun test test/plugin/session-start.test.ts
```

Observed result on 2026-05-03:
- On `devflow/hojo`, the adapted Effect-path hook test has 1 pass, 0 fail,
2 assertions.
- The test verifies plugin-provided context is injected into the first session
model call and not injected into a later model call in the same session.

Parent agent context PR `#15412`:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode/packages/opencode
bun test test/plugin/parent-agent.test.ts
```

Observed result on 2026-05-03:
- 5 pass, 0 fail, 5 assertions.

Permission ask PR `#19470`:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode/packages/opencode
bun test test/permission/next.test.ts
```

Observed result on 2026-05-03:
- 76 pass, 1 fail, 108 assertions.
- Failing test: `permission requests stay isolated by directory`.
- This PR must not be integrated into `devflow/hojo` until the failure is
understood or fixed.

## Root Commands

Root typecheck:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode
bun run typecheck
```

Root test command is intentionally not useful:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode
bun test
```

The root `package.json` script says `test: echo 'do not run tests from root' &&
exit 1`. Use package-level or file-level tests instead.

## Git Hygiene

Before switching branches or integrating PRs:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode
```

Current policy:
- `docs/devflow/opencode-port/` is our tracking documentation and should be
carried on the devflow fork branch.
- Generated lockfile changes from dependency install should be reviewed
separately and not mixed into a PR absorption without an entry in
`verification-log.md` and `opencode-fork-prs.md`.
135 changes: 135 additions & 0 deletions docs/devflow/opencode-port/experiment-runbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# OpenCode Experiment Runbook

Use this runbook to validate devflow experiments through the local OpenCode fork.
Keep runs isolated from the real `~/.opencode` config unless the task explicitly
asks for a real cutover rehearsal.

## Paths

- OpenCode fork: `/Users/jvanzyl/js/jopen/hojo-opencode`
- Devflow repo: `/Users/jvanzyl/js/ig/devflow2`
- Experiment suite: `/Users/jvanzyl/js/ig/devflow-experiments`
- Native OpenCode binary after local build: `/Users/jvanzyl/js/jopen/hojo-opencode/packages/opencode/dist/opencode-darwin-arm64/bin/opencode`

## Build The Binary

Build a native single-platform binary from the OpenCode package:

```bash
cd /Users/jvanzyl/js/jopen/hojo-opencode/packages/opencode
bun run script/build.ts --single --skip-install
```

Do not use root `bun test`; the root package intentionally refuses it. Use
package-level checks documented in `build-commands.md`.

## Prepare One Fresh Experiment

Create a new project copy and a fresh OpenCode config root:

```bash
ROOT=$(mktemp -d "/tmp/devflow-built-exp-root.XXXXXX")
PARENT=$(mktemp -d "/tmp/devflow-built-exp-project.XXXXXX")
PROJECT="$PARENT/0018-refactor-extract-method"

cp -R "/Users/jvanzyl/js/ig/devflow-experiments/templates/0018-refactor-extract-method" "$PROJECT"
/Users/jvanzyl/js/ig/devflow2/install.sh --target opencode --root "$ROOT"

git init "$PROJECT"
git -C "$PROJECT" add .
git -C "$PROJECT" commit -m "Initial experiment template"

printf 'ROOT=%s\nPROJECT=%s\n' "$ROOT" "$PROJECT"
```

Keep the printed `ROOT` and `PROJECT`; all following commands use them.

## Run The Experiment

Use the experiment prompt after the `---` separator in `EXPERIMENT-PROMPT.md`.
For `0018-refactor-extract-method`, the prompt is:

```text
Refactor the OrderProcessor class per the proposal at docs/work/20260428-refactor-extract-method/02-proposal.md. Existing tests must continue to pass.

/flow --autonomous --start-phase 04 --path refactor
```

Run OpenCode with the isolated config:

```bash
OPENCODE_CONFIG_DIR="$ROOT" /Users/jvanzyl/js/jopen/hojo-opencode/packages/opencode/dist/opencode-darwin-arm64/bin/opencode run --format json --dangerously-skip-permissions --dir "$PROJECT" '<prompt text>'
```

If the run stops early but makes progress, resume with a short continuation
prompt against the same `PROJECT` and `ROOT`. Do not modify generated work by
hand unless the task is to debug the harness itself.

When dispatching `devflow-tester`, include explicit write scope. Valid test
write paths are Java tests under `src/test/java/...` and Python tests under
`tests/...` or `src/test/python/...`. If the experiment starts after phase 00,
also verify `.devflow/phase.json` contains `initiative_path`; otherwise the
criteria coverage gate blocks even valid tester writes.

## Monitor Progress

Do not wait for a long `opencode run` timeout to learn whether an experiment is
stalled. Poll the run while it is active:

```bash
git -C "$PROJECT" status --short --branch
PGPASSWORD=devflow psql -h localhost -p 15433 -U devflow -d devflow -c "SELECT timestamp,sessionid,agenttype,toolname,filepath,command,blocked,blockreason FROM devflow_tool_calls WHERE timestamp > now() - interval '10 minutes' ORDER BY timestamp DESC LIMIT 60;"
PGPASSWORD=devflow psql -h localhost -p 15433 -U devflow -d devflow -c "SELECT sessionid,harness,sessiontype,status,startedat FROM devflow_sessions WHERE startedat > now() - interval '10 minutes' ORDER BY startedat DESC LIMIT 20;"
```

Treat these as stop-and-diagnose signals:

- Any `blocked=true` row.
- No new telemetry for more than a minute while an OpenCode process is alive.
- No git diff after a tester/programmer write task claims progress.
- `mvn test` still reports the original test count after a RED test task.
- A commit made outside OpenCode during an experiment. External commits bypass
devflow hooks, so `.devflow/commit-order-state.json` may not record
`testCommitted:true` and later programmer writes can be falsely blocked.
Exception: a final telemetry-only commit may be needed after all verification,
because committing `.devflow/workflow-state.json` through OpenCode records one
more commit event and dirties that same file again.

## Verify The Result

Run these from the experiment project:

```bash
mvn package
bash bin/measure-adherence.sh
git status --short
git log --oneline --decorate -10
```

Expected success shape for `0018-refactor-extract-method`:

- `mvn package` reports `BUILD SUCCESS`.
- The scorer reports `Score: 6/6 (100%)`.
- `git status --short` is clean.
- The history contains separate test/refactor/finalization commits.

## Full Suite Notes

Run one clean single-experiment smoke before attempting the full suite. When the
single smoke is green, use the same isolated-config pattern for additional
templates under `/Users/jvanzyl/js/ig/devflow-experiments/templates/`.

The stock experiment harness in `bin/run-experiment.py` was originally written
for Claude Code. Until it has an explicit OpenCode mode, prefer manual isolated
template runs or update the harness in a separate, reviewed change.

## Evidence To Capture

Record results in `verification-log.md` with:

- OpenCode branch and binary path.
- Devflow commit used for install.
- Experiment template name.
- `ROOT` and `PROJECT` paths if they still exist.
- Final Maven/scorer/status results.
- Any resumed prompts or harness defects discovered.
25 changes: 25 additions & 0 deletions docs/devflow/opencode-port/gap-log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# OpenCode Port Gap Log

This file records every known gap between current Claude Code devflow behavior
and OpenCode behavior. Do not close a gap without evidence.

| ID | Gap | Severity | Source | Closing Work | Upstream PR | Status | Evidence |
|---|---|---|---|---|---|---|---|
| G1 | OpenCode install rejects Claude-style agent `tools` array | P0 | Disposable `OPENCODE_CONFIG_DIR` install test | Agent frontmatter transform | None | Open | TBD |
| G2 | Mandatory rules are not guaranteed through `~/.claude/rules/` | P0 | OpenCode docs | `opencode.json` `instructions` plus `AGENTS.md` | Optional `#18903`/`#10090` | Open | TBD |
| G3 | OpenCode target currently installs only rules and agents | P0 | `manifests/install-modules.json` | Add skills, commands, plugin adapter, config modules | None | Open | TBD |
| G4 | Claude `hooks/hooks.json` is not consumed by OpenCode | P0 | OpenCode plugin model | Build JS/TS adapter that invokes canonical Python hooks | `#22654`/`#20053` behavior supports adapter substrate | Partial | `tool.execute.before` now exposes `ask()` and propagates mutated args before execution. The devflow adapter still needs to be implemented. |
| G5 | `/loop` depends on Claude `Stop` hook | P1 | `hooks/stop-hook.sh` | Use OpenCode `session.stopping` | `#16598` | Partial | `session.stopping` integrated on `devflow/hojo`; `bun test test/plugin/session-stopping.test.ts`, plugin typecheck, and opencode typecheck pass. Gap remains open until `/loop` command/config adapter uses it. |
| G6 | Telemetry scripts must record `harness=opencode` | P1 | Current telemetry behavior | Pass harness through adapter and telemetry scripts | None | Open | TBD |
| G7 | OpenCode `apply_patch` has no Claude `MultiEdit` equivalent payload | P1 | OpenCode tool model | Parse patch paths in adapter | None | Open | TBD |
| G8 | Subagent identity/parent context is insufficient for policy | P1 | Hook payload needs | Absorb parent agent context PR | `#15412` | Partial | `#15412` integrated on `devflow/hojo`; `bun test test/plugin/parent-agent.test.ts`, plugin typecheck, and opencode typecheck pass. Gap remains open until the devflow adapter consumes the context. |
| G9 | SessionStart parity is missing for startup telemetry/context | P2 | Hook lifecycle gap | Use OpenCode `session.start` and adapter output context | `#15224` | Partial | `session.start` integrated on `devflow/hojo`; `bun test test/plugin/session-start.test.ts`, affected plugin tests, plugin typecheck/build, and opencode typecheck pass. Gap remains open until the devflow adapter consumes it. |
| G10 | Post-tool hook timing for MCP/plugin tools may miss final output | P2 | Hook timing gap | Absorb after-MCP PR | `#21150` | Partial | Local Effect-path adaptation makes MCP `tool.execute.after` run after output assembly and lets mutations affect returned output. Gap remains open until devflow telemetry adapter consumes it. |

## Gap Closure Requirements

A gap is closed only when all are true:
- The implementation or fork PR is applied.
- A test or manual verification command proves the behavior.
- `parity-matrix.md` is updated.
- `verification-log.md` records the evidence.
Loading
Loading