Forja
Turn coding AI into an engineering team with process and memory:
every project starts from a spec, every decision becomes an ADR, and nothing is lost between sessions.
English · Português
Why Forja exists
Coding agents are amnesiac and undisciplined: every session starts from zero, architecture decisions evaporate, code drifts from intent — and if you run several products at once, you pay that tax multiplied by N.
Forja is the studio around the AI. It coordinates 6 agent roles through a
Spec-Driven (SDD) + Get-Stuff-Done (GSD) pipeline, keeps a hierarchical memory indexed
in SQLite that survives across sessions, and ties it all together behind a single core CLI with
gates and an audit trail (forja, ADR-0020). Multi-AI by design (Claude, Copilot, Gemini,
Codex). Everything is driven from the CLI.
Who it's for: the solo dev or small team running multiple products with AI as the main workforce — and needing the discipline of a big team without having one.
The 3 pillars
| Pillar | What it delivers | Proof |
|---|---|---|
| Memory that survives | hierarchical, searchable context, shared across sessions and AIs | SQLite FTS5, smart-context (ADR-0003) |
| Process that governs | nothing becomes code without a spec; nothing structural without an ADR; every command audited | SDD+GSD, 7-field handoffs (ADR-0005), forja core (ADR-0020) |
| A factory, not a single project | multi-product workspace, per-project agent teams | ADR-0019, harness, codegraph (ADR-0017) |
This repository is the engine (framework) — it does not host production apps. Your products live in the Forja workspace (
~/forja-workspaceby default), outside this repo. See ADR-0019 for the rationale.
Forja in 60 seconds
$ forja spec:new pix-payments
✓ Spec created: specs/pix-payments/spec.md # nothing becomes code without this
$ forja gsd:handoff plan pix-payments
Handoff recorded: product → sdd-architect # 7 fields, auditable (ADR-0005)
$ forja code:impact processPayment
Impact map: processPayment (depth 2) # blast radius BEFORE you edit
--- Direct callers ---
BillingController.charge · RetryWorker.run
$ forja gsd:check pix-payments
OK GSD runbook OK Spec directory
OK SDD spec check OK Codegraph
Result: baseline gates ready. # executable governance, not a checklist
And each command above was recorded in .context/forja-runs.jsonl — when governance asks "was the
process followed?", the answer is a file, not a promise.
Why not just…?
| Alternative | Where it stops | What Forja adds |
|---|---|---|
| Plain Claude Code / Copilot | brilliant in-session, amnesiac between sessions | FTS5 memory + process + audit around the AI |
| LangGraph / CrewAI | infrastructure to build agents | the layer above: it operates the agent team day to day |
| Templates & spec kits | stop once the spec is written | the full pipeline through governance, with gates that execute |
Key capabilities
- Single core CLI — every process command goes through
forja <command>: a declarative registry, cross-cutting gates (workspace), and append-only audit in.context/forja-runs.jsonl(ADR-0020). - Multi-agent orchestration — 6 roles (orchestrator, context-engineer, sdd-architect, product, marketing, governance) with tracked handoffs (7 fields, ADR-0005).
- Hierarchical memory — global → domain → task → summary, with FTS5 search and smart-context in 3 modes (ADR-0003).
- SDD + GSD pipeline —
spec → plan → tasks → check, decisions recorded as ADRs. - Self-verification (invariants that run) — the framework proves itself: a family of gates guards
each frontier (core, tarball, doc coherence, agent topology, generated project), and
check:allruns the whole battery into a single verdict. Governance stops depending on discipline — it becomes harness. - Token economy measured, not asserted — memory (the
context.mdas a map) saves ~60% vs exploring cold, andtoken:economyproves it across your domains.code:contextdelivers the map ready to paste;memory:auditguarantees it doesn't lie about the code. - Projects born connected to your AI —
project:newscaffolds a full project (memory, agents, a NestJS backend as the default boilerplate) and wires it to the AI you use: native instructions (AGENTS.md,CLAUDE.md,GEMINI.md, Copilot), Claude Code hooks that open every session with the project state and attach the spec you mention, six role sub-agents, and the Forja MCP server in Claude, Codex, Gemini and Copilot (VS Code). The memory is indexed from the first minute.project:wire --checkproves it;project:upgrade --applyre-wires older projects without touching the user's code — or the whole workspace with--all(ADR-0086). The NestJS backend follows the official NestJS 12 layout (ESM, Vitest, oxlint) and its/api/opspage shows the project's specs, open handoffs and indexed memory. - Validated templates —
project:new <name> --template clean-archstarts from a boilerplate whose install, build, tests and lint are proven in CI;project:templateslists what is a template and what is reference architecture (ADR-0088). - The user journey is a gate —
npm testandrelease:checkrun the whole journey (workspace → project → memory, context, specs, hooks, MCP, handoffs inside the project) against the source and against the installed tarball, and fail if any command writes into the package itself. - 3 integrated capabilities (ADR-0016): codegraph (code analysis via MCP), harness (agent-team design), ai-engineering (knowledge base).
- LLM Fit Loop — adapters de CLI, perfis no workspace, probes sem custo, observações e recomendação determinística por papel/tarefa; credenciais nunca entram no Forja.
- Engineering Control Plane (v3.0, ADR-0078) — the Engineering Graph turns ADRs/SPECs into
first-class, queryable nodes; the Architecture Constitution checks real code against decisions
already recorded; the Change Risk Engine scores a change 0-100 with named, evidenced factors;
forja simulatetests a ref in an isolated worktree and never promotes on its own. One façade,forja engineer "<goal>", composes all of it — context, relevant ADRs, architecture check, risk, recommended agents, similar past incidents — before you start. Every score is information for a human/policy rule to consult, never an autonomous decision on its own.
Quick start
# Install (the package is forjajs; the command is forja)
npm install -g forjajs
forja # help grouped by domain
# Prepare the production workspace (the fixed home for your projects)
forja workspace:init
# Create a new project (generated in ~/forja-workspace/projects/<name>, already wired to your AI)
forja project:new my-project --ai claude,copilot
cd ~/forja-workspace/projects/my-project
forja project:wire --check # instructions, hooks, sub-agents and MCP connected
forja status # memory indexed, specs, handoffs — then open your AI here
# Enter the SDD/GSD cycle for the first feature
forja spec:new my-feature
forja spec:plan my-feature
forja spec:tasks my-feature
forja spec:check my-feature
Already have a repository?
cd my-existing-app
forja project:wire --ai claude,codex # native instructions, hooks, sub-agents, MCP
forja project:upgrade --apply # memory and agents layer (additive: no backend, no overwrites)
forja sync:universal # index the memory
Maintenance commands
forja project:upgrade --apply # inside the project: new scaffold pieces + re-wire (pre-v5 projects)
forja project:upgrade --all # every workspace project: dry-run report (--apply to apply)
forja project:wire --check
forja code:context <domain> --code
forja memory:audit
forja token:economy --project <project>
forja spec:set-status <feature> <spec|plan|tasks> <draft|approved>
Prove supervised autonomy locally
The deterministic offline proof uses an external fixture, a real Git worktree,
human approval, a real npm test, diff validation, promotion, SQLite state,
GraphLoop evidence and a compact handoff:
npm run demo:autonomy
The full flow is documented in docs/2x/SPRINT-12-REAL-AUTONOMY-PLAN.md.
Measure the deterministic context baseline and cache evidence:
npm run benchmark:context
The sandbox also exposes an explicit, auditable rollback after promotion. Official
plugin boundaries are available as @forja/plugin-github and @forja/plugin-docker;
external network or Docker handlers must be injected and permissioned by the host.
Cloned the repo instead of installing? The same commands run as
node bin/forja.ts <command>— the npm scripts are just thin aliases of the core. The source is TypeScript and runs natively: dev needs Node ≥ 22.6 (type stripping). The published package shipsdist/*.jsand requires Node ≥ 22 — therelease-gateinstalls the tarball and runs the full user journey on it every release (SPEC-012, ADR-0086).
Step by step on create vs update a project: docs/processo-projeto.md.
How it works — the process
💡 Demand
├─ project does NOT exist ─► project:new + boilerplate + harness (designs the team)
└─ project DOES exist ─────► overlay --only-memory + codegraph init (understands the code)
│
▼
CLI-first CYCLE (docs/fluxo.md):
1·Understand → 2·Specify → 3·Architect → 4·Decompose → 5·Implement → 6·Govern → ✅
| Step | Role | Capability |
|---|---|---|
| 1 Understand | context-engineer | codegraph · ai-engineering |
| 2 Specify | product | — |
| 3 Architect | sdd-architect | harness · ADR |
| 4 Decompose | sdd-architect | — |
| 5 Implement | orchestrator + worker | codegraph (MCP) |
| 6 Govern | governance | codegraph (affected) |
Full cycle map: docs/fluxo.md.
The 3 integrated capabilities
| Capability | Role | How to use |
|---|---|---|
| codegraph | code analysis (local MCP) | forja code:index · codegraph explore "<area>" · MCP tools codegraph_explore/codegraph_node |
| harness | agent-team design (plugin) | in a Claude Code session: "build a harness for this project" → generates .claude/agents + .claude/skills |
| ai-engineering | knowledge base (reference) | see docs/capacidades-externas.md |
Details and reinstall: docs/capacidades-externas.md · ADR-0016.
The forja core
Every process command goes through a single entry point (ADR-0020):
forja # help grouped by domain
forja <command> [args] # in a cloned repo: node bin/forja.ts <command>
The core applies gates before running (e.g. product commands fail fast without a workspace) and
records an audit of each run (command, args, exit code, duration) in
<workspace>/.context/forja-runs.jsonl — the trail governance uses at review. The repo's npm
scripts are thin aliases that route through the core.
Essential commands
# Orientation — the happy path
forja status # where am I: workspace, sprint, run, specs, runs, handoffs
forja next # what now: one line — the next action + the exact command
forja help [<command>|--all] # the core, or one command's usage/args/examples/next steps
# Workspace & projects
forja workspace:init # create ~/forja-workspace
forja project:new <name> --ai claude,copilot # create a project in the workspace, wired to the AI
forja project:wire [--check] # (inside a project) connect/verify instructions, hooks, MCP
forja project:upgrade --apply # (inside a project) bring new scaffold + re-wire; --all for the workspace
forja project:templates # validated templates (project:new --template) vs reference
forja project:list # list workspace projects
forja workspace:project:check <name> # validate standards in a workspace project
# SDD pipeline
forja spec:new <slug> # also: spec:plan · spec:tasks · spec:check
# Sprint & handoffs (GSD)
forja sprint:start # also: sprint:status · sprint:complete
forja gsd:plan <slug> # GSD runbook in .context/
forja gsd:handoff <intent> <slug> # role-to-role handoff (ADR-0005)
forja agent:route list --open --mine # open handoffs of this project (each one stamped with its project)
forja gsd:check <slug> # baseline runbook gates
forja orchestrate "<goal>" --slug <s> # the default path: the whole SDD/GSD chain as a gated state machine (SPEC-021)
forja orchestrate:status <slug> # the machine state: stages, gates, verdicts
forja orchestrate:advance <slug> # run the stage gate; green → next; red → blocked
# Code analysis (codegraph)
forja code:check # trustworthy index (worktree + freshness)
forja code:impact <symbol> # callers + blast radius before you edit
forja code:query "<term>" # also: code:index · code:sync · code:status
forja drift:check [--domain <d>] # reindex + flag 'verified' relations that stopped being true
forja adr:list # ADRs as first-class graph nodes, with status (SPEC-032)
forja adr:show <id> # status, source file, constraints
forja adr:impact <id> # who/what depends on this ADR — GraphLoop.impact()
forja adr:graph [<id>] # ADR/SPEC subgraph as JSON
forja architecture:compile # ADRs (## Constraints) → constitution.json (SPEC-033)
forja architecture:check # real code vs. the compiled Constitution
forja architecture:status # active/proposed rules, last compile
forja architecture:explain <rule-id> # source ADR, original text, severity
forja architecture:approve <rule-id> # promotes a proposed rule to active (via ApprovalLedger)
forja risk:assess [ref] # 0-100 change risk score, 7 named factors (SPEC-034)
forja risk:explain <assessment-id> # replays a computed assessment, factor by factor
forja evidence:show <run-id> # aggregated view of a persisted run (SPEC-035)
forja engineer "<objetivo>" [--ref <ref>] [--role <role>] [--json] # façade: context + relevant ADRs + architecture check + risk + recommended agents + similar incidents + recommended flow (SPEC-035, SPEC-042)
forja agent:register <id> --role <role> [--provider <p>] [--model <m>] [--capabilities <c1,c2>] [--domains <d1,d2>] # register/update an agent (SPEC-036)
forja agent:list # registered agents, with trustLevel if already scored
forja agent:show <id> # detail of one registered agent
forja agent:score <id> [--domain <d>] # computes and persists trustLevel/autonomyLevel from real Observations
forja agent:history <id> # an agent's Observations, most recent first
forja agent:recommend --role <role> [--domain <d>] # ranks registered agents by fit — information, not assignment (SPEC-037)
forja simulate <ref> [--command "npm test"] [--json] # test+architecture+risk against an isolated worktree, never promotes (SPEC-038)
forja provenance:record <run-id> # extracts file<->agent provenance from a persisted RuntimeRun (SPEC-039)
forja blame <file> # provenance history for a file — file granularity, not line
forja sbom [--json] # AI-SBOM: provenance report aggregated by agent
forja agent:monitor <id> [--window-hours <n>] # compares recent behavior against historical baseline — information, never blocks (SPEC-040)
forja incident:record --title <t> [--description <d>] # records an incident in the Engineering Graph (SPEC-041)
forja incident:list # recorded incidents, most recent first
forja incident:similar "<query>" # keyword-based similar-incident suggestion — never applies anything
# Memory & context (workspace)
forja sync:universal # reindex the workspace SQLite FTS5
forja query:universal "<query>" # FTS5 search
forja context:smart --mode task --task pix # smart-context: global | domain | task (ADR-0003)
forja memory:compress # archive old runs + VACUUM
forja memory:extract # extract global knowledge from memory
# LLM adapters and evidence
forja llm:profiles:init # create workspace-local adapter profiles
forja llm:doctor # verify configured CLIs without invoking a model
forja llm:recommend --role worker --task implementation
forja llm:run --profile codex --task specs/my-feature/spec.md
forja llm:eval --scope model --id codex:default
forja cost:economy # real $ cost per model, from the observation store
# Quality & release
forja project:check # framework standards (pre-commit)
forja tools:doctor # core X-ray; tells permission/lock from corruption; exit 1 if broken
forja release:check --publish # tarball gate before publishing
forja project:smoke # generated-project gate; --full installs+builds; --ai <list> checks native instructions
forja project:dashboard # static status report
forja hook:session-start # what Claude Code runs at session start (briefing)
forja hook:user-prompt # what it runs per prompt (attaches the cited spec)
# Governance & audit
forja audit:sync # project the audit trail into a queryable table
forja audit:query --failed # query: --failed, --cmd <x>, --since 7d
forja governance:dashboard # static HTML panel (gates, SDD, audit) — no server
Framework vs workspace separation
Forja is split in two:
- Framework (this repository): the engine, conventions, scripts, and the framework's own memory.
- Workspace (
~/forja-workspaceby default): the "fixed home" where product projects, their universal memory, and product specs live.
The workspace path is resolved by priority:
FORJA_WORKSPACEenvironment variableworkspaceRootfield in~/.forjarc.json- Default:
~/forja-workspace
See ADR-0019 for the architectural decision.
Repository structure (framework)
bin/ CLIs (forja — the core; init-project, create-memory-nest-kit)
lib/ Reusable modules; lib/core/ is the invariant engine (registry, checks, health, release, doc-graph, gates)
scripts/ Automation (sprint-manager, agent-router, sync-universal-memory, …)
specs/ The framework's own SDD pipeline (spec → plan → tasks)
boilerplates/ Stack templates (api-rest, saas, ecommerce, microservices, monorepo)
memory/ Framework memory (00-global … 90-decisions/ADRs)
docs/ Documentation by persona and by topic (see DOC-MAP.md)
prompts/ Portable prompts for the 6 roles
.claude/ Claude Code sub-agents and settings
projects/ LEGACY — do not use; projects live in the external workspace
Workspace structure
~/forja-workspace/
projects/ # generated products
memory/
sqlite/universal.db # SQLite FTS5 for the products
30-projects/ # project records
specs/ # product specs
.context/ # product GSD runbooks
README.md
Inside a generated project
my-project/
AGENTS.md # how to operate the project — read natively by Codex, Copilot agent, Gemini
CLAUDE.md, GEMINI.md # import AGENTS.md (+ .github/copilot-instructions.md for Copilot)
.claude/
settings.json # hooks: forja hook:session-start / hook:user-prompt
agents/ # orchestrator, product, sdd-architect, context-engineer, governance, marketing
.mcp.json # forja MCP server (+ codegraph when installed)
.codex/config.toml # forja MCP for Codex · .gemini/settings.json (Gemini) · .vscode/mcp.json (Copilot)
.forja/models.json # AI fallback chain (engine switch)
memory/ # hierarchical memory, indexed in memory/sqlite/ (git-ignored)
specs/ # spec → plan → tasks
backend/ # NestJS 12, ESM + Vitest + oxlint (unless --skip-backend; or the --template's)
The Forja-managed part of each instruction file lives between <!-- forja:begin --> and
<!-- forja:end -->; everything outside it is yours and survives project:wire/project:upgrade.
Documentation
The docs are written in Brazilian Portuguese — that's part of the project's identity. The CLI output, code, and ADRs are readable regardless of language.
DOC-MAP.md— map by role and by topic (start here)docs/processo-projeto.md— create vs update a projectdocs/fluxo.md— the CLI-first cycle mapAGENTS.md— the 6 roles and the topologymemory/90-decisions/— ADRs with rationaleCHANGELOG.md— history
Conventions
- CLI-first — sprints, SDD, GSD, handoffs, and governance by command; the UI is never a gate.
- ADRs — every structural decision becomes
memory/90-decisions/NNNN-title.md. - Handoffs — 7 required fields (ADR-0005), stored in SQLite (ADR-0008).
- Releases — every new version reconciles the README with its behavior and opens its
CHANGELOG.mdentry with a### O que melhorousection (product-language diff vs. the previous version, reused as the GitHub release note). Runbook:docs/publishing.md. - pt-BR — communication and documentation in Portuguese.
Roadmap
The throughline: turn knowledge that lives as convention into an executable invariant. Each item below either closes a framework frontier with a gate, or carries that pattern into generated projects.
Shipped (v3.0.0 — Engineering Control Plane, ADR-0078)
- Engineering Graph — ADRs/SPECs as first-class, queryable nodes (
adr:list/show/impact/graph), deterministic extraction, no LLM (SPEC-032). - Architecture Constitution — ADR
## Constraintscompile into rules checked against real code (architecture:compile/check/status/explain/approve), reusingApprovalLedger, not a parallel approval system (SPEC-033). - Change Risk Engine — a 0-100 score with 7 named, evidenced factors (
risk:assess/explain);PolicyEnginecan optionally consult it (riskScoreRange), never a parallel decision engine (SPEC-034). - Evidence Ledger +
forja engineer— a per-run aggregated view, and the façade that composes context + relevant ADRs + architecture + risk + recommended agents + similar incidents + recommended flow before you start (SPEC-035, extended in SPEC-042). - Agent Identity & Reputation, Smart Routing — persistent agent registry with reputation
derived from real behavior, never self-declared (
agent:register/score/recommend, SPEC-036/037). - Predictive Change Simulation —
forja simulate <ref>tests a ref in an isolated git worktree; never promotes on its own (SPEC-038). - AI Code Provenance + Runtime Monitoring —
forja blame/sbom(file-granularity provenance),agent:monitor(behavior-anomaly detection vs. an agent's own baseline) — both information forPolicyEngine/a human to consult, never automatic (SPEC-039/040). - Learning Loop —
incident:record/list/similar, keyword-based suggestion, never automatic application (SPEC-041). - Autonomous Maintenance readiness — ADR-0079 documents the guardrails any future real autonomous-maintenance spec must respect; deliberately not enabled yet, by the vision's own design.
Shipped (through v1.6.0)
- Gate family — every framework frontier is guarded by an invariant that runs: core
(
tools:doctor, ADR-0023), tarball (release:check, ADR-0024), doc + ADR + agent-topology coherence (ADR-0025, SPEC-019), generated project (project:smoke, ADR-0029). Andcheck:allruns the whole battery into one verdict (SPEC-020). - TypeScript migration complete — source 100%
.ts, shipsdist/,noImplicitAnyON. Found latent bugs no test caught (SPEC-012). - Memory economy as a system — measured (
token:economyproves ~60% vs cold), delivered (code:context), protected (memory:audit, both directions), and propagated: the generated project inherits the maps gate (ADR-0030). -
project:upgrade— update an already-generated project without losing code: additive, never overwrites (SPEC-018). - Calibrated Clean Architecture — layers where they pay off, lean where they don't; and the token claim measured and corrected — the saving is memory's, not the layers' (ADR-0027).
- Generated backend
buildsunder new toolchains — the template now matches the framework'sbetter-sqlite3(^12, with prebuilds);check:all --fullcompiles the generated backend on Node 26. -
release-auditorconsumes the gate — the agent runs and judgesrelease:check --publish(ADR-0024), includingconsumer-spec-new; it doesn't reimplement the procedure.
Next (by dependency, not by wish)
- Cross-project Intelligence (Phase 6 remainder) — correlating incidents across multiple repositories; needs a data source this single-repo workspace doesn't have yet.
- Boilerplates beyond NestJS — the process is stack-agnostic; the templates will follow.
Suggestions? Open an issue — a non-trivial feature here starts from a spec, yours included.
Did Forja help you tame your agents?
A is what carries the project to more devs still paying the amnesiac-AI tax.
Forja (npm: forjajs) · MIT License · Contributing