Skip to content

Latest commit

 

History

History
108 lines (76 loc) · 10.2 KB

AGENTS.md

File metadata and controls

108 lines (76 loc) · 10.2 KB

opencode-auto-qcgates

OpenCode plugin for automated quality gate evaluation via test baselining. Ships two skills and two slash commands for use under any dot-agents-compatible agent (Claude Code, OpenCode, etc.); OpenCode-specific bindings are layered on top.

Developer Commands

bun run check   # TypeScript type check (may show tsconfig warnings in dev env)
bun test        # Run unit tests

Commands

Command Description
/test-baseline init Grill for tiers, generate testing-protocol.md, capture first baseline (BL-001)
/test-baseline eval Compare current tests against baseline; auto-updates the baseline when PASS + thresholds exceeded (DEFAULT)
/test-baseline update Manual escape hatch: re-baseline on request — accept a FAIL's new metrics, force a fresh baseline, or approve inspected numbers
/regression-check Answer quality questions (proactive or reactive)

Architecture

Two-skill system:

  • test-baselining — Runs tests, captures metrics, compares against baseline; builds the consumer's protocol + baseline on init
  • regression-checking — Interprets results, answers quality questions, emits decision signals for agents

Asset structure:

skills/test-baselining/
├── SKILL.md
├── refs/                      # Bundled reference assets — non-authoritative guidance
│   ├── source-controls.md     # Always-relevant: VCS discovery + change-detection commands (git, Mercurial, Subversion, Pijul, Fossil, **Unity VCS**, Perforce, Bazaar, Darcs)
│   ├── backends-ref.md        # Init-only: backend-toolchain map and tier-grill scaffolding (C#, JVM, Go, Rust, Python, Node, Elixir, …)
│   └── frontend-refs.md       # Init-only: frontend-stack map and tier-grill scaffolding (React, Vue, Svelte, Angular, Solid, **Aurelia 2**, Lit, Ember, HTMX, …)
└── templates/
    ├── testing-baseline.xml   # Baseline XML template (adapted to consumer tiers on init)
    └── testing-protocol.md     # Threshold/pass-fail criteria template (tailored on init)

skills/regression-checking/
└── SKILL.md                   # Loads test-baselining, reads protocol for thresholds

commands/
├── test-baseline.md
└── regression-check.md

manifest.json                  # Optional-dependencies declaration (optionalDependencies)

Install model — dot-agents universal, OpenCode-extras on top:

  • Universal install — src/plugin.ts → src/installer.ts copies skills, commands, and agents to a dot-agents layout (SKILL.md per skill folder). Other agents consume them directly.
  • OpenCode accommodation — The harness additionally registers the plugin in opencode.json, sets the agent.task.permission.skill allowlist for both skills, and migrates a root opencode.json to .opencode/opencode.json when present. OpenCode's loadSkill({ name }) tool resolves skills through the same layout.

Skill bodies stay agent-agnostic. OpenCode-specific bindings live in a tail section of each SKILL.md and in the command frontmatter (a command-specific subtask: false for /test-baseline so it stays in the main conversation, true for /regression-check so it spawns a subagent). Commands no longer pin an agent, so each runs under the current agent.

Consumer Project Files

After /test-baseline init, two files appear at the consumer project root:

File Purpose
testing-protocol.md Workflow stages, thresholds, pass/fail criteria — tailored to this consumer's tiers (code or non-code)
testing-baseline.xml Baseline metrics and changelog (BL-001, BL-002, …)

init grills the user for the actual tier set (code: toolchain per tier; non-code: repeatable verification procedures) and adapts both files to match. The shipped XML/Protocol templates are starting points, not the protocol.

File-location rule: skills locate these files at the consumer's source-control working-tree root, falling back to cwd. The VCS-agnostic lookup table lives in refs/source-controls.md (bundled with test-baselining). Never invent a path; warn if found elsewhere (e.g. a monorepo subpackage or a Unity Packages/com.<vendor>.<name>/).

