Plugin improver
For: tenant administrators and plugin users.
Use Plugin improver (ai.oz0/plugin-improver) to propose changes to plugins your tenant owns and keeps in its repositories. It works on a copy of one plugin repository and produces a changeset with evidence for a person to review.
Only after approval does GitHub's push_changes open a draft pull request. A person must merge it. The improver cannot change Orchestrator Zero, another publisher's plugin or itself.
| Kind | capability: one job, proposing changes to your plugins, owned by the team that maintains them |
| Category | Improve |
| Flows | improve-plugin (propose one change), improver-notice (what a routine's fire found), improver-after-merge (the result and the update after a pull request closes) |
| Agents | improver (Claude Agent SDK), improver-opencode and improver-goose (OpenCode and goose through harness-acp): one instruction file and one contract, one agent per harness |
| Tool | oz0_plugin_improver: the flows' own steps that need no model; local and read-only, reaches nothing |
| Built-ins | oz.evidence (where a target is installed from), oz.report_outcome and oz.propose_update (after a pull request closes), run as flow steps with no model |
| Uses | ai.oz0/github: resolve_ref, download_archive, get_pull_request and push_changes, nothing else |
| Skills | the build kit's skills, as its agents' own |
| Reaches | nothing of its own: every call to GitHub is ai.oz0/github's, with your connection |
"Verified" means the project tested, pinned and secured this plugin. It does not mean that GitHub, Anthropic or any other vendor endorses it.
Install
oz0 plugin install hub:ai.oz0/github
oz0 plugin install hub:ai.oz0/harness-claude # or harness-acp, for OpenCode or goose
oz0 plugin install hub:ai.oz0/plugin-improver --accept-reads results --reads-target notes --reads-target triage
# refused once with what it asks of ai.oz0/github
oz0 plugin install hub:ai.oz0/plugin-improver --accept-reads results --reads-target notes --reads-target triage \
--accept-uses sha256:...
oz0 setting set PLUGIN_IMPROVER_TARGETS "notes=acme/notes, triage=acme/plugins:plugins/triage@main"
oz0 setting set PLUGIN_IMPROVER_PUBLISHER acme # only when your plugins carry a hub listing
What it asks for:
| Grant | Why |
|---|---|
oz0_github.resolve_ref (read) | The commit a target's branch is at |
oz0_github.download_archive (read) | That commit's code, for the target's check and the session's copy |
oz0_github.get_pull_request (read) | A merged pull request, after the merge |
oz0_github.push_changes (write, waits for a person) | The approved changeset as a draft pull request; the connector keeps to GITHUB_ALLOWED_REPOS when it is set |
reads: [results], for the target plugins you name (--reads-target) | What those plugins' jobs came to, read with oz.evidence with your permissions at every read, and the results events the findings.yaml routine fires on. Grant the same plugins as PLUGIN_IMPROVER_TARGETS names; add or take one back later with oz0 plugin reads grant and revoke |
Its settings:
| Setting | Default | Meaning |
|---|---|---|
PLUGIN_IMPROVER_TARGETS | none | The plugins it may propose changes to: <plugin>=<owner>/<repository>[:<folder>][@<branch>], one per line or comma-separated, at most 50. Without it, every job ends with "Nothing to do" |
PLUGIN_IMPROVER_PUBLISHER | none | Your publisher name on a hub; a target whose listing names another publisher is refused, and with this empty, any listed target is |
PLUGIN_IMPROVER_FORGE_HOST | github.com | The host your GitHub is on, such as your GitHub Enterprise Server's; a target installed from a repository on another host is refused (one installed from a file:// mirror, which only an operator who allows file plugins can install, is compared by owner and name alone) |
PLUGIN_IMPROVER_HARNESS | claude-agent-sdk | The coding harness: claude-agent-sdk, opencode or goose. Codex and Gemini CLI run some calls without asking, so the job's hooks and approvals could not decide them: they are not offered |
PLUGIN_IMPROVER_CANARY, PLUGIN_IMPROVER_SOAK, PLUGIN_IMPROVER_SHADOW_RUNS | 1, 10m, 10 | The rollout the update after a merge proposes |
Changing them is a plugin configuration change, reviewed as your tenant
reviews them. Set the repositories your GitHub connection may write in GITHUB_ALLOWED_REPOS too, so that
push_changes refuses any other.
Its agents ask for your smart alias (the session) and fast (the judge), never a vendor's model: map them with
oz0 model alias set. The Claude Agent SDK speaks Anthropic's Messages API only, so improver needs an alias that
resolves to a provider that takes it; OpenCode and goose speak others.
Start it
A person runs it from the console or the CLI:
oz0 run improve-plugin '{"target": "notes", "task": "The date format eval case fails since the last model change"}'
oz0 run improve-plugin '{"target": "notes", "evidence": ["finding:f-2c91"], "harness": "goose"}'
evidence cites findings, eval runs and comparisons by ID (finding:<id>, eval:<run>, comparison:<id>); the
platform keeps the ones that are your tenant's in the change's record, with what it knows of each. An app starts it the
same way through the runtime API with its key, such as a CI job of the plugin's repository
whose tests failed:
- name: Ask the improver for a change
if: failure()
run: |
curl -fsS "$OZ0_URL/v1/agents/improve-plugin/jobs?tenant=acme" -H "Authorization: Bearer $OZ0_APP_KEY" \
-H "Content-Type: application/json" \
-d '{"target": "notes", "task": "CI test failed on ${{ github.sha }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"}'
env:
OZ0_URL: ${{ vars.OZ0_URL }}
OZ0_APP_KEY: ${{ secrets.OZ0_APP_KEY }}
Routines
No manifest key installs a routine, so the improver ships its routines as files in its folder,
plugins/plugin-improver/routines/, which an admin saves (oz0 routine save -f <file>) with an owner_team of the
tenant's:
| File | Fires on | Runs |
|---|---|---|
ci-failure.yaml | GitHub's workflow_run and check_suite events that completed with failure or timed_out on a target's repository and branch (not a pull request's run) | improver-notice |
findings.yaml | The platform's results events: a finding that opened on a target, a model alias or mapping rule that changed under its agents. They come only for the targets a person granted the improver the results of (--reads-target) | improver-notice |
weekly.yaml | A schedule, once a week, for one target (copy it per target) | improver-notice |
after-merge.yaml | GitHub's pull_request event, closed (merged or not), from an oz0/improver- branch | improver-after-merge |
A routine's fire is a job an outside event starts, and such a job never runs a shell and a write in one run
(routines). The improver's session writes files, and its changeset ends in
a write, so a fire does not run it: improver-notice reads only, works out the target and the cause,
and ends with the command that starts improve-plugin, for the person who reads the fire's job.
A CI system that should
start the improver itself does it through the runtime API, as above. improver-after-merge runs no session: its
routine lists the two platform built-ins its flow calls, oz.report_outcome and oz.propose_update.
Related tasks
- How an improvement runs: Follow evidence collection, candidate checks and the work after a merge.
- Improver limits and records: Look up its boundaries, retained evidence and agent names.
Previous section links
- Section: after a merge
- Section: limits
- Section: names
- Section: the candidate check
- Section: what a job does
- Section: what it leaves on record
- Section: what it never does