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
6 changes: 3 additions & 3 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ The four layers, brand-named and emitted cross-tool:
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 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.
exposing 20 MCP tools: the substrate checks (`substrate_check` / `predict_impact` /
`assumption_gate` / `rank_code` / …), 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
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,47 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **`forge rank` — load-bearing code, measured.** Weighted PageRank centrality over the
atlas graph (same edge priors as the blast-radius search), Tarjan SCC circular-import
clusters over the directed import graph, and Hopcroft–Tarjan articulation points
(chokepoint files whose removal splits the repo) — joined with each file's
past-incident history from the evidence ledger: `hazard = centrality × (1 + history)`,
where history is the val()-weighted sum of lesson and session claims naming the file.
Structurally central code that has already bitten the team outranks equally central
code that hasn't. Deterministic end to end (sorted-order power iteration, no
`Math.random`), fail-open without a ledger, and exposed to every MCP-capable agent as
the `rank_code` tool (20 MCP tools total).

- **Time-travel for team memory.** The ledger is append-only and every record carries
its day, so past beliefs are recomputable — now they are queryable: `forge ledger at
<date>` rebuilds any past day's state with `val` scored by that day's evidence and
clock, and `forge ledger diff <since> [<until>]` classifies what changed between two
days (appeared / retired / strengthened / weakened, with an epsilon floor). Pure
functions in the ledger core (`stateAt` is a lattice morphism — it commutes with the
CRDT merge, property-tested), no new storage, no clock reads.
- **Merkle state root.** `stateRoot()` hashes the whole verified ledger state into one
permutation-invariant root (leaf per claim over its logs in canonical order, shard
hashes over the store's 2-hex-char prefixes — so divergence is localized, not just
detected). Surfaced as `forge ledger root` and used by `ledger sync --dir` as an
O(state-read) already-in-sync fast path — the ref transport's tree-SHA equality
already was this check; now the dir transport has one too.

### Changed

- **`impact()` dequeues in O(1).** The label-correcting blast-radius search in
`src/atlas.js` drained its frontier with `queue.shift()` — O(n) per dequeue on V8
arrays, quadratic on large frontiers — and rescanned the start set with a linear
`includes` inside the inner loop. The queue now drains through an index pointer and
the start set is a `Set`; processing order, and therefore every reported confidence,
is unchanged. A new test pins the max-product diamond semantics any future rewrite
must preserve.
- **Lesson glob compilation is memoized.** `matchScore` runs per (lesson × file) on
every PreToolUse hook and recompiled the same trigger-glob RegExp each time; compiled
globs are now cached in a module-level map bounded by the distinct globs in the
lesson set.

## [0.27.4] - 2026-08-04

