package cockpit // geminiRenderer emits the whole selected playbook set as one GEMINI.md — the // Gemini CLI context convention, plain Markdown with no frontmatter. GEMINI.md // is advisory: Gemini reads it as context but enforces tool permissions in a // separate `.gemini/settings.json` `tools.core` layer (emitting that is C4, // not C2), so the file leads with the ADVISORY banner and names where real // enforcement lives. Aggregate target, like AGENTS.md. type geminiRenderer struct{} func (geminiRenderer) Target() string { return "gemini" } // Enforcement reports that GEMINI.md is advisory only (enforcement lives in a // separate settings layer). It satisfies the Fidelity interface. func (geminiRenderer) Enforcement() Enforcement { return EnforcementAdvisory } // AggRelPath is the single shared artifact path for the whole set. func (geminiRenderer) AggRelPath() string { return "GEMINI.md" } // RenderAll renders the set as one GEMINI.md document, deterministic in set // order (renderAggregateMarkdown sorts by Name). func (geminiRenderer) RenderAll(ps []Playbook) ([]byte, error) { return renderAggregateMarkdown(ps, "GEMINI.md — eeco-generated agent playbooks", "Gemini reads this file as context. Tool-permission enforcement is NOT here — it lives in "+ "`.gemini/settings.json` (`tools.core` / `tools.exclude`), which eeco does not emit in this slice."), nil } // RelPath / Render satisfy Renderer for interface completeness; the aggregate // emit path (GenerateAll) is what actually drives this target. func (r geminiRenderer) RelPath(Playbook) string { return r.AggRelPath() } func (r geminiRenderer) Render(p Playbook) ([]byte, error) { return r.RenderAll([]Playbook{p}) }