Build-order step 1: the critical path everything else sits on.
- StateStore: SQLite in WAL mode with synchronous=FULL, so every
state transition and intent-log write is committed and fsynced
before returning; a power cut cannot tear state
- Durable intent log: begin_intent records a unit of work before it
starts; commit/abort resolve it; pending intents survive restart
- schema_version stamped from the first commit, with a sequential
migration hook; a newer state file than the code supports is
refused rather than misread
- reconcile_on_boot (A3 first cut): pending intents are checked
against external truth by registered reconcilers (observable
checks, never model self-assessment); verified effects are
committed, verified no-ops aborted, anything unverifiable gates
to AWAIT_INPUT — never blind-resume
- Lives in nisse_dev per spec 0.1: the library is extracted after
the dev agent works, not designed up front
- Integration test kills a subprocess mid-work with os._exit and
verifies state integrity and intent visibility on reopen
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- uv workspace tying nisse-core, nisse-dev, nisse-ops together
(src layouts, workspace-sourced nisse-core dependency)
- Placeholder hello-world entry points for both agents, calling
through nisse-core to exercise the package boundary
- pytest unit tests per package; integration tests (marker-gated)
running the installed console scripts as subprocesses
- ruff lint + format, nisse_* declared first-party
- Gitea Actions workflow running lint, format check, unit and
integration tests; scripts/check.sh mirrors it locally
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Part H's repository-layout item is resolved: one repo, three packages.
Naming (S0), scope (S0.1), the step-10 extraction, and the repository
layout section are updated to match.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
nisse-core's history becomes the repo root; the spec moves to docs/ at
top level; nisse-dev and nisse-ops fold in as package directories, their
seed histories (pointer files only) discarded. Pointer READMEs and
CLAUDE.mds are rewritten for in-tree paths.
Rationale: for a solo operator the three-repo split tripled admin
surface (tokens, CI, webhooks, permissions, backups) and imposed a
version-pinning contract on nisse-core, while the repo boundary was
never a trust boundary — the VM is. The spec's Part H is updated in the
next commit to record the decision.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Seeds nisse-core as the home for system-level design documentation. The
spec covers the shared library (Part A), both agents (Parts B and C), and
the supporting services, build order, and open decisions.
nisse-core holds this because the document describes the shared design
rather than either agent's implementation; the repo gains code later, at
the extraction step in the build order.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>