Reorder the plan for a minimal live loop, checked by an end-to-end test
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m46s

The priority is the smallest new loop running live, so M1.4 and M1.5 move
after M2.1. Each milestone is now checked by an automated end-to-end test
(new M1.6) against real resources, not a manual live run; manual runs are
for the new loop's first runs and phase ends.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
This commit is contained in:
dongarandClaude Opus 5.5 committed 2026-10-02 22:51:26 +00:00
1 parent 92e67b8bd9
commit 577a08bf95
1 file changed
+41 -26
+41 -26
View File
@@ -6,9 +6,10 @@
architecture says *what and why*; this document says *how and when*, and is revised
as work lands.
**The priority is live testing.** Work is ordered so the agent runs live against
real resources as early and as often as possible, and what each run finds steers
what comes next.
**The priority is a minimal new loop, running live.** Work is ordered to reach the
smallest end-to-end version of the conversational loop (M2.1) as soon as
possible; everything not needed for it waits. Each milestone is checked by an
automated end-to-end test against real resources, not by hand.
---
@@ -66,9 +67,11 @@ Only `nisse-dev` has real code; `nisse-core` and `nisse-ops` are placeholders.
`CLAUDE.md`. A milestone marked **needs discussion** starts with a design
discussion first.
- **Every change comes with tests,** through `scripts/check.sh`.
- **A live run follows each milestone that changes behaviour,** not just each phase:
a short bring-up run of what the milestone added. Findings are filed as issues and
either fixed before moving on or deliberately deferred.
- **The end-to-end test follows each milestone** (M1.6): the real agent, real models,
the Gitea sandbox and a real build host, driven by a scripted operator. It runs
after each milestone, not on every push, since it spends model tokens. Manual
live runs are for the new loop's first runs and phase ends. Findings are filed as
issues and either fixed before moving on or deliberately deferred.
- **The Quint models move with the loop:** `orchestrator.qnt` while `control.py`
runs, `loop.qnt` for the new loop, whose properties become tests as each piece
lands (Phase 2).
@@ -86,11 +89,11 @@ Only `nisse-dev` has real code; `nisse-core` and `nisse-ops` are placeholders.
**M0.1 Retire the old spec.** **Done.** **M0.2 A bring-up script.** **Done.**
### Phase 1 — Execution over SSH, and the agent in a container
### Phase 1 — Execution over SSH, and an end-to-end test
**M1.1 Work items in the state store.** **Done.**
**M1.2 Transcript views.** **Done.** (#78 closes when a live run confirms it.)
**M1.2 Transcript views.** **Done.** (#78 confirmed live, and closed.)
**M1.3 Execution over SSH.** *Pre-approved.* **Done** (#93).
- `execute(host, command, *, secrets, stdin)` as the only way to run anything; file
@@ -106,26 +109,25 @@ Only `nisse-dev` has real code; `nisse-core` and `nisse-ops` are placeholders.
a branch named after the task; **publishing only the work (#80)**, brought
forward from M2.1; credentials kept out of every repr.
**M1.4 Projects** (D8). *Pre-approved.*
- The project entry in configuration: repository, default branch, build VM, label
defaults, secrets by name with their visibility, egress additions.
- Acceptance: the bring-up configuration is one project entry; a second project
needs only a second entry.
**M1.6 The end-to-end test.** *Pre-approved.*
- Automates bring-up run 3: the assembled agent, real models, the Gitea sandbox and
a real build host, with a scripted operator that answers whatever the agent asks.
- Asserts what was checked by hand: a PR on the sandbox containing only the work,
pushed with the push credential; no credential in the clone; the planner's next
turn citing the facts rather than the executor's turns.
- Runs against the current loop now, and against the new loop from M2.1.
**M1.5 The agent as a container image.** *Pre-approved.*
- A Dockerfile for `nisse-dev`, stateless with a volume for state; a Gitea Actions
workflow that builds it and pushes to Gitea's registry on each release tag (X4).
- `bringup.sh` runs the image instead of a venv.
- Acceptance: a tagged release produces an image; a live run from the image.
**Phase 1 acceptance:** the end-to-end test passes against the current loop.
**Phase 1 acceptance:** a live run, from the image, of a milestone and a review
comment on the build VM.
**Moved after M2.1:** M1.4 (projects) and M1.5 (the container image). Neither is
needed for a minimal loop running live; both are done before the switch-over
(M2.8), when several projects and deployment start to matter.
### Phase 2 — The new loop, as a thin slice first
Built alongside `control.py`, reusing the state store, log, views, publisher,
pollers and recovery. The first milestone is the smallest end-to-end path; each
later one widens it and is followed by a live run.
later one widens it and extends the end-to-end test (M1.6) to cover it.
**M2.1 The slice.** *Needs discussion* (the loop's shape in code).
- An issue assigned to `dev-agent` → a work item (D1); a restatement in the item's
@@ -137,23 +139,24 @@ later one widens it and is followed by a live run.
(#69, #70); the review-fix check after merge. (Publishing only the work, #80,
landed early in M1.3.)
- `loop.qnt`'s properties for these paths become tests.
- Acceptance: a live run of that path, plus a crash mid-publish.
- Acceptance: the end-to-end test runs that path on the new loop, plus a crash
mid-publish; then a first manual live run.
**M2.2 The queue.** *Pre-approved.* Several items: states, park-and-switch with
branches pushed, next-item order, blocked items from Gitea dependencies, a closed
PR handled (L1, D4). Live run with two issues and a dependency.
PR handled (L1, D4). End-to-end: two issues and a dependency.
**M2.3 Threads and labels.** *Pre-approved.* Routing by thread, ambiguous commands
asked about (L5); `bug` grace periods, `discuss`, `design`; questions and
plain-language go-aheads (D1). Live run.
plain-language go-aheads (D1). End-to-end: a bug and a feature, labelled and not.
**M2.4 Multi-milestone work and documents.** *Pre-approved.* Build plans in the
repository, `ARCHITECTURE.md` kept current, waiting for merges between milestones
(D2, D4). Live run of a two-milestone feature.
(D2, D4). End-to-end: a two-milestone feature.
**M2.5 Conversations and new projects.** *Needs discussion.* Work started in
conversation, record issues carrying their item's ID, the new-project flow and its
project entry (D1, D8, #29). Live run of a small new project.
project entry (D1, D8, #29). End-to-end: a small new project.
**M2.6 Roles and capability profiles.** *Pre-approved.* `driver`, `helper`,
`expert`, `classifier` (L9); escalation triggers; delegation and `ask_expert` on the
@@ -162,6 +165,18 @@ new loop.
**M2.7 Conversation.** *Pre-approved.* Explanations, progress in prose, asking
mid-work (L5, #42, #77).
**M1.4 Projects** (D8). *Pre-approved.*
- The project entry in configuration: repository, default branch, build VM, label
defaults, secrets by name with their visibility, egress additions.
- Acceptance: the bring-up configuration is one project entry; a second project
needs only a second entry.
**M1.5 The agent as a container image.** *Pre-approved.*
- A Dockerfile for `nisse-dev`, stateless with a volume for state; a Gitea Actions
workflow that builds it and pushes to Gitea's registry on each release tag (X4).
- `bringup.sh` runs the image instead of a venv.
- Acceptance: a tagged release produces an image; the end-to-end test runs from it.
**M2.8 Switch over.** *Pre-approved, after acceptance.* `nisse-dev` runs the new
loop; `control.py`, its tests and `orchestrator.qnt` are removed.