Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ jobs:
# and CITATION.cff must all carry the same version (scripts/bump.mjs keeps them in sync).
- run: node scripts/bump.mjs check

docs-drift:
name: Docs match code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # the CHANGELOG check compares src vs CHANGELOG.md commit times
- uses: actions/setup-node@v6
with:
node-version: 22
# Commands, env vars, MCP tools, and CHANGELOG reconciled against the code —
# a feature can't merge with its docs missing (src/docs_check.js).
- run: node src/cli.js docs check

dependency-review:
name: Dependency review
runs-on: ubuntu-latest
Expand Down
10 changes: 6 additions & 4 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ for the full list.
## Locked decisions
- **Brand = `Forge`** — CLI `forge`; layer names: skills→**tools**, agents→**crew**,
hooks→**guards**, code-graph→**atlas**, minimalism→**lean**, memory→**recall**.
Brand stored as **one token** (`brand.json` → `FORGE_BRAND`); rebrand = 1 edit.
Brand stored as **one token** (the `brand` key in `brand.json`); rebrand = 1 edit.
- **Distributable id = `forgekit`** (npm package + marketplace id) — fixed even if
the brand token changes, so a rename never breaks install.
- **Scope = full multi-tool day 1** — nine tools plus MCP, from one canonical source.
Expand Down Expand Up @@ -68,8 +68,10 @@ The four layers, brand-named and emitted cross-tool:
*enforces* rather than suggests.** A guard is a deterministic hook the model cannot
drift from. Prose rules in CLAUDE.md get acknowledged and then forgotten after
compaction; a guard does not. Every enforceable invariant belongs here.
- **mcp** — the protocol layer. Forge ships the `atlas` code-graph server and the
substrate tools (`substrate_check` / `predict_impact` / `assumption_gate`).
- **mcp** — the protocol layer. Forge ships one stdio server (`src/cortex_mcp.js`)
exposing 19 MCP tools: the substrate checks (`substrate_check` / `predict_impact` /
`assumption_gate` / …), memory reads AND writes (`forge_remember`, ledger
ratify/retract), and ops/health — the full table is in docs/GUIDE.md.

Cross-cutting concerns thread through all four: **atlas** (the code graph), **lean**
(minimalism — shipped as *both* a tool and a Stop-guard, so it applies whether or not
Expand Down Expand Up @@ -243,7 +245,7 @@ Roo Code and VS Code receive the Forge MCP server via `forge init`
```
forgekit/
package.json # npm CLI: bin `forge` → src/cli.js
brand.json # single FORGE_BRAND token + layer-name map
brand.json # single brand token + layer-name map
README.md # Start-Here index + one bootstrap command
src/
cli.js # init | sync | doctor | substrate | ledger | reuse | … (`forge --help` for all)
Expand Down
60 changes: 60 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,72 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- **Gateway environments work end to end** — `ANTHROPIC_AUTH_TOKEN` is recognized
everywhere `ANTHROPIC_API_KEY` is; `ANTHROPIC_MODEL` / `FORGE_MODEL` pin one model
(bypassing tier routing); a gateway-looking `ANTHROPIC_BASE_URL` auto-classifies as
LiteLLM; and the LLM proposer falls back to **direct HTTP** (`src/llm.js`, Anthropic
Messages API) when the `claude` CLI is absent — or on `FORGE_LLM_HTTP=1`.
- **`forge docs check`** (+ CI job + doctor check) — reconciles README/GUIDE/
ARCHITECTURE/ROADMAP against the code: every CLI command documented, every env var
read is documented and every documented var is real, MCP tool counts/names match the
registry, CHANGELOG sections non-empty. First run found 56 real drift issues,
including a phantom env var. `scripts/bump.mjs` now refuses to rotate an empty
`[Unreleased]`.
- **Docs are in the impact graph** — the atlas parses markdown into doc nodes with
`references` edges to the code they name, so `forge impact src/foo.js` lists the
docs that go stale, and the pre-edit hook says so before the edit.
- **Persistent goal** — `forge anchor set/show/clear` stores the active goal in
`.forge/goal.md`; SessionStart re-injects it and a bare `forge anchor` checks
against it. `goalDrift` also returns a graded `driftScore` for the CUSUM detector.
- **AGENTS.md auto-repair** — the Stop hook re-runs sync when the managed AGENTS.md
drifts from its canonical inputs (disable: `FORGE_AUTOSYNC=0`).
- **Entropy secret detection** — `src/secrets.js` is the single source of truth
(format grammars + Shannon-entropy gate for unknown-vendor tokens); the
`secret-redact` guard now imports it, ending the JS/shell regex divergence.
- **`src/math.js`** — Shannon entropy, charset classes, exact set Jaccard/overlap.

### Changed
- **Routing scores by exemplar similarity, not keyword lists** — the text rubric is
similarity-weighted k-NN over a labeled `EXEMPLARS` bank (overlap-coefficient on
stopword-filtered unigram+bigram sets, credibility-shrunk); the four topic keyword
regexes and their additive magic weights are gone. Tune routing by adding labeled
rows, not by editing weights.
- **Lesson matching is graded** — the keyword tier of `matchScore` scores by token
overlap (same-module partial credit) instead of all-or-nothing string equality.
- **Substrate minimality warnings derive from computed signals** (preflight missing
dimensions + route score) instead of a second keyword copy.
- **`forge scan` detects obfuscated payloads** — long high-entropy base64 blobs flag
as findings alongside the signature rules.
- **`providerStatus` probes `/health` on any custom base URL** and reports behavioral
gateway evidence (a proxy that answers /health is a gateway, whatever its hostname).

## [0.8.1] - 2026-07-08

### Added
- **MCP write tools** — `forge_remember`, `forge_ledger_ratify`,
`forge_ledger_retract` join the read tools (19 tools total).

### Changed
- Simplified CLI surface and improved dashboard UX empty states.

### Fixed
- Stale documentation across command references.

## [0.8.0] - 2026-07-08

### Added
- **Forge work system** — auto-install flow, multi-provider routing, the cost
dashboard (`forge dash`), and the cortex MCP server's read-path tools.
- **Zero-config provider auto-detection** — `autoDetectProvider()` resolves the
provider from the environment (LiteLLM local/hosted, OpenRouter, Anthropic);
`forge init` reports what it found.
- **Hosted LiteLLM gateway support** — `emitGatewayConfig()` writes a
`litellm.config.yaml` exposing complexity tiers as model aliases.

### Fixed
- TypeScript errors and Biome 2.5.2 lint warnings across source and tests.



## [0.7.0] - 2026-07-08
Expand Down
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@
- Match existing patterns: dynamic `await import()` for optional modules, brand
tokens from `src/brand.js` (never hardcode "Forge"/"forge"), `BRAND.root` for
package root paths.
- Run `npm test && npx biome check && npm run typecheck` before committing.
- Run `npm test && npx biome check && npm run typecheck && node src/cli.js docs check`
before committing — the docs check fails CI when commands/env vars/MCP tools/CHANGELOG
drift from the code, so update docs IN THE SAME CHANGE, not later.
- Version lives in `package.json` — `scripts/bump.mjs` keeps all manifests in sync.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,10 @@ git pull && forge ledger merge <path-to-their-ledger>

On Claude Code the substrate then runs on **every prompt automatically** via a
`UserPromptSubmit` hook — advisory only, silent on clean tasks. Every other tool gets a
native config rule plus MCP tools (`substrate_check`, `predict_impact`, `assumption_gate`,
`route_task`, `scope_files`) it can call itself.
native config rule plus **19 MCP tools** it can call itself — pre-action checks
(`substrate_check`, `predict_impact`, `assumption_gate`, `route_task`, `scope_files`),
memory reads and writes, and ops/health — the full list with schemas is in
[`docs/GUIDE.md`](docs/GUIDE.md#mcp-tools).

## Commands

Expand All @@ -154,6 +156,8 @@ default 25-file threshold).
| **Config layer** | `forge init` | emit every tool's native config from one source |
| | `forge sync` | recompile canonical source → each tool's native files (idempotent) |
| | `forge doctor` | pass/fail health check: tools, guards, MCP, drift |
| | `forge docs` | docs↔code drift check — commands, env vars, MCP tools, CHANGELOG vs reality |
| | `forge config` | provider setup — show / switch / add providers, set the default model |
| | `forge harden` | wire gitleaks pre-commit + sandbox settings |
| | `forge catalog` | Start-Here index of every tool / crew / guard |
| | `forge brand` | print the brand token map |
Expand All @@ -171,7 +175,7 @@ default 25-file threshold).
| | `forge imagine` | consequence sim + minimal dry-run suite (`--run` executes it sandboxed) |
| | `forge context` | budgeted context assembly + completeness gate |
| | `forge atlas` | build / query / has (hallucinated-symbol check) the code graph |
| | `forge anchor` | goal-drift check (advisory) |
| | `forge anchor` | goal-drift check (advisory) — `set`/`show`/`clear` persists the goal across sessions |
| | `forge diagnose` | doom-loop: same failure 3× → diagnosis + escalation |
| | `forge lean` | scope-minimality footprint (advisory) |
| | `forge cost` | real per-day spend · measured stage factors (`--stages`) |
Expand Down
30 changes: 20 additions & 10 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ every tool. This is where that brain is headed.
Direction, not promises — shaped by the two field reports this project is grounded in
(the SDLC pain-point map and the ecosystem landscape). Open a Discussion to weigh in.

## Now (`master`, v0.8.0)
Everything from 0.7.0 plus branding layer (`forge brand`), model-tier exports
(`forgekit/model-tiers`), and the Codex plugin manifest — same toolkit, two plugin
surfaces (Claude Code + Codex). See [CHANGELOG.md](./CHANGELOG.md).
## Now (`master`, v0.8.1+)
Everything from 0.8.0 plus gateway-environment support end to end — `ANTHROPIC_AUTH_TOKEN`
recognized everywhere, `ANTHROPIC_MODEL`/`FORGE_MODEL` model override, LiteLLM-gateway
auto-classification of `ANTHROPIC_BASE_URL`, direct-HTTP LLM calls when the `claude` CLI
is absent (`src/llm.js`) — plus decision math replacing keyword heuristics (exemplar k-NN
routing, entropy secret detection), docs↔code drift gating (`forge docs check`, in CI),
docs in the impact graph, and a persistent goal (`forge anchor set`).
See [CHANGELOG.md](./CHANGELOG.md).

## Shipped — Substrate v2 (all phases P0–P8, v0.5.0)
The plan lives in [docs/plans/substrate-v2/](./docs/plans/substrate-v2/00-overview.md)
Expand All @@ -22,12 +26,15 @@ confidence only from independent oracles, and merges across teammates conflict-f

## Shipped — 0.7.0
- **Zero-config provider auto-detection** — `autoDetectProvider()` probes env vars
for OpenRouter, LiteLLM (local + hosted gateway), OpenAI, Anthropic, and Gemini;
`forge init` reports what it found, no manual config needed.
- **Hosted LiteLLM gateway** — `emitGatewayConfig()` writes a guard that injects
`LITELLM_GATEWAY_URL` + key so every model call routes through the team proxy.
- **15 MCP tools** — the cortex MCP server (`src/cortex_mcp.js`) now exposes
read-path tools for ledger, brain, atlas, recall, cost, substrate, and dashboard.
for LiteLLM (local + hosted gateway), OpenRouter, and Anthropic (key, auth token,
or custom base URL); `forge init` reports what it found, no manual config needed.
(OpenAI and Gemini detection: see Next.)
- **Hosted LiteLLM gateway** — `emitGatewayConfig()` writes a `litellm.config.yaml`
exposing the complexity tiers as model aliases; point `ANTHROPIC_BASE_URL` at the
proxy and every model call routes through it.
- **MCP server** — the cortex MCP server (`src/cortex_mcp.js`) exposes read-path
tools for ledger, brain, atlas, recall, cost, substrate, and dashboard (19 MCP tools
as of 0.8.x, including the write tools added in 0.8.0).
- **Cost dashboard** — `forge dash` serves a local HTML dashboard showing model spend,
event timeline, and ledger health from `.forge/` data.

Expand All @@ -46,6 +53,9 @@ confidence only from independent oracles, and merges across teammates conflict-f
`/status/`.

## Next
- **OpenAI + Gemini provider detection** — extend `autoDetectProvider()` beyond
Anthropic/OpenRouter/LiteLLM (`OPENAI_API_KEY`, `GEMINI_API_KEY`) with the same
zero-config contract.
- **Legacy store retirement** — the read-path flip has shipped: every read surface
(cortex injection/status, the substrate advisory, routing, `recall list`, brain's
AGENTS.md index) is now a merged view (legacy ∪ ledger) via `src/ledger_read.js`,
Expand Down
Loading
Loading