Metadata-Version: 2.4
Name: fact-toolkit
Version: 0.3.5
Summary: Focused Agentic Context Toolkit — Spec Kit + RPI for Claude Code
Project-URL: Homepage, https://github.com/holaPymbu/fact
Project-URL: Repository, https://github.com/holaPymbu/fact
Project-URL: Issues, https://github.com/holaPymbu/fact/issues
Author: FACT contributors
License: MIT
Keywords: agent,ai,claude-code,rpi,skills,spec-kit
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.10
Requires-Dist: fastapi>=0.136
Requires-Dist: httpx>=0.28
Requires-Dist: jinja2>=3.1.6
Requires-Dist: markdown-it-py>=4.1
Requires-Dist: pygments>=2.20
Requires-Dist: rich>=15.0
Requires-Dist: typer>=0.25
Requires-Dist: uvicorn[standard]>=0.46
Requires-Dist: watchdog>=6.0
Requires-Dist: websockets>=16.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=1.3; extra == 'dev'
Requires-Dist: pytest>=9.0; extra == 'dev'
Requires-Dist: ruff>=0.15; extra == 'dev'
Description-Content-Type: text/markdown

# 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](https://github.com/github/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](https://github.com/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** — at 60% of the model's context the
  agent stops, writes a semantic summary to disk, and offers you three
  options (run `/compact`, close + reopen, or push through). You pick;
  the summary survives crashes so the next session resumes cleanly.
- **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](https://claude.com/claude-code) on `PATH` | the agent harness FACT plugs into |
| `git` | repo operations + Spec Kit |
| [`uv`](https://docs.astral.sh/uv/) *or* [`pipx`](https://pipx.pypa.io/) | to install FACT in an isolated env |

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

### Fresh machine — macOS

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

### Fresh machine — Windows (PowerShell)

```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

```bash
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

```bash
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

```bash
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`):

```bash
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](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.

```mermaid
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.

```mermaid
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](https://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](docs/img/dashboard-overview.png)

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](https://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 state** — `session_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.
