From 7b5f0dfd18d5b0a6e9230add89f9a41faba4880b Mon Sep 17 00:00:00 2001 From: Don Garrett Date: Fri, 2 Oct 2026 19:41:48 +0000 Subject: [PATCH] Rework the Development Plan around live testing and the revised architecture SSH execution and the agent as a container image come first (Phase 1), then the new loop as a thin end-to-end slice, widened milestone by milestone with a live run after each. Outline, Vikunja and per-agent VMs are gone; the vault, the infrastructure repository and the agent host replace them. The survey and issue map are refreshed. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE --- docs/Development-Plan.md | 401 ++++++++++++++++----------------------- 1 file changed, 164 insertions(+), 237 deletions(-) diff --git a/docs/Development-Plan.md b/docs/Development-Plan.md index e104578..6cf84e6 100644 --- a/docs/Development-Plan.md +++ b/docs/Development-Plan.md @@ -1,314 +1,241 @@ # Nisse — Development Plan -**Status: proposed for discussion.** How to get from the code as it is to the full -architecture in `docs/Architecture.md`, in what order, and how each step is -accepted. The architecture says *what and why*; this document says *how and when*, -and is revised as work lands. +**Status: agreed (PR #84); reworked in PR #92 after the architecture revision (PR #90).** How +to get from the code as it is to the architecture in `docs/Architecture.md`, in +what order, and how each step is accepted. The architecture says *what and why*; +this document says *how and when*, and is revised as work lands. -It follows the format the architecture asks agents to use (D2): phases of -milestones, each with a goal, scope and acceptance criteria, and each marked -**pre-approved** or **needs discussion**. +**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. --- ## 1. Where we are -A survey of the code on `main` (2026-09-30) against each architecture section. -**Done** means it exists and matches the architecture; **partial** means something -exists but needs changing; **none** means not started. +A survey of `main` (2026-10-02) against the architecture. **Done** means it exists +and matches; **partial**, something exists but needs changing; **none**, not +started. -Only `nisse-dev` has real code (about 10,000 lines in `nisse-dev/src/nisse_dev/`). -`nisse-core` and `nisse-ops` are placeholder packages. +Only `nisse-dev` has real code; `nisse-core` and `nisse-ops` are placeholders. | Section | Status | Notes | |---|---|---| -| **P** Principles | — | Guidance; each milestone below applies them | -| **L1** Work model | partial | One work item at a time with a minted ID; but the state store is a single row (`agent_state`, `CHECK (id = 1)`), not a work-items table with an active pointer. No duties, parking or switching (only `nisse-ops` needs duties) | -| **L2** Agent loop | partial | `control.py`: a fixed state machine (arch → milestone gates → executing → PR open), with the no-stranding rule, `stop`, `abandon`, restart questions. To be replaced by the conversational loop | -| **L3** Authority | partial | Revision binding and arrival stamping are done (`gates.py`, #74). Approvals are gates, not permissions; no pre-approved milestones, no trust dial | -| **L4** Action classifier | none | | -| **L5** Conversation | partial | Matrix transport, mention handling, case-insensitive commands. Only the planner can ask (`ask_human`); no question handling, no explanations or progress prose, a misleading reply in `IDLE` | -| **L6** Context and memory | partial | Context fitting is done (`context.py`). The transcript isn't scoped per work item and has no attribution or orchestrator facts (#78). No scope or agent memory | -| **L7** Canonical log | partial | `canonical.py`: user, assistant, tool call/result, plan, gate, delegation, compaction events. Missing: work item and actor on every event, `fact`, `classifier_verdict`, `knowledge_retrieved` | -| **L8** Durability and recovery | mostly done | WAL store, intents, boot reconciliation, adopting a published PR (#75), comment cursors and redelivery (#68, #76), Quint model (`specs/`). Needs moving onto the new loop and the work-items schema | -| **L9** Models, roles, helpers | partial | LiteLLM client and catalog, context budgets, delegation with passthrough and caps, `ask_expert`, tool-choice handling, eval capture. Roles are executor/planner/delegate/consultant with a frontier planner; no `driver`, no capability profiles, no driver-chosen escalation | -| **L10** Knowledge store | none | | -| **L11** Prompt injection | partial | Operator allowlists on every channel; no classifier, no structured intake beyond Gitea's JSON | -| **L12** Secrets, identity, logging | partial | Structured state-change log (`oplog.py`); secrets from `.env` files; no Vaultwarden, no LLDAP identity | -| **D2** Documents as workflow | none | Plans are posted to a Gitea issue; no project `ARCHITECTURE.md` or build plans in the repo | -| **D3** Workspace | partial | Cloned once and reused as-is; no fetch, no fresh workspace, no preflight (#62, #27) | -| **D4** Git and PRs | partial | Idempotent publishing (#75), committed work published (#63); `git add -A` sweeps in artifacts (#80); branches cut at publish from whatever `HEAD` is (#62) | -| **D5** Review and merge | partial | Review loop on PR conversation comments; inline comments unseen (#69); watch stall (#70); operator merges; no trust dial (#65) | -| **D7** Deployment | none | Bring-up runs on this box as root; no VM, VLAN or egress policy | -| **O** `nisse-ops` | none | | -| **X** Deployment model | none | | +| **L1** Work model | partial | Work items table with an active pointer (M1.1); no issue intake, queue, parking or blocked items | +| **L2** Agent loop | partial | `control.py`, a fixed state machine with no-stranding, `stop`, `abandon`. Replaced by the new loop (Phase 2) | +| **L3** Authority | partial | Revision binding and arrival stamping (`gates.py`); scope is still plan approval, not the issue and its conversation | +| **L4** Classifier | none | | +| **L5** Conversation | partial | Matrix transport, mentions, lenient commands; no threads, no question handling, little explanation | +| **L6** Context | partial | Context fitting, per-role views and orchestrator facts (M1.2); no scope or agent memory | +| **L7** Canonical log | partial | Work item and actor on every event, `fact` (M1.1, M1.2); no `classifier_verdict`, `knowledge_retrieved` | +| **L8** Durability | mostly done | WAL store, intents, boot reconciliation, PR adoption, comment redelivery; to move onto the new loop | +| **L9** Models and roles | partial | LiteLLM, delegation, `ask_expert`, eval capture; roles are still planner/executor, no capability profiles | +| **L10** Knowledge vault | none | | +| **L11** Injection | partial | Operator allowlists on every channel; no classifier | +| **L12** Secrets, logging | partial | Structured state-change log; secrets in `.env`; no per-operation handout or redaction | +| **L13** Execution | none | Tools run locally in the agent's process. The token leaks into the clone (#89) | +| **D1–D2** Workflow | none | Plans posted to a Gitea issue and gated; no issue intake, labels, or documents in the repo | +| **D3–D4** Workspace, git | partial | Idempotent publishing; no fresh workspace (#62), `git add -A` (#80) | +| **D5** Review | partial | PR conversation comments only (#69), watch stall (#70) | +| **D7–D8** Deployment, projects | none | Runs from a venv as a systemd unit on this box; one project in config | +| **O**, **X** | none | No container image yet | +| `specs/` | done for now | `orchestrator.qnt` (current loop), `loop.qnt` (the architecture, #91) | --- ## 2. The environment today -**Supporting services** (X5) are installed and running: Matrix (Synapse), Gitea, -LiteLLM, Vikunja, Outline, Vaultwarden, LLDAP with Authelia. Per-agent accounts and -tokens are created as each agent needs them. So far `nisse-dev` has a Matrix test -identity and room, a Gitea test account and sandbox repo, and dedicated LiteLLM -keys. - -**Local inference:** an RTX 4090 host, `inference-4090.garrett-hall.com`, running -llama-swap (one model resident at a time), capped at 320 W. The executor benchmark -(PR #55) chose `qwen3.8-27b` for `nisse-dev`'s local work. - -**Models by role today** (`nisse-dev.example.yaml`): executor `qwen3.8-27b`, planner -and delegate `claude-opus-5-5`, consultant `claude-haiku-4-5`. Phase 2 moves to the -architecture's roles (L9): driver local, helpers frontier. - -**Bring-up runs** happen on this box, against test resources: the sandbox repo, the -test Matrix room, a budget-capped LiteLLM key; configuration in `~/nisse-e2e/`. +- **Supporting services** (X5): Matrix, Gitea, LiteLLM, Vaultwarden, LLDAP with + Authelia. The infrastructure repository exists in Gitea. +- **Local inference:** llama-swap on an RTX 4090 host (320 W cap). The benchmark + (PR #55) chose `qwen3.8-27b` for local work. +- **Models by role today:** executor `qwen3.8-27b`, planner and helper + `claude-opus-5-5`, expert `claude-haiku-4-5`. Phase 2 moves to driver and helpers. +- **Bring-up** runs on this development VM (`scripts/bringup.sh`), against test + resources: the sandbox repository, the test Matrix room, a budget-capped LiteLLM + key; configuration in `/root/nisse-e2e/`. +- **A build VM for bring-up** is provided by the operator by hand until Terraform + (Phase 6); the agent reaches it over SSH with a key from `/root/nisse-e2e/ssh/`. --- ## 3. How we work -- **One PR per milestone,** usually. Every PR still starts with a short - implementation plan per `CLAUDE.md`. For a **pre-approved** milestone that plan is - a quick confirmation; a **needs discussion** milestone starts with a design - discussion before any plan. -- **Every change comes with tests,** per `CLAUDE.md`, and runs through - `scripts/check.sh` (lint, format, unit and integration tests). -- **The Quint model moves with the loop.** Any change to how the loop enters or - leaves a waiting point updates `specs/`, and every counterexample is reproduced - against the real code before it is fixed. -- **A bring-up run on this box ends each phase** where it can be run live. What it - finds is filed as issues and fixed before the next phase starts, or explicitly - deferred. -- **Bring-up runs on this development VM,** as root, like production. Guards: it - touches only test resources, and keeps today's structural gates on in its - bring-up configuration until the classifier and trust dial are proven (Phase 3). -- **This plan is revised as we go:** a milestone's scope may move once work shows - its real shape, recorded here in the same PR. +- **One PR per milestone,** each starting with a short implementation plan per + `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 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). +- **`control.py` gets fixes only,** and only for what blocks a live run. New + behaviour goes into the new loop. +- **Bring-up runs on this box as root,** against test resources only, with today's + gates on until the classifier and trust dial are proven (Phase 3). +- **This plan is revised as we go,** in the same PR as the work that changes it. --- ## 4. Phases -### Phase 0 — Housekeeping +### Phase 0 — Housekeeping (done) -**M0.1 Retire the old spec.** *Pre-approved.* **Done.** -- Update every section reference in code, tests, `specs/` and the `CLAUDE.md` and - `README.md` files from the old spec's A–H to the new letters. -- Delete `docs/Architecture-Build-Spec.md` (git keeps it), and the old-to-new - section table this plan carried for the purpose. -- Acceptance: `grep` finds no reference to the old spec or its section numbers. +**M0.1 Retire the old spec.** **Done.** **M0.2 A bring-up script.** **Done.** -**M0.2 A bring-up script.** *Pre-approved.* **Done.** -- `scripts/bringup.sh`: set aside the previous run's state, workspace and log; - export the ref under test; start the agent as a systemd unit, so it outlives the - shell that started it; collect the log and a readable transcript - (`python -m nisse_dev.dump`) afterwards. -- The agent runs as root on this development VM, as it will on its own VM in - production (D7), so installing packages works as it will there. -- Acceptance: a smoke run starts, answers `status`, stops cleanly, and `collect` - produces the log and transcript. +### Phase 1 — Execution over SSH, and the agent in a container -### Phase 1 — Foundations the new loop needs +**M1.1 Work items in the state store.** **Done.** -These fix problems found in the live runs that **survive the loop change.** Issues -that only exist because of `control.py`'s state machine (#61, #79, #81) are folded -into Phase 2's design instead of being fixed twice. +**M1.2 Transcript views.** **Done.** (#78 closes when a live run confirms it.) -**M1.1 Work items in the state store.** *Needs discussion* (schema). **Done.** -- A work-items table with an active pointer (L1); every canonical event carries its - work item and its actor (L7). A migration for existing stores. -- Acceptance: two work items back to back keep separate state and events; a - restart keeps both; migration tests. +**M1.3 Execution over SSH.** *Pre-approved.* +- `execute(host, command, *, secrets, stdin)` as the only way to run anything; file + tools over SSH; the host bound by the harness from the project (L13). +- The workspace lives on the build VM: cloned there, with no token in its + configuration; the push key handed to each push only (D4, #89). +- Every secret handed out is redacted from tool output (L12). +- Tests against a throwaway `sshd` container. +- Acceptance: the existing executor and delegation tests pass over SSH; a live run + of one milestone on the operator's build VM. -**M1.2 Transcript views.** *Needs discussion* (rendering). **Done.** -- Per-role rendering (L6): a role sees only its work item, attributed entries, and - orchestrator `fact` events; never another role's raw turns as its own (#78). -- Acceptance: the second live run's confusion can't happen (a planning call after - a milestone contains the milestone fact and PR, and no executor turns). +**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.3 A fresh workspace at `use`, and harness-owned branches.** *Pre-approved.* -- Fetch; clean checkout of the latest base; set aside anything left over and report - it (D3). Milestone branches cut by the harness from the task's workspace; - "changes to publish" counted from the milestone's start (D4). Covers #62 and the - clone-on-use half of #27. -- Acceptance: a leftover branch, uncommitted change and stale `origin` are each - handled and reported; a second milestone's PR contains only its own commits. +**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. -**M1.4 Publish only the work.** *Pre-approved.* -- Standard excludes in the clone, and commit only what the work changed (D4, #80). -- Acceptance: a milestone that ran pytest publishes no `.pyc`; excluded files are - reported. +**Phase 1 acceptance:** a live run, from the image, of a milestone and a review +comment on the build VM. -**M1.5 Review intake.** *Pre-approved.* -- Inline review comments and review bodies (#69); no stall when a watch is - replaced from its own callback (#70); replies in the thread where the comment was - made (D5). -- Acceptance: tests for each; inline comments work in the phase's bring-up run. +### Phase 2 — The new loop, as a thin slice first -**Phase 1 acceptance:** a bring-up run on the current loop with two milestones and -a review comment, including inline ones. +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. -### Phase 2 — The conversational loop +**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 + thread; a go-ahead bound to its revision (L3, L5); one milestone through + `start_milestone` / `finish_milestone` on a harness branch (D4); the PR; a review + comment answered (D5); the merge; the item closed. +- Includes what carries over: a fresh workspace at item start and harness-owned + branches (D3, D4, #62); publishing only the work (#80); review intake, inline + comments and the watch stall (#69, #70); the review-fix check after merge. +- `loop.qnt`'s properties for these paths become tests. +- Acceptance: a live run of that path, plus a crash mid-publish. -Built **alongside** `control.py`, reusing the state store, canonical log, context -fitting, publisher, pollers and recovery; `nisse-dev` switches over when the new -loop passes its tests and a bring-up run, and `control.py` is retired. +**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. -**M2.1 Loop design and its model.** *Needs discussion.* -- A short design note (in the PR, then folded into the architecture where it - settles something): the loop's turns, waiting points, pending questions, - permissions it checks, and recovery. A new Quint model for it before code, with - the no-stranding, approval-binding and at-least-once properties carried over. +**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. -**M2.2 The loop core.** *Needs discussion.* -- The driver-driven turn loop (L2): conversation, tool calls, pending questions, - `stop`, `abandon`, intents and boot recovery on the work-items schema. -- **Questions never change state** (L5): the recognition rule is decided here (Q). -- Acceptance: the new Quint model's scenarios reproduced as tests; no-stranding - under injected faults, as `test_no_stranding.py` does today. +**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. -**M2.3 Roles and capability profiles.** *Pre-approved.* -- Roles become `driver`, `helper`, `expert`, `classifier` (L9); capability profiles - in configuration, filled from the benchmark; the driver's prompt encourages asking - for help; observable escalation triggers; delegation and `ask_expert` wired to the - new loop. Supersedes #46 (separate architect and planner roles). +**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. -**M2.4 Conversation.** *Pre-approved* (the behaviour is set by L5). -- Explanations with plans and revisions, finished-work summaries, progress in prose - (#42), handling messages that can't be acted on yet, asking mid-work (#77). +**M2.6 Roles and capability profiles.** *Pre-approved.* `driver`, `helper`, +`expert`, `classifier` (L9); escalation triggers; delegation and `ask_expert` on the +new loop. -**M2.5 Documents as the workflow.** *Needs discussion.* -- Project `ARCHITECTURE.md` and build plans in the repo, discussed and landed by PR; - milestones marked pre-approved or needs discussion and whether they change code; - permissions derived from them (L3, D2). -- Milestones and projects end properly: the plan declares its milestones; a - no-change milestone that wasn't meant to change code is done; moving on checks the - PR's state; finishing closes the issue (D4, D5). Supersedes #61, #79, #81. +**M2.7 Conversation.** *Pre-approved.* Explanations, progress in prose, asking +mid-work (L5, #42, #77). -**M2.6 Switch over and retire `control.py`.** *Pre-approved, after acceptance.* -- `nisse-dev` runs the new loop; `control.py`, its tests and the old Quint model are - removed. - -**Phase 2 acceptance:** a bring-up run: a new small project from conversation to an -agreed `ARCHITECTURE.md` and build plan, two milestones (one pre-approved), a review -comment answered, a question asked by the agent mid-milestone, and a crash -mid-review. +**M2.8 Switch over.** *Pre-approved, after acceptance.* `nisse-dev` runs the new +loop; `control.py`, its tests and `orchestrator.qnt` are removed. ### Phase 3 — Authority -**M3.1 Action classes and the fast path.** *Needs discussion.* -- Every tool action classified by effect (P3); static fast-path rules per agent - (D6); the scope each class-2 action is checked against. +**M3.1 Action classes and the fast path.** *Needs discussion.* Harmless, contained +and dangerous actions per agent (P3, D6), static fast-path rules. -**M3.2 The action classifier.** *Needs discussion.* -- L4, including the model choice (Q), fail-closed behaviour, logged verdicts, and - operator overrides as an evaluation set. +**M3.2 The classifier.** *Needs discussion.* L4, its model, fail-closed verdicts, +overrides as an evaluation set. -**M3.3 Permissions and the trust dial.** *Needs discussion.* -- Approvals as scoped permissions, the operator-set trust dial, and agent merging - behind branch protection the agent can't satisfy, verified by a test (L3, D4, D5, - #65). - -**Phase 3 acceptance:** a bring-up run with the classifier active and gates first -on, then deliberately loosened in the bring-up configuration. +**M3.3 The trust dial.** *Needs discussion.* Per project (D8); agent merging behind +protection it can't satisfy, verified by a test (D4, D5, #65). ### Phase 4 — The environment -**M4.1 Toolchain preflight.** *Pre-approved.* Detect what the project needs, check -it, and install what's missing before planning; toolchain facts in the transcript -(D3). +**M4.1 Toolchain preflight, M4.2 recording installs, M4.3 environment repair.** +*Pre-approved.* All on the build VM (D3). -**M4.2 Recording installs.** *Pre-approved.* Every package or toolchain the agent -installs is recorded as a fact and in the project's scope memory, so the -environment can be rebuilt; recurring ones are noted for the VM image (D3, X4). +### Phase 5 — Memory -**M4.3 Environment repair.** *Pre-approved.* The driver may clean caches and -reinstall project dependencies within a task, and reports it (D3). +**M5.1 The vault.** *Pre-approved.* The folder, per-agent mounts, control tools, +atomic writes and provenance (L10). -### Phase 5 — Memory and knowledge +**M5.2 Agent memory** (*needs discussion*) and **M5.3 scope memory** +(*pre-approved*): when notes are written and read, verbatim corrections (L6). -**M5.1 The Outline client.** *Pre-approved.* Per-agent Outline user and token, -collections and documents by ID, revision reads, one writer per document (L10). +**M5.4 The operator's copy.** *Pre-approved.* Syncthing, directions per folder. -**M5.2 Agent memory.** *Needs discussion.* When notes are written and read, the -index, verbatim corrections (L6). +### Phase 6 — Production -**M5.3 Scope memory for repositories.** *Pre-approved.* Project documents read at -work-item start and snapshotted; summaries at close (L6). +**M6.1 The agent host.** *Needs discussion.* Containers, volumes, snapshots, +per-agent networks (X1, X2, X4). -### Phase 6 — `nisse-dev` in production +**M6.2 Build VMs by Terraform.** *Needs discussion.* The template, VLAN and egress +(D7, X2), collection when idle. -**M6.1 The VM, VLAN and egress policy.** *Needs discussion.* D7, X1, X2. +**M6.3 Secrets and identity.** *Pre-approved.* Per-agent secret sets on the host, +LLDAP principal (L12). -**M6.2 Secrets and identity.** *Pre-approved.* Vaultwarden machine accounts, LLDAP -principal, secrets out of `.env` files (L12). +**M6.4 Delivery.** *Pre-approved.* Watchtower, restarts gated on an idle flag (X4). -**M6.3 Images and delivery.** *Pre-approved.* Gitea Actions → OCI registry → -Watchtower, restarts gated on an idle flag (X4). - -**M6.4 The browser tool.** *Pre-approved.* Playwright on the internal test network -only (D7). +**M6.5 The browser tool.** *Pre-approved.* On the internal test network (D7). ### Phase 7 — `nisse-core` and `nisse-ops` -**M7.1 Extract `nisse-core`.** *Pre-approved.* A package split within the monorepo: -what both agents use moves into `nisse-core`. - -**M7.2 MCP servers.** *Needs discussion.* Per (service, site, privilege) instances, -tool profiles, configuration (X3, #37). - -**M7.3 Approved step sequences.** *Needs discussion.* The ops plan format, matcher, -policy file, expiry (O2). - -**M7.4 Tickets and duties.** *Needs discussion.* Vikunja intake and approvals, -scheduled checks and alert intake as duties (O5, #33). - -**M7.5 `nisse-ops` deployment.** *Needs discussion.* O6. +**M7.1 Extract `nisse-core`.** **M7.2 MCP servers** (#37). **M7.3 Approved step +sequences** (O2). **M7.4 Ops intake and duties** from the infrastructure +repository (O5). **M7.5 The ops tool VM and deployment** (O6). **M7.6 Requests +between agents:** `nisse-dev` asking for build VMs (L1, O5). All *needs discussion* +except M7.1. ### Not yet scheduled -From the architecture's open questions (Q) and older issues, to be placed when -their trigger arrives: -- more than one active work item per agent; -- vision for 3D design and video work; -- one local model for every agent, or agents taking turns on the inference host; -- several forges and projects (#26); a Matrix room per project (#28); creating a - project from scratch and who owns it (#29); one agent instance per project (#30); -- infrastructure as code for agent VMs. +From the architecture's open questions and older issues: filing issues from +conversation; stacked PRs; releases; `nisse-ops` issuing credentials; a server +database; recovering the agent host (an ops issue); more than one active work item; +vision; one local model for every agent; several forges (#26); a room per project +(#28). --- ## 5. Open issues and where they land -All 19 open issues, as of 2026-09-30: -- **11 land in a milestone** and stay open until it is done. -- **4 are superseded** by the new loop's design. They only exist because of - `control.py`'s state machine, so fixing them there would be thrown away. They are - closed, with a pointer to their milestone, when this plan is agreed. -- **4 are not yet scheduled** and stay open until their trigger arrives. - -| Issue | Status | Lands in | -|---|---|---| -| #26 multiple forges | Not yet scheduled | | -| #27 per-project state, clone on use | Milestone | M1.1 (state), M1.3 (clone) | -| #28 room per project | Not yet scheduled | | -| #29 create a project from scratch | Not yet scheduled | Ownership decision first | -| #30 agent instance per project | Not yet scheduled | | -| #33 Vikunja tickets | Milestone | M7.4 | -| #37 MCP servers | Milestone | M7.2 | -| #42 per-turn commentary | Milestone | M2.4 | -| #46 architect and planner roles | **Superseded** | M2.3 (one driver, helpers) | -| #61 simpler milestone gating | **Superseded** | M2.5 | -| #62 branch at execution start | Milestone | M1.3 | -| #65 agent merges approved PRs | Milestone | M3.3 | -| #69 inline review comments | Milestone | M1.5 | -| #70 watch stall | Milestone | M1.5 | -| #77 conversational agent | Milestone | M2.2 (questions), M2.4 | -| #78 transcript scoping and attribution | Milestone | M1.1, M1.2 | -| #79 ending projects and milestones | **Superseded** | M2.5 | -| #80 build artifacts in PRs | Milestone | M1.4 | -| #81 no-change milestones | **Superseded** | M2.5 | +| Issue | Lands in | +|---|---| +| #26 multiple forges | Not yet scheduled | +| #27 per-project state, clone on use | M1.3 (clone on the build VM), M1.4 (projects) | +| #28 room per project | Not yet scheduled (threads, M2.3, may make it unnecessary) | +| #29 create a project from scratch | M2.5 (ownership settled by D4, D8) | +| #37 MCP servers | M7.2 | +| #42 per-turn commentary | M2.7 | +| #62 branch at execution start | M2.1 | +| #65 agent merges approved PRs | M3.3 | +| #69 inline review comments | M2.1 | +| #70 watch stall | M2.1 | +| #77 conversational agent | M2.3 (questions), M2.7 | +| #78 transcript scoping and attribution | Done in M1.1, M1.2; closes after a live run | +| #80 build artifacts in PRs | M2.1 | +| #89 token in the clone's `.git/config` | M1.3 | ## 6. Implementation notes