Skip to main content

Focused Agentic Context Toolkit — Spec Kit + RPI for Claude Code

Project description

FACT — Focused Agentic Context Toolkit

An integration layer that gives Claude Code spec discipline, context discipline, and the cross-cutting reviews engineers normally do off-screen.


Context

FACT is the integration layer between three agent-engineering ideas that already work well on their own:

  • Spec Kit — GitHub's spec-driven development discipline (Constitution → Spec → Plan → Tasks → Implement).
  • RPI — HumanLayer's Research-Plan-Implement discipline: stay under the 40% context window, fork context with sub-agents, write semantic summaries at every phase boundary.
  • Skills — Anthropic's procedural-knowledge format, refined in collections like obra/superpowers.

On top of those, FACT layers the cross-cutting concerns an agent typically forgets when left to its own devices:

  • Architecture, security, code quality — continuous reviews that pause the workflow on real findings until the human decides.
  • Context-window discipline — automatic compaction triggers before quality drops, semantic state writes that survive crashes.
  • Test-first proactivity — TDD before code, verification checklist before any task is marked done.

It runs alongside Claude Code, never wrapping it. Hooks observe the session; a local dashboard shows kanban + tokens + cost in real time.


Installation

Prerequisites

Tool Why
Python 3.10+ FACT and its hooks (Claude Code calls them directly — no shell required, including on Windows)
Claude Code on PATH the agent harness FACT plugs into
git repo operations + Spec Kit
uv or pipx to install FACT in an isolated env

specify-cli (Spec Kit) is auto-installed on first fact init.

Fresh machine — macOS

brew install python git uv
# Claude Code: download from https://claude.com/claude-code
uv tool install fact-toolkit

Fresh machine — Windows (PowerShell)

winget install --id Python.Python.3.12 -e
winget install --id Git.Git -e
# Claude Code: download from https://claude.com/claude-code
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Close + reopen PowerShell so PATH refreshes, then:
uv tool install fact-toolkit

FACT hooks are pure Python — no bash, no Git Bash on PATH required.

Why not pipx on Windows? Its pipx.exe shim is hard-coded to a single Python install; if you upgrade Python the shim breaks with Unable to create process using ...python.exe. uv doesn't have that problem.

Already have the prerequisites? Pick one

uv tool install fact-toolkit                 # recommended
# or:
pipx install fact-toolkit
# or, clone for development:
gh repo clone holaPymbu/fact ~/.fact
python3 -m venv ~/.fact/.venv
~/.fact/.venv/bin/pip install -e ~/.fact

Quickstart

cd my-project/
fact init           # creates .specify/, .claude/, CLAUDE.md; starts the dashboard
claude              # open Claude Code in the same directory
> /fact-start       # picks workflow type and begins

The dashboard opens at http://localhost:7842. Keep that tab open while you work; it updates in real time.

Updating

uv tool upgrade fact-toolkit                # uv users
pipx upgrade fact-toolkit                   # pipx users
git -C ~/.fact pull                         # dev clone
# Then, inside any FACT project:
fact upgrade

Configuration

Dashboard port (default 7842):

fact init --port 7900
# or edit .specify/fact/config.json

Pricing data lives in the bundled pricing.json and refreshes with fact upgrade. Hook wiring lives in .claude/settings.json — don't hand-edit; fact upgrade is the supported way to change it.

Maintainers: see CONTRIBUTING.md for the release process, project layout, and design principles.


Workflow

FACT is human-in-the-loop by design. The agent never blasts through phases — at every meaningful gate, it stops and asks. Below is the full path from "empty directory" to "feature done", with every user-input gate marked.

