Generate and maintain architecture guidance for a repository. Explores the repo via LLM, reads directory structure, manifests, configs, and imports, then generates `.archeia/` docs, `AGENTS.md`, and `CLAUDE.md`. Maximizes determinism through structured templates, evidence grounding, and self-validation.
/archeia is the write path for Archeia.
Its job is to:
.archeia/ docs using structured templatesAGENTS.md and CLAUDE.mdThe durable output is maintained guidance, not a one-time scan report.
<!-- TEMPLATE META-STRUCTURE Every template in templates/ follows this structure: 1. YAML frontmatter (layer, depends_on, required_evidence, validation) 2. Purpose — what this document is and who reads it 3. Required Sections — sections that MUST appear in output 4. Conditional Sections — sections that appear only if evidence supports them 5. Inference Signals — what repo evidence maps to what content for this template 6. Quality Rubric — completeness, truthfulness, conciseness, determinism criteria 7. Anti-Patterns — DO NOT examples of bad output 8. Example Output — condensed example of good output (Layer 3 templates only) Frontmatter fields: - layer: 3 (auto-generate from evidence) or 2 (requires human confirmation) - depends_on: comma-separated template names that must be generated first - required_evidence: comma-separated file patterns to read before generating - validation: comma-separated quality checks for the self-validation pass The skill reads frontmatter to determine generation order and validation criteria. Frontmatter is consumed by the skill — it is NOT included in generated output. -->Before exploring the repo, check if .archeia/ already exists.
.archeia/ exists: ask the user whether to refresh (regenerate Layer 3
docs only, preserve all Layer 2 docs) or overwrite (regenerate everything
from scratch). Refresh is the default recommendation..archeia/ does not exist: proceed with full init.Read repo files in this exact priority order. Within each category, read files alphabetically. Stop exploring after reading ~30 files total — shift to generation if the budget is reached. If a critical file is discovered late, reading it is fine.
Priority 1 — Root manifests (read all that exist):
package.json, pyproject.toml, Cargo.toml, go.mod, Gemfile,
composer.json, pom.xml, build.gradle, Mix.exs, deno.json
Priority 2 — Root configs (read all that exist):
tsconfig.json, tsconfig*.json, ruff.toml, pyproject.toml [tool.*],
.eslintrc*, .prettierrc*, biome.json, Makefile, Justfile,
Taskfile.yml, Dockerfile, docker-compose.yml, fly.toml, render.yaml,
railway.json, vercel.json, netlify.toml
Priority 3 — Root docs (read all that exist):
README.md, CONTRIBUTING.md, CHANGELOG.md, AGENTS.md, CLAUDE.md
Priority 4 — CI/CD (read first 3 files alphabetically):
.github/workflows/*.yml, .gitlab-ci.yml, .circleci/config.yml
Priority 5 — Test setup (read config files, not test bodies):
tests/conftest.py, jest.config.*, vitest.config.*, test/test_helper.*,
.nycrc, pytest.ini, setup.cfg [tool:pytest], phpunit.xml
Priority 6 — Source sampling (read first 5 files alphabetically):
Files in src/, lib/, app/, or the primary source directory. Focus on
entry points and module index files (index.*, main.*, app.*, mod.rs).
Priority 7 — Existing .archeia/ (if refreshing):
All files in .archeia/ to understand current state.
Use this table to map discovered files to conclusions. When signals conflict, follow the priority order: manifest content > file extensions > directory structure > README claims.
| Signal | Conclusion |
|---|---|
package.json exists | Node.js/JavaScript project |
package.json has "type": "module" | ESM modules |
package.json → dependencies has react | React frontend |
package.json → dependencies has express/fastify/hono | HTTP server framework |
package.json → dependencies has next | Next.js full-stack |
package.json → devDependencies has typescript | TypeScript project |
package.json → scripts has test | Has test runner |
tsconfig.json exists | TypeScript (confirms) |
pyproject.toml exists | Python project |
pyproject.toml → [tool.ruff] | Uses ruff linter |
pyproject.toml → [tool.black] | Uses black formatter |
pyproject.toml → [tool.mypy] | Uses mypy type checker |
pyproject.toml → [tool.pytest] | Uses pytest |
requirements.txt / setup.py | Python (legacy packaging) |
Cargo.toml exists | Rust project |
go.mod exists | Go project |
Gemfile exists | Ruby project |
composer.json exists | PHP project |
pom.xml / build.gradle | Java/JVM project |
Mix.exs exists | Elixir project |
deno.json exists | Deno runtime |
Dockerfile exists | Containerized deployment |
docker-compose.yml exists | Multi-service local dev |
fly.toml | Deploys to Fly.io |
vercel.json / netlify.toml | Serverless/JAMstack deploy |
render.yaml / railway.json | PaaS deployment |
.github/workflows/ | GitHub Actions CI/CD |
.gitlab-ci.yml | GitLab CI |
Makefile / Justfile / Taskfile.yml | Has task automation |
tests/ / __tests__/ / spec/ / test/ | Has test directory |
.pre-commit-config.yaml | Uses pre-commit hooks |
src/ directory | Standard source layout |
lib/ directory | Library-style source layout |
app/ directory | Application-style layout (Rails, Next.js, etc.) |
packages/ / apps/ | Monorepo with workspaces |
.env.example | Environment-variable configuration |
uv.lock / poetry.lock | Python lockfile (uv or poetry) |
pnpm-lock.yaml / package-lock.json / yarn.lock | JS lockfile |
Generate Layer 3 docs in this order (respecting dependencies):
templates/ARCHITECTURE.md frontmatter and body.archeia/ARCHITECTURE.md from collected signalstemplates/SYSTEM.json example.archeia/SYSTEM.json — follow the example structure exactly,
replacing example data with evidence from this repo. Rules:
system: exactly one object, sourced from manifest + READMEpeople: infer from README audience, auth roles, route groups. Empty [] if none foundexternal_systems: every external service confirmed by manifest deps or docker-composerelationships: connect every entity. Every source/target must resolve to an id aboveevidence array with at least one file pathtemplates/CONTAINERS.json example.archeia/CONTAINERS.json — follow the example structure. Rules:
system_boundary: must match system from SYSTEM.json (same id, name, description)containers: runtime units (processes, databases, caches), NOT source directories.
type is one of: webapp | api | database | cache | queue | filesystem | worker | cliexternal_systems: carried forward from SYSTEM.json, must match exactlyrelationships: container-to-container and container-to-externalpeople_container_mappings: include only if SYSTEM.json has people, omit key otherwisetemplates/COMPONENTS.json example.archeia/COMPONENTS.json — follow the example structure. Rules:
containers: one entry per container from CONTAINERS.json with internal source code.
Skip containers with no app-side code (e.g., managed databases without schema code)components: code-level modules (directories/packages, not files).
type is one of: module | service | controller | repository | middleware | handler | library | config
Prefix IDs with container ID (e.g., api-routes, worker-jobs)external_systems: include only if components talk directly to externalsrelationships: focus on architecturally significant connections (layer crossings,
module boundaries, external integrations). Do NOT enumerate every importtemplates/STANDARDS.md frontmatter and body.archeia/STANDARDS.md (may reference ARCHITECTURE for topology)templates/GUIDE.md frontmatter and body.archeia/GUIDE.md (may reference ARCHITECTURE + STANDARDS)For each generated file:
<!-- INSUFFICIENT EVIDENCE: [description] --> for gapsAfter generating all Layer 3 docs, run a validation pass:
Step 1 — Rubric check: Re-read each generated file. For each template's quality rubric (listed at the bottom of the template), verify the output meets every criterion. Fix issues inline using the Edit tool. One fix pass maximum — if an issue persists after one fix attempt, note it and move on.
Step 2 — File-existence verification: Extract every file path cited in the
generated docs (paths like package.json, src/index.ts, etc.). Use Glob to
verify each path exists in the repo. Remove or annotate any citation where the
file does not exist.
Step 3 — Validation summary: Print a summary for the user:
If this is a full init (not just Layer 3 refresh):
AGENTS.md and CLAUDE.md.If this is a Layer 3 refresh: skip this phase, preserve existing Layer 2 docs.
<!-- INSUFFICIENT EVIDENCE: ... -->.Layer 3 (auto-generated, no human input):
.archeia/ARCHITECTURE.md.archeia/SYSTEM.json.archeia/CONTAINERS.json.archeia/COMPONENTS.json.archeia/STANDARDS.md.archeia/GUIDE.mdLayer 2 (requires human confirmation):
.archeia/DECISIONS.md.archeia/CONSTRAINTS.md.archeia/PREFERENCES.md.archeia/ASSUMPTIONS.mdSynthesis (combines Layer 2 + Layer 3):
AGENTS.mdCLAUDE.mdBelow is a condensed example of what .archeia/ARCHITECTURE.md should look
like for a Node.js Express API project. This demonstrates evidence-citing style,
section structure, and appropriate level of detail.
# Architecture
## System Overview
This is a Node.js REST API built with Express and TypeScript. It serves as the
backend for a task management application.
**Evidence:** `package.json` (Express 4.18, TypeScript 5.3), `tsconfig.json`
(strict mode, ES2022 target)
## Topology
- **Type:** Single-process HTTP server (monolith)
- **Primary areas:** `src/routes/`, `src/services/`, `src/models/`
- **External systems:** PostgreSQL (via `pg` in dependencies), Redis
(via `ioredis` in dependencies)
**Evidence:** `package.json` dependencies, `src/` directory structure,
`docker-compose.yml` (postgres and redis services)
## Module Boundaries
| Module | Path | Responsibility | Dependencies |
|--------|------|---------------|-------------|
| Routes | `src/routes/` | HTTP request handling | Services |
| Services | `src/services/` | Business logic | Models |
| Models | `src/models/` | Data access, ORM models | pg driver |
| Middleware | `src/middleware/` | Auth, logging, error handling | — |
**Evidence:** `src/` directory listing, import patterns in `src/routes/index.ts`
## Data Flow
1. HTTP request → Express middleware chain (`src/middleware/`)
2. Route handler (`src/routes/`) validates input
3. Service layer (`src/services/`) executes business logic
4. Model layer (`src/models/`) queries PostgreSQL
5. Response serialized and returned
**Evidence:** `src/routes/tasks.ts` imports from `src/services/taskService.ts`,
which imports from `src/models/task.ts`
## Build and Development
- **Package manager:** pnpm (`pnpm-lock.yaml` present)
- **Build:** `tsc` via `package.json` scripts.build
- **Dev server:** `tsx watch` via `package.json` scripts.dev
- **Test runner:** vitest (`vitest.config.ts` present)
**Evidence:** `package.json` scripts section, `pnpm-lock.yaml`, `vitest.config.ts`
## Change Notes
- **High-risk areas:** `src/models/` (database schema changes),
`src/middleware/auth.ts` (authentication logic)
- **Stable areas:** `src/routes/` (thin handlers, low logic density)
- **Open questions:** None at Layer 3 — architecture decisions deferred to
DECISIONS.md
Choose the lightest mode that fits the repo:
The run is successful when: