Polished bronze hand-mirror reflecting a glowing amber spiral of feedback loops curving inward to a glowing core, the inner reflection loop
Deep Dive · Act II, Forge

The Inner Loop

Seven subsystems, reflexion, trajectories, auto-skills, gate synthesis, postmortems, federation, and the opt-in reviewer, that turn every slice into a research step.

New here? Decode the seven words first. The subtitle drops a lot of jargon. Here's a one-line plain-English read on each:
  • Reflexion, when a slice fails, the model gets to re-read its own previous attempt before retrying. (Like reviewing your own essay before rewriting it.)
  • Trajectories, short notes the model leaves for itself about what worked and what didn't. Saved per slice.
  • Auto-skills, if a pattern keeps showing up across slices, Plan Forge auto-generates a reusable skill so the next slice starts from a higher baseline.
  • Gate synthesis, advisory suggestions for stricter validation gates based on what's been failing.
  • Postmortems, a one-paragraph summary written after every run: what retried, what cost more, what drifted.
  • Federation, optionally publish those postmortems to a shared store so sibling projects benefit from each other's lessons.
  • Opt-in reviewer, a second AI checks the slice before it commits. You decide whether to enable it.
All seven default to off, advisory, or read-only. Existing workflows don't change unless you opt in.
Opt-in by default. All seven subsystems default to off / suggest / read-only for existing projects. New installs get best-defaults. Toggle everything from the Dashboard → Config tab. Nothing in your current workflow breaks.

For the canonical system-wide overview covering Phase-25 and Phase-26 together, see The Self-Deterministic Agent Loop.

The Inner Loop — State Flow

The deterministic slice executor (Phase-1 through Phase-24) is the spine. The Phase-25 subsystems bolt on reflective behavior at specific transitions, they never replace the spine, they only enrich it.

Inner-loop state diagram. runPlan parses the plan, then walks through pre-flight gate synthesis (L6 advisory), per-slice prompt build, auto-skill lookup (L2), worker invocation, gate run, trajectory write on pass (L8), auto-skill capture (L2), reviewer check, and an optional reviewer invocation (L4, opt-in) that emits an advisory verdict or blocks on critical when blockOnCritical is true. Gate failure routes through a reflexion build (L7) that injects context into the next prompt attempt. Run completion writes a postmortem (L5) capturing retries, gateFlaps, costDelta, and driftDelta, optionally publishing to federation (L4-lite) when brain.federation.enabled is true.
Inner-loop state flow, Phase-25 subsystems (L2, L4, L5, L6, L7, L8) enriching the deterministic slice executor at specific transitions.

The Seven Subsystems

Each subsystem has a single job, a single config key (if any), and a single storage artifact. Add them up and you get a closed research loop where every run teaches the next.

1. Reflexion (L7) — the retry gets context

When a slice's validation gate fails, the orchestrator builds a compact Markdown block with the gate command, model, duration, and the stderr tail (≤2KB). That block is injected into the next attempt's prompt so the worker reasons about its prior failure instead of blindly trying the same thing.

  • Module: pforge-mcp/memory.mjs → buildReflexionBlock()
  • Config: none, always on
  • Storage: in-memory per attempt

2. Trajectories (L8) — what actually happened

On slice pass, Plan Forge extracts the sentinel-wrapped note the worker produced (<!-- PFORGE_TRAJECTORY:BEGIN -->…<!-- PFORGE_TRAJECTORY:END -->), word-caps it at 500, and writes it to disk. Postmortems and federation consumers read these for compact run narratives.

  • Module: pforge-mcp/memory.mjs → writeTrajectory()
  • Config: none, always on
  • Storage: .forge/trajectories/<slice>/<iso>.md

3. Auto-skills (L2) — patterns that earn promotion

