feat: config with agents rework

This commit is contained in:
m3tm3re
2026-04-13 16:53:17 +02:00
parent a81e178856
commit ccca3dd9db
47 changed files with 5940 additions and 22 deletions

2568
.pi-lens/cache/jscpd.json vendored Normal file

File diff suppressed because it is too large Load Diff

3
.pi-lens/cache/jscpd.meta.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"timestamp": "2026-04-11T03:55:48.815Z"
}

9
.pi-lens/cache/knip.json vendored Normal file
View File

@@ -0,0 +1,9 @@
{
"success": false,
"issues": [],
"unusedExports": [],
"unusedFiles": [],
"unusedDeps": [],
"unlistedDeps": [],
"summary": "Failed to parse output"
}

3
.pi-lens/cache/knip.meta.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"timestamp": "2026-04-11T03:55:49.603Z"
}

View File

@@ -0,0 +1 @@
null

View File

@@ -0,0 +1,3 @@
{
"timestamp": "2026-04-11T04:23:19.016Z"
}

18
.pi-lens/cache/todo-baseline.json vendored Normal file
View File

@@ -0,0 +1,18 @@
{
"items": [
{
"type": "TODO",
"message": "Replace with the first main section based on chosen structure]",
"file": "skills/skill-creator/scripts/init_skill.py",
"line": 58,
"column": 4
},
{
"type": "TODO",
"message": "Add actual script logic here",
"file": "skills/skill-creator/scripts/init_skill.py",
"line": 120,
"column": 6
}
]
}

View File

@@ -0,0 +1,3 @@
{
"timestamp": "2026-04-11T04:22:20.339Z"
}

View File

@@ -0,0 +1,3 @@
{
"signature": "/home/m3tam3re/p/NIX/nixpkgs/modules/home-manager/coding/agents/claude-code.nix::📐 Cascade errors in 1 other file(s) — fix before finishing turn:\n<diagnostics file=\"/home/m3tam3re/p/NIX/nixpkgs/modules/home-manager/coding/agents/pi.nix\">\n line 205, col 10 code=sema-duplicated-attrname: duplicated attrname `file`\n</diagnostics>"
}

View File

@@ -0,0 +1,3 @@
{
"timestamp": "2026-04-11T03:32:45.214Z"
}

1
.pi-lens/cache/turn-end-findings.json vendored Normal file
View File

@@ -0,0 +1 @@
null

View File

@@ -0,0 +1,3 @@
{
"timestamp": "2026-04-11T03:33:08.875Z"
}

6
.pi-lens/turn-state.json Normal file
View File

@@ -0,0 +1,6 @@
{
"files": {},
"turnCycles": 0,
"maxCycles": 3,
"lastUpdated": "2026-04-11T03:55:49.605Z"
}

77
.sisyphus/boulder.json Normal file
View File

@@ -0,0 +1,77 @@
{
"active_plan": "/home/m3tam3re/p/AI/AGENTS/.sisyphus/plans/harness-agnostic-migration.md",
"started_at": "2026-04-10T13:53:14.227Z",
"session_ids": [
"ses_28877ce54ffepCBENqWBi0fQr4"
],
"session_origins": {
"ses_28877ce54ffepCBENqWBi0fQr4": "direct"
},
"plan_name": "harness-agnostic-migration",
"agent": "atlas",
"task_sessions": {
"todo:1": {
"task_key": "todo:1",
"task_label": "1",
"task_title": "Capture Golden File Baseline",
"session_id": "ses_28852d166ffea2zvkAFvqhH7OX",
"agent": "Sisyphus-Junior",
"category": "quick",
"updated_at": "2026-04-10T13:56:10.927Z"
},
"todo:3": {
"task_key": "todo:3",
"task_label": "3",
"task_title": "Design Canonical agent.toml Schema",
"session_id": "ses_288508bf9ffeDi2kwwOT95s78z",
"agent": "Sisyphus-Junior",
"category": "deep",
"updated_at": "2026-04-10T13:59:52.937Z"
},
"todo:5": {
"task_key": "todo:5",
"task_label": "5",
"task_title": "Create All 6 agent.toml + system-prompt.md Files",
"session_id": "ses_2884d3d77ffeP8WZCH8MXK02Hv",
"agent": "Sisyphus-Junior",
"category": "unspecified-high",
"updated_at": "2026-04-10T14:04:28.811Z"
},
"todo:6": {
"task_key": "todo:6",
"task_label": "6",
"task_title": "Update AGENTS flake.nix with loadAgents + agentsJson Bridge",
"session_id": "ses_28840426bffeLNACasCLDil1oX",
"agent": "Sisyphus-Junior",
"category": "deep",
"updated_at": "2026-04-10T14:21:02.937Z"
},
"todo:7": {
"task_key": "todo:7",
"task_label": "7",
"task_title": "Create lib/agents.nix in nixpkgs with loadCanonical",
"session_id": "ses_288254a44ffer60bcJY7yAKtqh",
"agent": "Sisyphus-Junior",
"category": "deep",
"updated_at": "2026-04-10T14:46:28.743Z"
},
"todo:9": {
"task_key": "todo:9",
"task_label": "9",
"task_title": "Implement OpenCode Renderer in lib/agents.nix",
"session_id": "ses_2881e8981ffe8ZZZjBOJ60wU5O",
"agent": "Sisyphus-Junior",
"category": "deep",
"updated_at": "2026-04-10T15:07:43.465Z"
},
"todo:10": {
"task_key": "todo:10",
"task_label": "10",
"task_title": "Implement Claude Code Renderer in lib/agents.nix",
"session_id": "ses_2880cbb8affe03hwPbOGZKEFDC",
"agent": "Sisyphus-Junior",
"category": "deep",
"updated_at": "2026-04-10T15:42:05.656Z"
}
}
}

View File

@@ -0,0 +1,173 @@
{
"Apollo (Knowledge Management)": {
"description": "Private knowledge specialist. Manages Obsidian vault, personal notes, and private knowledge graph.",
"mode": "subagent",
"model": "zai-coding-plan/glm-5",
"permission": {
"bash": {
"*": "ask",
"cat *": "allow"
},
"edit": {
"*": "allow",
"/run/agenix/**": "deny"
},
"external_directory": {
"*": "ask",
"/run/agenix/**": "allow",
"/tmp/**": "allow",
"~/.config/opencode/**": "allow",
"~/p/**": "allow"
},
"question": "allow"
},
"prompt": "{file:./prompts/apollo.txt}"
},
"Athena (Researcher)": {
"description": "Work knowledge specialist. Manages Outline wiki, documentation, and knowledge organization.",
"mode": "subagent",
"model": "zai-coding-plan/glm-5",
"permission": {
"bash": {
"*": "ask",
"cat *": "allow",
"grep *": "allow"
},
"edit": {
"*": "allow",
"/run/agenix/**": "deny"
},
"external_directory": {
"*": "ask",
"/run/agenix/**": "allow",
"/tmp/**": "allow",
"~/.config/opencode/**": "allow",
"~/p/**": "allow"
},
"question": "allow",
"webfetch": "allow",
"websearch": "allow"
},
"prompt": "{file:./prompts/athena.txt}"
},
"Calliope (Writer)": {
"description": "Writing specialist. Creates documentation, reports, meeting notes, and prose.",
"mode": "subagent",
"model": "zai-coding-plan/glm-5",
"permission": {
"bash": {
"*": "ask",
"cat *": "allow",
"wc *": "allow"
},
"edit": {
"*": "allow",
"/run/agenix/**": "deny"
},
"external_directory": {
"*": "ask",
"/run/agenix/**": "allow",
"/tmp/**": "allow",
"~/.config/opencode/**": "allow",
"~/p/**": "allow"
},
"question": "allow",
"webfetch": "allow"
},
"prompt": "{file:./prompts/calliope.txt}"
},
"Chiron (Assistant)": {
"description": "Personal AI assistant (Plan Mode). Read-only analysis, planning, and guidance.",
"mode": "primary",
"model": "zai-coding-plan/glm-5",
"permission": {
"bash": {
"*": "ask",
"bd *": "allow",
"cat *": "allow",
"echo *": "allow",
"git branch*": "allow",
"git diff*": "allow",
"git log*": "allow",
"git show*": "allow",
"git status*": "allow",
"grep *": "allow",
"head *": "allow",
"ls *": "allow",
"nix *": "allow",
"tail *": "allow",
"td *": "allow",
"wc *": "allow",
"which *": "allow"
},
"edit": "deny",
"external_directory": {
"*": "ask",
"/run/agenix/**": "allow",
"/tmp/**": "allow",
"~/.config/opencode/**": "allow",
"~/p/**": "allow"
},
"question": "allow",
"webfetch": "allow",
"websearch": "allow"
},
"prompt": "{file:./prompts/chiron.txt}"
},
"Chiron Forge (Builder)": {
"description": "Personal AI assistant (Build Mode). Full execution and task completion capabilities with safety prompts.",
"mode": "primary",
"model": "zai-coding-plan/glm-5",
"permission": {
"bash": {
"*": "allow",
"git push --force*": "deny",
"git push -f *": "deny",
"git push*": "ask",
"git reset --hard*": "ask",
"rm -rf *": "ask"
},
"edit": {
"*": "allow",
"/run/agenix/**": "deny"
},
"external_directory": {
"*": "ask",
"/run/agenix/**": "allow",
"/tmp/**": "allow",
"~/.config/opencode/**": "allow",
"~/p/**": "allow"
},
"question": "allow",
"webfetch": "allow",
"websearch": "allow"
},
"prompt": "{file:./prompts/chiron-forge.txt}"
},
"Hermes (Communication)": {
"description": "Work communication specialist. Handles Basecamp tasks, Outlook email, and MS Teams meetings.",
"mode": "subagent",
"model": "zai-coding-plan/glm-5",
"permission": {
"bash": {
"*": "ask",
"cat *": "allow",
"echo *": "allow"
},
"edit": {
"*": "allow",
"/run/agenix/**": "deny"
},
"external_directory": {
"*": "ask",
"/run/agenix/**": "allow",
"/tmp/**": "allow",
"~/.config/opencode/**": "allow",
"~/p/**": "allow"
},
"question": "allow",
"webfetch": "allow"
},
"prompt": "{file:./prompts/hermes.txt}"
}
}

View File

@@ -0,0 +1,38 @@
Task 1: Capture Golden File Baseline
=====================================
Golden File Location:
/home/m3tam3re/p/AI/AGENTS/.sisyphus/evidence/agents-golden.json
Verification Results:
✓ File created successfully
✓ Valid JSON (jq parseable)
✓ Agent count: 6
✓ Sorted alphabetically by agent name
Agent Names (6 total):
1. Apollo (Knowledge Management)
2. Athena (Researcher)
3. Calliope (Writer)
4. Chiron (Assistant)
5. Chiron Forge (Builder)
6. Hermes (Communication)
Agent Object Structure (keys per agent):
- description
- mode
- model
- permission
- prompt
Permission Subkeys:
- question
- webfetch
- websearch
- edit
- bash
- external_directory
Sorting Method: jq --sort-keys (alphabetical)
Baseline Status: ✓ READY FOR TASK 8 (backward-compat bridge verification)

View File

@@ -0,0 +1,56 @@
=== Claude Code Renderer Output ===
Store path: /nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents
=== File listing ===
/nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/hermes.md
/nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/chiron-forge.md
/nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/chiron.md
/nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/apollo.md
/nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/calliope.md
/nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/athena.md
/nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/settings.json
=== chiron-forge.md frontmatter ===
---
description: "Personal AI assistant (Build Mode). Full execution and task completion capabilities with safety prompts"
---
You are Chiron-Forge, the Greek centaur smith of Hephaestus, specializing in execution and task completion as Chiron's build counterpart.
=== settings.json ===
{
"permissions": {
"allow": [
"Bash",
"Bash(bd *)",
"Bash(cat *)",
"Bash(echo *)",
"Bash(git branch*)",
"Bash(git diff*)",
"Bash(git log*)",
"Bash(git show*)",
"Bash(git status*)",
"Bash(grep *)",
"Bash(head *)",
"Bash(ls *)",
"Bash(nix *)",
"Bash(tail *)",
"Bash(td *)",
"Bash(wc *)",
"Bash(which *)",
"Edit",
"WebFetch"
],
"deny": [
"Bash(git push --force*)",
"Bash(git push -f *)",
"Edit(/run/agenix/**)"
]
}
}
Frontmatter validation: /nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/apollo.md -> OK: Private knowledge specialist. Manages Obsidian vau
Frontmatter validation: /nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/athena.md -> OK: Work knowledge specialist. Manages Outline wiki, d
Frontmatter validation: /nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/calliope.md -> OK: Writing specialist. Creates documentation, reports
Frontmatter validation: /nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/chiron-forge.md -> OK: Personal AI assistant (Build Mode). Full execution
Frontmatter validation: /nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/chiron.md -> OK: Personal AI assistant (Plan Mode). Read-only analy
Frontmatter validation: /nix/store/jnb2gls23ix4x73hjnw1iaa04xbd011k-claude-code-agents/.claude/agents/hermes.md -> OK: Work communication specialist. Handles Basecamp ta

View File

@@ -0,0 +1,45 @@
=== Pi Renderer Output ===
Store path: /nix/store/4xfs4pmikfjqqcm930rqbv1b179rlhh0-pi-agents
=== File listing ===
AGENTS.md
SYSTEM.md
=== AGENTS.md ===
# Agent Instructions
## Chiron (Assistant)
Personal AI assistant (Plan Mode). Read-only analysis, planning, and guidance
## Available Specialists
- **Apollo (Knowledge Management)**: Private knowledge specialist. Manages Obsidian vault, personal notes, and private knowledge graph
- **Athena (Researcher)**: Work knowledge specialist. Manages Outline wiki, documentation, and knowledge organization
- **Calliope (Writer)**: Writing specialist. Creates documentation, reports, meeting notes, and prose
- **Hermes (Communication)**: Work communication specialist. Handles Basecamp tasks, Outlook email, and MS Teams meetings
=== SYSTEM.md (first 20 lines) ===
You are Chiron, the wise centaur from Greek mythology, serving as the main orchestrator in plan and analysis mode. You coordinate specialized subagents and provide high-level guidance without direct execution.
**Your Core Responsibilities:**
1. Analyze user requests and determine optimal routing to specialized subagents or direct handling
2. Provide strategic planning and analysis for complex workflows that require multiple agent capabilities
3. Delegate tasks to appropriate subagents: Hermes (communication), Athena (work knowledge), Apollo (private knowledge), Calliope (writing)
4. Coordinate multi-step workflows that span multiple domains and require agent collaboration
5. Offer guidance and decision support for productivity, project management, and knowledge work
6. Bridge personal and work contexts while maintaining appropriate boundaries between domains
**Process:**
1. **Analyze Request**: Identify the user's intent, required domains (communication, knowledge, writing, or combination), and complexity level
2. **Clarify Ambiguity**: Use the Question tool when the request is vague, requires context, or needs clarification before proceeding
3. **Determine Approach**: Decide whether to handle directly, delegate to a single subagent, or orchestrate multiple subagents
4. **Delegate or Execute**: Route to appropriate subagent(s) with clear context, or provide direct analysis/guidance
5. **Synthesize Results**: Combine outputs from multiple subagents into coherent recommendations or action plans
6. **Provide Guidance**: Offer strategic insights, priorities, and next steps based on the analysis
**Delegation Logic:**
- **Hermes**: Work communication tasks (email drafts, message management, meeting coordination)
=== SYSTEM.md vs chiron/system-prompt.md diff ===
PASS: SYSTEM.md matches chiron prompt

View File

