Context
Today every Codex session that Symphony dispatches starts cold — no recall of how this repo solves common task patterns. Maintainers solve the same shape of problem repeatedly (add a migration, wire a new endpoint, fix a flaky test in package X) and that knowledge lives only in human memory or scattered docs.
This issue adds a skills system: repo-scoped reusable procedural recipes that get loaded into the agent's system prompt before each dispatch. Layout is intentionally compatible with the agentskills.io open standard so skills authored for one agent ecosystem work in another.
Scope: human-authored skills only in this issue. Agent-authored skills (the agent writes its own skill on successful completion) is a follow-up.
Design
File layout
Per-repo skills live under the repo's .symphony/skills/ directory:
.symphony/
config.yaml # existing per-repo config (already shipped)
skills/
add-migration/
SKILL.md # the recipe (markdown, front-matter optional)
wire-graphql-field/
SKILL.md
fix-flake-pattern-x/
SKILL.md
Skills are checked into git alongside code so they version with the repo and code review applies.
SKILL.md format (agentskills.io-compatible)
---
name: add-migration
description: Add an Ecto migration with the project's standard naming + safety checks.
when_to_use: Issue mentions schema change, new table, new column, or "migration".
---
# Add migration
Steps the agent should follow...
The front matter is small and stable: name, description, when_to_use (a one-liner that helps the agent decide if this skill applies). Body is free-form markdown.
Loading & prompt injection
- On agent dispatch, the loader walks
.symphony/skills/*/SKILL.md in the workspace, validates front matter, and produces a [name, description, when_to_use, body_path] index.
- The index is summarized into a
## Available skills block in the system prompt envelope. Each skill is listed as name — when_to_use. The agent decides which to read and reads bodies on demand via the existing file-read tool — bodies are not preloaded (keeps the prompt small even with many skills).
- Validation errors on skills (missing front matter, duplicate name, unparseable YAML) post a tracker comment on the issue being worked on but do not block dispatch — the agent just gets a smaller skill set.
Config schema
Add to WORKFLOW.md:
agent:
skills:
enabled: true # default on once shipped
path: ".symphony/skills" # relative to workspace root
max_skills_in_prompt: 50 # safety cap for very large repos
Files to touch
lib/symphony_elixir/skills/loader.ex — new module. Walks the skills dir, parses front matter, returns {:ok, [%Skill{}]} or {:error, [%ValidationError{}]}.
lib/symphony_elixir/agent_runner.ex — call the loader before dispatch; inject the ## Available skills block into the system prompt envelope.
lib/symphony_elixir/config/schema.ex — add agent.skills block + validations.
test/symphony_elixir/skills/loader_test.exs — new test module.
test/symphony_elixir/agent_runner_skills_test.exs — integration: skills index appears in the assembled prompt; bad SKILL.md surfaces an error comment.
- README / docs — explain the layout, the agentskills.io compat, and authoring guidance.
Acceptance
- A repo with no
.symphony/skills/ directory dispatches exactly like today (zero behavior change when skills enabled).
- A repo with three well-formed SKILL.md files surfaces all three in the agent prompt's
## Available skills block (name + when_to_use only).
- A repo with one malformed SKILL.md (e.g. missing
name) still dispatches, the valid skills appear, and a comment is posted on the issue noting the malformed file by path.
agent.skills.enabled: false skips the loader entirely (no walk, no prompt injection).
max_skills_in_prompt: 2 with three skills caps to two and logs which was dropped.
Why agentskills.io shape, not invented-here
Hermes (Nous Research) and a handful of other agent projects are converging on the agentskills.io front-matter shape. Matching it means a skill written for Symphony can be tried in another agent and vice versa, and we don't need to teach users a Symphony-specific format.
Test plan
Context
Today every Codex session that Symphony dispatches starts cold — no recall of how this repo solves common task patterns. Maintainers solve the same shape of problem repeatedly (add a migration, wire a new endpoint, fix a flaky test in package X) and that knowledge lives only in human memory or scattered docs.
This issue adds a skills system: repo-scoped reusable procedural recipes that get loaded into the agent's system prompt before each dispatch. Layout is intentionally compatible with the agentskills.io open standard so skills authored for one agent ecosystem work in another.
Scope: human-authored skills only in this issue. Agent-authored skills (the agent writes its own skill on successful completion) is a follow-up.
Design
File layout
Per-repo skills live under the repo's
.symphony/skills/directory:Skills are checked into git alongside code so they version with the repo and code review applies.
SKILL.md format (agentskills.io-compatible)
The front matter is small and stable:
name,description,when_to_use(a one-liner that helps the agent decide if this skill applies). Body is free-form markdown.Loading & prompt injection
.symphony/skills/*/SKILL.mdin the workspace, validates front matter, and produces a[name, description, when_to_use, body_path]index.## Available skillsblock in the system prompt envelope. Each skill is listed asname — when_to_use. The agent decides which to read and reads bodies on demand via the existing file-read tool — bodies are not preloaded (keeps the prompt small even with many skills).Config schema
Add to
WORKFLOW.md:Files to touch
lib/symphony_elixir/skills/loader.ex— new module. Walks the skills dir, parses front matter, returns{:ok, [%Skill{}]}or{:error, [%ValidationError{}]}.lib/symphony_elixir/agent_runner.ex— call the loader before dispatch; inject the## Available skillsblock into the system prompt envelope.lib/symphony_elixir/config/schema.ex— addagent.skillsblock + validations.test/symphony_elixir/skills/loader_test.exs— new test module.test/symphony_elixir/agent_runner_skills_test.exs— integration: skills index appears in the assembled prompt; bad SKILL.md surfaces an error comment.Acceptance
.symphony/skills/directory dispatches exactly like today (zero behavior change when skills enabled).## Available skillsblock (name + when_to_use only).name) still dispatches, the valid skills appear, and a comment is posted on the issue noting the malformed file by path.agent.skills.enabled: falseskips the loader entirely (no walk, no prompt injection).max_skills_in_prompt: 2with three skills caps to two and logs which was dropped.Why agentskills.io shape, not invented-here
Hermes (Nous Research) and a handful of other agent projects are converging on the agentskills.io front-matter shape. Matching it means a skill written for Symphony can be tried in another agent and vice versa, and we don't need to teach users a Symphony-specific format.
Test plan
make -C elixir allclean.## Available skillsblock when skills exist.