Skip to content

fix(materialize/renderers): stop consuming REGISTRY for OpenCode/Copilot installs#70

Merged
davidarce merged 1 commit into
mainfrom
fix/sdd-opencode-copilot-slim-orchestrator
May 10, 2026
Merged

fix(materialize/renderers): stop consuming REGISTRY for OpenCode/Copilot installs#70
davidarce merged 1 commit into
mainfrom
fix/sdd-opencode-copilot-slim-orchestrator

Conversation

@davidarce

Copy link
Copy Markdown
Owner

Summary

Pairs with the catalog PR that deletes `REGISTRY.opencode.md` / `REGISTRY.copilot.md` and slims `ORCHESTRATOR.{opencode,copilot}.md` to be the single-source orchestrator playbook.

OpenCode and Copilot have a primary `sdd-orchestrator` agent the user explicitly selects (custom agent in `opencode.json` / `.agent.md` in `.github/agents/`). That selection IS the consent to use the workflow. Until now, the renderer was also:

  1. Prepending `REGISTRY.{opencode,copilot}.md` to the synthesised orchestrator prompt
  2. Capturing the same content into `r.registryContents` for later injection into the ambient instructions file (AGENTS.md / copilot-instructions.md)

Both paths leaked workflow-specific rules into non-workflow sessions (ambient catalog) and duplicated / contradicted the orchestrator's own playbook (prompt prepend). They were a Claude/Factory pattern applied where it does not fit.

This change removes both consumers for OpenCode and Copilot. Claude / Factory / Codex paths are unchanged.

Changes

  • `opencode.go` (RenderWorkflow): skip `captureRegistryContent` for the workflow registry; pass `registryPath=""` to `synthesizeAgents`. Comment block at the call site explains why (primary-agent installs do not need REGISTRY).
  • `opencode.go` (buildOrchestratorEntry): signature unchanged for backward compatibility — non-empty `registryPath` is still honoured if a future caller passes one — but the canonical caller now passes "". Doc-comment updated.
  • `copilot.go`: parallel changes — skip `captureRegistryContent`; pass `registryPath=""` to `installOrchestratorAgent`. Same explanatory comment.

Tests

  • `TestOpenCodeRenderer_InstallWorkflow_RegistryInjectedIntoCatalog` → renamed to `TestOpenCodeRenderer_InstallWorkflow_RegistryNotCaptured`. Asserts `RegistryContents()` does NOT contain the workflow name. Negative assertion (no loose REGISTRY.md in skills dir) preserved.
  • `TestCopilotRenderer_InstallWorkflow_RegistryInjectedIntoCatalog` → renamed to `TestCopilotRenderer_InstallWorkflow_RegistryNotCaptured`. Same flip.
  • All other tests pass unchanged. `go test ./...` clean.

Compatibility

The change is forward-only: a workspace that materialised before this change still has the old REGISTRY-flavoured prompt in `opencode.json` / `.agent.md` until the next `devrune sync`, at which point the new prompt is rendered (REGISTRY content drops out, slim ORCHESTRATOR replaces it).

A workspace running this renderer against an old catalog (one that still ships `REGISTRY.{opencode,copilot}.md`) simply ignores those files — no error, no leak. A workspace running the old renderer against the new catalog (which deletes them) falls back to `REGISTRY.md` (generic Claude flavour) for the registry path, but reads an empty file capture, so the impact is harmless.

Pairing PR

Catalog: https://github.com/davidarce/devrune-starter-catalog/pull/new/fix/sdd-opencode-copilot-slim-orchestrator

Recommended order: merge catalog first, then this PR.

Test plan

  • `go test ./...` passes (already verified locally).
  • Merge both PRs, then `devrune sync` against an OpenCode workspace.
  • Verify `opencode.json` orchestrator prompt is the new slim ORCHESTRATOR alone (no Evaluation Gate, no "Your Role" defensive prose).
  • Verify `AGENTS.md` no longer carries the SDD orchestrator section.
  • Same for a Copilot install (`.github/agents/sdd-orchestrator.agent.md` body, `.github/copilot-instructions.md` ambient).

…lot installs

OpenCode and Copilot have a primary `sdd-orchestrator` agent the user
explicitly selects (a custom agent in opencode.json / a `.agent.md` in
.github/agents/). The orchestrator playbook lives in that agent's prompt
— rendered from ORCHESTRATOR.{opencode,copilot}.md alone.

Until now, the renderer was also:
- prepending REGISTRY.{opencode,copilot}.md to the orchestrator prompt
- capturing the same registry content into r.registryContents for later
  injection into AGENTS.md / copilot-instructions.md

Both paths leaked workflow-specific rules into non-workflow sessions
(ambient catalog) and duplicated / contradicted the orchestrator agent's
own playbook (prompt prepend). They were a Claude/Factory pattern
applied where it does not fit.

This change removes both consumers for OpenCode and Copilot:
- opencode.go: skip captureRegistryContent + pass registryPath="" to
  synthesizeAgents.
- copilot.go: skip captureRegistryContent + pass registryPath="" to
  installOrchestratorAgent.

buildOrchestratorEntry / installOrchestratorAgent still accept a
registryPath argument for backward compatibility — non-empty paths are
still read and prepended — but the canonical caller now passes "".

Tests updated to assert the new contract (RegistryContents must NOT
contain the workflow name for OpenCode/Copilot installs). Renames the
two test functions accordingly.

Pairs with devrune-starter-catalog change that deletes REGISTRY.opencode.md
/ REGISTRY.copilot.md (now dead code from the catalog's perspective) and
slims ORCHESTRATOR.{opencode,copilot}.md to remove duplication with the
deleted REGISTRY blocks.
@davidarce davidarce merged commit 12ff648 into main May 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant