docs: add AGENTS.md guide and skill definitions for AI agents
This commit is contained in:
parent
c25243a690
commit
0054ca793c
2 changed files with 195 additions and 0 deletions
121
.agents/skills/add-feature/SKILL.md
Normal file
121
.agents/skills/add-feature/SKILL.md
Normal file
|
|
@ -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/<name>/` 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/<name>/`) 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/<name>`?
|
||||||
|
- 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 `<untrusted_content>` 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/<name>/interface.go` or similar)
|
||||||
|
2. Create domain logic in `pkg/<name>/` (no external deps)
|
||||||
|
3. Implement adapters in `pkg/<name>/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
|
||||||
74
AGENTS.md
Normal file
74
AGENTS.md
Normal file
|
|
@ -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/<name>/` directory. These define the public API.
|
||||||
|
- Implementations (adapters) go in `pkg/<name>/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/<name>/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.
|
||||||
Loading…
Reference in a new issue