flowchart TD
    Start(["fact init → claude → /fact-start"]) --> Resume{prior session<br/>state on disk?}
    Resume -->|yes| Pick["fact-onboarding asks:<br/>continue or start fresh?"]
    Resume -->|no| Type{project type?}
    Pick -->|YOU pick| Type

    Type -->|Greenfield| Disc["fact-discovery<br/>Socratic Q&A,<br/>one question at a time"]
    Type -->|Brownfield| Res["fact-research<br/>7 parallel mappers"]
    Type -->|Demo| Tiny["tinyspec extension<br/>skip discovery + clarify"]

    Disc -->|YOU shape it| Vision["Vision draft"]
    Vision -->|YOU approve, max 2 iterations| Const
    Res --> ResMd["research.md"]
    ResMd -->|YOU validate| Const
    Tiny --> Plan

    Const["speckit.constitution"]
    Const --> Spec["speckit.specify → spec.md"]
    Spec --> Clar["speckit.clarify"]
    Clar -->|YOU resolve ambiguities| Plan["speckit.plan → plan.md"]
    Plan -->|YOU review the plan| Gate{Pre-implement<br/>audit gate}
    Gate -->|critical findings| Plan
    Gate -->|clean| Tasks["speckit.tasks → tasks.md"]

    Tasks --> Loop["For each task<br/>(see 'Inside the implementation loop' below)"]
    Loop --> AuditEdit["per-edit audit<br/>Haiku · security/quality"]
    AuditEdit -->|YOU decide on findings| More{more tasks<br/>in user story?}
    More -->|yes| Loop
    More -->|no| AuditUS["per-user-story audit<br/>Sonnet × 3 · sec/arch/qual"]
    AuditUS -->|YOU decide on findings| Next{more user<br/>stories?}
    Next -->|yes| Loop
    Next -->|no| Done(["Feature done"])

    Done -. opt-in .-> FactAudit["/fact-audit all<br/>full review + run test suite"]

    classDef user fill:#fff3cd,stroke:#856404,color:#000
    classDef gate fill:#f8d7da,stroke:#721c24,color:#000
    class Pick,Disc,Vision,Res,ResMd,Clar,Plan,AuditEdit,AuditUS user
    class Gate gate

Yellow boxes = your input. Red diamond = blocking gate.

Where you give input

Stage What you do
Onboarding Pick greenfield / brownfield / demo. If FACT detects prior session state, also pick: continue or start fresh.
Discovery (greenfield) Answer ~7 topics, one at a time: what to build, who for, what problem, 3-5 v1 features, references, constraints, stack. You can redirect any time ("first tell me about X").
Vision draft (greenfield) Read the draft and iterate (max 2 rounds). The agent pushes back on scope creep — "is this v1 or are you imagining v2?".
Research validation (brownfield) Read research.md, flag what's missing or wrong.
Constitution & spec Approve / revise the principles + spec the agent produces.
Clarify The agent surfaces ambiguities; you answer them in chat.
Plan review Read plan.md before tasks decomposition. fact-rpi-harness §6 explicitly stops here.
Audit gate (pre-implement) If there are critical findings on the plan, you decide: revise plan, override (with logged reason), or rollback.
Per-task audits After each task, the per-edit audit fires. On findings: fix automatically / fix manually / override / rollback.
[P] parallel tasks Tasks marked [P] in tasks.md are delegated to sub-agents in their own worktrees and reviewed in two stages (spec-compliance → code-quality). On needs_rework, you decide: re-dispatch, fix in main, or accept divergence.
End-of-user-story audit Larger 3-dimension review. Same approval flow.
Compaction (60% context) When context fills, the agent proposes 3 options: /compact, close+reopen, or push through. You pick.
/fact-audit all Anytime, run a full review on demand.

Inside the implementation loop

The Loop node above is one task. Internally each task can take two shapes — sequential (the main agent does it) or parallel (a [P]-tagged task delegated to a sub-agent in a worktree). FACT uses sub-agents in two distinct ways during implementation:

  1. Context-forking sub-agents (always available, every task): when the main agent needs to read a lot to act on a little — find call sites, summarize tests, look up library docs — it spawns a short-lived Haiku/Sonnet sub-agent that returns 10-30 lines of distilled findings. The main agent stays focused on the change.
  2. Task-delegation sub-agents (only for [P]-tagged tasks): independent tasks that don't share state can run in parallel, each in its own git worktree, each driven by its own sub-agent.
