feat(agents): implement the predefined agent archetype catalog - #39
feat(agents): implement the predefined agent archetype catalog#39rodrigottv wants to merge 5 commits into
Conversation
The lockfile still declared 0.1.11 while package.json is at 0.1.15, and carried stale `peer: true` markers on two dev dependencies. Regenerated by npm install; no dependency versions changed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both `opensquad agents` and `opensquad skills` printed a /tree/main/ URL, but the repository's default branch is master, so the links 404'd. This was harmless while agents/ did not exist; it now points at real content. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The agents/ registry was scaffolded in the initial commit — src/agents.js,
src/agents-cli.js, "agents/" in package.json files[], and 'agents' in
PROTECTED_PATHS — but the directory itself was never created, so the catalog
was always empty. docs/plans/2026-03-01-fix-init-distribution-plan.md
specified installAllAgents(); only its documentation task was ever executed.
This implements the feature end to end.
Catalog: 8 archetypes, one per "Discipline" entry in the best-practices
catalog, plus a generated _catalog.yaml index so the Architect can discover
them without reading every AGENT.md.
Archetypes are foundations, not finished agents. They ship without a persona
name — only a functional one ("Researcher") — so the squad-unique two-word
naming rule in design.prompt.md stays satisfiable when composing a squad.
Each carries a Specialization Contract stating what the Architect must fill
in. Deep domain knowledge stays in _opensquad/core/best-practices/; the
archetype holds the agent shape, not a second copy of the knowledge.
Flow, one direction only:
agents/{id}/AGENT.md
-> init/update installs agents/{id}.agent.md into the project
-> design.prompt.md Phase E reads the index and specializes a match
-> build.prompt.md writes squads/{code}/agents/{id}.agent.md
An archetype is an input to Design, never an output of Build. Build's Gate 1
now rejects any generated agent still carrying the ARCHETYPE banner or a
Specialization Contract, which is what catches a verbatim copy.
Wiring: init installs the full catalog; update backfills only archetypes
missing from the target, since 'agents' is in PROTECTED_PATHS and user
customizations must survive. _catalog.yaml is generated, so update refreshes
it in place.
Tests: six existing tests asserted the empty-registry state — four no-ops
guarded by `if (available.length === 0) return;` and two asserting that
init/update leave no agents/ directory. All six now exercise the real
catalog, alongside new coverage for catalog/directory correspondence, the
init install, and the update backfill preserving customized agents.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CLAUDE.md at the repo root was a copy of the end-user template shipped to consumer projects (templates/ide-templates/claude-code/CLAUDE.md), left over from the repo dogfooding itself. It is not in package.json files[], so nothing distributes or tests it. Replaced with guidance for developing the package: the installer/runtime split, the four copy mechanisms and their differing init-vs-update semantics, the multi-IDE golden rule, squad anatomy, the dashboard state.json contract, and the archetype flow. opensquad-dev predated the canonical-sources refactor and described a templates/_opensquad/core mirror, a templates/skills mirror, and an installAllAgents() that had never been implemented. Checks A and B now verify those mirrors stay absent rather than present; C, D, E, and H were rewritten against the real code; H, I, and K were added for the version file, localization, and the runner/dashboard state contract. The Golden Rule and the IDE-contamination check were already correct and are unchanged. Both files now note that docs/plans/ are historical records rather than current specs, since the 2026-03-01 plan was only partially executed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t files
The archetype-containment checks were listed under Gate 1's "For EACH
.agent.md file" loop, so they only ever scanned squads/{code}/agents/.
Leakage is not confined there: squad.yaml, step files and pipeline/data/
are just as likely to carry a stray archetype reference, and the scoped
check reports a clean pass while the leak sits in squad.yaml.
Found by building a real squad from the catalog and then auditing it. The
generated squad.yaml carried an `archetype_note:` provenance field on each
agent; the agent files themselves were clean, so Gate 1 passed. Verified by
re-injecting the same field: the new gate reports
squads/{code}/squad.yaml:45, the old check reports nothing.
Promotes the two leak checks out of Gate 1 into a squad-wide Gate 1c and
adds provenance fields to what it rejects, since a self-contained squad
should record which archetype it came from nowhere but the conversation.
The persona-name check stays in Gate 1, where it is genuinely per-agent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Update: Gate 1c — archetype containment now scans the whole squadPushed The gap. The archetype-containment checks were sitting inside Gate 1's "For EACH How it surfaced. I built a 3-agent LinkedIn-post squad from the catalog and audited the result. The generated The fix. Promotes the two leak checks out of Gate 1 into a squad-wide Gate 1c, and adds provenance fields to what it rejects — a self-contained squad should record which archetype it came from nowhere except the conversation with the user. The persona-name check stays in Gate 1, where it is genuinely per-agent. What the build exercise validatedBeyond the gap, the archetype flow held up:
Two design decisions from the PR description proved load-bearing in practice:
Caveat on this evidenceI wrote the Phase E instructions, so I'm a biased evaluator — following them is easier for me than for a fresh session. What this genuinely validates is structural: paths resolve, referenced files exist, Gate 1 is satisfiable, and the instructions don't contradict each other. It does not establish that an independent session reaches the same archetype choices. A clean-session run would be worth doing before merge. The exercise also skipped onboarding (no
|
Context
The
agents/registry has been scaffolded since the initial commit but the directory was never created.src/agents.jsandsrc/agents-cli.jsare fully implemented,"agents/"is inpackage.jsonfiles[], and'agents'is inPROTECTED_PATHS— yetopensquad agentshas always listed an empty catalog.I traced the whole history (159 commits, all branches): no path under
agents/ever existed, so nothing was removed.docs/plans/2026-03-01-fix-init-distribution-plan.mdspecifiedinstallAllAgents()in Step 3, but only its documentation task (Check H inopensquad-dev) was ever executed. The checklist has been asking for a function that was never written.This PR implements the feature end to end.
Design decisions
Two constraints shaped this, and I'd especially like your read on them:
1. Archetypes ship without a persona name.
design.prompt.mdrequires every agent to have a two-word alliterative name with a squad-unique initial letter. A static catalog with fixed names ("Ângela Ângulo") cannot satisfy that when composed arbitrarily. So archetypes carry only a functional name (Researcher), and the Architect assigns the persona name during specialization — the naming rule stays intact.2. Archetypes do not duplicate
best-practices/. That directory already holds the deep domain knowledge (350+ lines per discipline) anddesign.prompt.mdPhase A already reads it. Duplicating it into the catalog would repeat the mistake the canonical-sources refactor removed. The archetype holds the agent shape (~110 lines: persona stance, principles, process, decision criteria, anti-patterns, quality criteria); the best-practices file holds the knowledge. Each archetype'sbestPractices:field links the two, and the Architect reads both.What changed
Catalog — 8 archetypes, one per "Discipline" entry in
best-practices/_catalog.yaml, so the mapping isn't arbitrary:researcher,strategist,copywriter,technical-writer,image-designer,data-analyst,reviewer,publisher. Plus a generated_catalog.yamlindex, following the same read-the-index-first pattern as best-practices.Flow — one direction only:
An archetype is an input to Design, never an output of Build. Each carries a
## Specialization Contracttelling the Architect what to fill in. Gate 1 now rejects any generated agent still carrying theARCHETYPEbanner or a Specialization Contract — that's what catches a verbatim copy instead of a real specialization.Wiring —
initinstalls the full catalog;updatebackfills only archetypes missing from the target, sinceagentsis inPROTECTED_PATHSand user customizations must survive._catalog.yamlis generated, so update refreshes it in place.Graceful degradation — Phase E step 5: if
agents/_catalog.yamlis absent (older install, or the user deleted it), the Architect designs every agent from scratch as before. A missing catalog never fails a build.Tests
npm test: 126 → 140, all passing.npm run lintclean.Six existing tests asserted the empty-registry state and had to be inverted:
if (available.length === 0) return;with the comment "No bundled agents in dev environment — skip"init/updateleave noagents/directory (init does not create agents dir when no bundled agents exist,update succeeds when no bundled agents exist)New coverage: catalog↔directory exact correspondence (a directory missing from the index is invisible to the Architect; an index entry with no directory points at a nonexistent file), frontmatter parseability including
pt-BR/es, id validity againstvalidateAgentId(), the init install, and the update backfill preserving a customized agent.Also included
fix(cli): bothagentsandskillsprinted a/tree/main/browse URL, but the default branch ismaster— those links 404'd. Harmless whileagents/didn't exist; it now points at real content.chore:package-lock.jsondeclared 0.1.11 whilepackage.jsonis at 0.1.15.docs: rewroteCLAUDE.md(the root copy was a stale duplicate of the end-user template, not developer guidance) and theopensquad-devchecklist, whose Checks A/B/C/H described atemplates/mirror and aninstallAllAgents()that no longer match the code. The Golden Rule and the IDE-contamination check were already correct and are unchanged — and I verified my own prompt edits against Check J: no IDE-specific logic in shared files.One thing I did not touch
.gitignoreline 11 ignorestests/, but the 7 test files are tracked — so they work, yet a new test file needsgit add -for it silently never reaches CI. I hit this while committing. It looked out of scope for this PR, but it's worth a separate fix.🤖 Generated with Claude Code