@@ -0,0 +1,6 @@
=== Task 12: OpenCode HM Sub-Module ===
Module file: modules/home-manager/coding/agents/opencode.nix
Options: coding.agents.opencode.{enable, agentsInput, modelOverrides, externalSkills}
Config: renders agents to ~/.config/opencode/agents/
Use '--all-systems' to check all.

View File

@@ -0,0 +1,6 @@
=== Task 13: Claude Code HM Sub-Module ===
Module file: modules/home-manager/coding/agents/claude-code.nix
Options: coding.agents.claude-code.{enable, agentsInput, modelOverrides}
Config: renders agents to ~/.claude/agents/ + settings.json
Use '--all-systems' to check all.

View File

@@ -0,0 +1,6 @@
=== Task 14: Pi HM Sub-Module ===
Module file: modules/home-manager/coding/agents/pi.nix
Options: coding.agents.pi.{enable, agentsInput}
Config: renders AGENTS.md + SYSTEM.md to ~/.pi/agent/
Use '--all-systems' to check all.

View File

@@ -0,0 +1,7 @@
=== Task 15: Slimmed opencode.nix ===
Removed: agentsInput, externalSkills options; agents.json embedding; skills/context/commands/prompts symlinks
Kept: ohMyOpencodeSettings, extraSettings, extraPlugins, theme/formatter/plugin config
PASS: agentsInput removed
PASS: externalSkills removed
PASS: ohMyOpencodeSettings preserved

View File

@@ -0,0 +1,12 @@
=== Task 16: mkCodingRules rename ===
File: lib/coding-rules.nix (new)
Old file: lib/opencode-rules.nix (still exists for reference)
Both functions produce identical results:
true
lib/default.nix exports:
# Coding rules injection utilities (renamed from opencode-rules)
coding-rules = import ./coding-rules.nix {inherit lib;};
# Backward-compat alias: opencode-rules → coding-rules
opencode-rules = import ./coding-rules.nix {inherit lib;};

View File

@@ -0,0 +1,19 @@
=== Task 17: renderForTool + shellHookForTool ===
--- Tool: opencode ---
Store path: /nix/store/jmx3s0jgy3v5k4dc0r29d601c7xxy6wr-opencode-agents
Contents:
(listing failed)
--- Tool: claude-code ---
Store path: /nix/store/2hjsch59amjs3nbgh7ahcfzm2bfwl8zi-bash-5.3p9/bin/bash: line 15: nix: command not found
Contents:
(listing failed)
--- Tool: pi ---
Store path: /nix/store/2hjsch59amjs3nbgh7ahcfzm2bfwl8zi-bash-5.3p9/bin/bash: line 15: nix: command not found
Contents:
(listing failed)
--- shellHookForTool ---
/nix/store/2hjsch59amjs3nbgh7ahcfzm2bfwl8zi-bash-5.3p9/bin/bash: line 23: nix: command not found

View File

@@ -0,0 +1,45 @@
=== Task 18: Flake exports + Aggregator imports ===
homeManagerModule keys:
["agents","default","opencode","ports","zellij-ps"]
coding/default.nix imports:
# Coding-related Home Manager modules
{
imports = [
./editors.nix
./opencode.nix
./agents
];
}
coding/agents/default.nix:
# Per-tool agent sub-modules
# Each module handles rendering canonical agent.toml definitions
# for a specific AI coding tool.
{
imports = [
./opencode.nix
./claude-code.nix
./pi.nix
];
}
lib/default.nix:
# Library of helper functions for m3ta-nixpkgs
# Usage in your configuration:
# let
# m3taLib = inputs.m3ta-nixpkgs.lib.${system};
# in ...
{lib}: {
# Port management utilities
ports = import ./ports.nix {inherit lib;};
# Coding rules injection utilities (renamed from opencode-rules)
coding-rules = import ./coding-rules.nix {inherit lib;};
# Backward-compat alias: opencode-rules → coding-rules
opencode-rules = import ./coding-rules.nix {inherit lib;};
# Agent configuration management utilities
agents = import ./agents.nix {inherit lib;};
}

View File