flowchart TD
    Task[/Task line in tasks.md/]
    Task --> P{"tagged [P]?"}

    P -->|no| TddSeq["fact-tdd:<br/>RED → GREEN → REFACTOR"]
    TddSeq --> CodeSeq["implement<br/>(forks Haiku/Sonnet sub-agents<br/>for codebase lookups, doc reads,<br/>test summaries while coding)"]
    CodeSeq --> VfySeq["fact-verify checklist"]
    VfySeq --> Mark["mark x in tasks.md"]

    P -->|yes| Spawn["spawn sub-agent<br/>in its own worktree<br/>(model per fact-rpi-harness §3)"]
    Spawn --> SubRun["sub-agent runs the task<br/>(applies fact-tdd inside)"]
    SubRun --> Stage1["Stage 1 review<br/>Haiku · spec-compliance<br/>against tasks.md + plan.md"]
    Stage1 --> Stage2["Stage 2 review<br/>Sonnet · code-quality<br/>diff review"]
    Stage2 --> Mark

    Mark --> AuditE["per-edit audit<br/>Haiku · security/quality"]
    AuditE --> Next([next task])

    classDef user fill:#fff3cd,stroke:#856404,color:#000
    class VfySeq,Stage1,Stage2,AuditE user

The dashboard surfaces the difference visually: sequential work pulses blue on the active card; [P] worktree sub-agent work pulses violet, with a ⤵ subagent · model chip on the card so you can see which model is doing what.

Cost discipline notes (from fact-rpi-harness §3 and §8):

  • Lookup sub-agents: Haiku (~10× cheaper than Opus). Pass model="haiku" explicitly — without it sub-agents inherit Opus and cost balloons.
  • Synthesis sub-agents: Sonnet (~5× cheaper than Opus).
  • Stage 1 spec-compliance reviews: Haiku (cheap pattern-match).
  • Stage 2 code-quality reviews: Sonnet (judgement work).
  • The two-stage review typically adds < 5% to total session token cost and catches real bugs the main agent would have merged silently.

The three project types

Greenfield (new project)

The agent loads fact-discovery. You'll have a short, Socratic conversation — one question per message, with room to redirect. The topics it needs to leave the conversation having covered:

  1. What you want to build (one paragraph).
  2. For whom (target users, not "everyone").
  3. What problem it solves.
  4. Scope v1 — 3-5 core features.
  5. References — projects you admire / want to avoid.
  6. Constraints — budget, deadline, deployment, language.
  7. Stack preference (or it suggests after the vision draft).

After every answer, the agent decides: dig deeper, pivot to a topic you opened, or move on. If you say "wait, first I want to talk about X", it follows you. Six exchanges is usually enough.

Then the vision draft, your approval, and Spec Kit:

speckit.constitution   → 4-6 principles derived from your vision
speckit.specify        → first spec.md
speckit.clarify        → ambiguities surfaced; you answer
speckit.plan           → tech stack, architecture, code snippets
[ pre-implement audit gate ]   ← MANDATORY (see Functionalities → Audits)
speckit.tasks          → decompose plan into T-NNN tasks
speckit.implement      → write code, task by task

Brownfield (existing repo)

The agent loads fact-research. It spawns 7 parallel sub-agents (Haiku/Sonnet) that map, in one pass:

  • Folder structure
  • Stack & dependencies (pyproject.toml, package.json, etc.)
  • Code conventions (3-5 representative files)
  • Main modules / entry points
  • Test framework & coverage shape
  • Build & deploy (CI configs, Dockerfile, scripts)
  • Existing docs (README, ARCHITECTURE.md, ADRs)

Result: a research.md under 200 lines. You read it and flag what's missing or wrong. Then constitution + delta spec + plan + audit gate

  • tasks + implement, same as greenfield from there.

If the repo already has an AGENTS.md / CLAUDE.md / GEMINI.md, the agent absorbs its domain knowledge into the constitution and replaces the old file with a one-paragraph pointer back to .specify/memory/constitution.md.

Demo (quick experiment)

Uses the tinyspec Spec Kit extension. Skips discovery and clarify to ship a single throwaway from idea → plan → implement. Useful for spike work where you don't want the full ceremony.

Session summaries between phases

