Skip to content

feat(skills): repo-scoped procedural memory loaded into agent prompt #87

@corylanou

Description

@corylanou

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

  • make -C elixir all clean.
  • Loader unit tests cover: empty dir, well-formed, missing front matter, duplicate name, oversized count.
  • Agent-runner integration test asserts the assembled prompt contains the ## Available skills block when skills exist.
  • Dogfood: author one real skill for this repo (e.g. "add a new tracker adapter"), confirm Codex picks it up on a relevant issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions