Commit graph

7 commits

Author SHA1 Message Date
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
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
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
9b109ae94c Add checkpoint notes: additive founder annotations with kind (note/milestone/noise) 2026-04-13 19:10:37 +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
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