Skip to content

feat: forge rank (centrality × team history), temporal ledger queries + Merkle root, impact() tightening - #118

Merged
CodeWithJuber merged 3 commits into
masterfrom
claude/repo-review-agentic-generics-tteyld
Aug 7, 2026
Merged

feat: forge rank (centrality × team history), temporal ledger queries + Merkle root, impact() tightening#118
CodeWithJuber merged 3 commits into
masterfrom
claude/repo-review-agentic-generics-tteyld

Conversation

@CodeWithJuber

Copy link
Copy Markdown
Owner

What & why

A full-repo review (architecture + algorithm audit, cross-checked against currently-trending open-source agent tooling) found that forgekit's atlas graph and append-only ledger were each sitting on unused mathematical capability. Three commits, smallest-risk first:

  1. perf(atlas): impact() dequeues in O(1) — the label-correcting blast-radius search (the hottest path in the repo: consensus ≤10×, imagine ≤8×, gate ≤10× calls per invocation) drained its frontier with queue.shift() (O(n) per dequeue) and a linear starts.includes scan in the inner loop. Now an index pointer + a Set. Processing order is unchanged, so outputs are bit-identical — verified across all targets on this repo's own 9,205-node atlas; a synthetic 20,000-dependent frontier drops 2,463 ms → 102 ms. A new test pins the max-product diamond semantics. Also memoizes lesson trigger-glob compilation (ran per lesson × file on every PreToolUse hook).

  2. feat(rank): forge rank — load-bearing code, measured — answers the question every agent asks before touching a repo: what here is dangerous to change?

    • Weighted PageRank centrality over the atlas graph, reusing the same EDGE_WEIGHT priors the blast-radius search trusts (now exported).
    • Circular-import clusters via iterative Tarjan SCC over a new scope.directedImportGraph() (real import statements — measured first that atlas call-edges are too noisy: one coincidental unique-name match glued ~100 unrelated files into a mega-component).
    • Chokepoint files via iterative Hopcroft–Tarjan articulation points.
    • The original join: each file's past-incident history from the evidence ledger (val()-weighted lesson claims whose trigger globs match it, plus deja session summaries that list it) multiplies into hazard = centrality × (1 + history) — central code that has already bitten the team outranks equally central code that hasn't. Fail-open: no ledger → purely structural.
    • Exposed as the rank_code MCP tool (20 MCP tools — count reconciled in all six doc claims). Deterministic end to end: sorted-order power iteration, no Math.random.
  3. feat(ledger): temporal queries + Merkle state root — the store is append-only and every record carries its day, so past beliefs are recomputable — now they're queryable:

    • forge ledger at <date> — beliefs as of any past day, with val scored by that day's evidence and clock. stateAt is a lattice morphism (commutes with the CRDT merge — property-tested beside the semilattice suite).
    • forge ledger diff <since> [<until>] — appeared / retired / strengthened / weakened between two days.
    • forge ledger root — a permutation-invariant Merkle root over the verified state, with per-shard hashes that localize divergence; wired into ledger sync --dir as an already-in-sync fast path (the ref transport's tree-SHA equality already was this check).

Not done on purpose (over-engineering guard): no heap rewrite of impact() (label correction already converges; pointer fix gets the asymptotic win with identical output), no rank→substrate/route auto-integration (documented seam), no LSH for clusters() (no production caller yet), no new env vars or config knobs.

Note on reports/benchmarks.md: deliberately not regenerated — the committed table carries maintainer-hardware measurements that README bold claims reconcile against; regenerating on an ephemeral CI container would overwrite them with unrepresentative numbers. The impact() speedup receipt above was measured A/B on this container instead.

Checklist

  • npm test passes (1,088 pass / 0 fail locally, Node 20)
  • npm run check passes (Biome lint + format)
  • New public functions have a test (test/rank.test.js ×8, ledger temporal/root ×5, syncDir fast path, MCP rank_code ×2, impact diamond pin)
  • Conventional commit message (feat:/fix:/docs: …)
  • CHANGELOG.md updated under ## [Unreleased]
  • No new runtime dependency (dev deps ok)
  • Substrate/docs updated if this changes forge substrate, forge impact, router/gate, or MCP substrate tools (README, docs/GUIDE.md, ARCHITECTURE.md, mintlify pages, MCP tool count ×6)

Risk & rollback

  • Risk level: low — commit 1 is output-identical (pinned by test); commits 2–3 are additive surfaces (new command/subcommands/MCP tool); the only behavior change to an existing path is the syncDir fast path, which short-circuits only on exact state-root equality and is covered by a divergence-then-reconverge test.
  • Rollback plan: revert the three commits (each is self-contained and reverts cleanly in reverse order); no migrations, no storage-format changes, no new persisted files.

Extra checks (tick if applicable)

  • npm run typecheck passes
  • Input validated at boundaries; errors handled (no swallowing) — parseDay rejects malformed dates with usage + exit 1; rankReport fails open (built:false) without an atlas; corrupt ledger → structural-only ranking
  • Authorization/ownership checked (if it touches access) — n/a
  • Logs contain no secrets/PII
  • If AI-assisted: I understand it, verified the package APIs, and it has tests

🤖 Generated with Claude Code

https://claude.ai/code/session_01LXmzxfRVDRVPU6LG8W39Rz


Generated by Claude Code

claude added 3 commits August 7, 2026 06:49
…ompilation

The label-correcting blast-radius search 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 is unchanged, so every reported
confidence is bit-identical (verified across all targets on this repo's
own 9,205-node atlas); a synthetic 20,000-dependent frontier drops from
2,463 ms to 102 ms. A new test pins the max-product diamond semantics
any future queue/heap rewrite must preserve.

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 trigger globs
in the lesson set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LXmzxfRVDRVPU6LG8W39Rz
… rank_code MCP tool)

