Skip to content

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

StateDefinitionDetected via
idleNo .nubos-pilot/PROJECT.md in the workspace.archive.projectExists(cwd) === false
activePROJECT.md exists; at least one milestone is not yet verified.roadmap.yaml.project_status is missing or "active"; computeCompletionStatus().complete === false
completedAll 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"
archivedProject 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:

  1. Phase -1: --detect finds no PROJECT.md → skip to Phase 0.
  2. 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.123Z

into 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 --force if completion check reports blockers). Default carry-over learnings,solutions copies 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-project from 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 it

What 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 via archive-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 manual verify-work walks.
  • A deterministic archive path replaces destructive rm -rf cleanup, preserving history and carrying over institutional knowledge.

See ADR-0016 for the design rationale.