A slice that passes gets captured as a candidate auto-skill with its domain keywords, gate commands, and a SHA prefix. Before the next slice, the orchestrator retrieves matching skills (ranked by reuse count) and injects them into the prompt. A skill promotes to "stable" once its reuse count hits the threshold (default 3).

  • Module: pforge-mcp/memory.mjs → retrieveAutoSkills() / writeAutoSkill()
  • Config: none — defaults are Dashboard-editable in Phase-26
  • Storage: .forge/auto-skills/*.md

4. Adaptive gate synthesis (L6) — Tempering advises your plans

During plan pre-flight the orchestrator scans every slice. If a slice's title or file list matches a Tempering domain profile (domain / integration / controller) but declares no validation gate, it prints a suggested command using the project's Tempering coverage minimum and runtime budget. Default mode is suggest; set mode: "off" to silence it.

  • Module: pforge-mcp/orchestrator.mjs → synthesizeGateSuggestions()
  • Config: runtime.gateSynthesis: { mode, domains }
  • Storage: stdout only (never mutates your plan)

5. Plan postmortems (L5) — the hardener learns from you

After every run, pass or fail, Plan Forge writes a JSON postmortem with retriesPerSlice, gateFlaps, topFailureReason, costDelta, and driftDelta (deltas vs the prior run). Retention is 10 per plan. The Step-2 hardener now reads the newest 3 postmortems and folds their signals into the Scope Contract, closing the loop from execution back into planning.

  • Module: pforge-mcp/orchestrator.mjs → buildPlanPostmortem() / writePlanPostmortem()
  • Config: retention count via maxRunHistory-style defaults
  • Storage: .forge/plans/<plan-basename>/postmortem-*.json

6. Cross-project federation (L4-lite) — one project's memory helps another

Opt-in. When a cross.* brain recall misses L3 (OpenBrain), the facade fans out to the repos listed in brain.federation.repos[] and reads their .forge/brain/<entity>/<id>.json, read-only, absolute local paths only. URLs and relative paths are rejected by contract.

  • Module: pforge-mcp/brain.mjs → federationRead()
  • Config: brain.federation: { enabled, repos: [] }, defaults off
  • Security: absolute-local-paths-only (D9); .. rejected; defense-in-depth path containment check

7. Reviewer-agent in-loop (L4) — cheap second pair of eyes

Opt-in. When enabled, the brain.gate-check responder invokes a speed-quorum reviewer on each slice's diff summary and attaches a verdict to the response (score, critical, summary, durationMs). Advisory-only by default: critical verdicts do not block the next slice unless operators explicitly set blockOnCritical: true. Blocking mode enters Phase-26 after calibration data exists.

  • Module: pforge-mcp/brain.mjs → invokeReviewer()
  • Config: runtime.reviewer: { enabled, quorumPreset, blockOnCritical, timeoutMs }
  • Defaults: enabled=false, quorumPreset="speed" (D5), blockOnCritical=false (D6), timeoutMs=30000

Configuration Summary

Everything the Inner Loop exposes lives under two keys in .forge.json, and every key has a toggle in the Dashboard → Config tab.

{
  "runtime": {
    "gateSynthesis": { "mode": "suggest", "domains": ["domain", "integration", "controller"] },
    "reviewer":      { "enabled": false, "quorumPreset": "speed", "blockOnCritical": false, "timeoutMs": 30000 }
  },
  "brain": {
    "federation":    { "enabled": false, "repos": [] }
  }
}

Phase-26 additions (v2.58.0)

Three more subsystems close the loop further, the slice executor can now race strategies, draft its own patches when a gate fails, and flag token-cost drift without halting a run.

  • Competitive execution (L9), Opt-in worktree race. Two or more strategies run the same slice under isolated git worktrees; the winner is elected by gate result, reviewer verdict, and token-cost tie-breaker. Off by default. Config: innerLoop.competitive. See The Competitive Loop for the full flow.
  • Auto-fix patch proposals (L6), When a gate-fail trajectory suggests a small local correction, the orchestrator drafts a .patch file under .forge/proposed-fixes/. Advisory, nothing auto-applies unless applyWithoutReview: true.
  • Cost-anomaly detection (L5), Slices whose token cost drifts above the per-model median by more than ratio (default 2.0) are recorded in .forge/cost-anomalies.jsonl. Detection only; never halts a run.

Additional config block (added by the v2.58 best-defaults preset for new installs; existing projects opt in):

{
  "innerLoop": {
    "competitive": { "enabled": false, "maxParallel": 2, "timeoutSec": 1800 },
    "autoFix":     { "enabled": true, "applyWithoutReview": false },
    "costAnomaly": { "enabled": true, "ratio": 2.0, "medianWindow": 20 }
  }
}

All three are surfaced in the Dashboard's new Inner Loop tab alongside the Phase-25 subsystems.

See also: Chapter 2 — How It Works describes the Forge spine; this page describes the reflective layers the Inner Loop adds on top. The Competitive Loop covers the worktree-race mechanics in depth.