Adding Commands or Skills

  • New command: Create commands/<name>.md with a command-appropriate subtask (false to run in the current agent's main conversation, e.g. /test-baseline for its grilling flow; true to spawn a subagent, e.g. /regression-check) (OpenCode-specific — ignored by other agents). The body typically loads the corresponding skill.

New skill: Create skills/<name>/SKILL.md with required frontmatter (name, description). Use a templates/ subdirectory for files that should be copied to consumer projects. Body must be agent-agnostic; put any OpenCode-specific bindings in a tail ## OpenCode section.

Skill reference pattern:

!`tool loadSkill({ name: "skill-name" })`

Key Conventions

  • Baseline markers use BL-NNN format (zero-padded, e.g., BL-001)
  • Changelog is append-only and FIFO-pruned to 10 entries
  • Changelog auto-generates summaries based on which thresholds were exceeded — build-artifact deltas are first-class in the summary, never buried under test deltas
  • regression-checking delegates to test-baselining and reads testing-protocol.md for threshold interpretation
  • Commands do not pin an agent; the frontmatter subtask drives routing — false keeps the command in the current agent's main conversation, true forces a subagent (OpenCode-only — other agents use their own routing)
  • Skill bodies are agent-agnostic; OpenCode bindings live in a tail section per skill
  • refs/ is reference, not policy. Files under skills/<name>/refs/ are bundled with the skill and copied to the consumer; the skill body consults them during guided flows (init, Locating the Consumer Files, Caching Logic) but they are explicitly non-authoritative — the consumer's testing-protocol.md is the truth once it is written. source-controls.md is always-relevant; backends-ref.md and frontend-refs.md are init-only.
  • Skills are VCS-agnostic at the body level. Git-specific wording is a stand-in; the lookup table lives in refs/source-controls.md and the agent consults it for the consumer's actual source control. Coverage: Git, Mercurial, Subversion, Pijul, Fossil, Unity VCS (Unity Version Control / Plastic SCM), Perforce, Bazaar, Darcs.
  • Skills are backend-language and frontend-framework agnostic at the body level. Stack-specific guidance lives in refs/backends-ref.md and refs/frontend-refs.md and is used only during init — once the user configures their protocol, the references have no bearing.
  • Build artifacts are part of every eval and update. Captured per-tier (file count, total MB, build time, gzipped KB on critical files, lint-warning categories) in Stage 1, surfaced alongside test deltas in the eval output, and required for any update write — a baseline update that drops artefact fields is invalid.
  • Hooks never throw (ADR 0007). The Effect-first plugin definition (src/plugin.ts) wraps its entire effect body so any failure degrades to a console warn naming the exact remediation (bunx … install, plus the ~/.cache/opencode/npm/<name>@<version> dir to clear for cache rot); the effect's error channel stays never, so OpenCode still launches. Hard errors stay CLI-only; the effect never auto-deletes the cache (races in-flight installs). Registration detection (src/registration.ts, isPluginInConfigBase) is format-tolerant: both opencode.json and opencode.jsonc are honored in the global config dir, .opencode/, and the repo root.
  • Installer recommendations are non-blocking. The installer (src/installer.ts#detectAurelia, detectOptionalSkills) appends advisory messages to InstallResult.recommendations after a successful install when a known stack or optional skill is detected. detectAurelia is project-driven (looks at package.json); detectOptionalSkills is environment-driven (probes <configBase>/skills/<name>/). Recommendations suggest the right install path for the consumer's agent (OpenCode plugin config or npx skills add/use) but never modify the consumer config autonomously.
  • Skill dependencies are advisory. A skill may document optional dependencies in its frontmatter (metadata.optional-deps:) and chain to them at runtime via loadSkill. The frontmatter fields are non-functional — no host honors them; they exist for human/agent readers. The machine layer for optional dependencies is manifest.json (manifestVersion: 1; entries carry id, kind (skill | agent | mcp | plugin), description, and a typed source — bundled path, external-skill repo, plugin npm spec, or MCP command-or-url), validated on read by the loader in src/optional-deps.ts. The plugin never auto-installs dependencies. At install time the package's declarations are unioned by id into the consumer-side <name>.manifest.json optionalDependencies section with per-dependency state: pending (declared, undecided), accepted, or declined (both sticky; revisitable via the interactive menu). The merge is idempotent — existing accepted/declined state is preserved; a new or changed declaration (kind or source) flips back to pending, while description-only edits refresh the stored text without resetting state. When an optional dep is missing, detectOptionalSkills derives its non-blocking recommendation from the manifest and appends it to InstallResult.recommendations (mirroring detectAurelia). The runtime loadSkill call is best-effort and no-ops when the dep is absent. Currently the only declared optional dependency is grilling from mattpocock/skills (MIT), loaded by test-baselining init when the consumer's tier set cannot be inferred from the source-control working-tree root.

Agent skills

Issue tracker

Issues live as GitHub issues; use the gh CLI. See docs/agents/issue-tracker.md.

Triage labels

Default five-role triage vocabulary (needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix). See docs/agents/triage-labels.md.

Domain docs

Single-context: one CONTEXT.md and docs/adr/ at the repo root. See docs/agents/domain.md.