opencode
Native ADLC integration for the opencode terminal agent: an enforce-by-default rails-guard hook, nine lifecycle commands, native adlc_gate/adlc_prosecute tools, and a deterministic P5 prosecution loop (5 lenses + verifier) plus a prosecutor meta-agent.
ADLC in opencode
Brings the lifecycle into the opencode terminal agent as
a native plugin: an in-session rails-guard hook (tool.execute.before),
advisory session hooks, nine lifecycle commands, the adlc phase-routing
skill, two native model-callable tools (adlc_gate, adlc_prosecute), a
deterministic P5 prosecution loop (five lenses + a verifier fanned out over
write-disabled child sessions), and a separate @prosecutor meta-agent (seven
prosecution agents in all). The integration enforces by default: a thrown
denial in tool.execute.before aborts the tool call (documented host behavior,
regression-tested against a real binary).
What you get
- Rails-guard hook on
tool.execute.before. Denies structurededit/write/apply_patchto a frozen rail declared by the active ticket; in-session bash is gated too via the@adlc/coreshell classifier. - Native tools:
adlc_gate(the model runs a lifecycle gate, LLM-backed ones keyless through the host model) andadlc_prosecute(the deterministic first-party P5 loop: fan-out → dedupe → verify → loop-until-dry over write-disabled child sessions). - Advisory session/compaction hooks:
session.createdpreflight, asession.idlegate-manifest audit, per-turn + at-compaction context injection, and slash-command lifecycle/tamper advisories. They warn, never throw. - Commands:
/adlc-init,/adlc-ticket,/adlc-spec,/adlc-approve-spec,/adlc-decompose,/adlc-verify-build,/adlc-prosecute,/adlc-distill,/adlc-maintain. - Subagents: the five P5 prosecution lenses
(
@prosecutor-correctness|security|contract|diff|tests),@prosecutor-verifier, and the@prosecutormeta-agent (deterministic hollow-test / behavior-diff / review-calibration gates).
Install
Two commands (peer dependency: @opencode-ai/plugin ≥ 1.17.13):
npm install -g @adlc/cli # the gate toolkit the plugin shells out to
npx adlc-opencode init # scaffolds .adlc/ + .opencode/, registers the plugin (or npx @adlc/opencode init)Restart opencode so the hooks load. Inside the TUI, /adlc-init re-runs the same
idempotent scaffold. The bootstrap registers a resolvable plugin entry (the
npm name when installed from node_modules, the resolved local path from a source
checkout). Verify locally without an opencode binary:
node scripts/opencode-install-smoke.mjs .Per-repo config rides the ["@adlc/opencode", { … }] plugin-options
tuple (env vars override); see the integration guide for the option table.
Rail enforcement: two layers
- In-session (enforcing by default). A thrown denial in
tool.execute.beforeaborts the tool call: documented host behavior on@opencode-ai/plugin≥ 1.17.13, regression-tested end-to-end against a real opencode binary (required CI). Bash is gated via the@adlc/coreshell classifier; unrecognized structured tools carrying a path fail closed. The only downgrade is the explicitADLC_ALLOW_ADVISORY_HOOKS=1escape hatch (surface loudly, don't block). - Commit-time (unbypassable). The real control is
scripts/rails-guard-ci.mjs(viadocs/ci/rails-guard.yml): it reads the frozen rail set from the trusted base ref and rejects any PR that edits a rail, including the shell-driven writes the in-session hook cannot see. Make it a required check.
Rail contract
Mirrors the sibling integrations; all glob/ticket logic delegates to @adlc/core:
- Active ticket via
ADLC_TICKETor.adlc/current-ticket.json; a conflict fails closed. - Enforcement is phase-scoped to
ADLC_P4_ENFORCEMENT=1; otherwise no-op. - Rails in force = the single active ticket's
railsplus the trust-root rails.adlc/tickets.jsonand.adlc/current-ticket.json. - Symlink-aware: both the lexical path and the resolved real path are matched.
Formal ADLC coverage
| Phase | Status | Wired via |
|---|---|---|
| P0 Triage | Yes | /adlc-ticket |
| P1 Interrogate | Yes | /adlc-spec + /adlc-approve-spec (G1) + the adlc skill |
| P2 Decompose | Yes | /adlc-decompose |
| P3 Rail | Yes | in-session rails-guard hook (enforcing) + CI diff gate |
| P4 Build | Yes | rails-guard hook + shell gating + build-gate context-rot backstop + flail advisory |
| P5 Prosecute | Yes | /adlc-verify-build (G4) + the deterministic adlc_prosecute runner (5 lenses + verifier) + @prosecutor gates |
| P6 Integrate | Partial | session.idle gate-manifest audit; the human gate is by design |
| P7 Distill | Yes | /adlc-distill + /adlc-maintain |
Gaps
permission.askis a dormant lever. It is defined but never dispatched upstream (anomalyco/opencode#7006, re-verified at 1.17.17/1.17.18). The enforcing control is thetool.execute.beforethrow; the tolerant handler activates the instant upstream wires the hook.- The native TUI plugin module is deferred.
PluginModuletypestui?: neverat 1.17.17 (the surface is reserved, not shipped), so the persistent statusline slot / dialogs are a follow-on. The verifiable native touch (the statusline toast) ships now. - P6 acceptance is a human decision by design. The plugin surfaces evidence, it does not automate approval.
Go deeper
Source: plugins/adlc-opencode/
· design rationale: ADR 0004.
The deterministic prosecution loop this integration ships: Prosecution, Not Code Review.
Cursor
Native ADLC integration for Cursor: marketplace plugin with sessionStart context, preToolUse rails, packaged prosecutor agents + MCP wrapper (channel unverified), /adlc-* commands, and CI as the backstop.
pi
Native ADLC extension for the pi coding agent: in-session rail, scope, and suppression enforcement with git-diff revert, plus five phase skills.