@@ -0,0 +1,32 @@
=== Task 19: AGENTS.md Documentation Update ===
Check: agent.toml mentioned:
for f in agents/*/agent.toml; do nix eval --impure --expr "builtins.fromTOML (builtins.readFile ./$f)" --json > /dev/null && echo "OK: $f"; done
│ ├── SCHEMA.md # Canonical agent.toml schema definition
│ ├── agent.toml # Agent metadata, permissions, references
Agent definitions live in `agents/<name>/agent.toml` + `agents/<name>/system-prompt.md`.
1. Create `agents/<name>/agent.toml` with required fields (`name`, `description`) and optional fields (`mode`, `permissions`, etc.)
3. Verify: `nix eval --impure --expr 'builtins.fromTOML (builtins.readFile ./agents/<name>/agent.toml)' --json`
- `lib.loadAgents` — loads all canonical `agents/*/agent.toml` + `system-prompt.md` into an attrset
PASS
Check: system-prompt.md mentioned:
│ └── system-prompt.md # Agent system prompt (markdown)
Agent definitions live in `agents/<name>/agent.toml` + `agents/<name>/system-prompt.md`.
2. Create `agents/<name>/system-prompt.md` with the agent's system prompt
- `lib.loadAgents` — loads all canonical `agents/*/agent.toml` + `system-prompt.md` into an attrset
PASS
Check: agents.json NOT as canonical:
- `lib.agentsJson` — backward-compat bridge producing legacy agents.json shape (temporary, will be removed)
Found references (check they're not 'canonical'):
Check: loadAgents mentioned:
Renderers live in **m3ta-nixpkgs** (not this repo). They consume `lib.loadAgents` and produce:
- `lib.loadAgents` — loads all canonical `agents/*/agent.toml` + `system-prompt.md` into an attrset
PASS
Check: mkCodingRules mentioned:
Centralized AI coding rules consumed via `mkCodingRules` from m3ta-nixpkgs
m3taLib.coding-rules.mkCodingRules {
PASS

View File

@@ -0,0 +1 @@
{"description":"Minimal test agent with only required fields","name":"minimal-agent"}

View File

@@ -0,0 +1 @@
{"description":"Personal AI assistant (Build Mode). Full execution and task completion capabilities with safety prompts.","mode":"primary","name":"chiron-forge","permissions":{"bash":{"intent":"allow","rules":["rm -rf *:ask","git reset --hard*:ask","git push*:ask","git push --force*:deny","git push -f *:deny"]},"edit":{"intent":"allow","rules":["/run/agenix/**:deny"]},"external_directory":{"intent":"ask","rules":["~/p/**:allow","~/.config/opencode/**:allow","/tmp/**:allow","/run/agenix/**:allow"],"skills":["systematic-debugging","git-master"]},"question":{"intent":"allow"},"webfetch":{"intent":"allow"},"websearch":{"intent":"allow"}}}

View File

@@ -0,0 +1,34 @@
=== Task 21: End-to-End Integration Test ===
--- 1. AGENTS repo flake check ---
PASS: nix flake check passes
--- 2. nixpkgs flake check ---
PASS: nix flake check passes (21 checks, formatting clean)
--- 3. loadAgents returns 6 agents ---
PASS: 6 agents (chiron, chiron-forge, hermes, athena, apollo, calliope)
--- 4. OpenCode renderer ---
PASS: 6 .md files with correct YAML frontmatter
--- 5. Claude Code renderer ---
PASS: 6 .md files in .claude/agents/ + settings.json with permission DSL
--- 6. Pi renderer ---
PASS: AGENTS.md + SYSTEM.md, SYSTEM.md byte-identical to chiron prompt
--- 7. Skills composition ---
PASS: 18 skills in linkFarm output, mkOpencodeSkills unchanged
--- 8. Backward-compat bridge ---
PASS: agentsJson output matches golden file (zero diff)
--- 9. Coding rules backward compat ---
PASS: mkCodingRules == mkOpencodeRules (identical instructions output)
--- 10. Formatting ---
PASS: alejandra formatting clean on both repos (verified via flake check)
--- Summary ---
All checks PASS.

View File

@@ -0,0 +1 @@
{"context":["../../context/profile.md"],"description":"Personal AI assistant (Plan Mode). Read-only analysis, planning, and guidance","display_name":"Chiron (Assistant)","max_turns":50,"mode":"primary","name":"chiron","permissions":{"bash":{"intent":"ask","rules":["git status*:allow","git log*:allow","git diff*:allow","git branch*:allow","git show*:allow","grep *:allow","ls *:allow","cat *:allow","head *:allow","tail *:allow","wc *:allow","which *:allow","echo *:allow","nix *:allow"]},"edit":{"intent":"deny"},"external_directory":{"intent":"ask","rules":["~/p/**:allow","~/.config/opencode/**:allow","/tmp/**:allow","/run/agenix/**:allow"]},"question":{"intent":"allow"},"webfetch":{"intent":"allow"},"websearch":{"intent":"allow"}},"rules":["languages/nix","languages/python","concerns/testing"],"skills":["systematic-debugging","git-master","brainstorming"],"tags":["assistant","plan-mode","read-only"]}

View File

@@ -0,0 +1,53 @@
# agents/chiron/agent.toml
# Chiron — Personal AI Assistant (Plan Mode)
name = "chiron"
display_name = "Chiron (Assistant)"
description = "Personal AI assistant (Plan Mode). Read-only analysis, planning, and guidance"
mode = "primary"
tags = ["assistant", "plan-mode", "read-only"]
max_turns = 50
skills = ["systematic-debugging", "git-master", "brainstorming"]
context = ["../../context/profile.md"]
rules = ["languages/nix", "languages/python", "concerns/testing"]
[permissions.question]
intent = "allow"
[permissions.webfetch]
intent = "allow"
[permissions.websearch]
intent = "allow"
[permissions.edit]
intent = "deny"
[permissions.bash]
intent = "ask"
rules = [
"git status*:allow",
"git log*:allow",
"git diff*:allow",
"git branch*:allow",
"git show*:allow",
"grep *:allow",
"ls *:allow",
"cat *:allow",
"head *:allow",
"tail *:allow",
"wc *:allow",
"which *:allow",
"echo *:allow",
"nix *:allow",
]
[permissions.external_directory]
intent = "ask"
rules = [
"~/p/**:allow",
"~/.config/opencode/**:allow",
"/tmp/**:allow",
"/run/agenix/**:allow",
]

View File

@@ -0,0 +1,529 @@
# Task 4: OpenCode File-Based Agent Format Research
**Date**: 2026-04-10
**Status**: ✅ Complete
**Research Method**: WebFetch + Documentation Analysis
---
## Executive Summary
OpenCode supports **two agent configuration methods**:
1. **JSON** - Embedded in `opencode.json` (config.json)
2. **Markdown Files** - File-based in `.opencode/agents/` directory (per-project) or `~/.config/opencode/agents/` (global)
This research focuses on the **file-based markdown format**, which is the target for the harness-agnostic migration.
---
## File Location & Discovery
### Directory Structure
**Per-project agents** (takes precedence):
```
.opencode/agents/
├── agent-name.md
├── another-agent.md
└── ...
```
**Global agents** (fallback):
```
~/.config/opencode/agents/
├── agent-name.md
├── another-agent.md
└── ...
```
### Discovery Mechanism
- OpenCode **scans both directories** for `*.md` files
- The **filename (without .md extension)** becomes the **agent name**
- Per-project agents **override** global agents with the same name
- All agents are loaded at startup and available via `Tab` switching or `@mention`
### Key Finding
**The agent name is derived from the filename**, not from a `name` field in the frontmatter. Example:
- File: `review.md` → Agent name: `review`
- File: `code-reviewer.md` → Agent name: `code-reviewer`
---
## YAML Frontmatter Specification
All file-based agent markdown files must include YAML frontmatter with the following fields:
### Required Fields
| Field | Type | Description | Example |
|-------|------|-------------|---------|
| `description` | string | Brief description of agent purpose and when to use it. **REQUIRED**. | `"Reviews code for quality and best practices"` |
### Optional Fields
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `mode` | string | `all` | Agent mode: `primary`, `subagent`, or `all` |
| `model` | string | Model globally configured in config | Override LLM model for this agent |
| `temperature` | float | Model-specific (usually 0 or 0.55 for Qwen) | LLM response randomness (0.01.0) |
| `top_p` | float | — | Alternative to temperature for diversity control |
| `steps` | integer | No limit | Max agentic iterations before forced text-only response |
| `disable` | boolean | `false` | Set to `true` to disable the agent |
| `hidden` | boolean | `false` | Hide from `@` autocomplete (subagents only) |
| `color` | string | — | Hex color (e.g., `#FF5733`) or theme color (primary, secondary, accent, success, warning, error, info) |
| `permission` | object | — | Permission rules for edit, bash, webfetch, question, websearch, external_directory |
| `task` | object | — | Control which subagents this agent can invoke via Task tool |
### Provider-Specific Fields
Any additional fields are **passed through directly to the LLM provider**. Example for OpenAI reasoning models:
```yaml
---
description: Agent using high reasoning effort
model: openai/gpt-5
reasoningEffort: high
textVerbosity: low
---
```
---
## Permission Format (YAML)
Permissions control what actions an agent can perform. The format supports two styles:
### Simple Format (Single Action)
```yaml
permission:
edit: deny
bash: ask
webfetch: allow
```
### Granular Format (Rules Array)
For more control over specific patterns:
```yaml
permission:
edit:
"*": allow
"/run/agenix/**": deny
bash:
"*": ask
"git status*": allow
"git log*": allow
"git push": ask
"grep *": allow
webfetch: deny
question: allow
websearch: allow
external_directory:
"*": ask
"~/p/**": allow
"~/.config/opencode/**": allow
"/tmp/**": allow
```
### Permission Actions
| Value | Meaning |
|-------|---------|
| `allow` | Tool allowed without approval |
| `ask` | Prompt user for approval before running |
| `deny` | Tool disabled |
### Supported Permission Keys
| Key | Values | Notes |
|-----|--------|-------|
| `edit` | `allow\|ask\|deny` or nested rules | File write/patch operations |
| `bash` | `allow\|ask\|deny` or nested rules | Bash command execution; supports glob patterns |
| `webfetch` | `allow\|ask\|deny` | HTTP requests |
| `question` | `allow\|ask\|deny` | User questions/clarification |
| `websearch` | `allow\|ask\|deny` | Web search operations |
| `external_directory` | `allow\|ask\|deny` or nested rules | Access to external directories |
| `task` | nested rules | Subagent invocation control (glob patterns) |
### Glob Pattern Support
Patterns support wildcards and recursion:
- `*` — single-level wildcard
- `**` — recursive wildcard
- `git push*` — suffix matching
- `~/p/**` — home directory paths
- `/run/agenix/**` — absolute paths
### Rule Precedence
When multiple rules match, the **last matching rule wins**:
```yaml
bash:
"*": ask
"git status*": allow
"git push*": deny
```
In this example:
- `git status` matches both `*` and `git status*` → result: **allow** (last rule wins)
- `git push origin main` matches both `*` and `git push*` → result: **deny**
- `ls -la` matches only `*` → result: **ask**
---
## Mode Field Values
| Mode | Type | Description |
|------|------|-------------|
| `primary` | Primary agent | Agent available via `Tab` key switching; handles main conversation |
| `subagent` | Specialized agent | Invoked via `@mention` or automatically by other agents for specific tasks |
| `all` | Flexible | Can be used as both primary and subagent (default if omitted) |
---
## System Prompt Delivery
The markdown file body (after the YAML frontmatter) contains the **system prompt**:
```markdown
---
description: Code review without edits
mode: subagent
permission:
edit: deny
---
You are a code reviewer. Focus on:
- Code quality and best practices
- Potential bugs and edge cases
- Performance implications
- Security considerations
Provide constructive feedback without making direct changes.
```
The **markdown content is passed directly as the system prompt** to the LLM. It supports:
- Inline markdown formatting
- Lists and sections
- Structured instructions
- Code examples (fenced with backticks)
---
## Default Behavior for Omitted Fields
| Field | Default | Notes |
|-------|---------|-------|
| `description` | **ERROR** | Required; absence causes parse failure |
| `mode` | `all` | Agent can be used as primary or subagent |
| `model` | Global config model | Primary agents use global model; subagents use parent's model |
| `temperature` | Model-specific | Usually 0 for most models; 0.55 for Qwen models |
| `permission` | Full access | If omitted, all tools enabled (no restrictions) |
| `disable` | `false` | Agent is enabled by default |
| `hidden` | `false` | Agent visible in `@` autocomplete (if subagent) |
---
## Interaction with config.json (JSON Format)
### Current State (Task 1 Finding)
The current system embeds agents in **config.json** via JSON:
```json
{
"agent": {
"build": {
"description": "...",
"mode": "primary",
"permission": { ... }
}
}
}
```
### File-Based Agents Complement, Don't Replace
- **JSON agents** (in config.json) are loaded from embedded config
- **Markdown agents** (.opencode/agents/*.md files) are symlinked
- **Both are loaded** and available simultaneously
- **Markdown agents override** JSON agents with the same name
### Migration Path
The harness-agnostic migration will:
1. Move agent definitions from `agents.json``.opencode/agent/{name}.md` files
2. Update home-manager deployment to symlink `.opencode/agents/` instead of embedding `agents.json`
3. System prompt changes (markdown file edits) will **NOT require `home-manager switch`**
---
## Key Advantage: Prompt Changes Don't Require home-manager switch
### Current Limitation (JSON/Embedded)
```
agents.json → home-manager → embedded into config.json
Change required in nixpkgs module
home-manager switch (full system rebuild)
```
### New Capability (File-Based)
```
.opencode/agents/{name}.md → home-manager → symlinks to ~/.config/opencode/agents/
Change markdown file directly
OpenCode reloads on next startup (NO home-manager switch needed)
```
**This is the KEY ADVANTAGE** of file-based agents: faster iteration on prompts and agent configuration.
---
## Limitations & Gotchas
### No Name Field in Frontmatter
- Agent name comes from **filename only**
- No `name: foo` field in frontmatter
- Renaming file renames the agent
### Model References with {file:...}
In JSON config, you can reference external files:
```json
{
"prompt": "{file:./prompts/build.txt}"
}
```
In markdown files, the **body IS the prompt** — no `{file:...}` syntax. The entire markdown content after frontmatter is the system prompt.
### Subdirectories Not Scanned
- Only files directly in `.opencode/agents/` are loaded
- Subdirectories are ignored
- All agent definitions must be in one directory level
### Filename Validation
The filename should follow these conventions (not enforced, but recommended):
- Lowercase letters, numbers, hyphens: `[a-z0-9-]+`
- No spaces, no special characters
- Examples: `code-reviewer.md`, `security-auditor.md`, `docs-writer.md`
---
## Complete Example: File-Based Agent
### File: `.opencode/agents/code-reviewer.md`
```markdown
---
description: Performs comprehensive code review focusing on quality, security, and performance
mode: subagent
model: anthropic/claude-sonnet-4-20250514
temperature: 0.1
permission:
edit:
"*": deny
bash:
"*": allow
"grep *": allow
"git diff*": allow
webfetch: allow
question: allow
---
You are an expert code reviewer with deep knowledge of software architecture, security best practices, and performance optimization.
## Your Mission
Review code for:
1. **Correctness** - Logic errors, edge cases, off-by-one bugs
2. **Security** - Input validation, injection vulnerabilities, data exposure
3. **Performance** - Algorithmic efficiency, memory usage, unnecessary allocations
4. **Maintainability** - Code clarity, naming, documentation, SOLID principles
5. **Testing** - Coverage gaps, missing test cases, integration test concerns
## Process
1. Ask clarifying questions about context and constraints
2. Provide specific, actionable feedback with examples
3. Suggest refactorings with rationale
4. Never make changes directly (read-only mode)
5. Prioritize critical issues over style concerns
## Output Format
- **Critical Issues** (must fix before merge)
- **Important Improvements** (should fix)
- **Nice-to-Have Suggestions** (consider for future)
- **Questions** (for author clarification)
```
---
## Complete Example: JSON Config Format (For Reference)
For comparison, here's the equivalent in JSON config.json:
```json
{
"$schema": "https://opencode.ai/config.json",
"agent": {
"code-reviewer": {
"description": "Performs comprehensive code review focusing on quality, security, and performance",
"mode": "subagent",
"model": "anthropic/claude-sonnet-4-20250514",
"temperature": 0.1,
"permission": {
"edit": {
"*": "deny"
},
"bash": {
"*": "allow",
"grep *": "allow",
"git diff*": "allow"
},
"webfetch": "allow",
"question": "allow"
},
"prompt": "You are an expert code reviewer...\n\n## Your Mission\n..."
}
}
}
```
---
## Source Materials
### Documentation
- **Official**: https://opencode.ai/docs/agents
- **Agents Section**: Comprehensive spec for all agent config options
- **Markdown Example**: Review agent example provided in docs
- **Security Auditor Example**: Security-focused agent example
### Code References
- **GitHub**: https://github.com/anomalyco/opencode (dev branch)
- **Config Spec**: schema.json embedded in docs
- **Test Cases**: `.opencode/agents/` in opencode repo (example files)
### Current System Reference
- **Nix Module**: `/home/m3tam3re/p/NIX/nixpkgs/modules/home-manager/coding/opencode.nix`
- Line 149: `agent = builtins.fromJSON (builtins.readFile "${inputs.agents}/agents/agents.json");`
- Line 149: Shows current embedding pattern
- **AGENTS repo**: `/home/m3tam3re/p/AI/AGENTS/agents/agents.json`
- 6 agents: Chiron, Chiron Forge, Hermes, Athena, Apollo, Calliope
- Permission structure: nested objects with wildcard patterns
---
## Questions Addressed
### Q: Do file-based agents need `home-manager switch` for prompt changes?
**A: NO**
- File changes are immediately available
- `.opencode/agents/` is symlinked (not embedded)
- OpenCode reloads agent definitions at startup
- Prompt changes require only file edit + app restart
**This is the KEY ADVANTAGE** driving the migration.
### Q: What directory: `agent` or `agents`?
**A: `agents` (plural)** (both global and per-project)
- Global: `~/.config/opencode/agents/`
- Per-project: `.opencode/agents/`
### Q: Do agent names need a `name` field in frontmatter?
**A: NO**
- Agent name comes from **filename only**
- No `name: foo` field in frontmatter
- Example: `review.md` → agent name is `review`
### Q: What YAML frontmatter fields are required?
**A: Only `description`** is truly required
- All other fields have sensible defaults
- Missing fields use their defaults
- Frontmatter-less file will fail to parse
### Q: How are permissions specified in markdown?
**A: Same nested object format as JSON**
```yaml
permission:
edit:
"*": allow
"/sensitive/**": deny
bash:
"*": ask
"git push": deny
```
---
## Confirmation Summary
| Question | Finding |
|----------|---------|
| **Directory**: `agent` or `agents`? | `agents/` (both global and per-project) |
| **File naming**: How determined? | Filename (without .md) becomes agent name |
| **Required fields**: What's mandatory? | `description` only; others have defaults |
| **Permission format**: YAML or different? | Same nested object format as JSON |
| **Mode values**: Options? | `primary` \| `subagent` \| `all` |
| **Prompt format**: How specified? | Markdown body after frontmatter |
| **Requires HM switch for prompt changes?** | **NO** ✅ (major advantage) |
| **Does frontmatter need `name` field?** | **NO** (filename is the name) |
| **Can agents be in subdirectories?** | **NO** (only root level of `.opencode/agents/`) |
| **Can you override agents from JSON config?** | **YES** (markdown agents override JSON with same name) |
---
## Next Steps (Task 9: OpenCode Renderer)
The renderer will generate `.opencode/agents/{name}.md` files with:
1. **Frontmatter generation**:
- Convert agent.toml `[description]` → YAML `description:`
- Convert `[mode]` → YAML `mode:`
- Convert `[temperature]` → YAML `temperature:`
- Convert `[permission]` from two-level format → nested YAML objects
2. **Body generation**:
- Use agent.toml `system_prompt` field → markdown body
3. **File naming**:
- Filename: `{agent_name}.md` (from agent.toml `name` field)
- Agent name in OpenCode: derived from filename automatically
---
## Evidence Collection
- **Source 1**: https://opencode.ai/docs/agents (Official documentation)
- **Source 2**: `/home/m3tam3re/p/NIX/nixpkgs/modules/home-manager/coding/opencode.nix` (Current deployment)
- **Source 3**: `/home/m3tam3re/p/AI/AGENTS/agents/agents.json` (Current agent definitions)
- **Source 4**: `/home/m3tam3re/p/AI/AGENTS/AGENTS.md` (Repository documentation)
**Research Date**: 2026-04-10
**Researcher**: Sisyphus-Junior
**Task**: Task 4 of harness-agnostic-migration plan

View File

@@ -0,0 +1 @@
{"description":"Private knowledge specialist. Manages Obsidian vault, personal notes, and private knowledge graph","display_name":"Apollo (Knowledge Management)","mode":"subagent","name":"apollo","permissions":{"bash":{"intent":"ask","rules":["cat *:allow"]},"edit":{"intent":"allow","rules":["/run/agenix/**:deny"]},"external_directory":{"intent":"ask","rules":["~/p/**:allow","~/.config/opencode/**:allow","/tmp/**:allow","/run/agenix/**:allow"]},"question":{"intent":"allow"}}}

View File

@@ -0,0 +1 @@
{"description":"Work knowledge specialist. Manages Outline wiki, documentation, and knowledge organization","display_name":"Athena (Researcher)","mode":"subagent","name":"athena","permissions":{"bash":{"intent":"ask","rules":["grep *:allow","cat *:allow"]},"edit":{"intent":"allow","rules":["/run/agenix/**:deny"]},"external_directory":{"intent":"ask","rules":["~/p/**:allow","~/.config/opencode/**:allow","/tmp/**:allow","/run/agenix/**:allow"]},"question":{"intent":"allow"},"webfetch":{"intent":"allow"},"websearch":{"intent":"allow"}}}

View File

@@ -0,0 +1 @@
{"description":"Writing specialist. Creates documentation, reports, meeting notes, and prose","display_name":"Calliope (Writer)","mode":"subagent","name":"calliope","permissions":{"bash":{"intent":"ask","rules":["cat *:allow","wc *:allow"]},"edit":{"intent":"allow","rules":["/run/agenix/**:deny"]},"external_directory":{"intent":"ask","rules":["~/p/**:allow","~/.config/opencode/**:allow","/tmp/**:allow","/run/agenix/**:allow"]},"question":{"intent":"allow"},"webfetch":{"intent":"allow"}}}

View File

@@ -0,0 +1 @@
{"description":"Personal AI assistant (Build Mode). Full execution and task completion capabilities with safety prompts","display_name":"Chiron Forge (Builder)","mode":"primary","name":"chiron-forge","permissions":{"bash":{"intent":"allow","rules":["rm -rf *:ask","git reset --hard*:ask","git push*:ask","git push --force*:deny","git push -f *:deny"]},"edit":{"intent":"allow","rules":["/run/agenix/**:deny"]},"external_directory":{"intent":"ask","rules":["~/p/**:allow","~/.config/opencode/**:allow","/tmp/**:allow","/run/agenix/**:allow"]},"question":{"intent":"allow"},"webfetch":{"intent":"allow"},"websearch":{"intent":"allow"}}}

View File

@@ -0,0 +1 @@
{"description":"Personal AI assistant (Plan Mode). Read-only analysis, planning, and guidance","display_name":"Chiron (Assistant)","mode":"primary","name":"chiron","permissions":{"bash":{"intent":"ask","rules":["git status*:allow","git log*:allow","git diff*:allow","git branch*:allow","git show*:allow","grep *:allow","ls *:allow","cat *:allow","head *:allow","tail *:allow","wc *:allow","which *:allow","echo *:allow","td *:allow","bd *:allow","nix *:allow"]},"edit":{"intent":"deny"},"external_directory":{"intent":"ask","rules":["~/p/**:allow","~/.config/opencode/**:allow","/tmp/**:allow","/run/agenix/**:allow"]},"question":{"intent":"allow"},"webfetch":{"intent":"allow"},"websearch":{"intent":"allow"}}}

View File

@@ -0,0 +1 @@
{"description":"Work communication specialist. Handles Basecamp tasks, Outlook email, and MS Teams meetings","display_name":"Hermes (Communication)","mode":"subagent","name":"hermes","permissions":{"bash":{"intent":"ask","rules":["cat *:allow","echo *:allow"]},"edit":{"intent":"allow","rules":["/run/agenix/**:deny"]},"external_directory":{"intent":"ask","rules":["~/p/**:allow","~/.config/opencode/**:allow","/tmp/**:allow","/run/agenix/**:allow"]},"question":{"intent":"allow"},"webfetch":{"intent":"allow"}}}

View File

@@ -0,0 +1,6 @@
diff chiron: exit 0
diff chiron-forge: exit 0
diff hermes: exit 0
diff athena: exit 0
diff apollo: exit 0
diff calliope: exit 0

View File

@@ -0,0 +1,39 @@
{
"task": "task-7-lib-agents",
"status": "complete",
"timestamp": "2026-04-10",
"files": {
"created": [
"/home/m3tam3re/p/NIX/nixpkgs/lib/agents.nix"
],
"modified": [
"/home/m3tam3re/p/NIX/nixpkgs/lib/default.nix"
]
},
"checks": {
"alejandra_check": {
"command": "alejandra --check lib/agents.nix lib/default.nix",
"result": "PASS",
"output": "Congratulations! Your code complies with the Alejandra style."
},
"nix_flake_check": {
"command": "nix flake check",
"result": "PASS",
"exit_code": 0,
"notable": "21 flake checks ran, all derivations evaluated successfully"
}
},
"lib_agents_functions": {
"loadCanonical": "Takes { agentsInput } and returns agentsInput.lib.loadAgents",
"renderForOpencode": "Stub: pkgs.runCommand 'opencode-agents' {} 'echo stub > $out'",
"renderForClaudeCode": "Stub: pkgs.runCommand 'claude-code-agents' {} 'echo stub > $out'",
"renderForPi": "Stub: pkgs.runCommand 'pi-agents' {} 'echo stub > $out'",
"renderForTool": "Dispatcher by tool string: opencode | claude-code | pi"
},
"notes": [
"lib/agents.nix already existed with correct structure when task started",
"lib/default.nix already had the agents entry wired in",
"Both files passed alejandra --check without modification needed",
"nix flake check passed with EXIT: 0"
]
}

View File

@@ -0,0 +1,12 @@
## [2026-04-10] CRITICAL: Subagent Scope Creep - Skills Deleted
- Tasks 1 & 2 subagent DELETED skills from disk (basecamp, brainstorming, frontend-design, kestra-flow, kestra-ops, obsidian, prompt-engineering-patterns, systematic-debugging, xlsx)
- These were NOT in scope and MUST NOT be touched per the plan
- Skills were restored via: `git checkout HEAD -- skills/`
- ROOT CAUSE: Subagents may try to "clean up" untracked/modified files when working in the repo
- MITIGATION: All future delegation prompts must explicitly state "DO NOT touch skills/ directory or any existing files"
## [2026-04-10] NOTE: nix eval requires --impure for builtins.readFile with absolute paths
- Task 2 spike required `nix eval --impure --expr 'builtins.fromTOML (builtins.readFile <path>)'`
- This is expected for absolute filesystem paths outside the flake
- For flake-based rendering (nixpkgs lib), this is not an issue as files go through `pkgs.writeText` or are read at flake evaluation time via `inputs`

View File

@@ -0,0 +1,251 @@
# 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
- 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)
- No MCP in agent.toml (tool-specific infrastructure)
- 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
## [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
4. Chiron (Assistant) — primary agent, plan mode
5. Chiron Forge (Builder) — primary agent, build mode
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")
- `prompt` (string) — reference to prompt file via `{file:./prompts/...}`
- `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)
- `edit` → nested rules (allow/deny per path pattern)
- `bash` → nested rules (allow/deny per command pattern)
- `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
## [2026-04-10] Task 2: TOML Feasibility Spike
**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 <path>)' --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)
- `git push --force*` → intact (flag + pattern)
- `git push -f *` → intact (short flag + wildcard)
- `~/p/**` → intact (recursive glob)
- `~/.config/opencode/**` → intact (home + recursive)
- `/run/agenix/**` → intact (absolute + recursive)
- `/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
- Permissions: [permissions.TOOL] with intent + rules[]
- Supported tools: bash, edit, webfetch, websearch, question, external_directory
- Per-renderer matrix: documented
- Sample TOML parses: YES
- Evidence: .sisyphus/evidence/task-3-schema-sample.toml (TOML source)
- Evidence: .sisyphus/evidence/task-3-schema-sample-parsed.json (Nix parse result)
## [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:
"*": allow
"/sensitive/**": deny
bash:
"*": ask
"git push": deny
"git log*": allow
webfetch: allow
question: allow
websearch: allow
external_directory:
"*": 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 ✅
- Permission format: Nested objects like JSON ✅
- Mode values: `primary` | `subagent` | `all`
- System prompt: Markdown body after frontmatter ✅
- Requires HM switch for prompt changes: **NO**
- 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)
- OpenCode directory is `.opencode/agents/` (PLURAL), not `.opencode/agent/`
- Global agents: `~/.config/opencode/agents/` (PLURAL too)
- `description` is the only REQUIRED frontmatter field
- Agent name is derived from filename (no `name` field in frontmatter)
- Supported tools: edit, bash, webfetch, question, websearch, external_directory, task
- `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
"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`)
- Prompt diffs: all zero (6/6 byte-identical)
- Chiron mode: primary
- Chiron-Forge mode: primary
- Other 4 mode: subagent
- Commit: 7a8dd52 (12 files, 543 insertions)
- Permission translation notes:
- JSON `"*"` key → TOML `intent` field (straightforward)
- JSON non-`"*"` keys → TOML `rules` array as `"pattern:action"` strings
- Simple string permissions (e.g., `"question": "allow"`) → `intent` only, no rules array
- Description trailing periods stripped per SCHEMA.md constraint ("no trailing period")
- `td *` and `bd *` bash rules in chiron preserved (custom tool aliases)
- 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)
- nix flake check: PASS
- alejandra formatting: PASS
- Commit: a81e178 feat: export loadAgents and backward-compat agentsJson from flake

File diff suppressed because it is too large Load Diff

184
AGENTS.md
View File

@@ -1,6 +1,6 @@
# Opencode Skills Repository # Agent Skills Repository
Configuration repository for Opencode Agent Skills, context files, and agent configurations. Deployed via Nix home-manager to `~/.config/opencode/`. Configuration repository for AI Agent Skills, canonical agent definitions, context files, and agent configurations. Deployed via Nix home-manager to `~/.config/opencode/` (or equivalent paths for other tools).
## Quick Commands ## Quick Commands
@@ -12,6 +12,9 @@ Configuration repository for Opencode Agent Skills, context files, and agent con
# Skill creation # Skill creation
python3 skills/skill-creator/scripts/init_skill.py <name> --path skills/ python3 skills/skill-creator/scripts/init_skill.py <name> --path skills/
# Verify agent TOML parses
for f in agents/*/agent.toml; do nix eval --impure --expr "builtins.fromTOML (builtins.readFile ./$f)" --json > /dev/null && echo "OK: $f"; done
``` ```
## Directory Structure ## Directory Structure
@@ -28,8 +31,11 @@ python3 skills/skill-creator/scripts/init_skill.py <name> --path skills/
│ ├── languages/ # Python, TypeScript, Nix, Shell │ ├── languages/ # Python, TypeScript, Nix, Shell
│ ├── concerns/ # Testing, naming, documentation, etc. │ ├── concerns/ # Testing, naming, documentation, etc.
│ └── frameworks/ # Framework-specific rules (n8n, etc.) │ └── frameworks/ # Framework-specific rules (n8n, etc.)
├── agents/ # Agent definitions (agents.json) ├── agents/ # Canonical agent definitions (harness-agnostic)
├── prompts/ # System prompts (chiron*.txt) │ ├── SCHEMA.md # Canonical agent.toml schema definition
│ └── <name>/
│ ├── agent.toml # Agent metadata, permissions, references
│ └── system-prompt.md # Agent system prompt (markdown)
├── context/ # User profiles ├── context/ # User profiles
├── commands/ # Custom commands ├── commands/ # Custom commands
└── scripts/ # Repo utilities (test-skill.sh, validate-agents.sh) └── scripts/ # Repo utilities (test-skill.sh, validate-agents.sh)
@@ -76,6 +82,42 @@ compatibility: opencode
- `systematic-debugging/test-*.md` - Academic/pressure testing in wrong location - `systematic-debugging/test-*.md` - Academic/pressure testing in wrong location
- `pdf/forms.md`, `pdf/reference.md` - Docs outside references/ - `pdf/forms.md`, `pdf/reference.md` - Docs outside references/
## Canonical Agent Format
Agent definitions live in `agents/<name>/agent.toml` + `agents/<name>/system-prompt.md`.
This is a **harness-agnostic** format — renderers in m3ta-nixpkgs generate tool-specific configs.
See `agents/SCHEMA.md` for the full schema definition.
### Adding a new agent
1. Create `agents/<name>/agent.toml` with required fields (`name`, `description`) and optional fields (`mode`, `permissions`, etc.)
2. Create `agents/<name>/system-prompt.md` with the agent's system prompt
3. Verify: `nix eval --impure --expr 'builtins.fromTOML (builtins.readFile ./agents/<name>/agent.toml)' --json`
4. Add the agent to renderers by updating the consuming flake inputs
### How renderers work
Renderers live in **m3ta-nixpkgs** (not this repo). They consume `lib.loadAgents` and produce:
| Tool | Output | Path |
|------|--------|------|
| OpenCode | `.opencode/agents/*.md` | `~/.config/opencode/agents/` |
| Claude Code | `.claude/agents/*.md` + `settings.json` | `~/.claude/` |
| Pi | `AGENTS.md` + `SYSTEM.md` | `~/.pi/agent/` |
### Project-level usage
```nix
# In project flake.nix
m3taLib.agents.shellHookForTool {
inherit pkgs;
agentsInput = inputs.agents;
tool = "opencode";
modelOverrides = { chiron = "anthropic/claude-sonnet-4"; };
};
```
## Deployment ## Deployment
**Nix flake pattern**: **Nix flake pattern**:
@@ -87,16 +129,17 @@ agents = {
``` ```
**Exports:** **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.mkOpencodeSkills` — 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 - `packages.skills-runtime` — composable runtime with all skill dependencies
- `devShells.default` — dev environment for working on skills - `devShells.default` — dev environment for working with skills
**Mapping** (via home-manager): **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 `mkOpencodeSkills` (custom + external merged)
- `context/`, `commands/`, `prompts/` → symlinks - `context/`, `commands/` → symlinks
- `agents/agents.json` → embedded into config.json - Agent changes via file-based agents: visible on next tool restart (no `home-manager switch` needed for prompt changes)
- Agent changes: require `home-manager switch`
- Other changes: visible immediately
### External Skills (skills.sh) ### External Skills (skills.sh)
@@ -142,13 +185,130 @@ xdg.configFile."opencode/skills".source =
}; };
``` ```
## Migration Guide (for the repo owner)
This section documents how to complete the migration from the legacy `agents.json` + `prompts/*.txt` format to the canonical `agent.toml` + `system-prompt.md` format. The canonical files already exist; what remains is updating the consumer configs and removing legacy files.
### Current state
- ✅ All 6 agents exist in canonical format: `agents/{name}/agent.toml` + `agents/{name}/system-prompt.md`
-`lib.loadAgents` loads canonical agents from TOML
-`lib.agentsJson` backward-compat bridge produces the old JSON shape from TOML
- ⏳ Legacy files still present: `agents/agents.json`, `prompts/*.txt`
- ⏳ Consumer (home-manager) still reads `agents.json` directly via the old `coding.opencode` module
### Step 1: Update home-manager config in your NixOS/HM flake
Change from the old `coding.opencode` agent options to the new `coding.agents.opencode` module:
```nix
# BEFORE (legacy — agents embedded in config.json):
coding.opencode = {
enable = true;
agentsInput = inputs.agents;
externalSkills = [ ... ];
ohMyOpencodeSettings = { ... };
extraSettings = { ... };
};
# AFTER (new — file-based agents from canonical TOML):
coding.opencode = {
enable = true; # handles theme, plugins, formatter, oh-my-opencode
ohMyOpencodeSettings = { ... };
extraSettings = { ... };
};
coding.agents.opencode = {
enable = true;
agentsInput = inputs.agents;
externalSkills = [ ... ];
modelOverrides = {
chiron = "zai-coding-plan/glm-5";
"chiron-forge" = "zai-coding-plan/glm-5";
};
};
```
Key changes:
- `agentsInput` and `externalSkills` move from `coding.opencode` to `coding.agents.opencode`
- `modelOverrides` is new — per-agent model selection (previously hardcoded in agents.json)
- Skills, context, commands are now handled by the agents module
- Agents are deployed as file-based `~/.config/opencode/agents/*.md` instead of embedded in config.json
### Step 2: Run home-manager switch
```bash
home-manager switch --flake .
```
Verify that `~/.config/opencode/agents/` contains 6 `.md` files with the correct frontmatter.
### Step 3: Remove legacy files from AGENTS repo
After confirming everything works with the new setup:
```bash
cd /home/m3tam3re/p/AI/AGENTS
# Remove legacy agent definition
rm agents/agents.json
# Remove legacy prompt files (now in agents/*/system-prompt.md)
rm prompts/chiron.txt prompts/chiron-forge.txt prompts/hermes.txt \
prompts/athena.txt prompts/apollo.txt prompts/calliope.txt
rmdir prompts/ # if empty
# Remove backward-compat bridge from flake.nix
# 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.
### Step 4: Verify
```bash
# AGENTS repo: all TOML files parse
cd /home/m3tam3re/p/AI/AGENTS
for f in agents/*/agent.toml; do
nix eval --impure --expr "builtins.fromTOML (builtins.readFile ./$f)" --json > /dev/null && echo "OK: $f"
done
nix flake check
# nixpkgs: flake check passes
cd /home/m3tam3re/p/NIX/nixpkgs
nix flake check
# Home-manager: agents deployed correctly
ls ~/.config/opencode/agents/
```
### Optional: Enable other tool renderers
To also deploy agents for Claude Code or Pi, add to your home-manager config:
```nix
# Claude Code agents
coding.agents.claude-code = {
enable = true;
agentsInput = inputs.agents;
modelOverrides = { };
};
# Pi agents
coding.agents.pi = {
enable = true;
agentsInput = inputs.agents;
};
```
## Rules System ## Rules System
Centralized AI coding rules consumed via `mkOpencodeRules` from m3ta-nixpkgs: Centralized AI coding rules consumed via `mkCodingRules` from m3ta-nixpkgs
(`mkOpencodeRules` still works as backward-compat alias):
```nix ```nix
# In project flake.nix # In project flake.nix
m3taLib.opencode-rules.mkOpencodeRules { m3taLib.coding-rules.mkCodingRules {
inherit agents; inherit agents;
languages = [ "python" "typescript" ]; languages = [ "python" "typescript" ];
frameworks = [ "n8n" ]; frameworks = [ "n8n" ];

View File

@@ -167,26 +167,26 @@ support, "~" means partial/mapped support, "" means ignored.
| Field | OpenCode | Claude Code | Pi | | Field | OpenCode | Claude Code | Pi |
|-------|----------|-------------|----| |-------|----------|-------------|----|
| `name` | ✓ agent identifier | ✓ must be `[a-z0-9-]+` | in `AGENTS.md` | | `name` | ✓ agent identifier | ✓ must be `[a-z0-9-]+` | ✓ subagent frontmatter |
| `description` | ✓ agent picker | ✓ required | in `AGENTS.md` | | `description` | ✓ agent picker | ✓ required | ✓ subagent frontmatter |
| `display_name` | ✓ picker label | ignored | ignored | | `display_name` | ✓ picker label | ignored | in AGENTS.md |
| `mode` | ✓ maps to `mode` | all are subagents | primary only → `SYSTEM.md` | | `mode` | ✓ maps to `mode` | all are subagents | primary only → `SYSTEM.md` |
| `tags` | ~ future use | ignored | ignored | | `tags` | ~ future use | ignored | ignored |
| `max_turns` | ✓ maps to `steps` | ✓ maps to `maxTurns` | ignored | | `max_turns` | ✓ maps to `steps` | ✓ maps to `maxTurns` | ignored |
| `skills` | ✓ SKILL.md loaded | ✓ SKILL.md loaded | ✓ SKILL.md loaded | | `skills` | ✓ SKILL.md loaded | ✓ SKILL.md loaded | ✓ subagent `skill` field |
| `context` | ✓ injected | ✓ injected | ~ manual inclusion | | `context` | ✓ injected | ✓ injected | ~ manual inclusion |
| `rules` | ✓ rule injection | ✓ rule injection | ignored | | `rules` | ✓ rule injection | ✓ rule injection | ignored |
| `permissions.bash` | ✓ rule DSL | ✓ bash tool perms | no granularity | | `permissions.bash` | ✓ rule DSL | ✓ bash tool perms | ~ tool enable/disable |
| `permissions.edit` | ✓ path rules | ✓ path rules | no granularity | | `permissions.edit` | ✓ path rules | ✓ path rules | ~ tool enable/disable |
| `permissions.webfetch` | ✓ intent only | ✓ intent only | ignored | | `permissions.webfetch` | ✓ intent only | ✓ intent only | ~ tool enable/disable |
| `permissions.websearch` | ✓ intent only | ✓ intent only | ignored | | `permissions.websearch` | ✓ intent only | ✓ intent only | ~ tool enable/disable |
| `permissions.question` | ✓ intent only | not a tool | not a concept | | `permissions.question` | ✓ intent only | not a tool | not a concept |
| `permissions.external_directory` | ✓ path rules | not supported | not supported | | `permissions.external_directory` | ✓ path rules | not supported | ~ tools list (allow/ask → include) |
**Renderer summary**: **Renderer summary**:
- **OpenCode** — full support; most fields have direct mappings - **OpenCode** — full support; most fields have direct mappings
- **Claude Code** — strong support; drops `display_name`, `external_directory`, `mode` - **Claude Code** — strong support; drops `display_name`, `external_directory`, `mode`
- **Pi** — minimal support; reads `name`/`description` from `AGENTS.md`, skills via `SKILL.md`; permissions ignored - **Pi** — subagent support via `pi-subagents`; agent .md files with YAML frontmatter; permissions mapped to Pi tool list; skills via `SKILL.md`; AGENTS.md for discovery; SYSTEM.md for primary agent prompt
--- ---