microsoft / microsoft/agent-governance-toolkit

[Feature]: add out-of-band activation evidence for OpenCode governance

Open
#3,708 1 comment 0 reactions 0 assignees View on GitHub
needs-review:MEDIUM
Dominant language
Python
Stars
6.3k
Forks
1.1k
Avg merge
5d 11h
Merged PRs (30d)
142

Description

## Summary

Add a model-independent way for operators and automation to determine whether AGT's in-process OpenCode governance hooks are actually active.

This is a follow-up to the silently broken workspace-file installation documented in #3707. Correcting that example removes the immediate defect, but operators still need evidence that a discovered plugin was importable, initialized, and entered the session request path.

## Validated current behavior

Validated against:

- AGT `main`: `81955d48025c6b11deb3fc9dabf89f74f4145775`
- `@microsoft/agent-governance-opencode`: `5.0.0`
- OpenCode: `1.18.16`

### Available signals

1. **Startup log**

`session.created` attempts to log:

```text
[AGT] OpenCode governance active — mode=... source=...
```

The entire handler is wrapped in `try { ... } catch {}`. A runtime probe with a throwing log sink completed successfully, emitted no error, and created no audit file:

```json
{"sessionHookResolved":true,"logAttempts":1,"auditExists":false}
```

2. **`agt_policy_status`**

This is an in-process tool exposed to the model. If the plugin is absent, the tool is absent as well, so it cannot report the failure state. It also is not suitable as a container readiness probe or ordinary CI command.

3. **OpenCode `debug config`**

This is useful for checking discovery: it reports `plugin: []` for the unsupported `.mjs` workspace shim in #3707. However, it is not sufficient as activation evidence. A `.js` shim with a nonexistent re-export target remains listed in the resolved plugin configuration and the command exits successfully.

4. **Bundled launcher**

`bin/agt-node` only executes `node "$@"`; it does not inspect OpenCode discovery or AGT hook registration. The package also does not expose a dedicated verification command through `package.json`.

Validating a policy file is not equivalent to validating activation. A valid enforce-mode policy can remain untouched on disk when the plugin is absent.

## Desired outcome

Provide an out-of-band verification contract that distinguishes, at minimum:

- plugin not discovered;
- plugin discovered but not importable/initializable; and
- AGT session hook successfully activated.

The exact interface is open to maintainer preference. A practical staged design could combine:

1. a small command or exported verifier with stable JSON output and meaningful exit codes for workspace discovery/import checks; and
2. a metadata-only audit activation event, heartbeat, or equivalent runtime marker written when the session hook successfully registers/runs.

The first stage supports CI and readiness probes. The second proves runtime activation rather than only static configuration.

## Security and privacy constraints

- Verification must not require a model invocation.
- A missing or failed activation signal must not be reported as healthy.
- The signal must distinguish policy validity from plugin activation.
- Audit/heartbeat evidence must not include prompts, tool arguments, secrets, tokens, or raw policy content.
- Log-sink failure must not silently erase the only activation evidence.
- JSON output and exit-code semantics should remain stable enough for automation.

## Acceptance criteria

- [ ] A CI job or readiness probe can check AGT OpenCode activation without invoking a model tool.
- [ ] The check exits nonzero or returns an explicit unhealthy state when the plugin is not discovered.
- [ ] A discovered plugin with a broken import target is not reported as active.
- [ ] Successful `session.created` execution produces durable, metadata-only activation evidence or an equivalent externally queryable state.
- [ ] Documentation explains the difference between discovery, policy validity, plugin initialization, and runtime hook activation.
- [ ] Tests cover unsupported extension, broken import, successful activation, and unavailable log sink.

## Related work

- #3707 tracks the broken workspace installation and stale hook documentation.
- #2993 aligned the plugin's runtime hooks with OpenCode's contract.

## Related runtime integrity issue

- #3709 tracks duplicate activation and duplicate audit events when more than one shim registers AGT in the same workspace.

Contributor guide

Open the contributing guide

Research direction

Start with bin/agt-node, package.json, the session.created hook, and the existing agt_policy_status entry point to map current discovery and activation signals. Run the documented OpenCode checks for unsupported extensions and broken import targets, then cover the acceptance cases for stable JSON or exit status and metadata-only runtime evidence. Done means CI can distinguish discovery, initialization, and successful hook activation without a model invocation.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
devtools, security, testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.