### Fixed
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ 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 **19 MCP tools** it can call itself — pre-action checks
native config rule plus **20 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).
Expand Down Expand Up @@ -223,7 +223,7 @@ that never clobbers your existing settings (skip it with `install.sh --no-settin
| | `forge harden` | wire the pre-commit gate (gitleaks + commit gate) + sandbox settings |
| | `forge catalog` | Start-Here index of every tool / crew / guard |
| | `forge brand` | print the brand token map |
| **Memory & team** | `forge ledger` | proof-carrying memory — stats / verify / show / blame / query / ratify / retract / merge / sync / import |
| **Memory & team** | `forge ledger` | proof-carrying memory — stats / verify / show / blame / query / at / diff / root / ratify / retract / merge / sync / import |
| | `forge recall` | cross-session personal memory — list / add / consolidate |
| | `forge remember` | durable, repo-committable fact |
| | `forge brain` | portable project-memory index |
Expand All @@ -237,6 +237,7 @@ that never clobbers your existing settings (skip it with `install.sh --no-settin
| | `forge preflight` | assumption / info-gap check |
| | `forge route` | cheapest capable model tier (`route gateway` emits LiteLLM config) |
| | `forge impact` | predict blast radius for a symbol or file |
| | `forge rank` | load-bearing code — PageRank centrality × past-incident history, circular imports, chokepoint files |
| | `forge scope` | cluster + surface coupled files |
| | `forge imagine` | consequence sim + minimal dry-run suite (`--run` executes it sandboxed) |
| | `forge context` | budgeted context assembly + completeness gate |
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ confidence only from independent oracles, and merges across teammates conflict-f
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
tools for ledger, brain, atlas, recall, cost, substrate, and dashboard (20 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 Down
70 changes: 60 additions & 10 deletions docs/GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ recipes, and how to extend each piece. If you just want to get going, the

Every command is real and wired. Grouped by what it does:

| Group | Commands |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Config / cross-tool sync** | `forge init` · `forge sync` · `forge tools` · `forge doctor` · `forge update` · `forge docs` · `forge config` · `forge harden` · `forge catalog` · `forge brand` |
| **Memory & ledger (PCM)** | `forge ledger` · `forge recall` · `forge remember` · `forge brain` · `forge cortex` · `forge reuse` · `forge handoff` · `forge decide` · `forge know` |
| **Code graph & retrieval** | `forge atlas` · `forge stack` · `forge context` |
| **Substrate / pre-action** | `forge substrate` · `forge preflight` · `forge route` · `forge impact` · `forge scope` · `forge imagine` · `forge anchor` · `forge diagnose` · `forge lean` · `forge cost` |
| **Verification & safety** | `forge verify` · `forge precommit` · `forge radar` · `forge scan` · `forge spec` |
| **UI / design** | `forge taste` · `forge uicheck` |
| **Dashboard** | `forge dash` |
| Group | Commands |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Config / cross-tool sync** | `forge init` · `forge sync` · `forge tools` · `forge doctor` · `forge update` · `forge docs` · `forge config` · `forge harden` · `forge catalog` · `forge brand` |
| **Memory & ledger (PCM)** | `forge ledger` · `forge recall` · `forge remember` · `forge brain` · `forge cortex` · `forge reuse` · `forge handoff` · `forge decide` · `forge know` |
| **Code graph & retrieval** | `forge atlas` · `forge stack` · `forge context` |
| **Substrate / pre-action** | `forge substrate` · `forge preflight` · `forge route` · `forge impact` · `forge rank` · `forge scope` · `forge imagine` · `forge anchor` · `forge diagnose` · `forge lean` · `forge cost` |
| **Verification & safety** | `forge verify` · `forge precommit` · `forge radar` · `forge scan` · `forge spec` |
| **UI / design** | `forge taste` · `forge uicheck` |
| **Dashboard** | `forge dash` |

Storage in one line: the code graph is `.forge/atlas.json` (plain JSON, not SQLite); the
ledger is content-addressed claims under `.forge/ledger/` (git-committable, union-merge).
Expand Down Expand Up @@ -282,6 +282,38 @@ Forge impact — blast radius
- src/session.js
```

### `forge rank` — what here is dangerous to touch?

The standing companion to `forge impact`: impact answers "what breaks if I change X",
rank answers "which X-es should I worry about at all". Weighted PageRank over the atlas
graph scores structural centrality (using the same edge weights the blast-radius search
trusts), Tarjan SCC finds circular-import clusters, articulation points find chokepoint
files whose removal would split the import graph — and the ledger join is the part
nobody else has: each file's past-incident history (val()-weighted lesson and session
claims that name it) multiplies into `hazard = centrality × (1 + history)`, so central
code that has already bitten the team outranks equally central code that hasn't. Run
`forge atlas build` first. Also exposed to every MCP-capable agent as `rank_code`.

```console
$ forge rank --top 3
graph: 9285 nodes, 27083 edges

files (hazard = centrality × 1+history):
████████ 1.000 src/cli.js
███████░ 0.840 src/ledger.js
██████░░ 0.718 src/ledger_store.js

symbols (centrality):
0.004878 epochDay src/util.js
0.004005 sync src/sync.js
0.003897 loadClaims src/ledger_store.js

circular imports: none

chokepoints (removal splits the import graph):
src/sync.js splits off 10 subtree(s)
```

### `forge scope <file…>` — can this be split into sessions?

Groups the files you name into independent clusters and surfaces coupled files you
Expand Down Expand Up @@ -720,6 +752,23 @@ Forge ledger blame — lesson 3f2a91c04d7e
0.93 juber
```

The store is append-only and every record carries its day, so **time-travel is
recomputed, never guessed**: `forge ledger at <date>` rebuilds the beliefs of any past
day — which claims existed, with `val` scored by _that_ day's evidence and clock — and
`forge ledger diff <since> [<until>]` reports what changed between two days: claims
that appeared, were retired, strengthened, or weakened. `forge ledger root` prints one
Merkle root over the whole verified state (per-shard hashes localize any divergence);
two replicas share a root exactly when they share a state, which is also the fast path
`ledger sync --dir` uses to skip merges that have nothing to do.

```console
$ forge ledger diff 2026-07-01
appeared 2 · retired 1 · strengthened 1 · weakened 0
new fact b19b2961 · → 0.55 demo shared
gone lesson 3f2a91c0 0.82 → · stale port rule
up fact 88ac02d1 0.50 → 0.63 build needs node 20
```

The rest of the surface, briefly: `forge ledger merge <path>` folds in any other ledger
tree (a teammate's checkout, a worktree, a backup) — `merged: 3 new claim(s), 5 new
record(s) — conflict-free`, in any order; `query "<text>"` ranks live claims by the
Expand Down Expand Up @@ -1152,7 +1201,7 @@ one extra turn, exactly when that turn was owed.
> `forge substrate "<task>" --json` (or the MCP tool `substrate_check`). If
> `okToProceed` is false, ask the questions first; read `impact.impactedFiles` before editing.

…and exposes the substrate as **19 MCP tools** any MCP-capable agent can call directly
…and exposes the substrate as **20 MCP tools** any MCP-capable agent can call directly
(the stdio server is launched with `forge cortex-mcp`, wired automatically via the
emitted `.mcp.json`):

Expand All @@ -1173,6 +1222,7 @@ emitted `.mcp.json`):
| `forge_remember` | **write**: add a durable project fact |
| `forge_ledger_ratify` | **write**: human-ratify a claim into a decision |
| `forge_ledger_retract` | **write**: tombstone a claim |
| `rank_code` | load-bearing files/symbols, cycles, chokepoints |
| `forge_diagnose` | doom-loop failure check |
| `forge_doctor` | health check |
| `forge_provider_status` | provider detection + gateway reachability |
Expand Down
3 changes: 3 additions & 0 deletions mintlify/cli/memory.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ forge ledger verify # re-check claims are in normal form
forge ledger show <id> # a claim and its evidence
forge ledger blame <id-prefix> # who minted it, every oracle outcome, per-author trust
forge ledger query "<text>" # retrieve by relevance
forge ledger at <date> # beliefs as of any past day — recomputed, never guessed
forge ledger diff <since> [<until>] # appeared / retired / strengthened / weakened
forge ledger root # Merkle root over the verified state (sync fast path)
forge ledger ratify <id> # human accept
forge ledger retract <id> # tombstone a claim
forge ledger merge <path> # fold a teammate's ledger in, conflict-free
Expand Down
11 changes: 11 additions & 0 deletions mintlify/cli/substrate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ Predict the blast radius for a symbol or file from the atlas graph.
forge impact <symbol-or-file>
```

## `forge rank`

Load-bearing code: weighted PageRank centrality over the atlas graph joined with
past-incident history from the evidence ledger (`hazard = centrality × 1+history`),
plus circular-import clusters (Tarjan SCC) and chokepoint files (articulation points).
Also exposed as the `rank_code` MCP tool.

```bash
forge rank [--top <n>] [--json]
```

## `forge scope`

Decompose files into independent clusters — plus coupled files you didn't name.
Expand Down
2 changes: 1 addition & 1 deletion mintlify/concepts/config-compiler.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Each layer is brand-named and emitted cross-tool.
does not. Every enforceable invariant belongs here.
</Accordion>
<Accordion title="mcp — the protocol layer" icon="plug">
Forge ships one stdio server (`src/cortex_mcp.js`) exposing 19 MCP tools: the
Forge ships one stdio server (`src/cortex_mcp.js`) exposing 20 MCP tools: the
substrate checks (`substrate_check` / `predict_impact` / `assumption_gate` / …),
memory reads _and_ writes (`forge_remember`, ledger ratify/retract), and ops/health.
</Accordion>
Expand Down
2 changes: 1 addition & 1 deletion mintlify/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ forge substrate "Change verifyToken in src/auth.js to require length > 20; updat
<Note>
On Claude Code the substrate runs on **every prompt automatically** via a
`UserPromptSubmit` hook — advisory only, silent on clean tasks. Every other tool gets
a native config rule plus 19 MCP tools it can call itself.
a native config rule plus 20 MCP tools it can call itself.
</Note>

If `forge substrate` says `ASK FIRST`, ask the returned questions before editing. Read
Expand Down
Loading
Loading