Between every phase, the agent writes a short summary to .specify/fact/sessions/<UTC>.md (What was done, What was decided, What's pending / next). These power continuity — if the session crashes or you close at any point, the next session picks up from the last summary.


Functionalities

Skills

FACT ships nine base skills. Loading is automatic — they're invoked by other skills, by hooks, or by slash commands.

Skill When loaded What it does
fact-onboarding first thing in /fact-start Detects continuity, asks for project type, hands off to a workflow skill.
fact-rpi-harness always loaded The 40% rule, sub-agent strategy, intentional compaction, session summaries, two-stage [P] review.
fact-discovery greenfield workflow Socratic Q&A → vision → constitution → specify → clarify → plan.
fact-research brownfield workflow Parallel sub-agents map the codebase → research.md → delta spec.
fact-implement implement phase Per-task discipline: read plan, apply skills, write code, mark done.
fact-tdd by fact-implement for tasks that touch business logic RED-GREEN-REFACTOR cycle. Failing test first, smallest code to pass, refactor under green.
fact-verify by fact-implement before flipping [x] on any task Verification checklist: tests pass, type-check clean, behavior matches plan, no TODOs / skipped tests, diff matches files the plan listed.
fact-skill-installer when an external skill is needed Search skills.sh, present to user, install with explicit confirmation.
fact-audit when a hook trigger arrives Orchestrates security / architecture / quality reviews; runs the project test suite as a separate action on session-stop / /fact-audit all.

CLI commands

Command What it does
fact init Idempotent project setup. Auto-installs specify-cli.
fact init --port 7900 Use a non-default dashboard port.
fact init --no-dashboard Set up the project without starting the dashboard.
fact init --no-speckit Skip the auto-install of specify-cli.
fact dashboard Start (or check) the dashboard server.
fact dashboard --restart Force restart the dashboard.
fact stop Stop the dashboard.
fact doctor Diagnose: what's missing, what's broken.
fact doctor --fix Try to install anything missing (currently: specify-cli).
fact upgrade Re-copy bundled skills / commands / hooks into the project.

Slash commands (inside Claude Code)

Command What it does
/fact-start First time: pick workflow type and begin. Resumed sessions: detects continuity.
/fact-next Continue the current phase or advance to the next.
/fact-status Quick status report in chat (≤10 lines).
/fact-audit [security|architecture|quality|all] Run an audit on demand.

Plus all of Spec Kit's /speckit.* commands (constitution, specify, clarify, plan, tasks, implement, verify-tasks, …) which the FACT skills call internally.

Dashboard

A local single-page app on port 7842, live during the session.

FACT dashboard

Three live zones:

  • Header — phase pill (constitution, specify, plan, tasks, implement, done); tasks counter done/total; tokens (with input/output/cache breakdown on hover); cost in USD; saved vs Opus counterfactual showing what the workload would have cost if every sub-agent had used Opus.
  • Sidebar — file tree (every .md clickable, opens rendered); tokens grouped by model (opus-4-7, sonnet-4-6, haiku-4-5).
  • Kanban — stories from tasks.md (User Story / Phase / Workflow / Foundation), each with a progress bar + count pills
    • click-through to a task-detail modal. The active card pulses blue; [P] worktree sub-agent work pulses violet with a ⤵ subagent · model chip showing which model is running.

Search (focus with /), feature picker, filter by kind / priority / task tag, hide-workflow toggle. The footer shows live WebSocket status and auto-reconnects.

Audits

Hooks fire on tool use; they never run linters or audits themselves. Each trigger emits a structured prompt that pauses the workflow and instructs the agent to load the fact-audit skill, which spawns sub-agents loaded with domain skills from skills.sh.

Trigger When Sub-agent Dimensions
source-edit every Edit/Write to .py/.ts/etc Haiku security, quality
task-close edit to tasks.md (likely a task closed) Sonnet security, architecture, quality
session-stop the agent tries to close session Sonnet × 3 parallel sec/arch/qual + runs the project test suite

Tests run via pytest / npm test / cargo test if available. Test failures count as critical.

When findings of severity ≥ high exist, the agent surfaces them verbatim and gives you four choices:

  1. Fix automatically — agent edits the affected files; the next write re-triggers the audit and must come back clean.
  2. Fix manually — agent pauses while you edit.
  3. Override — agent records the override + your reason in the session summary, then continues.
  4. Rollback — agent proposes the inverse of its last edit.

Lower-severity findings (medium/low/info) are mentioned in passing without blocking.

A separate pre-implement audit gate is invoked by fact-discovery / fact-research after /speckit.plan and before /speckit.tasks: three Sonnet sub-agents review the plan against constitution + spec; critical findings → return to plan iteration.

Audit reports are written to .specify/fact/audits/<UTC>-<dim>.md. The conversation between agent and user is the canonical surface; the file is for record.

Continuity

FACT persists state continuously — not at session-close. If you Ctrl+C Claude or the process crashes, the latest snapshot is already on disk. On reopen, fact-onboarding reads:

  1. session_state.json — mechanical state (active task, recent files, model, last update).
  2. The latest .specify/fact/sessions/<UTC>.md — semantic state (decisions, what was tried, what's next).

It then asks if you want to continue. Three cases handled:

  • Clean close — last task was [x]. Continue with the next pending task?
  • Mid-task abandon — last task [ ] but files modified. Pick up where you left, or reset and start over?
  • Corrupt statesession_state.json missing/garbled. Falls back to the Spec Kit files alone, asks what to do.

If both layers are gone (rm -rf .specify/fact/), FACT degrades to Spec Kit-only — exactly how Spec Kit projects work without FACT.


Troubleshooting

Problem Fix
Dashboard shows nothing — empty kanban The agent hasn't run /speckit.tasks yet. Phase cards still appear; T-NNN cards arrive when tasks.md is generated.
Dashboard isn't reflecting changes Hard refresh the browser (Cmd+Shift+R). Cache headers should prevent this but a stale tab can stick.
specify not found / install failed Run fact doctor --fix. If still failing, install manually with uv tool install --from git+https://github.com/github/spec-kit.git specify-cli.
🔒 FACT AUDIT keeps re-firing on Stop Update FACT (fact upgrade). The Stop hook now fires at most once per session.
Cost shows $0.00 despite agent activity The dashboard reads tokens from the Claude Code transcript. Make sure the project was init'd with fact init; then fact upgrade to refresh hook helpers.
Agent forgot to write active_task_id The dashboard infers in-progress from the recent file edit buffer. Should self-correct after the next file edit.
fact upgrade says nothing changed That's fine — it's idempotent. To force a refresh, delete .claude/skills/fact-* and re-run.
I want to restart from scratch fact stop && rm -rf .specify .claude/skills/fact-* .claude/commands/fact-* .claude/hooks && fact init. Your code is untouched.
Windows: pipx install ... fails with Unable to create process using ...python.exe The pipx shim is hard-coded to a Python that no longer exists at that path. Either reinstall pipx (python -m pip install --user --upgrade pipx) or switch to uv (recommended on Windows).
Hooks don't fire / dashboard stays empty Hook commands in .claude/settings.json reference an absolute path to the Python interpreter that ran fact init. If that interpreter has since moved or been uninstalled, the hooks silently fail. Re-run fact upgrade to refresh the paths.
Claude Code shows Unknown hook event "SubagentEnd" Old FACT version. Run fact upgrade inside the project — it renames the event to SubagentStop (Claude Code's current name) and removes the stale entry from settings.json.

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fact_toolkit-0.3.3.tar.gz (258.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fact_toolkit-0.3.3-py3-none-any.whl (107.8 kB view details)

Uploaded Python 3

File details

Details for the file fact_toolkit-0.3.3.tar.gz.

File metadata

  • Download URL: fact_toolkit-0.3.3.tar.gz
  • Upload date:
  • Size: 258.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fact_toolkit-0.3.3.tar.gz
Algorithm Hash digest
SHA256 4c85ece6fdecf40ba504c4f2aaeb46534beea1d19cdf2334089006f0f607400d
MD5 0981aba487741cf534de7a6f978b77cc
BLAKE2b-256 8b65e65f12e992e1622cb696b66e6a6724ced4953c78b7202279170961d4e633

See more details on using hashes here.

Provenance

The following attestation bundles were made for fact_toolkit-0.3.3.tar.gz:

Publisher: release.yml on holaPymbu/fact

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fact_toolkit-0.3.3-py3-none-any.whl.

File metadata

  • Download URL: fact_toolkit-0.3.3-py3-none-any.whl
  • Upload date:
  • Size: 107.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fact_toolkit-0.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 11afe32e3ef49322def0ba9f5a6ca8794fe07660386a4f3f343a96972f2539a8
MD5 b0d4d1a4e55c82431f1e1a968dbedebb
BLAKE2b-256 6be7bc4d06e1a513527024148f8b78545f8d1f4950a958f8fafbf70d58105044

See more details on using hashes here.

Provenance

The following attestation bundles were made for fact_toolkit-0.3.3-py3-none-any.whl:

Publisher: release.yml on holaPymbu/fact

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page