opencode-workflow-guard 1.16.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,9 +4,9 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
  [![Tests](https://img.shields.io/badge/tests-1100%2B%20passing-brightgreen.svg)](test/test.mts)
6
6
 
7
- Deterministic policy and enforcement layer for OpenCode. Workflow Guard enforces safe engineering discipline through **hard plugin hooks**, not prompt instructions that LLMs can ignore, and pairs enforcement with a proactive workflow-tool surface for planning, review, worktree isolation, technical debt, and policy simulation.
7
+ Deterministic policy and enforcement layer for OpenCode. Workflow Guard enforces engineering discipline through **hard plugin hooks**, not prompt instructions that an LLM can ignore. The plugin also exposes a proactive workflow-tool surface for planning, review, worktree isolation, technical debt, and policy simulation.
8
8
 
9
- Workflow Guard is deliberately **not an agent harness**: it can constrain actions, record and explain decisions, and supply bounded context, but it does not plan, prioritize, delegate, or autonomously sequence the agent's work. Bounded continuation may resume an existing session with unfinished owned todos; it never chooses the next task or creates new work.
9
+ Workflow Guard is deliberately **not an agent harness**. It can constrain actions, record and explain decisions, and supply bounded context. It does not plan, prioritize, delegate, or autonomously sequence the agent's work. Bounded continuation may resume an existing session with unfinished owned todos. It never chooses the next task or creates new work.
10
10
 
11
11
  ---
12
12
 
@@ -22,11 +22,11 @@ opencode plugin add "opencode-workflow-guard@$VERSION" # OpenCode 2.x
22
22
  opencode plugin "opencode-workflow-guard@$VERSION" --global --force # OpenCode 1.x
23
23
  ```
24
24
 
25
- *Requires OpenCode >= 1.18.* OpenCode detects the package's server and TUI targets and updates both global configs. Use the same command after a release to upgrade; the explicit version gives OpenCode a fresh package-cache key. Restart OpenCode after installation. See [docs/installation.md](docs/installation.md) for details and links to the OpenCode plugin documentation.
25
+ *Requires OpenCode >= 1.18.* OpenCode detects the package's server and TUI targets and updates both global configs. Run the same command after a release to upgrade. The explicit version gives OpenCode a fresh package-cache key. Restart OpenCode after installation. See [docs/installation.md](docs/installation.md) for details and links to the OpenCode plugin documentation.
26
26
 
27
- The plugin supports both generations from one package: **OpenCode 1.x** loads the `server()` entrypoint, and **OpenCode 2.x** loads the `setup()` entrypoint (`@opencode/plugin`). Policies, tools, and configuration behave the same on both; V2 load tests run against a real OpenCode 2 binary in `npm run test:install`.
27
+ The plugin supports both generations from one package. **OpenCode 1.x** loads the `server()` entrypoint, and **OpenCode 2.x** loads the `setup()` entrypoint (`@opencode/plugin`). Policies, tools, and configuration behave the same on both. V2 load tests run against a real OpenCode 2 binary in `npm run test:install`.
28
28
 
29
- For the optional TUI badge, configure `"opencode-workflow-guard"` in `tui.json`. OpenCode resolves the package's exported `./tui` entrypoint automatically for TUI plugins. The companion keeps a static `Workflow Guard` shield in the prompt bar; warning toasts provide block details without changing agent behavior. Do not place the TUI module under the server `plugins/` directory.
29
+ For the optional TUI badge, configure `"opencode-workflow-guard"` in `tui.json`. OpenCode resolves the package's exported `./tui` entrypoint automatically for TUI plugins. The companion keeps a static `Workflow Guard` shield in the prompt bar. Warning toasts provide block details without changing agent behavior. Do not place the TUI module under the server `plugins/` directory.
30
30
 
31
31
  ![Workflow Guard status badge in the OpenCode TUI](docs/assets/workflow-guard-tui-badge.png)
32
32
 
@@ -43,12 +43,12 @@ WORKFLOW_GUARD_LIVE_E2E=1 npm run test:install # Also run policy probes with Ope
43
43
 
44
44
  ## Core Guardrails Overview
45
45
 
46
- The plugin enforces **24 deterministic policy rules** across four main pillars:
46
+ The plugin enforces **26 deterministic policy rules** across four main pillars:
47
47
 
48
- * **Branch & History Protection:** Enforces feature-branch workflows (blocks edits/commits on `main`/`master`), hard-blocks direct or forced pushes to protected branches, enforces mergeability pre-flight checks, enforces secondary review approval (bound to the reviewed worktree content) before PR creation by default, and requires PR changelogs / changesets.
49
- * **Task & Verification Discipline:** Gates file mutations on active `todowrite` tasks with subagent inheritance, requires each task's own recorded work before it can be marked completed (with an audited `[read-only]` marker for review and investigation tasks), blocks concurrent direct edits to the same canonical file across sessions, requires same-session fresh reads before `edit`/`write` can replace existing files, blocks silent task deletion, and enforces fresh test verification evidence before task completion.
50
- * **Secrets & Workspace Confinement:** Confines edit tools and recognized shell/git mutations within the workspace root (including symlink and `../` escape checks), scrubs sensitive environment variables in agent subshells, and redacts `.env` reads with safe schema masks. Arbitrary executables are not OS-sandboxed; use containers or filesystem isolation when hard confinement is required.
51
- * **Destructive CLI & Environment Safety:** Intercepts destructive cloud/database/infrastructure commands, stops script laundering and interpreter evasion, blocks TTY hangs (`vim`, `nano`, `sudo`), and guards against dangerous package manager flags.
48
+ * **Branch & History Protection:** Enforces feature-branch workflows and blocks edits and commits on `main`/`master`. Direct and forced pushes to protected branches are hard-blocked. The guard checks mergeability before PR creation, requires secondary review approval bound to the reviewed worktree content, and requires a PR changelog or changeset.
49
+ * **Task & Verification Discipline:** Gates file mutations on active `todowrite` tasks, which subagents inherit. A task can be marked completed only after its own recorded work. Review and investigation tasks use an audited `[read-only]` marker instead. The guard also blocks concurrent direct edits to the same canonical file across sessions. It requires a same-session fresh read before `edit`/`write` can replace an existing file. Silent task deletion is blocked, and task completion requires fresh test verification evidence. Completion claims and sweeping repository claims are journaled against their evidence. Repeated failures force a live-documentation lookup instead of a guess from training data.
50
+ * **Secrets & Workspace Confinement:** Confines edit tools and recognized shell/git mutations to the workspace root, including symlink and `../` escape checks. Agent subshells have sensitive environment variables scrubbed, and `.env` reads return a safe schema mask. Arbitrary executables are not OS-sandboxed. Use containers or filesystem isolation when hard confinement is required.
51
+ * **Destructive CLI & Environment Safety:** Intercepts destructive cloud, database, and infrastructure commands. Stops script laundering and interpreter evasion, blocks TTY hangs such as `vim`, `nano`, and `sudo`, and guards against dangerous package manager flags.
52
52
 
53
53
  For complete policy specifications and override rules, see [docs/policies.md](docs/policies.md).
54
54
 
@@ -56,17 +56,17 @@ For complete policy specifications and override rules, see [docs/policies.md](do
56
56
 
57
57
  ## Proactive Workflow Tools
58
58
 
59
- Enforcement is only half the surface. The plugin also registers first-class agent tools (same tool names on OpenCode 1.x and 2.x) so disciplined workflow is the path of least resistance:
59
+ Enforcement is only half the surface. The plugin also registers first-class agent tools under the same names on OpenCode 1.x and 2.x, so disciplined workflow is the path of least resistance:
60
60
 
61
- * **Task Planning:** `guard_next_tasks` surfaces durable repository planning context (`TODO.md`, `ROADMAP.md`, `PLAN.md`, `TASKS.md`, `BACKLOG.md`, their `docs/` counterparts, and plans under `docs/plans/`) at session start or during planning; `guard_status` reports active guardrails, branch protection, mutation counts, outstanding verification/review gates, a read-only git-hygiene snapshot, and the loaded `pluginVersion`.
62
- * **Review & Verification:** before PR creation, a secondary reviewer subagent evaluates the diff against `guard_review_rubric` (five core axes: test integrity, task completeness, cleanliness, security, platform) and records its verdict with `record_review`; approvals are bound to the reviewed worktree content.
63
- * **Worktree Isolation:** `guard_worktree_create` and `guard_worktree_cleanup` give parallel subagents isolated linked worktrees so concurrent mutations never collide.
64
- * **Technical Debt:** `guard_review_followups` lists open P2/P3 durable review follow-ups; `guard_review_followup_resolve` closes them after the underlying issue is fixed and verified.
65
- * **Policy Simulation:** `guard_why` returns the structured policy decision for a tool call or command without performing it; `guard_audit` shows recent audited policy entries.
66
- * **Project Memory** (on by default): `project_memory_search`, `project_memory_record`, `project_memory_export`, and `project_memory_import` maintain durable facts, decisions, constraints, and lessons; secret content is rejected, and export promotes records to the repo-local `.opencode/memory/project-memory.jsonl`.
61
+ * **Task Planning:** `guard_next_tasks` surfaces durable repository planning context at session start or during planning. It reads `TODO.md`, `ROADMAP.md`, `PLAN.md`, `TASKS.md`, `BACKLOG.md`, their `docs/` counterparts, and plans under `docs/plans/`. `guard_status` reports active guardrails, branch protection, mutation counts, outstanding verification and review gates, a read-only git-hygiene snapshot, and the loaded `pluginVersion`.
62
+ * **Review & Verification:** before PR creation, a secondary reviewer subagent evaluates the diff against `guard_review_rubric`. The rubric covers five axes: test integrity, task completeness, cleanliness, security, and platform. The reviewer records its verdict with `record_review`, and approvals bind to the reviewed worktree content.
63
+ * **Worktree Isolation:** `guard_worktree_create` and `guard_worktree_cleanup` give parallel subagents isolated linked worktrees, so concurrent mutations never collide.
64
+ * **Technical Debt:** `guard_review_followups` lists open P2/P3 durable review follow-ups. `guard_review_followup_resolve` closes one after the underlying issue is fixed and verified.
65
+ * **Policy Simulation:** `guard_why` returns the structured policy decision for a tool call or command without performing it. `guard_audit` shows recent audited policy entries.
66
+ * **Project Memory** (on by default): `project_memory_search`, `project_memory_record`, `project_memory_export`, and `project_memory_import` maintain durable facts, decisions, constraints, and lessons. Secret content is rejected. Export promotes records to the repo-local `.opencode/memory/project-memory.jsonl`.
67
67
  * **Socratic Learning** (off by default): `learning_checkpoint`, `learning_profile`, and `learning_record` maintain a global evidence-based learner profile with a per-session intervention budget.
68
68
 
69
- The context modules — project memory, Socratic learning, and recovery checkpoints (`guard_recovery_restore`) — are independently gated and can be disabled without weakening policy enforcement; see [docs/installation.md](docs/installation.md). Full tool specifications live in [docs/policies.md](docs/policies.md#custom-tools).
69
+ The context modules are project memory, Socratic learning, and recovery checkpoints (`guard_recovery_restore`). Each is independently gated, so any of them can be disabled without weakening policy enforcement. See [docs/installation.md](docs/installation.md). Full tool specifications live in [docs/policies.md](docs/policies.md#custom-tools).
70
70
 
71
71
  ---
72
72
 
@@ -74,11 +74,11 @@ The context modules — project memory, Socratic learning, and recovery checkpoi
74
74
 
75
75
  | Guide | Description |
76
76
  |---|---|
77
- | [**Policy Reference**](docs/policies.md) | Comprehensive specification of all 24 enforced policies, invariants, and the proactive tool surface (`guard_*`, `project_memory_*`, `learning_*`) |
78
- | [**Installation & Configuration**](docs/installation.md) | Setup options, global vs. local install, worktree isolation, and project configuration |
79
- | [**Static Policy Posture**](docs/policy-posture.md) | Emitting host-level policies for invariants a repository cannot lift: both host envelopes (`experimental.policies` on 2.0.x, top-level `policies` on 2.1.x), precedence, and residual risk |
77
+ | [**Policy Reference**](docs/policies.md) | Specification of all 26 enforced policies, invariants, and the proactive tool surface (`guard_*`, `project_memory_*`, `learning_*`) |
78
+ | [**Installation & Configuration**](docs/installation.md) | Setup options, global and local install, worktree isolation, and project configuration |
79
+ | [**Static Policy Posture**](docs/policy-posture.md) | How the guard emits host-level policies for invariants a repository cannot lift. Covers both host envelopes (`experimental.policies` on 2.0.x, top-level `policies` on 2.1.x), precedence, and residual risk |
80
80
  | [**Managed Deployment**](docs/managed-deployment.md) | Administrator-managed OpenCode policy, platform locations, and startup diagnostics |
81
- | [**Troubleshooting**](docs/troubleshooting.md) | Diagnosing policy blocks, common false positives, and emergency override procedures |
81
+ | [**Troubleshooting**](docs/troubleshooting.md) | Diagnosing policy blocks, common false positives, and the live-system override |
82
82
  | [**Testing Architecture**](docs/testing.md) | Test harness design, adversarial regression matrix, and CI verification |
83
83
  | [**Contributing Guide**](CONTRIBUTING.md) | Development workflow, coding conventions, test requirements, and changeset PR rules |
84
84
  | [**Security Policy**](SECURITY.md) | Vulnerability disclosure policy and threat model |
@@ -20,18 +20,18 @@ Policy decisions and operational evidence are separate concepts.
20
20
 
21
21
  `PolicyDecision` is the result of evaluating whether an operation may proceed. It should provide a stable machine-readable status and code, an optional policy identifier, a human-readable message, and bounded structured details. Human block text, audit entries, `guard_why`, and controller-facing output should derive from this result rather than independently interpreting policy state.
22
22
 
23
- `EvidenceRecord` represents operational proof or observation such as verification, secondary review, tool outcome, policy evaluation, or lifecycle state. Evidence records should carry common project/session/worktree provenance where applicable. Existing purpose-built stores remain authoritative; this work should introduce a common representation rather than another database.
23
+ `EvidenceRecord` represents operational proof or observation. Examples are verification, secondary review, tool outcome, policy evaluation, and lifecycle state. Evidence records should carry common project, session, and worktree provenance where applicable. Existing purpose-built stores remain authoritative. This work should introduce a common representation rather than another database.
24
24
 
25
25
  Evidence must be bound to the subject it actually establishes. Where applicable, that means identifying the workspace/worktree, commit or worktree fingerprint, session/call, actor or reviewer, policy/version, and observation time. A historical fact such as "verification passed" is not sufficient to establish that the current worktree is verified unless its subject still matches current state.
26
26
 
27
27
  Operational evidence should distinguish confidence classes rather than treating all machine-readable claims as equivalent:
28
28
 
29
29
  - Deterministic observation: repository state, changed files, tool execution/outcome, test exit status, or another directly observed fact.
30
- - Attestation: a reviewer, model, or human records a judgment such as approval. The fact that the attestation occurred is observable; the judgment is not converted into deterministic truth.
30
+ - Attestation: a reviewer, model, or human records a judgment such as approval. The fact that the attestation occurred is observable. The judgment is not converted into deterministic truth.
31
31
  - Derived state: a reproducible conclusion such as "verification is fresh" computed from subject-bound observations and current state.
32
32
  - Agent assertion: natural-language claims such as "tests pass" or "review is complete". These may be useful diagnostics but are never sufficient evidence for a safety or finalization gate by themselves.
33
33
 
34
- Prefer outcome and state predicates over prescribed trajectories. Workflow Guard may require demonstrable end state or consequential checkpoints, but should not require one exact sequence of otherwise-valid agent actions when the desired state can be established directly.
34
+ Prefer outcome and state predicates over prescribed trajectories. Workflow Guard may require demonstrable end state or consequential checkpoints. It should not require one exact sequence of otherwise-valid agent actions when the desired state can be established directly.
35
35
 
36
36
  Project memory and learning evidence remain separate from `EvidenceRecord`. Project memory represents durable repository knowledge. Learning evidence represents observations from real Socratic interactions. Neither should be forced into an allow/block or operational-proof model.
37
37
 
@@ -46,7 +46,7 @@ Project memory and learning evidence remain separate from `EvidenceRecord`. Proj
46
46
  7. Expand adversarial tests for stable decision codes, provenance invalidation, option/profile precedence, and machine-readable status. Add headless/server coverage proving core enforcement does not depend on the TUI or interactive approval.
47
47
  8. Update policy, installation, and managed-deployment documentation as behavior becomes user-visible.
48
48
 
49
- The accountability contracts now support an opt-in bounded autonomous-continuation add-on ("Ralph mode"). Its initial implementation only continues an agent while explicitly owned native todos remain unfinished; it does not interpret configured documents or invent completion criteria. It is disabled by default (including under the `autonomous` profile), user-interruptible, iteration-bounded, and preserves all core guardrails. It reports observable outcomes such as `completed`, `budget_exhausted`, or `user_stopped`; `blocked` is reserved for a demonstrable guard state rather than inferred from repeated idle events. Ralph remains an optional orchestration consumer rather than part of the accountability kernel.
49
+ The accountability contracts now support an opt-in bounded autonomous-continuation add-on ("Ralph mode"). Its initial implementation only continues an agent while explicitly owned native todos remain unfinished. It does not interpret configured documents or invent completion criteria. It is disabled by default, including under the `autonomous` profile. It is user-interruptible, iteration-bounded, and preserves all core guardrails. It reports observable outcomes such as `completed`, `budget_exhausted`, and `user_stopped`. `blocked` is reserved for a demonstrable guard state rather than inferred from repeated idle events. Ralph remains an optional orchestration consumer rather than part of the accountability kernel.
50
50
 
51
51
  ## Configuration Boundary
52
52
 
@@ -54,13 +54,13 @@ Safety invariants stay core and are not weakened by operation profiles or option
54
54
 
55
55
  Capabilities that express user workflow preference, add continuity/context, or approach orchestration must be configurable. Examples include project memory, Socratic learning, recovery checkpoints, review/documentation requirements, bounded continuation behavior, and future autonomous-operation conveniences. Optional capabilities must fail independently where practical so disabling or failing an add-on does not disable core enforcement.
56
56
 
57
- Workflow Guard must not become responsible for planning work, choosing the next task, delegating tasks, autonomous retry loops, sequencing agents, or deciding when an external job should terminate. External SDK/server clients or dedicated add-ons own orchestration. The existing bounded `session.idle` continuation may enforce already-owned unfinished work but must not grow into an orchestration loop.
57
+ Workflow Guard must not become responsible for planning work, choosing the next task, or delegating tasks. It also must not own autonomous retry loops, agent sequencing, or the decision that an external job should terminate. Those are orchestration duties. External SDK or server clients and dedicated add-ons own them. The bounded `session.idle` continuation may enforce already-owned unfinished work. It must never grow into an orchestration loop.
58
58
 
59
59
  The same boundary applies to review. Workflow Guard can prove that a review occurred against a particular subject, preserve the reviewer's disposition and findings, and enforce a configured review requirement. It must not infer that an approval proves correctness, choose reviewers, launch review loops, negotiate findings, or decide what work should happen next.
60
60
 
61
61
  ## External Research Rationale
62
62
 
63
- Recent OpenAI and Anthropic engineering/research material independently supports this architecture. These sources are design inputs rather than normative dependencies; Workflow Guard should continue to rely on supported OpenCode APIs and its own tested contracts.
63
+ Recent OpenAI and Anthropic engineering and research material independently supports this architecture. These sources are design inputs rather than normative dependencies. Workflow Guard should continue to rely on supported OpenCode APIs and its own tested contracts.
64
64
 
65
65
  - OpenAI's February 2026 [Harness engineering: leveraging Codex in an agent-first world](https://openai.com/index/harness-engineering/) describes mechanically enforced architectural invariants around agent autonomy. The applicable inference for Workflow Guard is to enforce boundaries centrally while leaving implementation strategy and task execution to the agent.
66
66
  - OpenAI's March 2025 [Detecting misbehavior in frontier reasoning models](https://openai.com/index/chain-of-thought-monitoring/) reports coding agents exploiting evaluation loopholes, including weakening or altering verification. The applicable inference is to retain independent provenance about changed artifacts and verification subjects rather than trusting reported success or an undifferentiated test-pass signal.
@@ -71,11 +71,11 @@ Recent OpenAI and Anthropic engineering/research material independently supports
71
71
  - Anthropic's September 2025 [Effective context engineering for AI agents](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) recommends the smallest high-signal context and just-in-time retrieval. The applicable inference is that `guard_status` should expose compact current state and stable evidence references rather than inject an ever-growing accountability transcript.
72
72
  - Anthropic's December 2024 [Building effective agents](https://www.anthropic.com/engineering/building-effective-agents) separates deterministic workflows from model-directed agents, recommends simple composable mechanisms, and uses programmatic gates where checks are appropriate. The applicable inference is to keep Workflow Guard a guardrail/accountability layer, not an orchestrator-worker or evaluator-optimizer implementation.
73
73
 
74
- The combined design principle is: Workflow Guard should answer, "May this operation happen, given what can actually be demonstrated about the current state?" It should not answer, "What should the agent do next?"
74
+ The combined design principle is this. Workflow Guard answers one question: "May this operation happen, given what can actually be demonstrated?" It does not answer, "What should the agent do next?"
75
75
 
76
76
  ## OpenCode API Boundary
77
77
 
78
- Use supported semantic OpenCode APIs wherever they provide enough information. `tool.execute.before` is the supported deterministic tool-blocking boundary. Current `session.idle` events and `experimental.text.complete` do not expose an explicit supported completion-veto result, so Workflow Guard must not emulate a hard completion gate through undocumented exception behavior.
78
+ Use supported semantic OpenCode APIs wherever they provide enough information. `tool.execute.before` is the supported deterministic tool-blocking boundary. Current `session.idle` events and `experimental.text.complete` expose no explicit supported completion-veto result. Workflow Guard must therefore not emulate a hard completion gate through undocumented exception behavior.
79
79
 
80
80
  Machine-readable controller outcomes should therefore come from Workflow Guard's own structured contracts, tools, and audit trail until OpenCode exposes a stronger lifecycle decision hook.
81
81
 
@@ -84,7 +84,7 @@ Shell matching remains defense in depth rather than a sandbox. Prefer structured
84
84
  ## Compatibility And Non-Goals
85
85
 
86
86
  - Preserve existing human-readable block messages at the hook boundary while internal consumers migrate to structured decisions.
87
- - Preserve existing verification history, review state, project-memory databases, learning profiles, and review-follow-up storage; migrate representations before considering storage changes.
87
+ - Preserve existing verification history, review state, project-memory databases, learning profiles, and review-follow-up storage. Migrate representations before considering storage changes.
88
88
  - Do not merge project memory, learner evidence, and operational evidence into a universal event store.
89
89
  - Do not claim managed deployment proves plugin provenance when OpenCode cannot provide that guarantee.
90
90
  - Do not add a hard completion gate until OpenCode exposes a supported block/continue lifecycle hook.
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Requirements
8
8
 
9
- - **OpenCode >= 1.18** (V1: requires the `GET /session/:id/todo` endpoint and the V1 `PluginModule` loader) or **OpenCode 2.x** (V2: loads through the `@opencode/plugin` API; the current todo list is reconstructed from session message history, or read from the native `todowrite` on 2.1.x when `experimental.todo` is enabled).
9
+ - **OpenCode >= 1.18** (V1: requires the `GET /session/:id/todo` endpoint and the V1 `PluginModule` loader) or **OpenCode 2.x**. V2 loads through the `@opencode/plugin` API. The current todo list is reconstructed from session message history, or read from the native `todowrite` on 2.1.x when `experimental.todo` is enabled.
10
10
  - **Node.js >= 22.18** or **Bun** (for running test scripts directly).
11
11
 
12
12
  ### Version Qualification
@@ -14,7 +14,7 @@
14
14
  The guard declares exact host dependency versions, so an unreviewed host API can
15
15
  never float in. A host release is qualified only when it appears in this table
16
16
  with the seats that were actually exercised against it. An unlisted version is
17
- unqualified by definition, which does not mean it is broken; it means nobody has
17
+ unqualified by definition. That does not mean it is broken. It means nobody has
18
18
  verified it.
19
19
 
20
20
  | Guard | OpenCode qualified | Hook seats exercised | Notes |
@@ -25,8 +25,8 @@ verified it.
25
25
 
26
26
  The 2.1.3 pins require the 2.1.x package set. `@opencode/plugin` and
27
27
  `@opencode/ai` are pinned to `2.1.3`, which depends on `effect@4.0.1` and
28
- requires `@opentui/solid >=0.6.6`; the guard pins `0.6.6`. A 2.0.x pin set on a
29
- 2.1.x host fails to load at all: the plugin imports an `effect` path the host no
28
+ requires `@opentui/solid >=0.6.6`. The guard pins `0.6.6`. A 2.0.x pin set on a
29
+ 2.1.x host fails to load at all. The plugin imports an `effect` path the host no
30
30
  longer provides, and the host reports `failed to load plugin` while every
31
31
  policy stays inert.
32
32
 
@@ -66,11 +66,11 @@ opencode plugin add "opencode-workflow-guard@$VERSION" # Open
66
66
  opencode plugin "opencode-workflow-guard@$VERSION" --global --force # OpenCode 1.x
67
67
  ```
68
68
 
69
- OpenCode 2 documents `opencode plugin add <package>` as the command to install a plugin and add it to the global configuration; OpenCode 1 documents `opencode plugin <module>` with `--global` and `--force`. Workflow Guard exposes both server and TUI targets, so OpenCode detects both and updates their global configuration files (OpenCode 2 uses one global `cli.json` for terminal-client settings). Restart OpenCode after installation because configuration is loaded at startup. See the [OpenCode plugin CLI documentation](https://opencode.ai/docs/cli/#plugin).
69
+ OpenCode 2 documents `opencode plugin add <package>` as the command to install a plugin and add it to the global configuration. OpenCode 1 documents `opencode plugin <module>` with `--global` and `--force`. Workflow Guard exposes both server and TUI targets, so OpenCode detects both and updates their global configuration files. OpenCode 2 uses one global `cli.json` for terminal-client settings. Restart OpenCode after installation, because configuration is loaded at startup. See the [OpenCode plugin CLI documentation](https://opencode.ai/docs/cli/#plugin).
70
70
 
71
- Use the same two commands to upgrade after a Workflow Guard release. Keep the explicit version in OpenCode's configuration rather than relying on a bare package name or `@latest`: OpenCode caches npm plugins, and an already-populated `@latest` cache key may continue resolving to the version that originally populated it. An explicit new version creates a new package-cache key without manually deleting OpenCode's cache.
71
+ Use the same two commands to upgrade after a Workflow Guard release. Keep the explicit version in OpenCode's configuration rather than relying on a bare package name or `@latest`. OpenCode caches npm plugins, and an already-populated `@latest` cache key may keep resolving to the version that originally populated it. An explicit new version creates a new package-cache key without manually deleting OpenCode's cache.
72
72
 
73
- If you only want the server guard without the TUI companion, add the package to your project's `opencode.json` (or global `~/.config/opencode/opencode.json`). OpenCode 2 reads only the plural `plugins` key; OpenCode 1.x uses the singular `plugin` key. A singular key in an OpenCode 2 config is dropped by the config schema without an error, so the guard will appear configured and never load:
73
+ If you only want the server guard without the TUI companion, add the package to your project's `opencode.json`, or to the global `~/.config/opencode/opencode.json`. OpenCode 2 reads only the plural `plugins` key. OpenCode 1.x uses the singular `plugin` key. The OpenCode 2 config schema drops a singular key without an error. The guard then appears configured and never loads:
74
74
 
75
75
  ```json
76
76
  {
@@ -104,18 +104,18 @@ config or a non-array plugin key.
104
104
  `tui.json` is the exception to the key rule. Its schema reads singular `plugin`
105
105
  on both majors, and OpenCode 2 migrates that key into `cli.json.plugins`. So
106
106
  `--major 2` writes `plugins` to the server config and still writes `plugin` to
107
- `tui.json`; a plural key there is silently ignored and the TUI badge never
107
+ `tui.json`. A plural key there is silently ignored, and the TUI badge never
108
108
  loads.
109
109
 
110
110
  ### Configure The Guard In One Location Only
111
111
 
112
- Name the guard in exactly one place per OpenCode process: either the global configuration (`~/.config/opencode/opencode.json[c]`, `plugins` on 2.x or `plugin` on 1.x) or a project configuration, never both. OpenCode 2 merges plugin arrays instead of replacing them, so listing `opencode-workflow-guard` globally and again in a project's `.opencode/opencode.json` loads the same entrypoint twice under two ids. Two instances register duplicate hooks and duplicate tool definitions, which evaluates and audits every tool call twice, lets one instance overwrite the other's tool-description enrichment, and primes the process-global workspace latch from two roots in the same tick.
112
+ Name the guard in exactly one place per OpenCode process: either the global configuration or a project configuration, never both. The global configuration is `~/.config/opencode/opencode.json[c]`, with `plugins` on 2.x or `plugin` on 1.x. OpenCode 2 merges plugin arrays instead of replacing them. Listing `opencode-workflow-guard` globally and again in a project's `.opencode/opencode.json` therefore loads the same entrypoint twice under two ids. Two instances register duplicate hooks and duplicate tool definitions. That evaluates and audits every tool call twice. One instance can overwrite the other's tool-description enrichment, and both prime the process-global workspace latch from two roots in the same tick.
113
113
 
114
- The guard detects the duplicate instead of failing silently: the first instance for a given (module path, workspace root) pair owns enforcement, and a later instance registers no hooks or tools. The duplicate is recorded at warn level in the server log and as an audit record (`tool: "plugin.instance"`, `reason: "duplicate_plugin_load"`) in `workflow-guard.jsonl`, so `grep 'loading plugin.*workflow-guard'` on a fresh server log showing two lines is a configuration error, not a supported setup. As a second layer, the first instance to reach a given (session, call, tool) claims its policy decision, so a guard loaded from two distinct paths (an npm cache copy plus a source checkout) still produces one decision per call.
114
+ The guard detects the duplicate instead of failing silently. The first instance for a given (module path, workspace root) pair owns enforcement, and a later instance registers no hooks or tools. The duplicate is recorded at warn level in the server log and as an audit record (`tool: "plugin.instance"`, `reason: "duplicate_plugin_load"`) in `workflow-guard.jsonl`. A server log with two `loading plugin.*workflow-guard` lines on a fresh start is therefore a configuration error, not a supported setup. As a second layer, the first instance to reach a given (session, call, tool) claims its policy decision. A guard loaded from two distinct paths, such as an npm cache copy plus a source checkout, still produces one decision per call.
115
115
 
116
116
  A repository that ships its own `.opencode/opencode.json` with a `plugin`/`plugins` entry is the usual source of the second copy. Remove the entry there and let the global configuration carry the guard. Because OpenCode settings are tamper-protected from agent edits, that file must be changed by the operator.
117
117
 
118
- A configured bare package name is resolved through Node's parent-directory lookup from OpenCode's configuration location: any `node_modules` above that location that contains a copy of the package (a pnpm-managed home directory, a manual `npm install`, or a workspace dependency) is loaded instead, shadowing both OpenCode's own plugin cache and a global `npm install -g` — updating the wrong copy leaves an old version running while the update appears to succeed, and OpenCode's own plugin-update check can fail with only a server-log record (`NpmInstallFailedError`). Update the copy that actually loads (for a pnpm-managed home directory: `pnpm add opencode-workflow-guard@<version>` in that directory, or remove the dependency so OpenCode manages its own copy), then restart the background service (`opencode service restart`) — the plugin loads there, so a TUI-only restart is not enough. Verify what loaded: `guard_status` reports the loaded version as `pluginVersion`, the startup app log states `Workflow Guard v<version> plugin initialized`, and the server log records the resolved module path in its `loading plugin` entry.
118
+ A configured bare package name is resolved through Node's parent-directory lookup from OpenCode's configuration location. Any `node_modules` above that location that contains a copy of the package is loaded instead. That includes a pnpm-managed home directory, a manual `npm install`, and a workspace dependency. This shadows both OpenCode's own plugin cache and a global `npm install -g`. Updating the wrong copy leaves an old version running while the update appears to succeed. OpenCode's own plugin-update check can also fail with only a server-log record (`NpmInstallFailedError`). Update the copy that actually loads. For a pnpm-managed home directory, run `pnpm add opencode-workflow-guard@<version>` in that directory, or remove the dependency so OpenCode manages its own copy. Then restart the background service with `opencode service restart`. The plugin loads there, so a TUI-only restart is not enough. Verify what loaded in three places. `guard_status` reports the loaded version as `pluginVersion`. The startup app log states `Workflow Guard v<version> plugin initialized`. The server log records the resolved module path in its `loading plugin` entry.
119
119
 
120
120
  ---
121
121
 
@@ -130,7 +130,7 @@ cp -r src/lib src/policies .opencode/workflow-guard-source/
130
130
  printf '%s\n' 'import { WorkflowGuard } from "../workflow-guard-source/workflow-guard.ts";' 'export default { id: "workflow-guard-local", server: WorkflowGuard };' > .opencode/plugins/workflow-guard.ts
131
131
  ```
132
132
 
133
- OpenCode automatically discovers the adapter from the project-level `.opencode/plugins/` directory at startup. For deterministic development and test fixtures, it can also be registered explicitly in `.opencode/opencode.json` as `"./plugins/workflow-guard.ts"`; OpenCode deduplicates the resulting file URL. npm installation is recommended for normal use; the local-file form is primarily useful when developing from a source checkout.
133
+ OpenCode automatically discovers the adapter from the project-level `.opencode/plugins/` directory at startup. For deterministic development and test fixtures, it can also be registered explicitly in `.opencode/opencode.json` as `"./plugins/workflow-guard.ts"`. OpenCode deduplicates the resulting file URL. npm installation is recommended for normal use. The local-file form is primarily useful when developing from a source checkout.
134
134
 
135
135
  ---
136
136
 
@@ -138,7 +138,7 @@ OpenCode automatically discovers the adapter from the project-level `.opencode/p
138
138
 
139
139
  To enable the static `Workflow Guard 🛡️` prompt-bar badge, with block details reported separately through warning toasts:
140
140
 
141
- The recommended `opencode plugin add "opencode-workflow-guard@$VERSION"` command configures this automatically: OpenCode detects both targets and registers the server plugin in the global `opencode.json(c)` and the TUI companion in the global `~/.config/opencode/cli.json` (OpenCode 2). For manual installation, use the same explicit package version in the TUI target of your OpenCode generation - global `~/.config/opencode/cli.json` with the `plugins` array on OpenCode 2:
141
+ The recommended `opencode plugin add "opencode-workflow-guard@$VERSION"` command configures this automatically. OpenCode detects both targets and registers the server plugin in the global `opencode.json(c)`. On OpenCode 2 it also registers the TUI companion in the global `~/.config/opencode/cli.json`. For manual installation, use the same explicit package version in the TUI target of your OpenCode generation. On OpenCode 2 that target is the global `~/.config/opencode/cli.json` with the `plugins` array:
142
142
 
143
143
  ```json
144
144
  {
@@ -160,7 +160,7 @@ or `~/.config/opencode/tui.json` with the `plugin` array on OpenCode 1.x:
160
160
  }
161
161
  ```
162
162
 
163
- The version above is illustrative; replace it with the version you intend to install. The package exposes separate server and TUI entrypoints. In the terminal-client config, configure the package spec; OpenCode resolves its exported `./tui` entrypoint automatically. Do not place `workflow-guard-ui.ts` under `plugins/`; the server loader rejects TUI-only modules.
163
+ The version above is illustrative. Replace it with the version you intend to install. The package exposes separate server and TUI entrypoints. In the terminal-client config, configure the package spec. OpenCode resolves its exported `./tui` entrypoint automatically. Do not place `workflow-guard-ui.ts` under `plugins/`, because the server loader rejects TUI-only modules.
164
164
 
165
165
  On OpenCode 2, `plugin check` and `plugin update` cover both server and TUI-only package plugins.
166
166
 
@@ -168,7 +168,7 @@ The TUI badge uses OpenCode's Solid slot API (`@opentui/solid`). It is a runtime
168
168
 
169
169
  ## Recovery Checkpoints
170
170
 
171
- Workflow Guard supports two optional operation profiles in `.opencode/workflow-guard.json` (JSONC is also supported): `interactive` is the default and preserves the standard behavior, while `autonomous` enables durable recovery checkpoints by default for longer-running agent work. Profiles only supply defaults for optional workflow behavior; they never weaken secret protection, protected-path protection, workspace confinement, protected-branch safeguards, or other deterministic policy checks.
171
+ Workflow Guard supports two optional operation profiles in `.opencode/workflow-guard.json`. JSONC is also supported. `interactive` is the default and preserves the standard behavior. `autonomous` enables durable recovery checkpoints by default for longer-running agent work. Profiles only supply defaults for optional workflow behavior. They never weaken secret protection, protected-path protection, workspace confinement, protected-branch safeguards, or other deterministic policy checks.
172
172
 
173
173
  ```json
174
174
  {
@@ -188,15 +188,15 @@ Durable recovery checkpoints can also be enabled directly per project:
188
188
 
189
189
  For each genuine user run in a root session, Workflow Guard captures the pre-run tracked and untracked workspace state in private Git objects. The objects are kept reachable under `refs/workflow-guard/checkpoints/` and do not add entries to the user's stash list. Subagent runs and Workflow Guard's synthetic continuation messages do not create or replace checkpoints.
190
190
 
191
- When the root session reaches idle, the checkpoint records the resulting workspace fingerprint. The `guard_recovery_restore` tool can then restore a selected run, but only for that same root session and only while the workspace still exactly matches the recorded idle boundary. Any intervening workspace change makes recovery refuse rather than overwrite newer work. Recovery checkpoints require an existing Git commit and deliberately fail open if a snapshot cannot be created.
191
+ When the root session reaches idle, the checkpoint records the resulting workspace fingerprint. The `guard_recovery_restore` tool can then restore a selected run. It works only for that same root session, and only while the workspace still exactly matches the recorded idle boundary. Any intervening workspace change makes recovery refuse rather than overwrite newer work. Recovery checkpoints require an existing Git commit, and they fail open if a snapshot cannot be created.
192
192
 
193
- With the optional TUI companion installed, open the command palette and choose **Workflow Guard: Project Options** (or run `/guard-options`) to toggle recovery checkpoints, project memory, learner mode, Ralph mode, or the title-settle workaround for the current project. The command writes the existing Workflow Guard project config location, defaulting to `.opencode/workflow-guard.json`; restart OpenCode after changing a setting so the server plugin can expose the matching tools.
193
+ With the optional TUI companion installed, open the command palette and choose **Workflow Guard: Project Options**, or run `/guard-options`. The command toggles recovery checkpoints, project memory, learner mode, Ralph mode, or the title-settle workaround for the current project. It writes the existing Workflow Guard project config location, which defaults to `.opencode/workflow-guard.json`. Restart OpenCode after changing a setting, so the server plugin can expose the matching tools.
194
194
 
195
- The title-settle workaround is on by default because Workflow Guard's automatic continuation can race OpenCode's asynchronous native title generation. Workflow Guard briefly waits for native title generation before sending an automatic continuation for unfinished root-session work; set `titleSettleWorkaround: false` to opt out. The wait is bounded, applies only when that session owns unfinished todos, and never changes the title or provider/model parameters itself.
195
+ The title-settle workaround is on by default, because Workflow Guard's automatic continuation can race OpenCode's asynchronous native title generation. Workflow Guard briefly waits for native title generation before sending an automatic continuation for unfinished root-session work. Set `titleSettleWorkaround: false` to opt out. The wait is bounded. It applies only when that session owns unfinished todos, and it never changes the title or provider and model parameters itself.
196
196
 
197
- Ralph mode is also off by default, including under the `autonomous` profile. Enable it explicitly with `ralphMode: true`; `ralphMaxIterations` sets its positive integer continuation budget from 1 through 100 (default 10; invalid values use the default). Ralph only continues a root session while that session already owns unfinished native todos. It does not create, prioritize, select, sequence, or delegate work, and every resumed run remains subject to the normal guardrails. Genuine user input stops an active Ralph run instead of resetting its budget. Reaching the budget with unfinished work reports `budget_exhausted`; completion is reported only when owned todos are actually finished. A `blocked` outcome is reserved for a demonstrable guard state and is never inferred merely from repeated idle events. `guard_status` exposes the effective Ralph configuration and current calling-session outcome.
197
+ Ralph mode is also off by default, including under the `autonomous` profile. Enable it explicitly with `ralphMode: true`. `ralphMaxIterations` sets its positive integer continuation budget from 1 through 100. The default is 10, and invalid values use the default. Ralph only continues a root session while that session already owns unfinished native todos. It does not create, prioritize, select, sequence, or delegate work, and every resumed run remains subject to the normal guardrails. Genuine user input stops an active Ralph run instead of resetting its budget. Reaching the budget with unfinished work reports `budget_exhausted`. Completion is reported only when owned todos are actually finished. A `blocked` outcome is reserved for a demonstrable guard state and is never inferred merely from repeated idle events. `guard_status` exposes the effective Ralph configuration and current calling-session outcome.
198
198
 
199
- OpenCode's model/provider request timeout is separate from Workflow Guard. In OpenCode 1.18+, configure it under the selected provider's `options.timeout` in project `opencode.json[c]`; the default is 300000 ms (5 minutes), and `false` disables the provider request timeout. Workflow Guard does not impose a whole-session wall-clock limit.
199
+ OpenCode's model and provider request timeout is separate from Workflow Guard. In OpenCode 1.18+, configure it under the selected provider's `options.timeout` in project `opencode.json[c]`. The default is 300000 ms (5 minutes), and `false` disables the provider request timeout. Workflow Guard does not impose a whole-session wall-clock limit.
200
200
 
201
201
  ---
202
202
 
@@ -204,7 +204,7 @@ OpenCode's model/provider request timeout is separate from Workflow Guard. In Op
204
204
 
205
205
  Workflow Guard enforces secondary review approval (`requireReview`) by default during PR creation (`gh pr create` and `az repos pr create`). Before a pull request can be opened, an agent must invoke a secondary review subagent and record passing review approval using `record_review` evaluated against `guard_review_rubric`.
206
206
 
207
- The recorded verdict is bound to the reviewed repository content (commit hash + tracked-content worktree fingerprint of the directory it was recorded against), and the PR preflight accepts any approval whose binding matches the tree the PR would publish. A review recorded by a subagent rooted in a linked git worktree therefore satisfies a `pr create` run from that worktree, even from a different session than the one that spawned the reviewer. Review freshness is scoped to tracked content: deleting an untracked scratch file does not invalidate an approval, but any tracked edit or new commit does. Because reviewer agents are frequently configured with read-only toolsets that exclude `record_review`, the tool accepts recorders of any session type and binds the verdict to the recording session's directory; the audit trail records who recorded it and where it is bound.
207
+ The recorded verdict binds to the reviewed repository content: the commit hash and the tracked-content worktree fingerprint of the directory it was recorded against. The PR preflight accepts any approval whose binding matches the tree the PR would publish. A review recorded by a subagent rooted in a linked git worktree therefore satisfies a `pr create` run from that worktree. That holds even from a different session than the one that spawned the reviewer. Review freshness is scoped to tracked content. Deleting an untracked scratch file does not invalidate an approval, and any tracked edit or new commit does. Reviewer agents are frequently configured with read-only toolsets that exclude `record_review`. The tool therefore accepts recorders of any session type and binds the verdict to the recording session's directory. The audit trail records who recorded it and where it is bound.
208
208
 
209
209
  To opt out of the PR secondary review gate for a project, set `requireReview: false` in `.opencode/workflow-guard.json`:
210
210
 
@@ -216,7 +216,27 @@ To opt out of the PR secondary review gate for a project, set `requireReview: fa
216
216
 
217
217
  Or set `WORKFLOW_GUARD_REQUIRE_REVIEW=0` in your environment. Conversely, `WORKFLOW_GUARD_REQUIRE_REVIEW=1` enforces the review gate regardless of repository configuration.
218
218
 
219
- For stricter environments, set `requireSubagentReview: true` in `.opencode/workflow-guard.json` to reject approvals recorded by the root session itself: a passing verdict must then be recorded from a subagent session (one with a parent session), never by the root session approving its own work. Changes-requested findings remain relayable from any session. `WORKFLOW_GUARD_REQUIRE_SUBAGENT_REVIEW=1` enables the same requirement for any project; `WORKFLOW_GUARD_REQUIRE_SUBAGENT_REVIEW=0` disables it even when project config enables it.
219
+ For stricter environments, set `requireSubagentReview: true` in `.opencode/workflow-guard.json`. That setting rejects approvals recorded by the root session itself. A passing verdict must then be recorded from a subagent session, which is one with a parent session. The root session can never approve its own work. Changes-requested findings remain relayable from any session. `WORKFLOW_GUARD_REQUIRE_SUBAGENT_REVIEW=1` enables the same requirement for any project. `WORKFLOW_GUARD_REQUIRE_SUBAGENT_REVIEW=0` disables it even when project config enables it.
220
+
221
+ ---
222
+
223
+ ## Live-Documentation Research Floor
224
+
225
+ Policy 25 is enabled by default. A session that accumulates failed tool calls with no live-documentation lookup since gets its next mutating or shell call blocked. The block holds until the agent consults a current source. Only non-research failures count, so a failed `websearch` never deepens the block. Reads, greps, and research tools are never gated.
226
+
227
+ The builtin research names cover `websearch`, `webfetch`, and common aliases. MCP documentation servers are matched on whole server names. That means a guard inspection tool or a generic file reader cannot clear the debt by name accident. If your docs server uses an unrecognised name, declare it:
228
+
229
+ ```json
230
+ {
231
+ "requireLiveDocs": true,
232
+ "liveDocFailureThreshold": 3,
233
+ "researchTools": ["acme-docs", "internal-wiki"]
234
+ }
235
+ ```
236
+
237
+ Or set `WORKFLOW_GUARD_REQUIRE_LIVE_DOCS=0` to disable the floor, `WORKFLOW_GUARD_LIVE_DOC_THRESHOLD` to retune the trigger, and `WORKFLOW_GUARD_RESEARCH_TOOLS` (comma-separated) to add research names. An unparseable, zero, or negative threshold falls back to the default of 3.
238
+
239
+ The acting agent must be permitted to call at least one research tool. An agent whose toolset denies `websearch`/`webfetch` and exposes no MCP docs server cannot satisfy the floor, so grant one or disable the policy.
220
240
 
221
241
  ---
222
242
 
@@ -259,7 +279,7 @@ Project memory and Socratic learning are context modules, not part of Workflow G
259
279
 
260
280
  ### Experimental Learning Mode
261
281
 
262
- Socratic learning is disabled by default. Enable its agent-facing tools with the `learning: true` project option (including through `/guard-options`), or set `WORKFLOW_GUARD_LEARNING=1` in your user environment before OpenCode starts to enable it regardless of the project setting.
282
+ Socratic learning is disabled by default. Enable its agent-facing tools with the `learning: true` project option, including through `/guard-options`. Alternatively, set `WORKFLOW_GUARD_LEARNING=1` in your user environment before OpenCode starts. That enables it regardless of the project setting.
263
283
 
264
284
  To customize the per-session intervention budget, add:
265
285
 
@@ -269,7 +289,7 @@ To customize the per-session intervention budget, add:
269
289
  }
270
290
  ```
271
291
 
272
- to `.opencode/workflow-guard.json` (JSONC is also supported). The intervention budget limits high-value checkpoints per session; learning remains advisory and does not alter policy enforcement or direct the workflow.
292
+ to `.opencode/workflow-guard.json` (JSONC is also supported). The intervention budget limits high-value checkpoints per session. Learning remains advisory and does not alter policy enforcement or direct the workflow.
273
293
 
274
294
  The global learner profile is stored at `$XDG_DATA_HOME/opencode/workflow-guard/learner-profile.json`, falling back to `~/.local/share/opencode/workflow-guard/learner-profile.json`. The parent directory and file are created with user-only permissions where supported. The profile contains distilled learning evidence and project/session references, so it can be backed up or removed separately from any repository.
275
295
 
@@ -279,10 +299,10 @@ The global learner profile is stored at `$XDG_DATA_HOME/opencode/workflow-guard/
279
299
 
280
300
  Project memory is optional supporting context, enabled by default, and requires no additional dependency or service. Set `projectMemory: false` (or toggle it through `/guard-options`) to disable its initialization and tools for a project without weakening policy enforcement. Its authoritative working index is a local SQLite database under `$XDG_DATA_HOME/opencode/workflow-guard/project-memory/`, falling back to `~/.local/share/opencode/workflow-guard/project-memory/`. Repositories use their Git common directory as the local identity where available, so linked worktrees share an index.
281
301
 
282
- The plugin exposes `project_memory_search`, `project_memory_record`, `project_memory_export`, and `project_memory_import`. Recording is intended only for durable facts, decisions, constraints, and lessons; recognized secret content is rejected. Routine tool/test/verification output, transient errors and retries, successful operational telemetry, todos, and session progress belong in their existing operational stores rather than project memory.
302
+ The plugin exposes `project_memory_search`, `project_memory_record`, `project_memory_export`, and `project_memory_import`. Recording is intended only for durable facts, decisions, constraints, and lessons. Recognized secret content is rejected. Routine tool, test, and verification output, transient errors and retries, successful operational telemetry, todos, and session progress belong in their existing operational stores. They do not belong in project memory.
283
303
 
284
- Project-memory maintenance runs opportunistically when a project index is opened, at most once per day. Superseded memories and resolved review follow-ups are retained for 90 days and then pruned; current memories are not expired just because they are old. Maintenance checkpoints and compacts the active SQLite database, and reaps coordination markers (`*.sqlite.active.*`) left behind by processes that died without closing their store; markers owned by live or unidentifiable processes are never removed. When the project-memory directory exceeds 100 MB, least-recently-used inactive project databases are evicted toward about 80 MB when eligible databases exist. The current project's database is never selected for global eviction, and maintenance failures do not disable core guard enforcement.
304
+ Project-memory maintenance runs opportunistically when a project index is opened, at most once per day. Superseded memories and resolved review follow-ups are retained for 90 days and then pruned. Current memories are not expired just because they are old. Maintenance checkpoints and compacts the active SQLite database. It also reaps coordination markers (`*.sqlite.active.*`) left behind by processes that died without closing their store. Markers owned by live or unidentifiable processes are never removed. When the project-memory directory exceeds 100 MB, least-recently-used inactive project databases are evicted toward about 80 MB when eligible databases exist. The current project's database is never selected for global eviction, and maintenance failures do not disable core guard enforcement.
285
305
 
286
306
  Portable project knowledge lives at the fixed path `.opencode/memory/project-memory.jsonl`. Importing that file bootstraps the local index, but exporting is always explicit and accepts selected record IDs rather than dumping private working memory. The plugin adds `.opencode/memory/` to `.git/info/exclude` for the local clone. To share promoted knowledge through Git, deliberately remove that local exclusion or force-add the JSONL file after reviewing its contents. Do not commit the SQLite database.
287
307
 
288
- Compaction receives a bounded set of recent current local memories. Imported portable records are never injected automatically and require an explicit memory search. Path-backed local memories with a recorded Git commit are excluded when those paths have committed, staged, or unstaged changes since that commit; repository contents remain authoritative over remembered context. Memory supplies context rather than instructions and does not select, prioritize, or sequence work.
308
+ Compaction receives a bounded set of recent current local memories. Imported portable records are never injected automatically and require an explicit memory search. Path-backed local memories with a recorded Git commit are excluded when those paths have committed, staged, or unstaged changes since that commit. Repository contents remain authoritative over remembered context. Memory supplies context rather than instructions. It does not select, prioritize, or sequence work.
@@ -6,10 +6,10 @@ As documented by OpenCode, managed configuration has the highest configuration p
6
6
 
7
7
  A typical managed configuration should restrict organization-level capabilities, for example with `enabled_providers`, `disabled_providers`, `experimental.policies` (2.0.x) or top-level `policies` (2.1.x), and `permission`. Install workflow-guard through your controlled OpenCode distribution or configuration alongside those settings, and pin/review the package version according to your normal software-supply-chain process.
8
8
 
9
- Workflow Guard's project `profile` is a convenience for optional workflow defaults, not a security level. The `interactive` default and `autonomous` profile enforce the same core safety invariants; `autonomous` currently enables recovery checkpoints by default. Explicit project feature settings override profile defaults. Ralph mode is orchestration-adjacent and therefore remains disabled unless the project explicitly sets `ralphMode: true`; selecting `autonomous` does not enable it.
9
+ Workflow Guard's project `profile` is a convenience for optional workflow defaults, not a security level. The `interactive` default and the `autonomous` profile enforce the same core safety invariants. `autonomous` currently enables recovery checkpoints by default. Explicit project feature settings override profile defaults. Ralph mode is orchestration-adjacent and therefore remains disabled unless the project explicitly sets `ralphMode: true`. Selecting `autonomous` does not enable it.
10
10
 
11
- For headless or centrally operated environments, use `guard_status` and `guard_why` as the machine-readable accountability surfaces rather than scraping log prose or relying on the optional TUI. `guard_status` reports effective configuration, fresh verification/review references, bounded outstanding requirements, and Ralph configuration/outcome. `guard_why` evaluates the authoritative structured policy decision in simulation mode without performing verification, remote PR lookups, durable audit writes, or other mutation accounting. When a simulated Git operation passes local checks but its final result can depend on intentionally unqueried GitHub/Azure PR state, `guard_why` reports `needs_approval` with code `remote_state_unchecked` instead of claiming the operation is allowed. Core server enforcement does not depend on the TUI.
11
+ For headless or centrally operated environments, use `guard_status` and `guard_why` as the machine-readable accountability surfaces. Do not scrape log prose, and do not rely on the optional TUI. `guard_status` reports effective configuration, fresh verification and review references, bounded outstanding requirements, and Ralph configuration and outcome. `guard_why` evaluates the authoritative structured policy decision in simulation mode. It performs no verification, remote PR lookups, durable audit writes, or other mutation accounting. A simulated Git operation may pass local checks while its final result depends on GitHub or Azure PR state that was intentionally not queried. In that case `guard_why` reports `needs_approval` with code `remote_state_unchecked` instead of claiming the operation is allowed. Core server enforcement does not depend on the TUI.
12
12
 
13
- At startup workflow-guard writes an informational app-log diagnostic stating whether a file-based managed configuration was detected at the platform's standard location. This is observational only. OpenCode's V1 plugin API does not provide a supported provenance/trust signal proving that workflow-guard itself came from an administrator-controlled source, and managed configuration precedence does not prove that untrusted project plugins cannot also run.
13
+ At startup workflow-guard writes an informational app-log diagnostic. It states whether a file-based managed configuration was detected at the platform's standard location. This is observational only. OpenCode's V1 plugin API does not provide a supported provenance or trust signal proving that workflow-guard itself came from an administrator-controlled source. Managed configuration precedence also does not prove that untrusted project plugins cannot run alongside it.
14
14
 
15
15
  Reference: https://opencode.ai/docs/config/#managed-settings (retrieved August 25, 2026).