forge rank answers the question every agent asks before touching a repo:
what here is dangerous to change? Three classical graph readings plus one
join none of the trending code-graph tools have:

- Weighted PageRank over the atlas graph, using the same EDGE_WEIGHT
  priors the blast-radius search trusts (now exported), with per-source
  out-weight normalization and uniform dangling redistribution —
  deterministic fixed-order power iteration, no Math.random.
- Circular-import clusters via iterative Tarjan SCC over a new DIRECTED
  import graph (scope.directedImportGraph; the undirected decomposition
  graph is now derived from it). Deliberately not the atlas call edges:
  unique-name call resolution glues unrelated files into one
  mega-component — measured on this repo before choosing.
- Chokepoint files via iterative Hopcroft–Tarjan articulation points on
  the undirected import graph.
- The join: each file's past-incident history from the evidence ledger —
  val()-weighted lesson claims whose trigger globs match it and deja
  session summaries that list it — multiplies into
  hazard = centrality × (1 + history). Central code that has already
  bitten the team outranks equally central code that hasn't. Fail-open:
  no ledger → purely structural ranking.

Surface: forge rank [--top N] [--json] (Labs group), plus the rank_code
MCP tool (20 tools total; count reconciled across all six doc claims).
lessons.globToRe is exported for the glob join; docs and mintlify pages
updated in the same change per the docs-check gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LXmzxfRVDRVPU6LG8W39Rz
…c fast path

The store is append-only and every record carries its day, so past
beliefs are recomputable — now they are queryable:

- stateAt(state, day): the state as it stood at end of a day — claims by
  mint day, logs cut at the day. A lattice morphism (commutes with the
  CRDT merge), property-tested beside the semilattice suite.
- beliefDiff(state, dayA, dayB): appeared / retired / strengthened /
  weakened, with val() evaluated AT each day's own clock — answers
  "what did we believe then", not "what does today think of then".
- stateRoot(state): a permutation-invariant Merkle root — leaf per claim
  over its canonical logs, shard hashes over the store's 2-hex-char
  prefixes, so divergence between replicas is localized, not just
  detected. Two replicas share a root ⇔ they share a verified state.

Surfaced as forge ledger at <date> / diff <since> [<until>] / root (all
inherit --personal and --json), and wired into ledger sync --dir as an
already-in-sync fast path — mirroring the tree-SHA equality the ref
transport always had. Zero new storage, zero clock reads in the pure
core, zero new dependencies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LXmzxfRVDRVPU6LG8W39Rz
@mintlify

mintlify Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
forgekit-docs 🟢 Ready View Preview Aug 7, 2026, 7:11 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@CodeWithJuber
CodeWithJuber marked this pull request as ready for review August 7, 2026 07:22
@CodeWithJuber
CodeWithJuber merged commit d4ac53c into master Aug 7, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants