Commit graph

42 commits

Author SHA1 Message Date
Himanshu Dongre
0c63ead534 Stop swallowing chat-title generation failures silently
Some checks failed
Deploy website to GitHub Pages / deploy (push) Has been cancelled
The /api/v4/chat/sessions/{id}/title endpoint wrapped its entire body
in a bare `except Exception: pass`. When the background LLM provider
was missing or the call failed, the endpoint silently returned the
unchanged session — clients could not tell "title not requested yet"
apart from "tried and failed because no provider." Same anti-pattern
as the extract bug (713ed9a), lower severity (titles are cosmetic).

This is the smallest correct fix:

  - Title generation is still best-effort. The endpoint always returns
    200 with the session. The chat surface is never blocked.
  - Failures are no longer silent. The bare except is replaced with
    three typed branches:
      * ProviderNotConfiguredError → WARNING log + status
        "skipped:provider_not_configured"
      * generic provider call error → WARNING log + status
        "skipped:provider_error"
      * DB write error after successful generation → ERROR log + status
        "skipped:db_error" (also rolls back the session)
  - SessionResponse gains an optional `title_generation_status: str` field
    (default None). The title endpoint sets it to one of the four enum
    values above ("ok" on success). Every other endpoint that returns
    SessionResponse continues to return null for this field — additive,
    no client-breaking change.
  - Logs carry session_id, provider, model, exception type, and message
    — enough to diagnose, no secrets (provider SDK errors do not place
    API keys in str(e); the test asserts no "sk-" / "bearer " patterns).

Chat-send is not touched. Title generation is only invoked by the
dedicated /title endpoint (verified by grep), so chat-send was already
independent of this code path and remains independent.

Tests (new file backend/tests/integration/test_chat_title.py):
  - test_title_generation_succeeds_with_provider: pins the happy path
    (status "ok", no WARNING/ERROR noise).
  - test_title_generation_fails_loud_without_provider: regression test
    for the bare-except bug — asserts 200, session title unchanged,
    status "skipped:provider_not_configured", exactly one WARNING log
    with diagnostic context, no exception bubbles.
  - test_title_generation_handles_provider_call_error: pins the generic
    provider-error branch.
  - test_title_endpoint_400_when_no_turns: pins the existing precondition
    so the typed-except rewrite doesn't accidentally swallow it.
  - test_other_session_endpoints_omit_title_generation_status: confirms
    the additive field is null on other SessionResponse endpoints.

Full backend integration suite: 170 passed locally (was 165 + 5 new).
2026-05-23 18:09:27 +05:30
Himanshu Dongre
713ed9a007 Refuse to silently extract mock content into a real Space
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).
2026-05-23 17:48:14 +05:30
Himanshu Dongre
3b6ef000dc Detect repo drift against the last checkpoint
The repo-state section added by the previous commit shows working-tree
and git-upstream drift. It does not answer the question Smriti's trust
story actually needs: has the repo moved since the last checkpoint?

Record git provenance on checkpoints and compare against it. The CLI
captures the git HEAD and branch when it creates a checkpoint; the V4
commit endpoint stores that under the commit's context_blob and returns
it on read. `smriti state` then compares the working repo against the
latest checkpoint's recorded HEAD/branch and surfaces:
  - repo unchanged since the last checkpoint
  - repo is N commit(s) ahead — recorded state may be stale
  - repo history has diverged from the last checkpoint
  - the last checkpoint was taken on a different branch

All local and read-only: no fetch, no reconciliation. Checkpoints made
before this feature (or by the MCP server) record no git state and are
simply left uncompared.
2026-05-19 23:22:22 +05:30
Himanshu Dongre
e303f7a547 Require force to delete a non-empty space at the API layer
The deletion-safety thread guarded the CLI (`--force`) and the MCP tool
(`confirm_space`), but `DELETE /api/v2/repos/{id}` itself still cascade-
deleted a fully populated space — every checkpoint, session, and turn —
with no server-side check. Any client that bypassed the CLI/MCP guards
(a direct API call, the web UI, a future client) reopened the incident
path.

Gate the route: `delete_repo` now counts the space's checkpoints and
refuses with 409 plus a structured detail (`message`, `checkpoint_count`,
`requires_force`) unless `?force=true` is passed — the same shape as the
`checkpoint delete` dependent-guard. An empty space still deletes with no
force.

Wire the existing clients through the new signal so their behavior is
unchanged: the CLI passes `force=args.force` (its own `--force` gate),
the MCP tool passes `force=true` after its `confirm_space` gate, and
quickstart passes `force=true` to tear down its own demo space.
2026-05-19 01:36:58 +05:30
Himanshu Dongre
ab8d6f6b6f Clarify claim completion metrics 2026-05-18 00:07:42 +05:30
Himanshu Dongre
2bbb7d27bc Fix smriti current crash on list-valued blocked_by
External-machine validation found GET /api/v5/current 500s on a real
project: a structured task can carry `blocked_by` as a list of dependency
labels, but CurrentTask.blocked_by is typed Optional[str], so constructing
the model raised a Pydantic ValidationError.

Add a field validator that normalizes `blocked_by` — string, list, or null —
to a single display string. The API contract is unchanged (blocked_by stays
a string), so the CLI and the Project Current State UI panel, which both
read this endpoint, need no change. Adds a regression test.
2026-05-17 16:20:32 +05:30
Himanshu Dongre
76f6f4c2c7 Polish external validation output and docs 2026-05-17 12:15:14 +05:30
Himanshu Dongre
448484c4c3 Expand doctor activation diagnostics 2026-05-17 00:26:03 +05:30
Himanshu Dongre
f22056418d Add optional local-first SQLite mode (Phase A core)
Smriti can now run against a file-backed SQLite database with no Docker
and no Postgres, removing the operate-a-backend burden for solo builders.
Postgres remains the stronger shared/team mode, unchanged.

- Portable column types (app/db/types.py): JSON renders as JSONB on
  PostgreSQL and generic JSON on SQLite; the pgvector embedding column
  renders as JSON on SQLite. Same models and create_all on both backends.
- Mode resolution (config.py): SMRITI_DB_MODE=local|postgres, defaulting
  to local when unconfigured. An explicitly-set Postgres DATABASE_URL
  preserves Postgres behavior, so existing setups are unaffected. Local
  DB defaults to ~/.smriti/smriti.db; SMRITI_LOCAL_DB_PATH overrides.
- SQLite engine setup (database.py): check_same_thread plus foreign_keys
  / WAL / busy_timeout pragmas; a lazy first-run create_all bootstrap on
  first DB use, which keeps the integration test suite insulated.
- Removed the integration-test JSONB/VECTOR DDL substitution hack — the
  models are genuinely portable now, so conftest needs no type patching.
- Alembic resolves its URL through the same logic (Postgres mode only).
- New persistent file-backed SQLite smoke test, plus mode-resolution and
  per-dialect type-rendering tests.

Local mode uses create_all, not Alembic. No schema changes.
2026-05-16 22:26:05 +05:30
Himanshu Dongre
ef8faf6e4d Add Project Current State endpoint and UI panel
Add GET /api/v5/current/spaces/{id} — a packaged, computed-on-demand
snapshot of where a space is right now: current direction, counts,
attention signals (open questions, divergence, active work), active
work claims, open tasks grouped by intent, recent milestones, and
recent activity. Shared payload contract with the smriti current CLI
surface built in parallel.

