A fresh Smriti install with no provider configured could still run
`smriti checkpoint create --extract`, which silently returned
MockAdapter content like "Mock decision from provider". If committed,
that placeholder text became part of the user's real reasoning state.
Root cause: backend/app/api/routes/checkpoint.py:417 called
`get_adapter(cfg.background.provider, allow_mock=True)`. The
`allow_mock=True` flag means the registry quietly returns MockAdapter
when no API key is configured, rather than raising. The CLI received
the canned mock JSON and committed it without inspecting whether it
came from a real LLM.
The extract endpoint was the only route in the codebase with this
pattern — draft, review, chat title, and chat send already correctly
pass `allow_mock=False`.
The new contract:
- Core Smriti (setup, doctor, quickstart, state/current/metrics,
claims, attach, manual JSON checkpoints) requires no API key.
- Real LLM-backed paths (`--extract`, draft, review, chat send)
require a configured provider — OpenAI / Anthropic / OpenRouter /
generic OpenAI-compatible (local models like Ollama).
- Mock extraction still works for tests and demos, but only when the
caller explicitly opts in (use_mock=true on the HTTP payload).
It is never silently the default.
Backend:
- POST /api/v5/checkpoint/extract now passes allow_mock=False and
catches ProviderNotConfiguredError, returning HTTP 412 with a
structured detail: error code, human message, the provider it
tried, and a list of fix paths the CLI surfaces.
- CheckpointExtractResponse gains `provider` and `model` echo fields
(additive, default empty) so callers can confirm what answered.
CLI:
- checkpoint create --extract catches 412 and prints the actionable
fix list; exits 78 (EX_CONFIG). Defense in depth: even on a 200,
refuses to commit if response.provider == "mock" on the default
path (so any future regression in the backend is still caught).
- smriti doctor surfaces background provider state prominently:
`ready (real LLM extraction enabled)` or `⚠ MOCK or DISABLED — …
will fail until a provider is configured`.
- smriti doctor --strict exits 78 when the background provider is
mock/disabled or the backend is unreachable. Safe to wire into
CI before any --extract step.
- On a successful --extract commit, the CLI shows `extracted via
<provider>/<model>` under the commit confirmation.
Docs:
- README: new "Provider configuration (LLM-backed features)" section
drawing the boundary explicitly; mentions the generic provider for
local OpenAI-compatible models; flags mock as test-only.
- .env.example: rewrote the provider section so an empty key or a
model-without-a-key is not interpreted as "ready".
- Skill pack template: new §4.1 "Before your first --extract: verify
the provider" telling agents to run `smriti doctor`, refuse
--extract when background_provider is mock/disabled, and fall back
to manual JSON checkpoints or ask the human to configure a
provider. Re-rendered to AGENTS.md (Codex target). The Claude Code
target (.claude/skills/smriti/SKILL.md) is gitignored per-user
install; rerun `smriti skills install claude-code` to refresh.
- website/index.html: Try-it lede now spells out which features need
a provider rather than gesturing at "optional LLM features".
Tests:
- test_extract_without_provider_fails_loud: regression for the bug —
monkeypatches get_adapter to raise ProviderNotConfiguredError,
asserts HTTP 412 with the structured detail shape, and asserts
the response body contains neither "Mock decision from provider"
nor "Mock Checkpoint". This test would fail on pre-fix code.
- test_extract_with_provider_echoes_provider_and_model: pins the
green path — provider and model must be echoed and must not be
"mock" when the real adapter answers.
- test_extract_happy_path_with_mock: unchanged, still pins the
explicit use_mock=true contract.
- Full backend integration suite: 165 passed locally (with the
pre-existing real-provider draft test passing under
backend/config/providers.yaml).
Add a "Multiple projects" beat to the attach step (§4) explaining that
attachment is per-project-directory, not global — each project's
.smriti.json, SessionStart hook, and skill packs live inside that
project's directory, and a Claude Code or Codex session opened in a
project's directory automatically lands on that project's space. The
MCP server registration is machine-wide but stateless (every call
passes space="..." explicitly), so the server has no "current space"
of its own.
A clarification gap surfaced in user discussion: the README explained
`.smriti.json` but never explicitly walked through the multi-project
mental model.
A public-facing positioning rewrite — the README was factually current after
the docs-truth pass but read like a backend feature list and undersold the
actual product.
- Lead with the thesis: "Code has Git. Multi-agent reasoning does not."
Position Smriti as version control for project reasoning state.
- Add a Git analogy table (commit -> checkpoint, branch -> fork, diff ->
compare, revert -> restore, working-tree drift -> repo-state drift) plus
the coordination primitives Git doesn't have.
- Add a concrete "why markdown handoffs aren't enough" section listing
what markdown can't reliably provide rather than just claiming it breaks.
- Reframe provider setup: the core coordination loop runs without API
keys; keys are only for the LLM-assisted features (extract, draft,
review, chat send). Previous wording over-emphasized keys.
- Rewrite the smriti init wording: cd into the project you want to
attach; init writes project-local files in cwd; the wrong directory
attaches the wrong project. Replaces the defensive "wire up Smriti's
own repo by mistake" line.
- Reorder so positioning leads, then setup -> doctor -> quickstart ->
init/attach -> no-arg daily workflow, then "What you get" details
primitives value-framed, then "Built with Smriti" lands as evidence.
- Drop the standalone "Single-user story" section (folds into "Versioned
reasoning") and condense the 13-item primitives list into 9
value-framed bullets.
301 lines (was 369). Command syntax, metrics, and screenshot blocks
preserved verbatim from the docs-truth pass.
The step-5 hook snippet showed `smriti state my-project --compact` and
claimed it was what `smriti init` generates. `smriti init` actually
generates a space-agnostic hook (`smriti state --compact`) that resolves
the space from the repo's .smriti.json attachment — verified in
`_build_session_start_hook_command`. Correct the snippet and note the
space-agnostic resolution.
Caught while integrating the cli/README.md command-reference refresh,
closing the docs truth pass as one coherent unit.
A focused truth + packaging pass before the website sprint — the product
moved a lot since the last docs sync (local-first SQLite, quickstart,
doctor, attached-repo no-arg workflow, repo-state drift detection,
deletion safety).
README: refresh the stale "Built with Smriti" metrics to current numbers;
add repo-state drift detection and destructive-action guards to the
coordination/trust surfaces; add an explicit no-arg daily-workflow block
so the new-user path (setup -> doctor -> quickstart -> attach -> no-arg
state/current/metrics) routes cleanly.
ARCHITECTURE: correct the /health capabilities list (add
activation_health); document repo-state drift detection.
DECISIONS: record why drift detection is CLI-side and why destructive
Space deletion is gated, not prevented.
REPO_STRUCTURE / CONTRIBUTING: correct the CLI command list (add attach,
quickstart; 16 commands) and the skill-pack template version (2.4).
cli/README.md was already current and is unchanged. The agent skill pack
still teaches manual reconciliation and is deliberately left for its own
versioned follow-up pass.
Smriti was repo-local wiring: every command needed an explicit <space>, and
the SessionStart hook hard-coded the space name, so working across projects
and sessions meant re-stating the space constantly.
Add a `.smriti.json` attachment file at the repo root binding the repo to a
space. The CLI resolves `<space>` from it — walking up from the working
directory the way git finds `.git` — so `<space>` is now optional on the
everyday commands (state, current, metrics, claim, checkpoint, branch,
worktree). `smriti attach <space>` is the explicit binding verb (`smriti
attach` with no argument shows the current binding); `smriti init` also
writes the attachment. The generated SessionStart hook is now space-agnostic
— `smriti state --compact` resolves from the attachment, so the hook is
identical for every project and survives re-attaching.
`space delete` still requires an explicit space. No backend changes —
attach/init reuse the existing set_project_root endpoint.
The 3-way merge auto-applied both Claude's and Codex's MCP-config intros
without flagging a conflict, leaving two paragraphs that both say "smriti
init prints the config." Collapse them into one — keeping the quickstart-first
onboarding wording and folding in Codex's `which smriti-mcp` manual-config tip.
An external-machine validation pass confirmed setup, local-first, doctor,
quickstart, and init all work — but the README still routed a new user
straight to `smriti init`, which opens an empty space where Smriti's value
is not yet visible.
Restructure the "Getting started" flow: a new step 3 runs `smriti doctor`
then `smriti quickstart` so the first thing a user sees is a populated demo
space. The init step now says to cd into your own project first; the MCP
guidance defers to the resolved config `smriti init` prints rather than a
bare `smriti-mcp`; mock-mode limits and "Try the demo" are clarified to match.
Packaging/readiness pass — documentation only, no feature or behavior change.
- REPO_STRUCTURE.md, CONTRIBUTING.md: corrected test counts (156 integration,
133 unit, 151 CLI), local-first setup flow (make setup-local / dev-local),
command count, new routes/types/test files.
- README.md: refreshed dogfood metrics, added Project Current State and
smriti doctor to the surfaces, SQLite to the tech stack.
- cli/README.md: MCP tool count 17 -> 21 (added the four worktree tools),
documented the smriti worktree commands.
- ARCHITECTURE.md: API table now lists the Project Current State and metrics
endpoints; new Database modes section (local SQLite / Postgres).
- DECISIONS.md: recorded the local-first SQLite mode and Project Current
State surface decisions.
- AGENTS.md: regenerated from skill pack template v2.3 (was a stale v1.5
render); the .claude/ claude-code render was likewise refreshed locally.
.env.example, docs/DEMO_SCRIPT.md, and CLAUDE.md were reviewed and left as-is.
V1 mentioned that claim binding and state-brief enrichment would land
in V2. V2 is now on main (39003a8), so update the bullet to describe
the actual current behavior: bind a claim to a worktree, see drift
in state brief, skill pack v2.0 teaches the reflex. Tool count
unchanged at 21 (V2 added params to existing tools, not new ones).
- README: 17 → 21 MCP tools, add worktrees bullet to coordination
primitives (notes V1 = CRUD primitive only; binding + state-brief
enrichment deferred to V2)
- CONTRIBUTING: 17 → 21 MCP tools
DECISIONS.md and skill pack template are intentionally not touched —
the V1 prompt explicitly deferred those to V2 so the rationale and
skill pack reflexes can be written together with the actual usage
patterns we'll learn from V2 (claim binding + state brief).
Captured three screenshots for the README using playwright against
the live local environment:
- lineage-dashboard.png — real LineagePage showing 56 checkpoints,
summary panel, needs-attention signal, author badges
- checkpoint-detail.png — the autonomy milestone checkpoint with
structured tasks (intent badges), entities, and founder notes
- cli-state-and-metrics.png — terminal-styled render of real CLI
output from smriti state --compact and smriti metrics
Fixed a crash in CommitDetailPage exposed by the screenshot attempt:
diffList was typed list[str] but tasks are now structured objects
after the task IDs feature landed. React threw "Objects are not
valid as a React child" when trying to render the diff result.
Fix normalizes tasks to their text field before diffing.
README now references real images instead of inline code blocks.
TypeScript clean, 331 tests pass.
The 3 screenshot placeholders pointed at files that don't exist yet,
which would render as broken images on GitHub. Replaced with inline
code blocks showing real CLI output (smriti state --compact and
smriti metrics) — these render cleanly now and can be swapped for
actual screenshots later when captured.
Removed stale Loom link and old checkpoint-diff screenshot reference.
README now references 3 new screenshots matching the current product:
LineagePage dashboard, CLI state+metrics, checkpoint detail with
structured tasks and notes. Screenshots are placeholders until
captured from the live environment.
Added docs/DEMO_SCRIPT.md: 3-act, 4-5 minute recording script
covering the state surface, coordination proof (metrics + autonomy
milestone), and developer experience. Includes exact commands,
highlight points, and a screenshot capture checklist.
Restructured from single-user chat-drift framing to multi-agent
coordination as the primary story. Leads with the problem (agents
have no shared state), the solution (structured reasoning-state
backend), and the proof (56 checkpoints, 30 cross-agent handoffs,
autonomous complementary task selection). Single-user value prop
preserved as a secondary section. All claims grounded in current
reality — no future hype, no unqualified comparisons.
cli/README.md:
- Add an "Installing the Smriti skill pack" subsection between the MCP
server section and the Commands reference. Walks through the target
list (claude-code, codex), the CLI install flow, the MCP-tool flow
(read the returned markdown, write via host file tools), and the
verification criterion ("agent calls state unprompted, never writes
HANDOFF.md").
- Update the MCP tools table to 13 entries (add smriti_install_skill).
- Update the Commands reference to include smriti skills list/show/
install and the new --main-only flag on smriti state.
- Update the "Using Smriti from a coding agent" walkthrough to note
multi-branch state as the default, with caps and the --main-only
escape hatch.
README.md (root):
- Expand the agent-facing surfaces section to list four surfaces, not
three: chat UI, CLI, MCP server, agent skill pack. Explain what the
skill pack does in one paragraph.
- Update the "Where this is going" outlook to acknowledge that the
transport gap is closed, the fluency gap is what the skill pack
addresses, and the open questions are now shape questions.
DECISIONS.md:
- Add "Why skill packs are a first-class surface, not documentation" —
records the reasoning for shipping versioned instruction files into
agent host project directories rather than a docs site, and explains
why Section 5 ("When NOT to checkpoint") gets equal weight to "When
to checkpoint."
- Add "Why smriti state is multi-branch by default" — records why the
default was flipped, what the hard caps are, that divergence
detection reuses the compare normalization, and that --main-only /
main_only=True preserves the legacy path for scripts.
ARCHITECTURE.md:
- Split the agent-facing backend section into runtime surfaces (CLI,
MCP, chat UI) and the onboarding surface (skill pack) to make the
distinction between how agents call Smriti and how they learn to
call Smriti explicit.
- Expand the CLI + MCP surface descriptions to reference the new V4
state endpoint and the new smriti_install_skill MCP tool (13 tools
now).
- Add a "Multi-branch state" subsection documenting the new endpoint,
the hard caps, the reuse of _diff_lists from lineage, and the
backward-compat story via --main-only / main_only=True.
- Update the API versioning table to note /api/v4/chat/spaces/{id}/state
as the agent-facing default alongside /head.
Five rounds of dogfood testing closed the basic agent handoff loop and MCP
shipped as the second transport. Update the docs to match:
- cli/README.md: replace the brief "Typical agent workflow" + "Multi-branch
workflow" sections with a transport-agnostic "Using Smriti from a coding
agent" walkthrough. CLI commands and their MCP tool equivalents are shown
side by side. Covers orient → work → checkpoint → hand off, the extractor
path (no hand-written JSON anymore), and the branching/compare/restore
flow.
- README.md (root): list MCP as a third surface alongside the chat UI and
CLI. Update the "Where this is going" outlook to acknowledge that the
handoff loop is proven and the open questions are now shape questions,
not transport questions.
- ARCHITECTURE.md: add MCP server as a third entry in the agent-facing
backend section, with the deliberate differences from the CLI (no cwd
auto-capture, no per-tool confirmation) spelled out.
- DECISIONS.md: keep the original "why CLI first, not MCP" entry as
historical context and add a "Shipping MCP as the second transport"
entry recording the design decisions made at ship time (same package,
FastMCP, stdio only, 12 tools, extract-only create_checkpoint, empty
project_root default, MagicMock unit tests).
Introduce a thin Python CLI that wraps the backend REST API. Seven
commands: space list, space create, state, checkpoint create,
checkpoint show, checkpoint list, checkpoint review. Reads piped
JSON on stdin for checkpoint create, prints a continuation-oriented
markdown brief for state. Supports --json on every command for
structured output.
Fixes a V2 schema drift where the commit response omitted
assumptions and artifacts, so the CLI can read full checkpoints
via the cleaner V2 single-resource endpoints. Updates README,
ARCHITECTURE, and DECISIONS to frame Smriti as a reasoning-state
backend with the chat UI and CLI as two clients of the same core.
Update README with restore UX, checkpoint review, assumptions,
and artifacts. Add when-to-use guidance. Sharpen problem statement
around drift and recovery. Update ARCHITECTURE with new checkpoint
fields and restore terminology. Add three new decisions to
DECISIONS.md. Document review endpoint and new fields in API docs.