From d1837fc113ec0af3e8b1a59c863f7882d90b9f55 Mon Sep 17 00:00:00 2001 From: m3tam3re Date: Mon, 11 May 2026 18:49:26 +0200 Subject: [PATCH] refactor: mkOpencodeSkills -> mkSkills --- .gitignore | 3 +- .sisyphus/evidence/task-21-e2e.txt | 2 +- .../harness-agnostic-migration/learnings.md | 49 ++++++- .sisyphus/plans/harness-agnostic-migration.md | 120 +++++++++++------- AGENTS.md | 11 +- README.md | 59 ++++----- flake.nix | 6 +- 7 files changed, 157 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index ac20f11..efd2102 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ .direnv/ result -.pi* +.pi/ +.sisyphus/ diff --git a/.sisyphus/evidence/task-21-e2e.txt b/.sisyphus/evidence/task-21-e2e.txt index bfcf8f5..a98c19a 100644 --- a/.sisyphus/evidence/task-21-e2e.txt +++ b/.sisyphus/evidence/task-21-e2e.txt @@ -19,7 +19,7 @@ PASS: 6 .md files in .claude/agents/ + settings.json with permission DSL PASS: AGENTS.md + SYSTEM.md, SYSTEM.md byte-identical to chiron prompt --- 7. Skills composition --- -PASS: 18 skills in linkFarm output, mkOpencodeSkills unchanged +PASS: 18 skills in linkFarm output, mkSkills unchanged --- 8. Backward-compat bridge --- PASS: agentsJson output matches golden file (zero diff) diff --git a/.sisyphus/notepads/harness-agnostic-migration/learnings.md b/.sisyphus/notepads/harness-agnostic-migration/learnings.md index 7e94f6b..069e721 100644 --- a/.sisyphus/notepads/harness-agnostic-migration/learnings.md +++ b/.sisyphus/notepads/harness-agnostic-migration/learnings.md @@ -1,13 +1,14 @@ # Learnings ## [2026-04-10] Session Initialized + - Plan: harness-agnostic-migration (21 tasks + 4 final) - AGENTS repo: /home/m3tam3re/p/AI/AGENTS - nixpkgs repo: /home/m3tam3re/p/NIX/nixpkgs - TOML chosen as canonical format (builtins.fromTOML, no IFD) - Renderers belong in nixpkgs, not AGENTS repo - 6 agents: chiron, chiron-forge, hermes, athena, apollo, calliope -- OpenCode: file-based agents (.opencode/agent/*.md) NOT config.json embedding +- OpenCode: file-based agents (.opencode/agent/\*.md) NOT config.json embedding - Pi: no subagents — renders AGENTS.md + SYSTEM.md only - Claude Code: name must be [a-z0-9-]+ (slugified) - No model in agent.toml (per-machine via home-manager) @@ -15,19 +16,23 @@ - No YAML files as canonical source - Permission model: two-level — intent (allow/deny/ask) + rules array "pattern:action" - mkOpencodeRules → mkCodingRules (backward-compat alias) -- lib.mkOpencodeSkills stays unchanged +- lib.mkSkills stays unchanged + ## [2026-04-10] Task 1: Capture Golden File Baseline ### Golden File Created + - **Path**: `.sisyphus/evidence/agents-golden.json` - **Method**: `jq --sort-keys . agents/agents.json` - **Status**: ✓ Valid JSON, parseable, verified ### Agent Count + - **Total**: 6 agents - **Verification**: `jq 'keys | length'` → 6 ✓ ### Agent Names (Alphabetically Sorted) + 1. Apollo (Knowledge Management) — subagent, private knowledge specialist 2. Athena (Researcher) — subagent, work knowledge specialist 3. Calliope (Writer) — subagent, writing specialist @@ -36,7 +41,9 @@ 6. Hermes (Communication) — subagent, communication specialist ### Agent Object Structure + Every agent has 5 top-level keys: + - `description` (string) — agent purpose and capabilities - `mode` (string) — "primary" or "subagent" - `model` (string) — LLM model ID (all use "zai-coding-plan/glm-5") @@ -44,7 +51,9 @@ Every agent has 5 top-level keys: - `permission` (object) — capability matrix with granular controls ### Permission Structure + All agents have 6 permission categories: + - `question` → "allow" | "deny" | "ask" - `webfetch` → "allow" | "deny" | "ask" - `websearch` → "allow" | "deny" | "ask" (not all agents) @@ -53,10 +62,12 @@ All agents have 6 permission categories: - `external_directory` → nested rules (allow/deny per path pattern) ### Baseline Purpose + This golden file serves as the **canonical reference** for backward-compat verification in Task 8. It will be compared against output from the harness-agnostic bridge to ensure config integrity. ### Next Steps + - Task 8 will generate a comparable JSON from the bridge - Diff will be computed: `jq --sort-keys . bridge_output.json > bridge-output.json && diff agents-golden.json bridge-output.json` - Any structural or content changes will be flagged @@ -66,12 +77,15 @@ It will be compared against output from the harness-agnostic bridge to ensure co **Result: ✅ PASS** ### Test Execution + - Full Chiron-Forge TOML (16 lines, 5 permission sections, 15 bash rules, 4 external_directory rules): **PARSED SUCCESSFULLY** - Minimal TOML (2 lines, name + description only): **PARSED SUCCESSFULLY** - Parser: `nix eval --impure --expr 'builtins.fromTOML (builtins.readFile )' --json` ### Glob Patterns Verified + All complex patterns preserved exactly: + - `rm -rf *` → intact (wildcard in rule) - `git reset --hard*` → intact (pattern suffix) - `git push*` → intact (pattern suffix) @@ -83,25 +97,31 @@ All complex patterns preserved exactly: - `/tmp/**` → intact (absolute + recursive) ### Special Handling + - TOML arrays of strings work perfectly for `rules` list - Two-level structure (`intent` + `rules`) maps cleanly from JSON nested objects - No datetime fields used (confirmed limitation is not a blocker for permissions schema) - No multi-line inline tables needed (flat key-value structure only) ### Conclusion + **✅ TOML is suitable for agent permission config.** The proposed two-level model (`intent = "allow"|"deny"|"ask"` + `rules = [...]` array) is: + - **Parseable**: `builtins.fromTOML` handles it perfectly with `--impure` flag - **Pattern-safe**: All glob patterns (wildcards, recursion, flags) preserved exactly - **Backward-compatible**: Maps cleanly from existing JSON nested object format ### Evidence Files + - `/home/m3tam3re/p/AI/AGENTS/.sisyphus/evidence/task-2-toml-spike.json` (full Chiron-Forge parsed result) - `/home/m3tam3re/p/AI/AGENTS/.sisyphus/evidence/task-2-toml-minimal.json` (minimal test parsed result) ### Next Steps + No workarounds needed. Ready to implement full harness with TOML permission loader. ## [2026-04-10] Task 3: Canonical Schema Designed + - SCHEMA.md created at agents/SCHEMA.md - Required fields: name, description - Optional: display_name, mode, tags, max_turns, skills, context, rules @@ -115,21 +135,25 @@ No workarounds needed. Ready to implement full harness with TOML permission load ## [2026-04-10] Task 4: OpenCode File-Based Agent Format ### File Location + - **Per-project**: `.opencode/agents/` - **Global**: `~/.config/opencode/agents/` - Per-project agents override global agents with same name ### Agent Naming + - **Filename determines agent name** — no `name` field in frontmatter - Example: `review.md` → agent named `review` - Naming convention: `[a-z0-9-]+` (lowercase, hyphens) ### YAML Frontmatter Structure + - **Required**: `description` (string) - **Optional**: `mode` (`primary`|`subagent`|`all`), `model`, `temperature`, `top_p`, `steps`, `disable`, `hidden`, `color`, `permission`, `task` - Provider-specific fields pass through to LLM (e.g., `reasoningEffort` for OpenAI) ### Permission Format in Markdown + ```yaml permission: edit: @@ -146,46 +170,55 @@ permission: "*": ask "~/p/**": allow ``` + - Actions: `allow` | `ask` | `deny` - Nested rules support glob patterns (`*`, `**`, wildcards) - Last matching rule wins ### Mode Field Values + - `primary` — available via Tab switching - `subagent` — invoked via @mention or by other agents - `all` — flexible, can be used both ways ### System Prompt Delivery + - Markdown body (after frontmatter) IS the system prompt - No `{file:...}` syntax in markdown (unlike JSON config) - Direct markdown content → sent to LLM ### Default Behaviors + - `mode` → `all` (if omitted) - `model` → global config (primary agents) or parent's model (subagents) - `temperature` → model-specific default (0 for most, 0.55 for Qwen) - `permission` → full access (if omitted, all tools enabled) ### Interaction with config.json + - **Both** JSON and markdown agents are loaded - Markdown agents **override** JSON agents with same name - No conflict; complementary ### KEY ADVANTAGE: Prompt Changes Don't Require home-manager switch + - File changes → OpenCode reloads on next startup - NO home-manager switch needed - This is the primary motivation for file-based migration ### Limitations + - **No subdirectories**: only root level of `.opencode/agents/` scanned - **No name field**: filename is authoritative - **Filename must be valid**: [a-z0-9-]+ convention ### Evidence File + - `/home/m3tam3re/p/AI/AGENTS/.sisyphus/evidence/task-4-opencode-agent-format.md` - Complete spec with examples, frontmatter reference, permission format, YAML/JSON comparison ### Confirmed Answers + - Directory: `agents/` (both global and per-project) ✅ - File naming: Filename determines agent name ✅ - Required fields: `description` only ✅ @@ -196,13 +229,14 @@ permission: - Frontmatter needs `name` field: **NO** ✅ ### Sources + - https://opencode.ai/docs/agents (official documentation) - /home/m3tam3re/p/NIX/nixpkgs/modules/home-manager/coding/opencode.nix (current deployment) - /home/m3tam3re/p/AI/AGENTS/agents/agents.json (current 6 agents) - /home/m3tam3re/p/AI/AGENTS/AGENTS.md (repo documentation) - ## [2026-04-10] Task 4: Key Finding — OpenCode Permission Rule Precedence + - OpenCode uses LAST-MATCHING-RULE-WINS (not first-match!) - This matters for renderer: when translating `rules[]` array, order must be preserved - The wildcard `"*"` rule becomes the fallback (keep it first in YAML output, others after) @@ -214,18 +248,22 @@ permission: - `task` permission controls which subagents can be invoked (glob patterns) ## [2026-04-10] Task 4: OpenCode Permission YAML Format + The granular format is nested YAML objects, NOT a rule array: + ```yaml permission: bash: - "*": ask # This is the intent/default - "git status*": allow # These are the rules + "*": ask # This is the intent/default + "git status*": allow # These are the rules "git push*": deny ``` + The renderer must convert from canonical `intent + rules[]` format to this nested YAML format. The `"*"` key always goes FIRST (as the fallback), then specific rules after it. ## [2026-04-10] Task 5: All 6 agent.toml Files Created + - Directories: agents/{chiron,chiron-forge,hermes,athena,apollo,calliope}/ - Each has: agent.toml + system-prompt.md - All TOML parse: YES (6/6 verified via `nix eval --impure`) @@ -243,6 +281,7 @@ The `"*"` key always goes FIRST (as the fallback), then specific rules after it. - No model field, no prompt field per schema exclusion rules ## [2026-04-10] Task 6: loadAgents + agentsJson Bridge Complete + - Fix applied: description = agent.description + "." (SCHEMA.md has no trailing period; golden file does) - All 6 agents load correctly via lib.loadAgents - agentsJson bridge matches golden file exactly (zero diff) diff --git a/.sisyphus/plans/harness-agnostic-migration.md b/.sisyphus/plans/harness-agnostic-migration.md index 10f30ff..4ac67f5 100644 --- a/.sisyphus/plans/harness-agnostic-migration.md +++ b/.sisyphus/plans/harness-agnostic-migration.md @@ -3,14 +3,15 @@ ## TL;DR > **Quick Summary**: Migrate AGENTS repo from OpenCode-specific agents.json to a tool-agnostic canonical format (agent.toml + system-prompt.md per agent). Build Nix rendering pipeline in m3ta-nixpkgs that generates tool-specific configs for OpenCode, Claude Code, and Pi. Support system-level (home-manager) and project-level (flake.nix + direnv). -> +> > **Deliverables**: +> > - 6 canonical agent definitions in AGENTS repo (TOML + Markdown) > - 3 tool renderers in m3ta-nixpkgs (OpenCode, Claude Code, Pi) > - Home-manager modules per tool replacing current opencode.nix > - Project-level lib functions for flake.nix + direnv usage > - Backward-compatible bridge during migration -> +> > **Estimated Effort**: Large > **Parallel Execution**: YES — 4 waves > **Critical Path**: TOML spike → canonical agents → lib/agents.nix → per-tool HM modules → golden file verification @@ -20,10 +21,13 @@ ## Context ### Original Request + Restructure AGENTS repo to be harness-agnostic so the same agent definitions, skills, prompts work across OpenCode, Claude Code, Codex, Pi, and future coding agents. Build corresponding Nix infrastructure in m3ta-nixpkgs for system-level and project-level consumption. ### Interview Summary + **Key Discussions**: + - YAML rejected for canonical format — TOML chosen (native `builtins.fromTOML`, no IFD) - Renderers belong in m3ta-nixpkgs, not AGENTS repo (AGENTS stays pure data) - OpenCode + Claude Code + Pi renderers now; Codex/Aider later on demand @@ -35,6 +39,7 @@ Restructure AGENTS repo to be harness-agnostic so the same agent definitions, sk - Project-level: lib functions returning derivations, usable via shellHook in devShells **Research Findings**: + - **OpenCode**: Now supports file-based agents (`.opencode/agent/*.md` with YAML frontmatter) — modern path, avoids config.json embedding - **Claude Code**: Subagents require `name` (kebab-case) + `description` as mandatory frontmatter fields - **Pi**: No subagent concept. Uses AGENTS.md/CLAUDE.md for instructions, SYSTEM.md for prompt override, same SKILL.md format as OpenCode @@ -43,7 +48,9 @@ Restructure AGENTS repo to be harness-agnostic so the same agent definitions, sk - **TOML in Nix**: `builtins.fromTOML` supports TOML 1.0.0 strict. No datetime fields, no multi-line inline tables. ### Metis Review + **Identified Gaps** (addressed): + - **oh-my-opencode.json ownership**: Non-agent OpenCode config stays in slimmed opencode.nix (not in agents.nix) - **Pi has no subagents**: Pi renderer produces AGENTS.md + SYSTEM.md from primary agent only. Subagents skipped. - **Claude Code name format**: Renderer must slugify to `[a-z0-9-]+` @@ -59,9 +66,11 @@ Restructure AGENTS repo to be harness-agnostic so the same agent definitions, sk ## Work Objectives ### Core Objective + Transform the AGENTS repository into a tool-agnostic data repository and build a Nix rendering pipeline that generates tool-specific configurations for multiple coding agents. ### Concrete Deliverables + - `AGENTS/agents/{chiron,chiron-forge,hermes,athena,apollo,calliope}/agent.toml` — 6 canonical agent definitions - `AGENTS/agents/{name}/system-prompt.md` — 6 system prompts (byte-identical to current .txt files) - `AGENTS/flake.nix` — Updated with `lib.loadAgents` and backward-compat `lib.agentsJson` @@ -73,6 +82,7 @@ Transform the AGENTS repository into a tool-agnostic data repository and build a - `nixpkgs/lib/coding-rules.nix` — Renamed from opencode-rules.nix with backward-compat alias ### Definition of Done + - [ ] `nix flake check` passes on both repos - [ ] Rendered OpenCode agent output is semantically equivalent to current agents.json (golden file diff = 0) - [ ] All 6 agents parse successfully via `builtins.fromTOML` @@ -80,9 +90,10 @@ Transform the AGENTS repository into a tool-agnostic data repository and build a - [ ] Pi renderer produces valid AGENTS.md + optional settings.json - [ ] System prompt content is byte-identical to current .txt files - [ ] `nix fmt` (alejandra) produces no changes -- [ ] `lib.mkOpencodeSkills` still works unchanged +- [ ] `lib.mkSkills` still works unchanged ### Must Have + - All 6 agents in canonical TOML format with system-prompt.md - OpenCode renderer producing `.opencode/agent/*.md` file-based agents - Claude Code renderer producing `.claude/agents/*.md` with valid YAML frontmatter @@ -92,13 +103,14 @@ Transform the AGENTS repository into a tool-agnostic data repository and build a - Project-level `renderForTool` lib function for flake.nix + direnv ### Must NOT Have (Guardrails) + - No YAML files as canonical source (TOML only — no IFD) - No renderer code in AGENTS repo (renderers live in nixpkgs) - No Codex or Aider renderers (design for extensibility, implement only 3) - No MCP configuration in agent.toml (MCP is tool-specific infrastructure) - No prompt content changes during migration (byte-identical rename only) - No skills/rules/context migration in this plan (separate concern) -- No `mkOpencodeSkills` changes (stays as-is) +- No `mkSkills` changes (stays as-is) - No datetime fields in TOML schema (requires experimental Nix flag) - No multi-line inline tables in TOML (not supported by Nix's TOML 1.0.0) - No generic permission translation DSL (each renderer hard-codes its own mapping) @@ -111,11 +123,13 @@ Transform the AGENTS repository into a tool-agnostic data repository and build a > **ZERO HUMAN INTERVENTION** — ALL verification is agent-executed. No exceptions. ### Test Decision + - **Infrastructure exists**: YES — Nix evaluation + alejandra formatter - **Automated tests**: Nix eval comparison (golden file diff) - **Framework**: `nix eval`, `jq --sort-keys`, `diff`, `python3` for YAML validation ### QA Policy + Every task MUST include agent-executed QA scenarios. Evidence saved to `.sisyphus/evidence/task-{N}-{scenario-slug}.{ext}`. @@ -170,29 +184,29 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): ### Dependency Matrix -| Task | Depends On | Blocks | Wave | -|------|-----------|--------|------| -| 1 | — | 8, 21 | 1 | -| 2 | — | 3, 5 | 1 | -| 3 | 2 | 5, 6, 7 | 1 | -| 4 | — | 9, 12 | 1 | -| 5 | 2, 3 | 6, 8, 9, 10, 11 | 2 | -| 6 | 3, 5 | 8, 17 | 2 | -| 7 | 3 | 9, 10, 11, 12, 13, 14, 17 | 2 | -| 8 | 1, 5, 6 | 20 | 2 | -| 9 | 4, 5, 7 | 12 | 3 | -| 10 | 5, 7 | 13 | 3 | -| 11 | 5, 7 | 14 | 3 | -| 12 | 9 | 18, 21 | 3 | -| 13 | 10 | 18, 21 | 3 | -| 14 | 11 | 18, 21 | 3 | -| 15 | — | 18 | 3 | -| 16 | — | 18 | 3 | -| 17 | 6, 7 | 21 | 4 | -| 18 | 12, 13, 14, 15, 16 | 21 | 4 | -| 19 | 5 | — | 4 | -| 20 | 8 | — | 4 | -| 21 | 1, 12, 13, 14, 17, 18 | F1-F4 | 4 | +| Task | Depends On | Blocks | Wave | +| ---- | --------------------- | ------------------------- | ---- | +| 1 | — | 8, 21 | 1 | +| 2 | — | 3, 5 | 1 | +| 3 | 2 | 5, 6, 7 | 1 | +| 4 | — | 9, 12 | 1 | +| 5 | 2, 3 | 6, 8, 9, 10, 11 | 2 | +| 6 | 3, 5 | 8, 17 | 2 | +| 7 | 3 | 9, 10, 11, 12, 13, 14, 17 | 2 | +| 8 | 1, 5, 6 | 20 | 2 | +| 9 | 4, 5, 7 | 12 | 3 | +| 10 | 5, 7 | 13 | 3 | +| 11 | 5, 7 | 14 | 3 | +| 12 | 9 | 18, 21 | 3 | +| 13 | 10 | 18, 21 | 3 | +| 14 | 11 | 18, 21 | 3 | +| 15 | — | 18 | 3 | +| 16 | — | 18 | 3 | +| 17 | 6, 7 | 21 | 4 | +| 18 | 12, 13, 14, 15, 16 | 21 | 4 | +| 19 | 5 | — | 4 | +| 20 | 8 | — | 4 | +| 21 | 1, 12, 13, 14, 17, 18 | F1-F4 | 4 | ### Agent Dispatch Summary @@ -564,11 +578,11 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): - Maps canonical permission format back to OpenCode's nested objects - Maps `systemPrompt` back to `"prompt": "{file:./prompts/chiron.txt}"` format (or inline) - Adds `model` field from a configurable default (since agent.toml has no model) - - Keep ALL existing exports unchanged: `lib.mkOpencodeSkills`, `packages.skills-runtime`, `devShells.default` + - Keep ALL existing exports unchanged: `lib.mkSkills`, `packages.skills-runtime`, `devShells.default` - `lib` export must be system-independent (no `forAllSystems` wrapper — pure functions) **Must NOT do**: - - Change mkOpencodeSkills + - Change mkSkills - Remove any existing exports - Add renderer logic (that goes in nixpkgs) - Hardcode machine-specific model assignments @@ -585,7 +599,7 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): **References**: - `flake.nix` — Current AGENTS flake (188 lines). Keep structure, add to `lib` section. - - `flake.nix:52-123` — `lib.mkOpencodeSkills` pattern (linkFarm approach) + - `flake.nix:52-123` — `lib.mkSkills` pattern (linkFarm approach) - `agents/agents.json` — Target output shape for agentsJson bridge function - `agents/SCHEMA.md` (from Task 3) — Canonical schema definition @@ -636,7 +650,7 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): - Returns the canonical attrset (or wraps/validates it) - Stub functions for renderers (to be implemented in Tasks 9-11): - `renderForOpencode { canonical; modelOverrides ? {}; }` → derivation placeholder - - `renderForClaudeCode { canonical; modelOverrides ? {}; }` → derivation placeholder + - `renderForClaudeCode { canonical; modelOverrides ? {}; }` → derivation placeholder - `renderForPi { canonical; }` → derivation placeholder - `renderForTool { agentsInput; tool; modelOverrides ? {}; }` → dispatcher - Wire into `lib/default.nix` alongside existing `ports` and `opencode-rules` @@ -917,17 +931,21 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): - Skill symlinks — Pi uses same SKILL.md dirs at `~/.pi/agent/skills/` or `.agents/skills/` - Only PRIMARY agents render to SYSTEM.md. Subagent prompts get embedded as sections in AGENTS.md. - Generate AGENTS.md with sections per agent: + ```markdown # Agent Instructions - + ## Chiron (Assistant) + Primary assistant for read-only analysis... - + ## Available Specialists + - Hermes: Work communication (Basecamp, Outlook, Teams) - Athena: Work knowledge (Outline wiki) - ... + ... ``` + - Pi's tools config: `--tools read,bash,edit,write` maps from canonical permissions - Handle: Pi has no permission granularity — only tool enable/disable @@ -1001,7 +1019,7 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): - Config (mkIf enabled): - Call `lib.agents.renderForOpencode { canonical; modelOverrides; }` to get rendered derivation - Symlink rendered `.opencode/agent/` dir via `xdg.configFile` or `home.file` - - Symlink skills via existing `mkOpencodeSkills` (if agentsInput set) + - Symlink skills via existing `mkSkills` (if agentsInput set) - Symlink context/ and commands/ from AGENTS input - Create `modules/home-manager/coding/agents/default.nix` aggregator importing opencode.nix, claude-code.nix, pi.nix - Update `modules/home-manager/coding/default.nix` to import `./agents` subdir @@ -1476,7 +1494,7 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): --- -- [ ] 20. Remove Legacy agents.json + prompts/*.txt from AGENTS Repo +- [ ] 20. Remove Legacy agents.json + prompts/\*.txt from AGENTS Repo **What to do**: - ONLY after Task 8 confirms backward-compat bridge works @@ -1543,7 +1561,7 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): - Claude Code: rendered .claude/agents/ contains 6 .md files with valid YAML + required fields - Pi: rendered output contains AGENTS.md + SYSTEM.md 3. Project-level: test `renderForTool` for each tool - 4. Skills: verify `mkOpencodeSkills` still produces correct output + 4. Skills: verify `mkSkills` still produces correct output 5. Formatting: `nix fmt --check` on both repos 6. Flake checks: `nix flake check` on both repos - Document all results in evidence files @@ -1587,9 +1605,9 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): Scenario: Skills composition unchanged Tool: Bash - Preconditions: mkOpencodeSkills not modified + Preconditions: mkSkills not modified Steps: - 1. nix eval --raw '/home/m3tam3re/p/AI/AGENTS#lib.mkOpencodeSkills { pkgs = import {}; customSkills = ./skills; }' + 1. nix eval --raw '/home/m3tam3re/p/AI/AGENTS#lib.mkSkills { pkgs = import {}; customSkills = ./skills; }' 2. List contents of output directory 3. Assert contains all active skill directories Expected Result: Skills output identical to before migration @@ -1608,32 +1626,34 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): > **Do NOT auto-proceed after verification. Wait for user's explicit approval before marking work complete.** - [ ] F1. **Plan Compliance Audit** — `oracle` - Read the plan end-to-end. For each "Must Have": verify implementation exists (read file, nix eval, diff). For each "Must NOT Have": search codebase for forbidden patterns — reject with file:line if found. Check evidence files exist in .sisyphus/evidence/. Compare deliverables against plan. - Output: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT` + Read the plan end-to-end. For each "Must Have": verify implementation exists (read file, nix eval, diff). For each "Must NOT Have": search codebase for forbidden patterns — reject with file:line if found. Check evidence files exist in .sisyphus/evidence/. Compare deliverables against plan. + Output: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT` - [ ] F2. **Code Quality Review** — `unspecified-high` - Run `nix flake check` on both repos. Run `nix fmt --check` (alejandra). Review all .nix files for: unused variables, hardcoded paths, missing mkIf guards, type errors. Check TOML files parse without error. Verify no AI slop: no excessive comments, no placeholder values, no TODO markers in production code. - Output: `Flake Check [PASS/FAIL] | Format [PASS/FAIL] | Nix Quality [N clean/N issues] | TOML Parse [N/N] | VERDICT` + Run `nix flake check` on both repos. Run `nix fmt --check` (alejandra). Review all .nix files for: unused variables, hardcoded paths, missing mkIf guards, type errors. Check TOML files parse without error. Verify no AI slop: no excessive comments, no placeholder values, no TODO markers in production code. + Output: `Flake Check [PASS/FAIL] | Format [PASS/FAIL] | Nix Quality [N clean/N issues] | TOML Parse [N/N] | VERDICT` - [ ] F3. **Real Manual QA** — `unspecified-high` - Execute EVERY QA scenario from EVERY task. Capture evidence. Test cross-task integration: AGENTS repo `lib.loadAgents` → nixpkgs `loadCanonical` → each renderer → home-manager module output. Test edge cases: agent with many permission rules, agent with minimal config, model override. Save to `.sisyphus/evidence/final-qa/`. - Output: `Scenarios [N/N pass] | Integration [N/N] | Edge Cases [N tested] | VERDICT` + Execute EVERY QA scenario from EVERY task. Capture evidence. Test cross-task integration: AGENTS repo `lib.loadAgents` → nixpkgs `loadCanonical` → each renderer → home-manager module output. Test edge cases: agent with many permission rules, agent with minimal config, model override. Save to `.sisyphus/evidence/final-qa/`. + Output: `Scenarios [N/N pass] | Integration [N/N] | Edge Cases [N tested] | VERDICT` - [ ] F4. **Scope Fidelity Check** — `deep` - For each task: read "What to do", read actual changes. Verify 1:1 — everything in spec was built (no missing), nothing beyond spec was built (no creep). Check "Must NOT do" compliance. Detect: skills/rules changes (forbidden), MCP in agent.toml (forbidden), Codex/Aider renderers (forbidden), prompt content changes (forbidden). Flag unaccounted changes. - Output: `Tasks [N/N compliant] | Scope [CLEAN/N issues] | Forbidden Patterns [CLEAN/N found] | VERDICT` + For each task: read "What to do", read actual changes. Verify 1:1 — everything in spec was built (no missing), nothing beyond spec was built (no creep). Check "Must NOT do" compliance. Detect: skills/rules changes (forbidden), MCP in agent.toml (forbidden), Codex/Aider renderers (forbidden), prompt content changes (forbidden). Flag unaccounted changes. + Output: `Tasks [N/N compliant] | Scope [CLEAN/N issues] | Forbidden Patterns [CLEAN/N found] | VERDICT` --- ## Commit Strategy ### AGENTS Repo -- **Commit A1**: `feat: add canonical agent.toml definitions for all 6 agents` — agents/*/agent.toml + system-prompt.md + +- **Commit A1**: `feat: add canonical agent.toml definitions for all 6 agents` — agents/\*/agent.toml + system-prompt.md - **Commit A2**: `feat: export loadAgents and backward-compat agentsJson from flake` — flake.nix updates - **Commit A3** (after nixpkgs consuming): `chore: remove legacy agents.json and prompts/*.txt` - **Commit A4**: `docs: update AGENTS.md for canonical agent format` ### m3ta-nixpkgs + - **Commit N1**: `feat(lib): add agents.nix with loadCanonical and 3 tool renderers` - **Commit N2**: `feat(hm): add per-tool agent HM sub-modules (opencode, claude-code, pi)` - **Commit N3**: `refactor(hm): slim opencode.nix to non-agent config only` @@ -1646,6 +1666,7 @@ Wave FINAL (After ALL tasks — 4 parallel reviews, then user okay): ## Success Criteria ### Verification Commands + ```bash # AGENTS repo: all TOML files parse for f in agents/*/agent.toml; do nix eval --expr "builtins.fromTOML (builtins.readFile ./$f)" --json > /dev/null; done @@ -1667,6 +1688,7 @@ diff <(nix eval --json '.#homeConfigurations.sk.config.xdg.configFile."opencode/ ``` ### Final Checklist + - [ ] All 6 agents have both `agent.toml` and `system-prompt.md` - [ ] All "Must Have" items present and verified - [ ] All "Must NOT Have" items absent @@ -1675,5 +1697,5 @@ diff <(nix eval --json '.#homeConfigurations.sk.config.xdg.configFile."opencode/ - [ ] Golden file comparison passes (OpenCode output unchanged) - [ ] Claude Code frontmatter valid (name + description present, kebab-case) - [ ] Pi output valid (AGENTS.md exists, optional JSON valid) -- [ ] `lib.mkOpencodeSkills` unchanged and functional +- [ ] `lib.mkSkills` unchanged and functional - [ ] Prompt content byte-identical to originals diff --git a/AGENTS.md b/AGENTS.md index 4620ff3..852d4a2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -265,7 +265,7 @@ agents = { **Exports:** - `lib.loadAgents` — loads all canonical `agents/*/agent.toml` + `system-prompt.md` into an attrset -- `lib.mkOpencodeSkills` — compose custom + external [skills.sh](https://skills.sh) skills into one directory +- `lib.mkSkills` — compose custom + external [skills.sh](https://skills.sh) skills into one directory - `lib.agentsJson` — backward-compat bridge producing legacy agents.json shape (temporary, will be removed) - `packages.skills-runtime` — composable runtime with all skill dependencies - `devShells.default` — dev environment for working with skills @@ -273,7 +273,7 @@ agents = { **Mapping** (via home-manager + m3ta-nixpkgs renderers): - `agents/` → rendered per-tool via `lib.agents.renderForTool` in m3ta-nixpkgs -- `skills/` → composed via `mkOpencodeSkills` (custom + external merged) +- `skills/` → composed via `mkSkills` (custom + external merged) - `context/`, `commands/` → symlinks - Agent changes via file-based agents: visible on next tool restart (no `home-manager switch` needed for prompt changes) @@ -283,7 +283,7 @@ This repo supports composing skills from external [skills.sh](https://skills.sh) alongside custom skills. External repos follow the [Agent Skills](https://agentskills.io) standard (same `SKILL.md` format). -**`lib.mkOpencodeSkills` parameters:** +**`lib.mkSkills` parameters:** - `pkgs` (required) — nixpkgs package set - `customSkills` (optional) — path to custom skills directory (e.g., `"${inputs.agents}/skills"`) @@ -303,7 +303,7 @@ inputs = { }; xdg.configFile."opencode/skills".source = - inputs.agents.lib.mkOpencodeSkills { + inputs.agents.lib.mkSkills { pkgs = nixpkgs.legacyPackages.${system}; customSkills = "${inputs.agents}/skills"; }; @@ -389,7 +389,7 @@ rmdir prompts/ # if empty # Delete the lib.agentsJson section from flake.nix ``` -After removing `lib.agentsJson`, update flake.nix to remove the bridge function. The `lib.loadAgents` and `lib.mkOpencodeSkills` exports remain. +After removing `lib.agentsJson`, update flake.nix to remove the bridge function. The `lib.loadAgents` and `lib.mkSkills` exports remain. ### Step 4: Verify @@ -462,6 +462,7 @@ coding.agents.gitIdentity = { ### Environment Variables When enabled, these are automatically set: + - `GIT_AUTHOR_NAME`, `GIT_AUTHOR_EMAIL` - `GIT_COMMITTER_NAME`, `GIT_COMMITTER_EMAIL` - `GIT_SSH_COMMAND` (for authenticated push) diff --git a/README.md b/README.md index 8ed9c4a..4fbd714 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ This repository is a **Nix flake** that exports: - **`devShells.default`** — development environment for working on skills (activated via direnv) - **`packages.skills-runtime`** — composable runtime with all skill script dependencies (Python packages + system tools) -- **`lib.mkOpencodeSkills`** — compose custom skills with external [skills.sh](https://skills.sh) skills into a single directory +- **`lib.mkSkills`** — compose custom skills with external [skills.sh](https://skills.sh) skills into a single directory **Consume in your system flake:** @@ -92,7 +92,7 @@ let in { # Skills — composed from custom + external sources xdg.configFile."opencode/skills".source = - inputs.agents.lib.mkOpencodeSkills { + inputs.agents.lib.mkSkills { inherit pkgs; customSkills = "${inputs.agents}/skills"; externalSkills = [ @@ -118,6 +118,7 @@ in { ``` > **Note**: If you don't use external skills, you can still use the simple form: +> > ```nix > xdg.configFile."opencode/skills".source = "${inputs.agents}/skills"; > ``` @@ -140,7 +141,7 @@ in { in { # Project-level skills (placed in .agents/skills/) ".agents/skills".source = - agents.lib.mkOpencodeSkills { + agents.lib.mkSkills { inherit pkgs; externalSkills = [ { src = skills-anthropic; selectSkills = [ "mcp-builder" ]; } @@ -256,40 +257,40 @@ python3 skills/skill-creator/scripts/quick_validate.py skills/my-skill-name ## 📚 Available Skills -| Skill | Purpose | Status | -| ------------------------------- | -------------------------------------------------------------- | --------------- | -| **agent-development** | Create and configure Opencode agents | ✅ Active | -| **brainstorming** | General-purpose ideation and strategic thinking | ✅ Active | -| **doc-translator** | Documentation translation to German/Czech with Outline publish | ✅ Active | -| **excalidraw** | Architecture diagrams from codebase analysis | ✅ Active | -| **obsidian** | Obsidian vault management via Local REST API | ✅ Active | -| **outline** | Outline wiki integration for team documentation | ✅ Active | -| **pdf** | PDF manipulation, extraction, creation, and forms | ✅ Active | -| **prompt-engineering-patterns** | Advanced prompt engineering techniques | ✅ Active | -| **qmd** | Knowledge retrieval and memory via Query Markup Documents | ✅ Active | -| **reflection** | Conversation analysis and skill improvement | ✅ Active | -| **skill-creator** | Guide for creating new Opencode skills | ✅ Active | -| **systematic-debugging** | Debugging methodology for bugs and test failures | ✅ Active | -| **xlsx** | Spreadsheet creation, editing, and analysis | ✅ Active | -| **mem0-memory** | Legacy memory skill (deprecated — use opencode-memory plugin) | ⚠️ Deprecated | +| Skill | Purpose | Status | +| ------------------------------- | -------------------------------------------------------------- | ------------- | +| **agent-development** | Create and configure Opencode agents | ✅ Active | +| **brainstorming** | General-purpose ideation and strategic thinking | ✅ Active | +| **doc-translator** | Documentation translation to German/Czech with Outline publish | ✅ Active | +| **excalidraw** | Architecture diagrams from codebase analysis | ✅ Active | +| **obsidian** | Obsidian vault management via Local REST API | ✅ Active | +| **outline** | Outline wiki integration for team documentation | ✅ Active | +| **pdf** | PDF manipulation, extraction, creation, and forms | ✅ Active | +| **prompt-engineering-patterns** | Advanced prompt engineering techniques | ✅ Active | +| **qmd** | Knowledge retrieval and memory via Query Markup Documents | ✅ Active | +| **reflection** | Conversation analysis and skill improvement | ✅ Active | +| **skill-creator** | Guide for creating new Opencode skills | ✅ Active | +| **systematic-debugging** | Debugging methodology for bugs and test failures | ✅ Active | +| **xlsx** | Spreadsheet creation, editing, and analysis | ✅ Active | +| **mem0-memory** | Legacy memory skill (deprecated — use opencode-memory plugin) | ⚠️ Deprecated | ## 🤖 AI Agents ### Primary Agents -| Agent | Mode | Purpose | -| -------------------------- | ------- | ---------------------------------------------------- | -| **Chiron (Assistant)** | primary | Read-only analysis, planning, and guidance | -| **Chiron Forge (Builder)** | primary | Full execution and task completion with safety | +| Agent | Mode | Purpose | +| -------------------------- | ------- | ---------------------------------------------- | +| **Chiron (Assistant)** | primary | Read-only analysis, planning, and guidance | +| **Chiron Forge (Builder)** | primary | Full execution and task completion with safety | ### Subagents (Specialists) -| Agent | Domain | Purpose | -| ------------------------------- | ----------------- | ------------------------------------------ | -| **Hermes (Communication)** | Communication | Basecamp, Outlook, MS Teams | -| **Athena (Researcher)** | Research | Outline wiki, documentation, knowledge | -| **Apollo (Knowledge Management)** | Private Knowledge | Obsidian vault, personal notes | -| **Calliope (Writer)** | Writing | Documentation, reports, prose | +| Agent | Domain | Purpose | +| --------------------------------- | ----------------- | -------------------------------------- | +| **Hermes (Communication)** | Communication | Basecamp, Outlook, MS Teams | +| **Athena (Researcher)** | Research | Outline wiki, documentation, knowledge | +| **Apollo (Knowledge Management)** | Private Knowledge | Obsidian vault, personal notes | +| **Calliope (Writer)** | Writing | Documentation, reports, prose | **Model**: All agents use `zai-coding-plan/glm-5`. **Configuration**: `agents/agents.json` + `prompts/*.txt` diff --git a/flake.nix b/flake.nix index fb3fe11..bfda3ed 100644 --- a/flake.nix +++ b/flake.nix @@ -19,7 +19,7 @@ # # Usage (home-manager): # xdg.configFile."opencode/skills".source = - # inputs.agents.lib.mkOpencodeSkills { + # inputs.agents.lib.mkSkills { # pkgs = nixpkgs.legacyPackages.${system}; # customSkills = "${inputs.agents}/skills"; # externalSkills = [ @@ -30,7 +30,7 @@ # # Usage (project flake — project-level skills): # ".agents/skills".source = - # inputs.agents.lib.mkOpencodeSkills { + # inputs.agents.lib.mkSkills { # pkgs = nixpkgs.legacyPackages.${system}; # externalSkills = [ # { src = inputs.skills-anthropic; selectSkills = [ "mcp-builder" ]; } @@ -50,7 +50,7 @@ # Custom skills always take priority over external ones. # Among external sources, earlier entries in the list take priority. - lib.mkOpencodeSkills = { + lib.mkSkills = { pkgs, customSkills ? null, externalSkills ? [],