Render it as the ProjectCurrentState panel at the top of LineagePage,
replacing the hand-rolled current-state summary. Extract a shared
_get_active_claims helper so the state and current endpoints report
active work identically. No schema changes.
2026-05-16 20:01:16 +05:30
Himanshu Dongre
c470947477
Polish worktree short ids and clean finish (#5) 2026-05-04 15:28:19 +05:30
Himanshu Dongre
8c963198e1 Add canonical project root for spaces 2026-05-04 13:43:44 +05:30
Himanshu Dongre
3cb514b279 Add V3 dirty paths and skill pack v2.1 2026-05-04 13:11:20 +05:30
Himanshu Dongre
1bab89cdea Populate worktree list probe columns 2026-05-04 12:52:35 +05:30
Himanshu Dongre
39003a8aa6 Add V2 worktree-bound claims 2026-05-04 12:16:32 +05:30
Himanshu Dongre
b5ccdce758 Add V1 worktree primitive
Adds WorkTree schema and migration, /api/v5/worktrees CRUD, CLI and MCP worktree surfaces, targeted regression tests, health capability, and minimal docs. Live Postgres migration/manual localhost verification intentionally remain pending until the full backend provider-config gate is resolved.
2026-05-04 00:58:30 +05:30
Himanshu Dongre
64caf0c801 Add space metrics endpoint and sync docs with current product surface
Metrics: GET /api/v5/metrics/spaces/{id} returns coordination (checkpoints,
agents, cross-agent continuations, claim completion rate), state quality
(decisions/tasks per checkpoint, structured task adoption, milestones),
and branch lifecycle KPIs. All computed on demand from existing data —
no new schema, no events, no background jobs. CLI: smriti metrics <space>.

Doc sync: fix stale tool counts (CONTRIBUTING 15→17, cli/README 16→17),
update REPO_STRUCTURE (skill pack v1.5→v1.9, test files/counts), remove
shipped branch-lifecycle from ARCHITECTURE "not yet" section, add task
IDs + task-referenced claims + capabilities manifest + recheck pattern
to ARCHITECTURE structured tasks section, add coordination primitives
summary to README.
2026-04-14 01:11:56 +05:30
Himanshu Dongre
9e570a04e3 Advertise task ID capability in health 2026-04-14 00:37:41 +05:30
Himanshu Dongre
beae3b5c9b Add stable task IDs and task-referenced claims for collision detection
Tasks gain an optional id field (short slug like "impl-1", "docs-arch").
Claims gain an optional task_id field referencing a specific task. The
state brief shows (id: X) on tasks and (task: X) on claims, making it
precise which task a claim covers.

Skill pack v1.9 teaches the recheck pattern: after creating a claim,
re-read state to detect if another agent claimed the same task_id in
the race window. If collision detected, abandon and pivot.

This solves the near-simultaneous start problem from the autonomy
validation where both agents picked [docs] because claims had no
task-level identity.
2026-04-14 00:16:46 +05:30
Himanshu Dongre
6da93ae856 Add capabilities manifest to /health for stale-backend detection
The health endpoint now returns git_sha and a capabilities list so
agents can detect when the running backend is missing features they
need (e.g., claims, structured_tasks). Skill pack v1.8 teaches the
capabilities probe: check /health when a 404 or missing section
suggests the backend is stale, tell the human to restart.

Diagnosed from the autonomy validation where Codex hit a backend
without /api/v5/claims — the backend process was running old code.
2026-04-13 23:06:34 +05:30
Himanshu Dongre
422597015f Widen ManualCommitRequest.tasks to accept structured task objects
The V4 chat commit endpoint had tasks: list[str], which rejected
the structured task objects produced by the extract prompt. Widened
to bare list to match CommitCreate and CommitModel.
2026-04-13 22:47:25 +05:30
Himanshu Dongre
73f26e721c Add structured tasks with intent hints for autonomous work selection
Tasks in checkpoints evolve from flat strings to objects with optional
intent_hint (implement/review/investigate/docs/test), blocked_by
(dependency label), and status (open/done). Agents reading the state
brief can now self-select complementary work by matching task intents
against active claim intent_types — no founder routing needed.

Backward-compatible: old string tasks normalize at render time. No
schema migration. JSONB handles both shapes. Skill pack v1.7 teaches
the autonomous selection reflex.
2026-04-13 22:27:32 +05:30
Himanshu Dongre
64b158e4c8 Add note indicators to LineagePage checkpoint cards 2026-04-13 19:25:43 +05:30
Himanshu Dongre
9b109ae94c Add checkpoint notes: additive founder annotations with kind (note/milestone/noise) 2026-04-13 19:10:37 +05:30
Himanshu Dongre
44db645460 Add --since freshness parameter to smriti state for pull-time staleness detection 2026-04-13 18:05:05 +05:30
Himanshu Dongre
8d01e1e866 Surface active work claims and branch disposition in LineagePage 2026-04-13 17:22:33 +05:30
Himanshu Dongre
5f5e15c7aa Add generic OpenAI-compatible provider for cheap/local model support 2026-04-13 16:56:34 +05:30
Himanshu Dongre
405592da55 Add branch disposition for lifecycle closure: integrated, abandoned, active 2026-04-13 13:03:22 +05:30
Himanshu Dongre
011af9bba6 Add work claims for pre-work intent visibility 2026-04-12 23:22:38 +05:30
Himanshu Dongre
0b6ea2c34f Fix config reload follow-up 2026-04-12 21:59:22 +05:30
Himanshu Dongre
b52b6339a0 Make config startup reliable: honest status, startup warning, defensive dotenv 2026-04-12 21:21:55 +05:30
Himanshu Dongre
fa62e2eff3 Load .env via python-dotenv so extractor gets API keys reliably 2026-04-12 13:11:57 +05:30
Himanshu Dongre
28dbdedae9 Show author_agent in LineagePage checkpoint cards 2026-04-12 10:48:15 +05:30
Himanshu Dongre
7eabdc820e Add multi-branch space state endpoint
GET /api/v4/chat/spaces/{id}/state is the richer sibling of /head. It
returns main HEAD plus up to 5 active non-main branches plus a
lightweight divergence signal when any active branch disagrees with
main on decisions. Hard caps (5 branches, 2 divergent pairs, 3
decisions per side per pair) keep the aggregate response digestible.

Divergence detection reuses lineage._diff_lists so matching stays
consistent with smriti compare — decisions differing only in case or
punctuation normalize equal and do not trigger a false divergence
signal.

The query helper uses a Python-side per-branch dedupe rather than
Postgres DISTINCT ON so integration tests can run on sqlite without
dialect-specific workarounds. The non-main commit space for any real
project is small, so the cost is negligible.

No schema changes. No migrations. No behavior change for existing
callers of /head.
2026-04-12 01:58:03 +05:30
Himanshu Dongre
6028dacff1 Extract checkpoint fields from freeform markdown via LLM
Round 3 of the dogfood confirmed that every multi-branch CLI command
works end-to-end, but the single biggest remaining friction is still
checkpoint payload construction. Each agent hands off a ~15-18 KB
markdown document; turning that into the Smriti schema (decisions,
assumptions, tasks, open_questions, entities, artifacts) is three
minutes of hand-written JSON per checkpoint and adds no product value.

This build adds an LLM-powered extractor that collapses that work into
one pipe command:

  cat /tmp/r3_agent_a_output.md | smriti checkpoint create my-project \
      --extract --author-agent codex-A

The CLI reads stdin as freeform markdown, calls the new
POST /api/v5/checkpoint/extract endpoint, maps the returned fields
into a commit payload, and writes the checkpoint. --dry-run prints the
extracted payload without committing so users can review first.
--extract and --from-json are mutually exclusive.

Backend architecture mirrors the existing review endpoint: stateless
LLM call (no session or commit ID required), uses the same background
intelligence provider (cfg.background.provider / cfg.background.model)
as draft and review, same JSON-mode prompt shape, same 502-on-parse-
error pattern. The extractor endpoint differs in one small way: it
passes allow_mock=True to get_adapter so unconfigured test envs fall
back to MockAdapter without raising 500. Production envs always have
a real provider configured and never hit this fallback.

The extractor is the first LLM-backed endpoint that gets tested
against a real mock response. To make that work, MockAdapter.send now
detects response_format={"type": "json_object"} in kwargs and returns
a canned JSON blob covering every field any current Smriti endpoint
looks for (title, objective, summary, decisions, assumptions, tasks,
open_questions, entities, artifacts, issues, suggestions). Existing
chat.send text-mode tests are unaffected because they don't pass
response_format. This also unblocks future tests for draft and review.

Manual verification against a real OpenAI provider: piped a realistic
23-line handoff markdown with 4 decisions, 3 assumptions, 3 tasks,
2 open questions, and a python code block. The extractor returned
exactly those items in the right fields (4/3/3/2/1) and produced a
valid checkpoint with all fields populated. Round 4's load-bearing
claim — zero hand-written JSON per checkpoint — is now achievable.

153/153 backend tests pass (149 pre-existing + 4 new extract tests).
2026-04-11 19:15:03 +05:30
Himanshu Dongre
f2c5c08942 Record project_root and author_agent on checkpoints
Cross-agent handoffs need to know two things the old schema did not
carry: where the project lives on disk (so the receiving agent opens
the right repo), and which agent wrote the checkpoint (so branches
can be attributed when two agents have forked the same tree). Round 1
of the dogfood lost the first one — Agent A designed files at one
path and Agent B wrote them at a different path because nothing in
the schema carried "where we are". Round 2 worked around it by putting
the path in the prompt, but the schema still had no slot for it.

This build adds a `project_root` column to the commits table (nullable
TEXT, no backfill), plumbs it through the V2 commit-create path and
V4 chat-commit path, and has `smriti checkpoint create` auto-capture
the current working directory by default. `--project-root /path`
overrides and `--no-project-root` opts out.

`author_agent` already existed on the model but the V4 chat-commit
endpoint hardcoded it to the session's active provider (e.g.
"anthropic"), so it was a provider name, not an agent identifier.
This build makes the request's `author_agent` field win when provided
and falls back to the session provider only when it isn't. CLI adds
`--author-agent <name>` so agents can tag themselves cleanly as
"claude-code" or "codex-local" rather than the underlying provider.

Both fields surface in `smriti state`, `smriti checkpoint show`, and
`smriti restore` meta lines — `by <agent>` and `at <path>` (with $HOME
tilde-expanded for readability). The meta line elides each segment
cleanly when the field is null, so old checkpoints without either
value still render correctly.

While I was here, flipped `smriti state` to show full artifacts by
default. `--preview` is the new way to get truncated previews.
`--full-artifacts` is kept as a no-op alias so existing scripts that
explicitly passed it still work. The CLI is agent-first and agents
want the full content for handoff; humans wanting a quick glance can
pass `--preview`.

149/149 backend tests pass (147 pre-existing + 2 new: round-trip of
the two fields and the author_agent fallback regression).
2026-04-11 18:08:13 +05:30
Himanshu Dongre
2a6614bd80 Add fork, compare, restore CLI commands and fix compare correctness
Round 2 of the agent handoff dogfood showed that every multi-branch
operation required reaching past the CLI into curl: fork had no CLI
command, `smriti checkpoint create` always spawned a fresh session with
no way to attach to a forked one, and the compare endpoint returned
useless output (common_ancestor_commit_id was missing from the response,
and shared-set matching was exact-string so two agents phrasing the
same commitment differently showed zero overlap).

This ships the full CLI surface for multi-branch workflows plus the
backend fixes that make compare actually useful:

  smriti fork <checkpoint-id> [--branch <name>]
  smriti restore <checkpoint-id>
  smriti compare <checkpoint-a> <checkpoint-b>
  smriti checkpoint create <space> --session <session-id>

