feat: config with agents rework
This commit is contained in:
12
.sisyphus/notepads/harness-agnostic-migration/issues.md
Normal file
12
.sisyphus/notepads/harness-agnostic-migration/issues.md
Normal 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`
|
||||
251
.sisyphus/notepads/harness-agnostic-migration/learnings.md
Normal file
251
.sisyphus/notepads/harness-agnostic-migration/learnings.md
Normal 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
|
||||
Reference in New Issue
Block a user