# Architecture

## Zero External Dependencies

No external runtime dependencies — Node.js standard library only. `devDependencies` (Jest, Biome, etc.) are OK.

## File-Based State

No database. All state as YAML, JSON, JSONL, or Markdown files:
- DAG format: `dag.yaml`, `TaskStatus` enum (`pending` | `in_progress` | `completed` | `blocked`)
- Locking: DAG ops use file-based locking via `scripts/lib/locking.js`

## Worktree Isolation

Epics run in their own git worktrees, each tracked via an `.arcforge-epic`
marker file. Worktrees live at a home-based canonical location
(`~/.arcforge/worktrees/<project>-<hash>-<epic>/`) computed by
`scripts/lib/worktree-paths.js`; never hardcode worktree paths in skills,
rules, or tests. See `docs/guide/worktree-workflow.md` for the full
derivation rules and `skills/arc-using/SKILL.md` for the agent Worktree Rule.

## Component Responsibilities

| Directory | Role | Error Strategy |
|-----------|------|----------------|
| `scripts/lib/` | Core engine — canonical source | Throw with context |
| `hooks/` | Event-driven extensions | Silent catch |
| `skills/` | Markdown definitions (TDD for docs) | N/A |
| `templates/` | Subagent prompts with `{VARIABLE}` placeholders | N/A |
| `agents/` | Specialized subagent definitions | N/A |
| `docs/` | Design docs, platform guides | N/A |

**Exception:** the learning dashboard control plane (an HTTP server plus inline
HTML — `scripts/lib/learning-dashboard-http.js` and
`scripts/lib/learning-dashboard.html`) lives in `scripts/lib/` as an
intentional exception to the file-based-engine role. It is a local review/control
surface, not part of the DAG engine, but it ships in the canonical lib directory.

## Canonical Source Rule

`scripts/lib/` is canonical. Hooks import directly from it (e.g. `require('../../scripts/lib/utils')`) — there is no `hooks/lib/` re-export layer. Never duplicate logic — import from the canonical location.

## Skill Routing & Composition

`arc-using` is a **bounded router** and skill index. SessionStart injects only a minimal bootstrap; it does not inject full `arc-using` content or mandatory global routing language.

Use the smallest useful workflow. Respect user constraints, higher-priority instructions, and harness/eval isolation. For simple answers, read-only inspection, grading, or single-skill evals, do not force routing.

Skills compose in three ways depending on type:

| Skill Type | Composition | Mechanism |
|------------|-------------|-----------|
| Workflow | Sequential handoff | Each skill's "After This Skill" section defines next step |
| Discipline | Conditional routing | `arc-using` maps concrete conditions → skills |
| Meta | Direct invocation | User, maintainer, or project-level task triggers as needed |

Discipline skills (arc-tdd, arc-debugging, arc-verifying, arc-requesting-review, arc-receiving-review, arc-evaluating) are quality gates that fire when their condition is actually present. They should be documented in `arc-using`'s conditional trigger table, but they are not mandatory steps for every message.

## Multi-Platform

| Scope | Components |
|-------|-----------|
| Platform-agnostic (all platforms) | Skills, CLI, Templates |
| Claude Code-specific | Hooks, Commands, Agents |

## Directory Layout

```
scripts/          # Node.js CLI and core engine
hooks/            # Claude Code event hooks
skills/           # Markdown skill definitions
templates/        # Subagent prompt templates
agents/           # Specialized subagent definitions
docs/             # Design docs, platform guides
```

Worktrees live outside the repo at `~/.arcforge/worktrees/` — derived by
`scripts/lib/worktree-paths.js`, not a tracked directory.
