From 0054ca793c7530fe7f18ee1e2c81fdc60c3935a9 Mon Sep 17 00:00:00 2001 From: Victor Vargas Date: Tue, 30 Jun 2026 23:53:34 -0700 Subject: [PATCH] docs: add AGENTS.md guide and skill definitions for AI agents --- .agents/skills/add-feature/SKILL.md | 121 ++++++++++++++++++++++++++++ AGENTS.md | 74 +++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 .agents/skills/add-feature/SKILL.md create mode 100644 AGENTS.md diff --git a/.agents/skills/add-feature/SKILL.md b/.agents/skills/add-feature/SKILL.md new file mode 100644 index 0000000..df76b90 --- /dev/null +++ b/.agents/skills/add-feature/SKILL.md @@ -0,0 +1,121 @@ +--- +name: add-feature +description: >- + Use ONLY when adding new features to rony-llm-agent or its downstream products + (rony-harness, rony-chat-bot). This skill enforces adherence to the architecture + spec and asks probing questions before any implementation. Trigger when the user + says "add feature", "implement X", "build Y", or describes a new capability not + yet in scope. +--- + +# Add Feature — Architecture-First Agent Skill + +## Purpose + +Guide the addition of new features to `rony-llm-agent` (or its consumers) while +**strictly following** [`docs/architecture.md`](../../docs/architecture.md). + +Before writing any code, you **must ask questions** about every aspect of the feature +that could affect: package boundaries, interfaces, dependencies, or security model. + +## Pre-Implementation Checklist + +### 1. Scope & Package Placement + +Read first, in this order: +1. `docs/architecture.md` — hexagonal layers, core interfaces, security model +2. `docs/components.md` — per-package boundaries and public APIs +3. `docs/phase2.md` — check if the feature overlaps or conflicts with Phase 2 backlog +4. `AGENTS.md` — code conventions (naming, errors, context usage) + +Then answer **before** proposing implementation: + +- [ ] Which package(s) need new interfaces vs existing ones? +- [ ] Does this create a new top-level `pkg//` or fit inside an existing one? +- [ ] What is the public-facing interface (port)? Can it be written as a pure Go interface? +- [ ] Is there an existing adapter that can extend, or does it need a new one? + +### 2. Interface Design + +For every new or modified interface: + +- Does the interface name follow capability naming? (`LLMClient`, `Loop`, `Embedder`, `Memory`) +- Does every method take `ctx context.Context` as first parameter? +- Are return types Go-native (structs, `iter.Seq2` for streams), not callbacks? +- Is the interface minimal — only what consumers actually need? + +### 3. Dependencies & Package Layers + +- Does the domain package (`pkg//`) import anything external except stdlib? + **NO.** External SDKs live in adapters under `internal/`. +- If a new package is needed, does its `import` path follow `github.com/VictorVargas/rony-llm-agent/pkg/`? +- Are adapters isolated behind interfaces? No adapter should leak into domain code. + +### 4. Security Model + +Refer to `docs/architecture.md` §4 — "Modelo de Seguridad": + +- Does the feature introduce new filesystem access? → Must use `os.Root` sandbox, never raw paths. +- Does it execute external commands? → Command validation needed; delegate to products. +- Does it accept user input into LLM prompts? → Consider `` wrapping (Phase 2). +- Are there permission implications for tools? → Use `Permission: Allow | Ask | Deny` policy. +- Is the feature compliant with least-privilege principle? + +### 5. Testing Strategy + +Before implementation, identify: + +- What existing mock can be reused? (`mock.MockLLMClient`, `mock.MockMemory`) +- Are there critical-path tests to add? See `docs/architecture.md` §6 — "Tabla de tests críticos" +- Is the test deterministic (no network calls) or integration (real provider/backend)? +- If streaming, does it properly consume the full `iter.Seq2` channel without goroutine leaks? + +### 6. Concurrency & Context Propagation + +- Does every blocking call take a context? +- Are contexts properly cancelled on timeout/interrupt? +- Is the new code safe for concurrent use by multiple products simultaneously? + +## Questioning Protocol + +**Never assume.** If an answer isn't explicitly in architecture.md, components.md, or phase2.md, ask: + +1. "Where does this belong architecturally?" — before writing anything +2. "What interface does this consume or provide?" — define ports first +3. "How does this interact with the sandbox/security model?" — always check permissions +4. "Which existing package depends on this?" — verify no circular deps +5. "What's the failure mode and error path?" — use `ErrXXX` sentinels + `%w` wrapping + +## Constraints (Never Break) + +| Constraint | Why | +|---|---| +| Go 1.26+ required | Uses `os.Root`, `iter.Seq2`, `unique.Handle` | +| No reflection, no codegen, no DSLs | "Zero magic" principle | +| Ports first, implementations second | Hexagonal architecture — ports are pure interfaces | +| All blocking takes `ctx context.Context` | Cancellation and timeout support | +| Sandbox with `os.Root`, not path prefix checks | Kernel-level guarantee against symlinks, TOCTOU, encoding attacks | +| Downstream-first validation | Check what harness/chat-bot does before implementing | + +## When to Defer to Phase 2 + +Do NOT implement these unless explicitly requested: + +- MCP server/client protocol +- Full RAG pipeline (beyond existing `pkg/rag/`) +- Skills system for agent behavior customization +- Sub-agents and hierarchical prompting +- Observability/tracing/export + +Reference `docs/phase2.md` if the feature overlaps. + +## Implementation Checklist + +After questions are answered: + +1. Define interfaces at top of package (`pkg//interface.go` or similar) +2. Create domain logic in `pkg//` (no external deps) +3. Implement adapters in `pkg//internal/` or provider-specific dirs +4. Add tests using mocks where possible +5. Run `go vet ./...`, then `go test ./...` once code exists +6. Document public interfaces in package-level godoc \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..67d2793 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,74 @@ +# AGENTS.md — Working in rony-llm-agent + +## Repo status: **Design/spec only** — no Go source exists yet. All code described in docs (architecture.md, components.md, phase2.md) is aspirational. The README explicitly states this library hasn't been implemented; once `harness/` ships, the lib will be extracted as real code following these specs. + +## What to read first + +| If you need... | Read... | +|---|---| +| Package layout and entrypoints | [`docs/architecture.md`](./docs/architecture.md) | +| Per-package boundaries | [`docs/components.md`](./docs/components.md) | +| Features not yet planned | [`docs/phase2.md`](./docs/phase2.md) — Phase 2 backlog | + +These three docs are the source of truth. **Read them before writing any code.** The `pkg/*/README.md` files mirror content from these docs; they're convenient but architecture.md is canonical. + +## How to build and test (once Go code exists) + +```bash +# Requires Go 1.26+ — required for os.Root, iter.Seq2, unique.Handle +go mod tidy # resolves imports, creates go.sum +go test ./... # all packages +go test -race ./... # race detector (always use in CI once implemented) +``` + +No Makefile, no linters configured yet. Once code exists: lint → typecheck → test is the expected order. Run `golangci-lint` if installed. + +## Key constraints to never break + +### Go version +Requires **Go 1.26+**. The module declares it in go.mod. Using older Go will not compile because of `os.Root`, `iter.Seq2`, `unique.Handle`. + +### Hexagonal architecture — package boundaries +- Interfaces (ports) live at the top level of each `pkg//` directory. These define the public API. +- Implementations (adapters) go in `pkg//internal/` or subdirectories like `pkg/llm/providers/openai/`, `pkg/rag/backends/chroma/`. +- Package names are lowercase, singular (`agent`, `tools`, `llm`, `rag`, `persona`). +- No external dependencies in domain packages — only stdlib and SDKs of providers (in adapters). + +### Module path +`github.com/VictorVargas/rony-llm-agent` — imported as-is by downstream products. + +### Streaming uses `iter.Seq2` +The library is designed around Go 1.23+'s `iter.Seq2[T, error]` for streaming LLM output. When implementing or reading code, this is the primary stream pattern. + +### Sandbox uses `os.Root` (Go 1.24+) +Filesystem sandboxing must use `os.Root`, not path string prefix checks. This is non-negotiable for security — naive prefix checks can't handle symlinks, TOCTOU, or path encoding attacks. + +## Testing conventions (when code exists) + +- Use `pkg/llm/mock.MockLLMClient` for deterministic tests that don't call real APIs. +- Use `pkg/rag/mock.MockMemory` for memory tests. +- All public API must be concurrent-safe (documented in architecture.md). +- Every function that can block takes `ctx context.Context` as the first parameter. + +## Code style conventions + +- Interfaces end with capability names: `LLMClient`, `Loop`, `Embedder`, `Memory`. +- Sentinel errors prefixed with `Err`: `ErrToolNotFound`, `ErrSandboxViolation`. +- Constructors use `New` for the primary and `NewXxx` for variants. +- Error wrapping uses `%w`, never lossy formatting. + +## Relationship to downstream products + +This library is consumed by: +- **rony-harness** — TUI agent for software development (the reference implementation that triggered this extraction) +- **rony-chat-bot** — HTTP chatbot for portfolios/websites + +If you're unsure about behavior, check what harness or chat-bot does first. They are the real-world consumers driving design decisions. + +## Agent skills + +Reusable skills for any AI agent live in `.agents/skills//SKILL.md` — this is the canonical, tool-agnostic location read by OpenCode, Claude Code, Cursor, and other modern agents. Each skill's `SKILL.md` starts with a YAML frontmatter (`name`, `description`) followed by instructions. Do not mirror skills into `.opencode/skills/` — opencode reads `.agents/skills/` natively. + +## Phase 2 awareness + +Phase 2 features (MCP server/client, full RAG pipeline, skills system, sub-agents, observability) are planned but not in scope for initial implementation. Do not start implementing phase 2 code unless explicitly asked. Reference `docs/phase2.md` for spec when needed.