sequenceDiagram
participant FS as Filesystem
participant OC as opencode
participant Plugin as opencode-semantic-anchors
participant Engine as RuleEngine
participant Config as ConfigLoader
OC->>Plugin: load plugin (opencode.jsonc)
Plugin->>Config: load(opencode-semantic-anchors.yaml)
Config->>FS: read YAML file
FS-->>Config: raw YAML
Config->>Config: validate against Zod schema
alt Config valid
Config-->>Plugin: LoadedConfig { contracts, presets, settings }
Plugin->>Engine: new RuleEngine(config)
Engine-->>Plugin: ready
Plugin-->>OC: Plugin loaded
else Config invalid
Config-->>Plugin: ValidationError
Plugin-->>OC: Plugin loaded with defaults + warning
end
OC->>Plugin: agent.activate({ role: "software-developer" })
Plugin->>Engine: setRole("software-developer")
Engine->>Config: getActiveContracts("software-developer")
Config-->>Engine: [contract-A, contract-B, ...]
Engine-->>Plugin: SessionState { role, toolCallCount: 0 }
Plugin-->>OC: ready
6. Runtime View
Startup Sequence
Tool Execution: Blocked Path
Occurs when an active contract triggers a BLOCK (e.g., Step Confirmation after 3 tool calls without "Weiter?"):
sequenceDiagram
participant User
participant OC as opencode
participant Plugin as opencode-semantic-anchors
participant Engine as RuleEngine
Note over User,Engine: Tool-Call #3 ohne vorheriges "Weiter?"
User->>OC: "edit file src/main.ts"
OC->>Plugin: tool.execute.before(edit, { file: "src/main.ts" })
Plugin->>Engine: evaluate({ type: "tool", toolName: "edit" })
Engine->>Engine: toolCallCount = 3, interval = 3, no confirmation
Engine-->>Plugin: Verdict { allow: false, contract: { id: "step-confirmation" } }
Plugin->>Plugin: throw new Error("🚫 Step Confirmation: ...")
Plugin--xOC: Error: block message
OC->>User: Show block message
User->>OC: "/anchor bypass 'continuing intentional edit'"
OC->>Plugin: anchor-bypass.execute({ reason: "continuing intentional edit" })
Plugin->>Engine: incrementOverride()
Engine-->>Plugin: overrideCount: 1/3
Plugin-->>OC: "Override 1/3: ..."
OC->>Plugin: tool.execute.before(edit, ...) [retry by LLM]
Plugin->>Engine: evaluate({ type: "tool", toolName: "edit" })
Engine-->>Plugin: Verdict { allow: true }
Plugin-->>OC: proceed
OC->>User: Execute edit
Tool Execution: Warn Path
Occurs when a contract matches in WARN mode (e.g., Source Anchor on write without prior source citation):
sequenceDiagram
participant User
participant OC as opencode
participant Plugin as opencode-semantic-anchors
participant Engine as RuleEngine
User->>OC: "write the implementation"
OC->>Plugin: tool.execute.before(write, { file: "..." })
Plugin->>Engine: evaluate({ type: "tool", toolName: "write" })
Engine->>Engine: check message history for source citation
Engine-->>Plugin: Verdict { allow: true, contract: { id: "source-anchor-warn" } }
Plugin->>Plugin: client.app.log({ level: "warn", message: "⚠️ Source Anchor: ..." })
Plugin-->>OC: proceed (no throw)
OC->>User: Execute write + [warning in log]
Chat Message Flow
No blocking, only gentle reminders:
sequenceDiagram
participant User
participant OC as opencode
participant Plugin as opencode-semantic-anchors
participant Engine as RuleEngine
User->>OC: "refactor this module"
OC->>Plugin: event({ type: "message.updated", content: "refactor this module" })
Plugin->>Engine: evaluate({ type: "message", content: "refactor this module" })
Engine->>Engine: check Intent (missing: what? why? verify?)
Engine-->>Plugin: Verdict { allow: true, message: "No explicit intent detected" }
Plugin->>Plugin: client.app.log({ level: "info", message: "Tip: ..." })
Plugin-->>OC: proceed
OC->>User: Process message (suggestion in log)
Agent Role Change
sequenceDiagram
participant OC as opencode
participant Plugin as opencode-semantic-anchors
participant Engine as RuleEngine
participant Config as ConfigLoader
OC->>Plugin: agent.activate({ role: "software-architect" })
Plugin->>Engine: setRole("software-architect")
Engine->>Config: getActiveContracts("software-architect")
Config-->>Engine: [boundary-anchor, emergence-anchor, step-confirmation]
Engine->>Engine: Reset toolCallCount
Engine-->>Plugin: SessionState { role: "software-architect" }
Plugin-->>OC: ready
OC->>Plugin: agent.activate({ role: "software-developer" })
Plugin->>Engine: setRole("software-developer")
Engine->>Config: getActiveContracts("software-developer")
Config-->>Engine: [step-confirmation, source-anchor, intent-anchor]
Engine->>Engine: Reset toolCallCount
Engine-->>Plugin: SessionState { role: "software-developer" }
Plugin-->>OC: ready
Error Scenarios
Config Validation Error
sequenceDiagram
participant FS as Filesystem
participant Plugin as opencode-semantic-anchors
participant Config as ConfigLoader
Plugin->>Config: load("opencode-semantic-anchors.yaml")
Config->>FS: read
FS-->>Config: invalid YAML
Config->>Config: log Warning
Config-->>Plugin: DefaultConfig (built-in fallback)
Plugin->>Plugin: continue with defaults
Hook Throw-Error
sequenceDiagram
participant OC as opencode
participant Plugin as opencode-semantic-anchors
participant Engine as RuleEngine
OC->>Plugin: tool.execute.before(edit, ...)
Plugin->>Engine: evaluate(...)
Engine--xPlugin: throws Error
Plugin->>Plugin: catch Error, log, do NOT re-throw
Plugin-->>OC: proceed (tool executes)
Fail-Open principle: On any error in a hook, the plugin returns
{ allow: true }so the agent is not blocked. The error is logged. This behaviour is specified in05-building-block-view.mdsection "Error Handling" (four scenarios: Config/RuleEngine/Hook/Tool).
Bypass Maximum Reached
sequenceDiagram
participant User
participant Plugin as opencode-semantic-anchors
participant Engine as RuleEngine
User->>Plugin: "/anchor bypass 'one more time'"
Plugin->>Engine: getState()
Engine-->>Plugin: SessionState { overrideCount: 3, maxOverrides: 3 }
Plugin-->>User: "Error: Max overrides (3) reached. Cannot bypass."
Session Reset (Plugin Reload)
On plugin reload (e.g., after config change + /anchor config-reload):
-
ConfigLoader re-reads YAML
-
Validates against Zod schema
-
RuleEngine is initialised with new config
-
SessionState is reset (toolCallCount = 0, overrideCount = 0)
-
Role is preserved (if set)
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.