Geração orientada por manifesto
Todo repo gerenciado pelo Octopus tem um arquivo que o humano edita:
.octopus.yml. Todo o resto sob .claude/, .github/,
AGENTS.md, GEMINI.md e .opencode/ é gerado. A
geração é o mecanismo central da arquitetura.
Por que geração em vez de templates
A alternativa ingênua é cada projeto partir de um repo template e editar diretamente o arquivo de config de cada agente. Isso quebra rapidamente:
- Um time que usa três agents tem três arquivos para manter em sincronia a cada mudança de política.
- O lançamento de um novo agent significa que cada repo precisa ser tocado manualmente para adicionar suporte.
- Skills customizadas entram como uma edição por repo em vez de um artefato compartilhado.
A geração colapsa os três: a política vive uma vez no manifesto, a geração sabe como entregá-la a cada agent e adicionar um agent é uma mudança apenas no gerador.
Os dois modos de conteúdo
Agents diferentes esperam formatos diferentes. O Octopus suporta dois:
Modo template — a saída do agent é um único arquivo com
placeholders que o gerador preenche. O Claude Code usa isso no
seu CLAUDE.md: há um template agents/claude/CLAUDE.md com
marcadores {{rules}}, {{skills}}, {{commands}}, etc., e o
gerador substitui pelo conteúdo que o manifesto selecionou. Esse
modo é apropriado quando o arquivo tem uma estrutura fixa que o usuário quer
ver.
Modo concatenate — a saída do agent é montada por concatenação de seções ordenadas: header + core + rules + skills + commands + roles. Copilot, Codex, Gemini e OpenCode todos usam esse modo. A ordem de concatenação é fixa; o conteúdo de cada seção vem do manifesto.
A escolha entre os modos é por agent, definida em
agents/<name>/manifest.yml. O gerador lê o modo e
executa o pipeline correto.
O pipeline de geração
.octopus.yml │ │ 1. Validate manifest schema │ 2. Expand bundles → flat list of skills + roles + rules │ 3. Resolve transitive dependencies (e.g., audit-all pulls audit-security) │ 4. For each agent in `agents:`: │ a. Load agents/<name>/manifest.yml (capabilities) │ b. Pick template or concatenate mode │ c. Deliver each capability (symlink, inline, file copy) │ 5. Update .gitignore with generated paths │ 6. Write .env.octopus.example for any MCP servers selected ▼.claude/CLAUDE.md, .claude/settings.json, .claude/rules/, .claude/skills/, .claude/agents/, .claude/commands/.github/copilot-instructions.mdAGENTS.mdGEMINI.md.opencode/rules.md, .opencode/commands/, .opencode/skills/, .opencode/agents/, .opencode/settings.jsonPerfis na lista de bundles
A lista bundles: aceita tanto intent bundles quanto perfis
auto-detectados. Após o octopus setup rodar a detecção, um manifesto
típico pode parecer com:
bundles: - starter - backend - quality - stack-csharp # auto-detectado a partir de *.csproj - db-mssql # auto-detectado a partir de Microsoft.Data.SqlClientPerfis de stack e banco de dados seguem as mesmas regras de expansão dos intent bundles — são simplesmente entradas com categoria específica no catálogo de bundles.
Excluindo membros individuais com exclude:
O manifesto suporta uma lista de nível raiz exclude: que subtrai skills
ou roles individuais depois que toda a expansão de bundles e perfis é
concluída. Use-a quando um perfil ou bundle traz um membro que você não
quer:
bundles: - backend - db-mongodb
exclude: - dba-mongodb # db-mongodb detectado, mas este repo usa uma réplica somente-leituraexclude: é aplicado por último, então funciona independentemente de qual
bundle introduziu o membro. Não afeta dependências transitivas de outras
skills que permanecem na lista efetiva.
Você não precisa escrevê-lo à mão: o octopus setup interativo roda em
duas etapas. Primeiro você escolhe os bundles, os profiles de
stack/database e as features; depois, se algum intent bundle
escolhido tiver membros, uma segunda tela lista essas skills, roles e
rules — todas marcadas por padrão — e o que você desmarcar (SPACE) é
gravado aqui como exclude:. Profiles de stack/DB são atômicos (um
engine/stack cada), então são escolhidos como itens únicos na etapa um e
nunca ganham um grupo na etapa dois. O fallback de terminal (sem fzf)
oferece as mesmas duas etapas como listas numeradas.
Por que o manifesto nunca é editado automaticamente
octopus setup escreve arquivos gerados; nunca escreve de volta no
.octopus.yml. A direção contrária seria um efeito colateral
oculto — o usuário perderia a noção de quais linhas escreveu e
quais a ferramenta decidiu. Manter o manifesto exclusivamente humano significa que o
modelo mental fica limpo: edite o manifesto, rode o setup, inspecione
o diff.
A única exceção é octopus update, que pode atualizar a versão
fixada no .octopus.yml para corresponder à CLI recém-instalada. Essa é a
única linha que a ferramenta escreve; o resto do manifesto permanece sob
posse do humano.
Como os agents descobrem a config gerada
Cada agent tem sua própria convenção de descoberta:
- Claude Code lê
.claude/CLAUDE.md, maissettings.jsonpara hooks e MCP servers, mais a árvore de arquivos sob.claude/skills/,.claude/commands/,.claude/agents/. - Copilot lê
.github/copilot-instructions.md. - Codex lê
AGENTS.md. - Gemini lê
GEMINI.md. - OpenCode lê
.opencode/rules.md+ a árvore de arquivos sob.opencode/.
O gerador respeita a convenção de cada agent — nenhum agent precisa conhecer o Octopus para consumir sua saída.