The compare endpoint now walks parent chains to compute a lowest
common ancestor (bounded to 1000 steps with a cycle guard) and returns
it on CheckpointDiff as an optional uuid. Shared-set matching uses a
lightweight lowercase + punctuation-strip + whitespace-collapse
normalization for keying, but returns the original A-side strings so
the output stays readable. Four new compare tests cover direct and
two-step LCA, null LCA for unrelated checkpoints, and normalized
shared-set matching. Existing compare tests still pass unchanged
because their data ("Use Redis" vs "Use Postgres") is distinct at any
sensible normalization level.

`smriti restore <checkpoint>` is a pure read — it renders any
checkpoint as a continuation brief matching `smriti state <space>`
shape. `smriti fork` derives the space from the checkpoint so the
user does not have to pass it separately. `--session` on checkpoint
create is purely additive: when absent, the existing auto-session
behavior is unchanged.

147/147 backend tests pass (143 pre-existing + 4 new).
2026-04-11 17:50:03 +05:30
Himanshu Dongre
73c71b4c9d Add delete endpoints for spaces, checkpoints, and sessions
Two rounds of agent-handoff dogfood testing surfaced that Smriti had no
way to delete spaces, sessions, or checkpoints via any surface. This
adds DELETE endpoints to the V2/V4 API, new CLI commands, and UI
affordances on the workspace overview and chat history panel so the
daily cleanup path does not require opening a Python shell.

Checkpoint delete refuses with 409 Conflict when child commits or
forked sessions reference the target, because silently orphaning them
would cause walk_ancestors to collapse lineage and forked sessions to
lose isolation. The refusal is escaped via ?cascade=true on the API,
--cascade on the CLI, and a two-step confirm with a dependents list
plus checkbox in the UI modal.

Space delete relies on the existing DB-level cascade chain from the
earlier commit/session/turn migrations — no new Alembic migration is
needed. Session delete cascades turn events but preserves commits
authored by the session, since commits are space-owned artifacts.

14 integration tests cover cascade correctness, 409 refusal, the
cascade escape hatch, cross-user 404s, subtree ordering, and
idempotency. Existing tests pass unchanged (143/143).
2026-04-11 17:25:36 +05:30
Himanshu Dongre
89b6df16cf Add CLI for agent and programmatic access
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.
2026-04-11 11:10:01 +05:30
Himanshu Dongre
d01a180975 Add artifact-aware checkpoints
Checkpoints can now hold attached artifacts — text content captured
from chat messages or added manually. Artifacts are included in
prompt context when a checkpoint is active, grounding reasoning in
actual content rather than just summaries. Add capture button on
messages, artifact management in checkpoint modal, and collapsible
artifact display in checkpoint detail.
2026-04-04 21:35:41 +05:30
Himanshu Dongre
2f155e8dcc Add checkpoint review and assumptions field
Separate assumptions from decisions as a first-class checkpoint
field. Add review endpoint that surfaces reasoning consistency
issues: contradictions, hidden assumptions, resolved questions,
and unused entities. Extend draft extraction, prompt context,
and compare diff to include assumptions.
2026-04-04 21:07:41 +05:30
Himanshu Dongre
befea97bf6 Initial public release 2026-03-22 13:48:50 +05:30