Skip to content
Pocketto
Reference

Lifecycle state

The shapes of log.json and lifecycle.json, the task and phase state transitions, and the rule that only the Pocketto CLI writes these files.

Two files carry execution state, with a strict division of labor: log.json is the detailed task-execution projection; lifecycle.json is authoritative for lifecycle state, the event journal, and delivery state.

log.json

{
  "header": {
    "plan_dir": "…",
    "plan_type": "phased",
    "status": "DONE",
    "date_started": "2026-08-15",
    "date_completed": "2026-08-16",
    "baseline_sha": "…",
    "pipeline": 5,
    "phase_branches": { "mode": "stacked" }
  },
  "phases": [
    {
      "order": 1,
      "file": "execution-plan/phase-1.md",
      "status": "REVIEW",
      "tasks": [
        { "id": "T1", "name": "…", "status": "DONE", "depends": "…", "done_sha": "…" }
      ],
      "corrections": [
        { "sha": "…", "files": ["…"], "for_task": "T4" }
      ]
    }
  ]
}

(Illustrative shape, fields abbreviated.)

Transitions

EntityFrom → ToCommand
TaskWAITING → DONElog update <plan_dir> <phase_file> DONE --task T1 --sha <audited_head>
TaskWAITING → BLOCKEDlog update <plan_dir> <phase_file> BLOCKED --task T1
PhaseWAITING → REVIEWlog update <plan_dir> <phase_file> REVIEW (after the phase pass records its result)
PhaseREVIEW → DONElog update <plan_dir> <phase_file> DONE (closing only, never --task)
Plan→ DONElog close <plan_dir> (verifies every phase DONE)
Phase (stacked)handofflog handoff <plan_dir> <phase_file>, after DONE, before log close

The invariants

  • done_sha is set only when a task is marked DONE with --sha after a passing audit, and it never moves afterwards; phase-level fixes are append-only --correction records.
  • DUPLICATE_DONE_SHA hard-errors when two tasks would share a merge commit (a parallel-group footgun; merge and log one task at a time). --allow-duplicate-sha exists only for tasks that legitimately produced no new commit.
  • REVIEW is a phase-only status: a task is never REVIEW.
  • The pipeline marker refuses state-changing commands against plans from an older pipeline generation (PIPELINE_TOO_OLD).
  • The CLI is the only writer. A log.json that exists but fails to parse is refused (LOG_JSON_UNPARSEABLE), not silently treated as absent: --reset is the explicit way to discard it.

lifecycle.json

Managed by the lifecycle CLI (see Lifecycle events):

  • root schema: 2 (Core also reads schema 1; above 2 fails closed)
  • plan state: normalized plan_id, required spec_dir, optional plan_dir, state snapshot, revision
  • the event journal: allowlisted events with deterministic IDs <plan_id>:<type>:r<revision>, artifact refs, payload hashes, opaque proof references, delivery state
  • stacked plans record phase_branches including the root base branch

Commits are atomic: state and its event land together, before the projection update and long before any remote delivery.

On this page