Data Lifecycle
What Data Exists
| Data | Location | Tracked | Retention |
|---|---|---|---|
| Specs | .chant/specs/*.md | Git | Forever (git history) |
| Prompts | .chant/prompts/*.md | Git | Forever |
| Config | .chant/config.md | Git | Forever |
| Locks | .chant/.locks/*.pid | No | Until released |
| Index | .chant/.store/ | No | Rebuilt on demand |
| Logs | .chant/logs/ | Optional | Configurable |
Spec Lifecycle
┌──────────┐
│ Created │ chant add "Fix bug"
└────┬─────┘
│
▼
┌──────────┐
│ Pending │ Waiting for work or dependencies
└────┬─────────────────────┐
│ │
│ │ has unmet
│ │ dependencies
│ ▼
│ ┌──────────┐
│ │ Blocked │ Waiting for depends_on
│ └────┬─────┘
│ │
│ │ dependencies
│ │ complete
│ ▼
│ ┌──────────┐
│ │ Pending │
│ └──────────┘
│
│ (if --needs-approval)
│
├──────────────────────────────┐
│ │
│ ▼
│ ┌───────────────────┐
│ │ Approval Required │
│ └────┬──────────┬───┘
│ │ │
│ approved │ │ rejected
│ ▼ ▼
│ ┌────────┐ ┌──────────┐
│ │Approved│ │ Rejected │
│ └────┬───┘ └──────────┘
│ │
│◄────────────────────────┘
│
▼
┌──────────┐
│In Progress│ Agent working
└────┬─────┘
│
├──────────────┐
▼ ▼
┌──────────┐ ┌──────────┐
│Completed │ │ Failed │
└────┬─────┘ └────┬─────┘
│ │
│ │ retry
│ ▼
│ ┌──────────┐
│ │ Pending │
│ └──────────┘
│
▼
┌──────────┐
│ Archived │ (optional, after retention period)
└──────────┘
Cancelled (any status) ← chant cancel
│
└─────► Excluded from lists and work
Approval Gate
When a spec is created with --needs-approval, it must be approved before work can begin. See the Approval Workflow Guide for details.
Spec Statuses
Pending
- Spec created and ready for work
- Or failed spec that has been retried
- Can have unmet dependencies
Blocked
- Pending spec with unmet dependencies
- Waiting for one or more specs in
depends_onto complete - Status automatically applied when spec is loaded if dependencies incomplete
- Excluded from
chant workuntil dependencies complete - Use
chant list --summaryto see which specs are blocked
In Progress
- Spec is currently being executed by an agent
- Lock file created in
.chant/.locks/{spec-id}.pid - Agent writes status to
.chant-status.jsonin worktree (parallel mode)
Completed
- Spec execution completed successfully
- All acceptance criteria were checked
- Commit hash, timestamp, and model recorded in frontmatter
- Auto-finalized by
chant workwhen criteria pass
Failed
- Spec execution failed (agent error or acceptance criteria unchecked)
- Can be retried with
chant resume {spec-id} --work - Can be manually finalized with
chant finalize {spec-id}if work was done - Use
chant log {spec-id}to view agent output
Cancelled
- Spec soft-deleted with
chant cancel {spec-id} - Status changed to
Cancelled, file preserved - Excluded from
chant listandchant work - Can still be viewed with
chant showor filtered withchant list --status cancelled - Use
chant cancel {spec-id} --deleteif you want to permanently remove the spec file
Dependency Blocking
Specs can declare dependencies using depends_on:
---
type: code
status: pending
depends_on:
- 2026-01-26-001-auth # This spec depends on 001
---
When a spec has unmet dependencies:
- Status automatically changes to
Blocked - Spec excluded from
chant work(can’t execute) - Spec excluded from
chant list(hidden by default) - When all dependencies complete, status reverts to
Pending - Spec becomes available for work
View blocked specs:
chant list --status blocked # Show all blocked specs
chant list --summary # See overview with block reasons
Retention Policies
Spec Files
Specs stay in .chant/specs/ forever by default. Git history is the archive.
# config.md
lifecycle:
specs:
retention: forever # forever | duration
# retention: 90d # Archive after 90 days
Archival (Optional)
If retention is set, completed specs can be archived:
lifecycle:
specs:
retention: 90d
archive:
enabled: true
location: .chant/archive/
compress: true # Gzip archived specs
.chant/
├── specs/ # Active specs
│ └── 2026-01-22-001-x7m.md
└── archive/ # Archived (gitignored or separate branch)
└── 2025/
└── 12/
└── 2025-12-15-042-abc.md.gz
Note: Archival changes spec IDs (moved file). References break. Use sparingly.
Data Flow Diagram
Human
│
│ chant add
▼
┌─────────────────────────────────────────────────────────────┐
│ Spec File Created │
│ │
│ .chant/specs/2026-01-22-001-x7m.md │
│ status: pending │
└──────────────────────────┬──────────────────────────────────┘
│
│ git add, git commit
▼
┌─────────────────────────────────────────────────────────────┐
│ Git Repository │
│ │
│ Permanent history of all spec changes │
└──────────────────────────┬──────────────────────────────────┘
│
│ chant work
▼
┌─────────────────────────────────────────────────────────────┐
│ Execution │
│ │
│ Worktree created: /tmp/chant-{spec-id}/ (parallel only) │
│ Lock created: .chant/.locks/{spec-id}.pid │
└──────────────────────────┬──────────────────────────────────┘
│
│ completion
▼
┌─────────────────────────────────────────────────────────────┐
│ Cleanup │
│ │
│ Lock released (immediate) │
│ Worktree removed (immediate, after merge) │
│ Spec updated (status: completed) │
│ Branch merged and deleted │
└──────────────────────────┬──────────────────────────────────┘
│
│ long-term
▼
┌─────────────────────────────────────────────────────────────┐
│ Long-term │
│ │
│ Spec: stays in git history forever │
│ Logs: rotated, old logs deleted │
│ Branch: deleted after merge │
└─────────────────────────────────────────────────────────────┘
Watch Coordinator
Watch is the unified lifecycle coordinator for all work execution. It runs as an ephemeral daemon that handles state transitions, merging, and cleanup.
Architecture
Agent (worktree) Watch (main)
──────────────── ────────────
create worktree + branch
write status: "working" → see working → update spec: InProgress
do work, commit to branch
write status: "done" → see done → merge → finalize → cleanup
(or "failed" on error) (or handle failure)
exit
Auto-Start Behavior
chant work commands automatically start watch if not running:
chant workchecks if watch is running via PID file (.chant/watch.pid)- If not running, spawns
chant watchas a detached background process - Watch writes its PID to
.chant/watch.pidon startup - Watch exits gracefully after idle timeout (default: 5 minutes)
Use --no-watch flag to disable auto-start (useful for testing).
PID Management
- Watch writes PID to
.chant/watch.pidon startup - Watch removes PID file on graceful exit (SIGINT, idle timeout,
--once) is_watch_running()checks: PID file exists AND process alive AND is chant- Stale PID file (process dead or wrong process) is automatically cleaned up
Agent Status File
Agents communicate with watch via .chant-status.json in the worktree root:
{
"spec_id": "2026-02-03-02p-ydf",
"status": "working",
"updated_at": "2026-02-03T14:30:00Z",
"error": null,
"commits": ["abc123"]
}
Status values:
working- Agent is actively workingdone- Agent completed successfullyfailed- Agent encountered an error
Startup Recovery
On startup, watch recovers from previous crashes:
- Scans for existing worktrees with
.chant-status.json donestatus but not merged → queued for mergeworkingstatus but stale (>1 hour) → marked failed- Orphaned worktrees (no status file, old) → cleaned up
Idle Timeout
Watch automatically exits when idle (configurable):
# config.md
watch:
idle_timeout_minutes: 5 # Exit after 5 minutes of no activity
Activity is detected when:
- In-progress specs exist
- Active worktrees with agents are found
- Status file changes are observed
Git Branch Lifecycle
lifecycle:
branches:
delete_after_merge: true # Delete chant/* branches after merge
retain_unmerged: 30d # Keep unmerged branches for 30d
Branches are cleaned up automatically when specs are completed.
Export
Export spec data in various formats using chant export. See CLI Reference for full details.
# Export to JSON
chant export --format json > specs.json
# Export to CSV
chant export --format csv > specs.csv
# Export with filters
chant export --status completed --from 2026-01-01
Backup
Git IS the Backup
Spec files are git-tracked. Normal git backup applies:
- Push to remote
- Mirror to backup location
- Standard git disaster recovery
Note: Local state (index, logs, clones) can be rebuilt. Git history is the permanent archive.
Configuration Reference
# config.md
lifecycle:
specs:
retention: forever # forever | 30d | 90d | 1y
archive:
enabled: false
location: .chant/archive/
compress: true
branches:
delete_after_merge: true
retain_unmerged: 30d