Appearance
Project Lifecycle
Above the milestone lifecycle sits the project lifecycle. /np:new-project creates a nubos-pilot project. It accumulates milestones until the work is done, gets a project-wide aggregate verification via /np:close-project, and is then either retained for future extensions or archived to make room for a successor in the same workspace.
mermaid
stateDiagram-v2
[*] --> idle: empty workspace
idle --> active: /np:new-project<br/>(scaffolds PROJECT.md + M001)
active --> active: /np:new-milestone<br/>/np:execute-phase<br/>/np:verify-work
active --> completed: /np:close-project<br/>(all milestones verified)
active --> archived: /np:new-project Phase -1<br/>(Archive and start fresh)
completed --> archived: /np:new-project Phase -1
archived --> [*]: archive lives under<br/>.nubos-pilot/archive/<slug>-<date>/States
| State | Definition | Detected via |
|---|---|---|
| idle | No .nubos-pilot/PROJECT.md in the workspace. | archive.projectExists(cwd) === false |
| active | PROJECT.md exists; at least one milestone is not yet verified. | roadmap.yaml.project_status is missing or "active"; computeCompletionStatus().complete === false |
| completed | All milestones have M<NNN>-VERIFICATION.md (status verified) and M<NNN>-VALIDATION.md (zero UNCOVERED). roadmap.yaml.project_status = "completed". | computeCompletionStatus().complete === true OR roadmap.yaml.project_status === "completed" |
| archived | Project content has been moved into .nubos-pilot/archive/<slug>-<YYYYMMDD>/. Workspace is idle again. | Entry visible via archive-project list |
Transitions
idle → active
/np:new-project:
- Phase -1:
--detectfinds no PROJECT.md → skip to Phase 0. - Phase 0..3 scaffolds the project (see planning workflows).
active → active
The normal grind. /np:new-milestone, /np:plan-phase <N>, /np:execute-phase <N>, /np:verify-work <N>, /np:validate-phase <N> are all in-state transitions; none of them touch project_status.
active → completed
/np:close-project runs the aggregate report. When no blockers remain (or the user chose "Force complete"), close-project mark-completed writes:
yaml
project_status: completed
completed_at: 2026-05-11T08:42:01.123Zinto roadmap.yaml and persists PROJECT-SUMMARY.md at .nubos-pilot/PROJECT-SUMMARY.md. PROJECT-SUMMARY.md is render-only: every refresh is a full re-write from computeCompletionStatus, so it never drifts from the milestone artefacts.
active|completed → archived
/np:new-project Phase -1 detects an existing PROJECT.md and presents the user with three options:
- Archive and start fresh — calls
archive-project do(with--forceif completion check reports blockers). Default carry-overlearnings,solutionscopies institutional knowledge into the archive AND keeps the originals at top-level so the new project inherits them. - Close project first, then ask — chains into
/np:close-project, then re-runs/np:new-projectfrom the top. - Abort — exits without changes.
archive-project do is also callable directly (e.g. when wrapping a project up without immediately starting a new one).
Archive layout
Every archive lives at .nubos-pilot/archive/<slug>-<YYYYMMDD>[-N]/ where N is 2, 3, … on same-day collisions. Contents:
archive/<slug>-<date>/
ARCHIVE.json # manifest: archived_at, project_name, completion_status, …
PROJECT.md
REQUIREMENTS.md
RULES.md
ROADMAP.md
STATE.md
roadmap.yaml # snapshot at archive time, includes project_status
milestones/ # full M<NNN>/ trees with slices/, tasks/, VERIFICATION.md, …
codebase/ # if a scan ran
messages/ threads/ handoffs/ todos/ reports/ knowledge/ session/
learnings/ # only if carry-over included it
solutions/ # only if carry-over included itWhat never moves into the archive (stays at top-level so the next project keeps using it):
config.json— workspace-level config (response_language,text_mode).archive/itself (recursion is not a state)..tmp/,state/(knowledge index),worktrees/(refused if non-empty without--force).memory/— vector store. Vector records are project-specific; they remain available top-level for the new project, and you can also read them out of an archive by name viaarchive-project read --name <archive> --rel memory/records.jsonl.
Cross-project memory
Default behavior: learnings/ and solutions/ carry over into the new project automatically. The new project's first agents see them as if they had always been there, so the team's accumulated patterns (failure modes, solved bugs, conventions) survive the archive.
For deeper cross-project queries, archive-project read --name <archive> --rel <path> is a path-traversal-safe read into any single archived file. Memory tools (memory-query) can be pointed at archived records via the manifest list returned by archive-project list.
Why this exists
Before this lifecycle, /np:new-project hard-refused when .nubos-pilot/PROJECT.md existed (project-already-initialized), forcing users to either rm -rf the planning state or stay in an active project forever. There was no aggregate "is this whole project done?" check; every milestone was verified in isolation. The closing and archiving lifecycle replaces both problems:
- A single aggregate check (
/np:close-project) replaces N manualverify-workwalks. - A deterministic archive path replaces destructive
rm -rfcleanup, preserving history and carrying over institutional knowledge.
See ADR-0016 for the design rationale.
