@theglitchking/persistent-planning 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,13 +6,13 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Official marketplace for persistent-planning - Persistent markdown-based planning for Claude Code. Context engineering pattern with task directories, progress tracking, and working memory that persists across sessions.",
9
- "version": "3.0.0"
9
+ "version": "3.0.1"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "persistent-planning",
14
14
  "description": "Persistent markdown-based planning for Claude Code. Uses on-disk markdown files as working memory for planning, progress tracking, and knowledge storage. Plans persist across sessions and support multiple concurrent tasks.",
15
- "version": "3.0.0",
15
+ "version": "3.0.1",
16
16
  "author": {
17
17
  "name": "TheGlitchKing"
18
18
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "persistent-planning",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Persistent markdown-based planning with task directories, progress tracking, and context engineering for multi-step Claude Code workflows",
5
5
  "author": {
6
6
  "name": "TheGlitchKing"
package/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [3.0.1] - 2026-05-08
6
+
7
+ ### Fixed
8
+ - **Critical: lg-mode init scripts and templates were excluded from the npm package.** The 3.0.0 release had `scripts/link-skills.js` (singular file) in the package.json `files` array instead of `scripts/` (whole dir), and `templates/` was missing entirely. As a result, users installing v3.0.0 got the slash command markdown but the underlying `init-phase.sh`, `init-task.sh`, `init-atom.sh`, `detect-mode.sh`, `lib/planning.sh`, and the four lg-mode templates (`phase.md`, `task.md`, `atom.md`, `notes.md`) were all missing — meaning lg mode silently broke on first invocation.
9
+
10
+ This patch updates the `files` array to include `scripts/` and `templates/` directories, and bumps to 3.0.1. v3.0.0 should be considered broken; consumers should upgrade to 3.0.1 immediately.
11
+
12
+ ### How this happened
13
+ The `files` array was the legacy v2 contents (which only needed `scripts/link-skills.js`). When v3.0 added new scripts and templates I missed updating the array. Caught when verifying the published 3.0.0 tarball contents.
14
+
5
15
  ## [3.0.0] - 2026-05-07
6
16
 
7
17
  ### Added — Lg-mode (large/team) layered planning
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theglitchking/persistent-planning",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Persistent markdown-based planning with task directories, progress tracking, and context engineering for multi-step Claude Code workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,8 @@
13
13
  "bin/",
14
14
  "commands/",
15
15
  "hooks/",
16
- "scripts/link-skills.js",
16
+ "scripts/",
17
+ "templates/",
17
18
  "skills/",
18
19
  "docs/",
19
20
  ".claude-plugin/",
@@ -0,0 +1,67 @@
1
+ #!/bin/bash
2
+ ###############################################################################
3
+ # detect-mode.sh - Sm/lg mode detection for persistent-planning v3.0
4
+ #
5
+ # Usage:
6
+ # bash scripts/detect-mode.sh [--explain]
7
+ #
8
+ # Output:
9
+ # "sm" or "lg" on stdout. With --explain, also prints a one-line decision
10
+ # banner to stderr explaining which signals fired.
11
+ #
12
+ # Heuristic:
13
+ # - If $CLAUDE_PROJECT_DIR/.planning/.meta/workspace.json exists with a
14
+ # "mode" field, that wins (override is sticky).
15
+ # - Otherwise count distinct git authors over the last 90 days. Two or
16
+ # more distinct emails → "lg". Otherwise "sm".
17
+ # - If the repo isn't a git repo or git fails for any reason, default
18
+ # to "sm" (the safer/less-surprising option for solo flows).
19
+ #
20
+ # Why this design:
21
+ # - Solo devs get the historical sm experience with zero ceremony.
22
+ # - Multi-contributor projects get the layered model surface immediately.
23
+ # - The decision banner avoids "magic" — the user sees what fired.
24
+ # - The workspace.json override means a single --mode flag sticks for
25
+ # all subsequent runs (no flag needed every time).
26
+ ###############################################################################
27
+ set -e
28
+
29
+ EXPLAIN=0
30
+ if [[ "${1:-}" == "--explain" ]]; then
31
+ EXPLAIN=1
32
+ fi
33
+
34
+ PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
35
+ WORKSPACE_JSON="${PROJECT_ROOT}/.planning/.meta/workspace.json"
36
+
37
+ # 1. Override wins if workspace.json exists
38
+ if [[ -f "$WORKSPACE_JSON" ]]; then
39
+ # Naive jq-free read: grep the mode line. workspace.json is small/structured.
40
+ MODE_FROM_JSON=$(grep -oE '"mode"[[:space:]]*:[[:space:]]*"(sm|lg)"' "$WORKSPACE_JSON" | sed -E 's/.*"(sm|lg)".*/\1/')
41
+ if [[ "$MODE_FROM_JSON" == "sm" || "$MODE_FROM_JSON" == "lg" ]]; then
42
+ echo "$MODE_FROM_JSON"
43
+ if [[ $EXPLAIN -eq 1 ]]; then
44
+ echo "[mode] $MODE_FROM_JSON (from .planning/.meta/workspace.json)" >&2
45
+ fi
46
+ exit 0
47
+ fi
48
+ fi
49
+
50
+ # 2. Auto-detect via git author count over 90 days
51
+ DETECTED="sm"
52
+ CONTRIB=0
53
+ if command -v git >/dev/null 2>&1 && git -C "$PROJECT_ROOT" rev-parse --git-dir >/dev/null 2>&1; then
54
+ CONTRIB=$(git -C "$PROJECT_ROOT" log --since="90 days ago" --format='%ae' 2>/dev/null | sort -u | wc -l | tr -d ' ')
55
+ if [[ "$CONTRIB" -ge 2 ]]; then
56
+ DETECTED="lg"
57
+ fi
58
+ fi
59
+
60
+ echo "$DETECTED"
61
+ if [[ $EXPLAIN -eq 1 ]]; then
62
+ if [[ "$DETECTED" == "lg" ]]; then
63
+ echo "[mode] lg (auto-detected: $CONTRIB distinct git authors over the last 90 days; threshold ≥ 2)" >&2
64
+ else
65
+ echo "[mode] sm (auto-detected: $CONTRIB distinct git authors over the last 90 days; threshold for lg is ≥ 2)" >&2
66
+ fi
67
+ fi
@@ -0,0 +1,139 @@
1
+ #!/bin/bash
2
+ ###############################################################################
3
+ # init-atom.sh - Create a new atom (subagent hand-off unit) under a task in lg mode
4
+ #
5
+ # Usage:
6
+ # bash scripts/init-atom.sh "Atom Name" --parent <task-slug>
7
+ #
8
+ # Creates:
9
+ # .planning/<phase-slug>/<task-slug>/atoms/<atom-slug>.md
10
+ #
11
+ # The atom's sequence number is auto-assigned: 1 + (max existing sequence in
12
+ # the same task's atoms/ directory). Atoms within a task default to sequential
13
+ # processing.
14
+ #
15
+ # --parent must be a task-slug. The phase is auto-resolved by walking the
16
+ # .planning/ tree to find the task.
17
+ ###############################################################################
18
+ set -e
19
+
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ source "${SCRIPT_DIR}/lib/planning.sh"
22
+
23
+ # Parse arguments
24
+ ATOM_NAME=""
25
+ PARENT_TASK=""
26
+ while [[ $# -gt 0 ]]; do
27
+ case "$1" in
28
+ --parent)
29
+ PARENT_TASK="$2"
30
+ shift 2
31
+ ;;
32
+ -h|--help)
33
+ cat <<EOF
34
+ Usage: bash scripts/init-atom.sh "Atom Name" --parent <task-slug>
35
+
36
+ Examples:
37
+ bash scripts/init-atom.sh "Update zod schema" --parent hewtd-schema-extension
38
+ bash scripts/init-atom.sh "Add plan-tier tests" --parent hewtd-schema-extension
39
+ EOF
40
+ exit 0
41
+ ;;
42
+ *)
43
+ if [[ -z "$ATOM_NAME" ]]; then
44
+ ATOM_NAME="$1"
45
+ fi
46
+ shift
47
+ ;;
48
+ esac
49
+ done
50
+
51
+ if [[ -z "$ATOM_NAME" || -z "$PARENT_TASK" ]]; then
52
+ planning_err "Both atom name and --parent <task-slug> are required."
53
+ echo "Usage: bash scripts/init-atom.sh \"Atom Name\" --parent <task-slug>"
54
+ exit 1
55
+ fi
56
+
57
+ ATOM_SLUG=$(planning_slugify "$ATOM_NAME")
58
+
59
+ if [[ -z "$ATOM_SLUG" ]]; then
60
+ planning_err "Atom name must contain at least one alphanumeric character."
61
+ exit 1
62
+ fi
63
+
64
+ MODE=$(planning_mode)
65
+ if [[ "$MODE" != "lg" ]]; then
66
+ planning_err "Current mode is '$MODE' but init-atom.sh requires lg mode."
67
+ exit 1
68
+ fi
69
+
70
+ ROOT=$(planning_root)
71
+ PLANNING="$(planning_dir)"
72
+ TODAY=$(planning_today)
73
+ TEMPLATE_DIR="${ROOT}/templates/lg"
74
+
75
+ if [[ ! -d "$TEMPLATE_DIR" ]]; then
76
+ TEMPLATE_DIR="${SCRIPT_DIR}/../templates/lg"
77
+ fi
78
+ if [[ ! -d "$TEMPLATE_DIR" ]]; then
79
+ planning_err "Cannot locate templates/lg directory."
80
+ exit 1
81
+ fi
82
+
83
+ # Find the parent task — walk .planning/<phase>/<task>/task.md
84
+ TASK_DIR=""
85
+ for phase_path in "${PLANNING}"/*/; do
86
+ candidate="${phase_path%/}/${PARENT_TASK}"
87
+ if [[ -f "${candidate}/task.md" ]]; then
88
+ TASK_DIR="$candidate"
89
+ break
90
+ fi
91
+ done
92
+
93
+ if [[ -z "$TASK_DIR" ]]; then
94
+ planning_err "Parent task '${PARENT_TASK}' not found under .planning/<phase>/."
95
+ echo ""
96
+ echo "Available tasks:"
97
+ for phase_path in "${PLANNING}"/*/; do
98
+ phase_slug=$(basename "$phase_path")
99
+ [[ "$phase_slug" == ".meta" || "$phase_slug" == "archive" ]] && continue
100
+ for task_path in "${phase_path%/}"/*/; do
101
+ task_slug=$(basename "$task_path")
102
+ if [[ -f "${task_path}task.md" ]]; then
103
+ echo " --parent ${task_slug} (in phase: ${phase_slug})"
104
+ fi
105
+ done
106
+ done
107
+ exit 1
108
+ fi
109
+
110
+ ATOMS_DIR="${TASK_DIR}/atoms"
111
+ mkdir -p "$ATOMS_DIR"
112
+
113
+ # Auto-assign sequence: 1 + max existing sequence in the atoms/ dir
114
+ NEXT_SEQUENCE=1
115
+ if compgen -G "${ATOMS_DIR}/*.md" >/dev/null 2>&1; then
116
+ MAX_SEQ=$(grep -h '^sequence:' "${ATOMS_DIR}"/*.md 2>/dev/null | grep -oE '[0-9]+' | sort -n | tail -1)
117
+ if [[ -n "$MAX_SEQ" ]]; then
118
+ NEXT_SEQUENCE=$((MAX_SEQ + 1))
119
+ fi
120
+ fi
121
+
122
+ planning_log "Initializing atom: ${ATOM_NAME} (parent: ${PARENT_TASK}, sequence: ${NEXT_SEQUENCE})"
123
+
124
+ planning_render_and_log \
125
+ "${TEMPLATE_DIR}/atom.md" \
126
+ "${ATOMS_DIR}/${ATOM_SLUG}.md" \
127
+ "atom at ${ATOMS_DIR}/${ATOM_SLUG}.md (sequence: ${NEXT_SEQUENCE})" \
128
+ "ATOM_TITLE_PLACEHOLDER=${ATOM_NAME}" \
129
+ "TASK_SLUG_PLACEHOLDER=${PARENT_TASK}" \
130
+ "ATOM_DATE_PLACEHOLDER=${TODAY}" \
131
+ "ATOM_SEQUENCE_PLACEHOLDER=${NEXT_SEQUENCE}"
132
+
133
+ echo ""
134
+ planning_ok "Atom '${ATOM_NAME}' ready"
135
+ echo ""
136
+ echo "Next steps:"
137
+ echo " 1. Edit ${ATOMS_DIR}/${ATOM_SLUG}.md to define what to do, inputs, outputs, and acceptance criteria"
138
+ echo " 2. A subagent will pick up this atom when status: ready"
139
+ echo " 3. Status transitions: ready → in_progress → done (or → blocked)"
@@ -0,0 +1,141 @@
1
+ #!/bin/bash
2
+ ###############################################################################
3
+ # init-phase.sh - Create a new phase in lg-mode persistent-planning
4
+ #
5
+ # Usage:
6
+ # bash scripts/init-phase.sh "Phase Name"
7
+ #
8
+ # Creates:
9
+ # .planning/<phase-slug>/phase.md (HEWTD-frontmattered phase template)
10
+ # .planning/<phase-slug>/notes.md (cross-cutting notes for the phase)
11
+ # .planning/.meta/workspace.json (mode = lg, on first phase init)
12
+ #
13
+ # Refuses to run unless mode is lg. Run init-planning.sh for sm-mode tasks.
14
+ ###############################################################################
15
+ set -e
16
+
17
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
18
+ source "${SCRIPT_DIR}/lib/planning.sh"
19
+
20
+ case "${1:-}" in
21
+ -h|--help)
22
+ cat <<EOF
23
+ Usage: bash scripts/init-phase.sh "Phase Name"
24
+
25
+ Creates:
26
+ .planning/<phase-slug>/phase.md
27
+ .planning/<phase-slug>/notes.md
28
+ .planning/.meta/workspace.json (on first phase init, with mode=lg)
29
+
30
+ Refuses to run unless mode is lg. Run init-planning.sh for sm-mode tasks.
31
+
32
+ Examples:
33
+ bash scripts/init-phase.sh "Foundation"
34
+ bash scripts/init-phase.sh "Multi-corpus refactor"
35
+ EOF
36
+ exit 0
37
+ ;;
38
+ "")
39
+ planning_err "Phase name required."
40
+ echo ""
41
+ echo "Usage: bash scripts/init-phase.sh \"Phase Name\""
42
+ echo " bash scripts/init-phase.sh --help"
43
+ exit 1
44
+ ;;
45
+ esac
46
+
47
+ PHASE_NAME="$1"
48
+ PHASE_SLUG=$(planning_slugify "$PHASE_NAME")
49
+
50
+ if [[ -z "$PHASE_SLUG" ]]; then
51
+ planning_err "Phase name must contain at least one alphanumeric character."
52
+ exit 1
53
+ fi
54
+
55
+ # Refuse to run in sm mode
56
+ MODE=$(planning_mode)
57
+ if [[ "$MODE" != "lg" ]]; then
58
+ planning_err "Current mode is '$MODE' but init-phase.sh requires lg mode."
59
+ echo ""
60
+ echo "Switch to lg mode by running:"
61
+ echo " /start-planning --mode lg \"<phase name>\""
62
+ echo "or by editing .planning/.meta/workspace.json directly."
63
+ exit 1
64
+ fi
65
+
66
+ ROOT=$(planning_root)
67
+ PLANNING="$(planning_dir)"
68
+ META="$(planning_meta_dir)"
69
+ WORKSPACE_JSON="$(planning_workspace_json)"
70
+ TODAY=$(planning_today)
71
+ PHASE_DIR="${PLANNING}/${PHASE_SLUG}"
72
+ TEMPLATE_DIR="${ROOT}/templates/lg"
73
+
74
+ # Fallback: when run from the installed plugin location, templates live in the
75
+ # plugin's own directory, not the project root.
76
+ if [[ ! -d "$TEMPLATE_DIR" ]]; then
77
+ TEMPLATE_DIR="${SCRIPT_DIR}/../templates/lg"
78
+ fi
79
+ if [[ ! -d "$TEMPLATE_DIR" ]]; then
80
+ planning_err "Cannot locate templates/lg directory. Tried:"
81
+ echo " ${ROOT}/templates/lg"
82
+ echo " ${SCRIPT_DIR}/../templates/lg"
83
+ exit 1
84
+ fi
85
+
86
+ planning_log "Initializing phase: ${PHASE_NAME}"
87
+
88
+ # Bootstrap .planning/.meta/workspace.json if missing
89
+ mkdir -p "$META"
90
+ if [[ ! -f "$WORKSPACE_JSON" ]]; then
91
+ CONTRIB=0
92
+ if command -v git >/dev/null 2>&1 && git -C "$ROOT" rev-parse --git-dir >/dev/null 2>&1; then
93
+ CONTRIB=$(git -C "$ROOT" log --since="90 days ago" --format='%ae' 2>/dev/null | sort -u | wc -l | tr -d ' ')
94
+ fi
95
+ cat > "$WORKSPACE_JSON" <<EOF
96
+ {
97
+ "schema_version": "1.0",
98
+ "mode": "lg",
99
+ "auto_detected": true,
100
+ "detected_contributors": ${CONTRIB},
101
+ "created_at": "$(date -Iseconds)"
102
+ }
103
+ EOF
104
+ planning_ok "Created .planning/.meta/workspace.json (mode=lg, contributors=${CONTRIB})"
105
+ fi
106
+
107
+ # Create phase directory
108
+ mkdir -p "$PHASE_DIR"
109
+
110
+ # Render phase.md
111
+ planning_render_and_log \
112
+ "${TEMPLATE_DIR}/phase.md" \
113
+ "${PHASE_DIR}/phase.md" \
114
+ "phase.md at ${PHASE_DIR}/phase.md" \
115
+ "PHASE_TITLE_PLACEHOLDER=${PHASE_NAME}" \
116
+ "PHASE_SLUG_PLACEHOLDER=${PHASE_SLUG}" \
117
+ "PHASE_DATE_PLACEHOLDER=${TODAY}"
118
+
119
+ # Render notes.md (scoped to the phase)
120
+ planning_render_and_log \
121
+ "${TEMPLATE_DIR}/notes.md" \
122
+ "${PHASE_DIR}/notes.md" \
123
+ "notes.md at ${PHASE_DIR}/notes.md" \
124
+ "NOTES_TITLE_PLACEHOLDER=${PHASE_NAME} — Notes" \
125
+ "NOTES_SCOPE_PLACEHOLDER=${PHASE_SLUG}" \
126
+ "NOTES_DATE_PLACEHOLDER=${TODAY}"
127
+
128
+ # Add .planning/ to .gitignore if missing (preserve existing behavior)
129
+ GITIGNORE="${ROOT}/.gitignore"
130
+ if [[ -f "$GITIGNORE" ]] && ! grep -q "^\.planning/" "$GITIGNORE"; then
131
+ echo ".planning/" >> "$GITIGNORE"
132
+ planning_ok "Added .planning/ to .gitignore"
133
+ fi
134
+
135
+ echo ""
136
+ planning_ok "Phase '${PHASE_NAME}' ready at .planning/${PHASE_SLUG}/"
137
+ echo ""
138
+ echo "Next steps:"
139
+ echo " 1. Edit .planning/${PHASE_SLUG}/phase.md to describe the phase goal"
140
+ echo " 2. Add tasks with: /start-task \"<task name>\" --parent ${PHASE_SLUG}"
141
+ echo " 3. Add cross-cutting context to .planning/${PHASE_SLUG}/notes.md"
@@ -0,0 +1,233 @@
1
+ #!/bin/bash
2
+
3
+ ###############################################################################
4
+ # init-planning.sh - Persistent Planning Directory Setup
5
+ #
6
+ # Part of the persistent-planning plugin by TheGlitchKing
7
+ # https://github.com/TheGlitchKing/persistent-planning
8
+ #
9
+ # Usage:
10
+ # bash scripts/init-planning.sh [task-name]
11
+ # bash scripts/init-planning.sh "Refactor database layer"
12
+ #
13
+ # What it does:
14
+ # 1. Creates .planning/[task-slug]/ directory (separate per task)
15
+ # 2. Creates task_plan.md with templates
16
+ # 3. Creates notes.md with templates
17
+ # 4. Adds .planning/ to .gitignore (optional)
18
+ # 5. Confirms creation and provides next steps
19
+ #
20
+ # Multiple tasks example:
21
+ # /start-planning "Refactor auth" -> .planning/refactor-auth/
22
+ # /start-planning "Debug memory leak" -> .planning/debug-memory-leak/
23
+ # Both plans coexist without conflicts!
24
+ ###############################################################################
25
+
26
+ set -e
27
+
28
+ # Validate that task name was provided
29
+ if [ -z "$1" ]; then
30
+ echo "Error: Task name required"
31
+ echo ""
32
+ echo "Usage: bash scripts/init-planning.sh \"Your Task Name\""
33
+ echo ""
34
+ echo "Examples:"
35
+ echo " bash scripts/init-planning.sh \"Refactor authentication\""
36
+ echo " bash scripts/init-planning.sh \"Debug API performance\""
37
+ exit 1
38
+ fi
39
+
40
+ TASK_NAME="$1"
41
+
42
+ # Convert task name to slug
43
+ # "Refactor Authentication" -> "refactor-authentication"
44
+ task_name_to_slug() {
45
+ local name="$1"
46
+ name=$(echo "$name" | tr '[:upper:]' '[:lower:]')
47
+ name=$(echo "$name" | sed 's/[[:space:]_]\+/-/g')
48
+ name=$(echo "$name" | sed 's/[^a-z0-9-]//g')
49
+ name=$(echo "$name" | sed 's/^-\+\|-\+$//g')
50
+ name=$(echo "$name" | sed 's/-\+/-/g')
51
+ echo "$name"
52
+ }
53
+
54
+ TASK_SLUG=$(task_name_to_slug "$TASK_NAME")
55
+
56
+ # Validate slug
57
+ if [ -z "$TASK_SLUG" ]; then
58
+ echo "Error: Task name must contain at least one alphanumeric character"
59
+ echo "Provided: $TASK_NAME"
60
+ exit 1
61
+ fi
62
+
63
+ # Determine project root
64
+ PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
65
+ PLANNING_DIR="${PROJECT_ROOT}/.planning"
66
+ TASK_DIR="${PLANNING_DIR}/${TASK_SLUG}"
67
+
68
+ # Color codes
69
+ GREEN='\033[0;32m'
70
+ BLUE='\033[0;34m'
71
+ YELLOW='\033[1;33m'
72
+ CYAN='\033[0;36m'
73
+ NC='\033[0m'
74
+
75
+ echo -e "${BLUE}Initializing Planning Structure${NC}"
76
+ echo ""
77
+
78
+ # Step 1: Create .planning directory
79
+ if [ ! -d "$PLANNING_DIR" ]; then
80
+ mkdir -p "$PLANNING_DIR"
81
+ echo -e "${GREEN}+${NC} Created .planning/ directory"
82
+ else
83
+ echo -e "${YELLOW}*${NC} .planning/ directory exists"
84
+ fi
85
+
86
+ # Step 2: Create task directory
87
+ if [ ! -d "$TASK_DIR" ]; then
88
+ mkdir -p "$TASK_DIR"
89
+ echo -e "${GREEN}+${NC} Created task directory: ${CYAN}.planning/${TASK_SLUG}/${NC}"
90
+ else
91
+ echo -e "${YELLOW}*${NC} Task directory already exists: ${CYAN}.planning/${TASK_SLUG}/${NC}"
92
+ fi
93
+
94
+ # Step 3: Create task_plan.md
95
+ TASK_PLAN_FILE="${TASK_DIR}/task_plan.md"
96
+ if [ ! -f "$TASK_PLAN_FILE" ]; then
97
+ cat > "$TASK_PLAN_FILE" << 'EOF'
98
+ # Task Plan: TASK_NAME_PLACEHOLDER
99
+
100
+ ## Goal
101
+ [One sentence describing the end state]
102
+
103
+ ## Phases
104
+ - [ ] Phase 1: Plan and setup
105
+ - [ ] Phase 2: Research/gather information
106
+ - [ ] Phase 3: Execute/build
107
+ - [ ] Phase 4: Review and deliver
108
+
109
+ ## Key Questions
110
+ 1. [Question to answer]
111
+ 2. [Question to answer]
112
+
113
+ ## Decisions Made
114
+ - [Decision]: [Rationale]
115
+
116
+ ## Errors Encountered
117
+ - [Error]: [Resolution]
118
+
119
+ ## Status
120
+ **Currently in Phase 1** - Setting up planning structure
121
+
122
+ ---
123
+
124
+ ## Notes
125
+ - This file persists across sessions
126
+ - Update status after each phase
127
+ - Mark completed phases with [x]
128
+ - Save research to notes.md instead of stuffing context
129
+ EOF
130
+
131
+ sed -i "s/TASK_NAME_PLACEHOLDER/${TASK_NAME}/g" "$TASK_PLAN_FILE"
132
+ echo -e "${GREEN}+${NC} Created task_plan.md"
133
+ else
134
+ echo -e "${YELLOW}*${NC} task_plan.md already exists (not overwritten)"
135
+ fi
136
+
137
+ # Step 4: Create notes.md
138
+ NOTES_FILE="${TASK_DIR}/notes.md"
139
+ if [ ! -f "$NOTES_FILE" ]; then
140
+ cat > "$NOTES_FILE" << 'EOF'
141
+ # Notes: TASK_NAME_PLACEHOLDER
142
+
143
+ ## Key Findings
144
+ - [Finding 1]
145
+ - [Finding 2]
146
+
147
+ ## Research Sources
148
+ - [Source 1]: [URL or reference]
149
+ - [Source 2]: [URL or reference]
150
+
151
+ ## Synthesized Findings
152
+
153
+ ### [Category/Topic 1]
154
+ - [Finding]
155
+ - [Finding]
156
+
157
+ ### [Category/Topic 2]
158
+ - [Finding]
159
+ - [Finding]
160
+
161
+ ## Decisions Made
162
+ - [Decision]: [Rationale]
163
+ - [Decision]: [Rationale]
164
+
165
+ ## Errors & Solutions
166
+ - [Error]: [Resolution]
167
+ - [Error]: [Resolution]
168
+
169
+ ---
170
+
171
+ ## Append-Only Log
172
+ Store findings here as you discover them. This builds a searchable history.
173
+
174
+ ### [Date/Time]
175
+ - [What I found/did]
176
+ EOF
177
+
178
+ sed -i "s/TASK_NAME_PLACEHOLDER/${TASK_NAME}/g" "$NOTES_FILE"
179
+ echo -e "${GREEN}+${NC} Created notes.md"
180
+ else
181
+ echo -e "${YELLOW}*${NC} notes.md already exists (not overwritten)"
182
+ fi
183
+
184
+ # Step 5: Update .gitignore
185
+ if [ -f "${PROJECT_ROOT}/.gitignore" ]; then
186
+ if ! grep -q "^\.planning/" "${PROJECT_ROOT}/.gitignore"; then
187
+ echo ".planning/" >> "${PROJECT_ROOT}/.gitignore"
188
+ echo -e "${GREEN}+${NC} Added .planning/ to .gitignore"
189
+ else
190
+ echo -e "${YELLOW}*${NC} .planning/ already in .gitignore"
191
+ fi
192
+ else
193
+ echo -e "${YELLOW}*${NC} No .gitignore found (not added)"
194
+ fi
195
+
196
+ # Step 6: List other active tasks
197
+ OTHER_TASKS=$(find "$PLANNING_DIR" -maxdepth 1 -type d -not -name ".planning" -not -path "$TASK_DIR" 2>/dev/null | wc -l)
198
+ if [ "$OTHER_TASKS" -gt 0 ]; then
199
+ echo ""
200
+ echo -e "${CYAN}Other active tasks:${NC}"
201
+ find "$PLANNING_DIR" -maxdepth 1 -type d -not -name ".planning" -not -path "$TASK_DIR" | sort | while read dir; do
202
+ task_slug=$(basename "$dir")
203
+ echo " .planning/${task_slug}/"
204
+ done
205
+ fi
206
+
207
+ # Step 7: Confirmation
208
+ echo ""
209
+ echo -e "${GREEN}=====================================${NC}"
210
+ echo -e "${GREEN}Task Plan Ready${NC}"
211
+ echo -e "${GREEN}=====================================${NC}"
212
+ echo ""
213
+
214
+ echo -e "${BLUE}Task:${NC} ${TASK_NAME}"
215
+ echo -e "${BLUE}Location:${NC} .planning/${TASK_SLUG}/"
216
+ echo ""
217
+
218
+ echo -e "${BLUE}Files:${NC}"
219
+ echo " task_plan.md (your task plan)"
220
+ echo " notes.md (research & findings)"
221
+ echo ""
222
+
223
+ echo -e "${BLUE}Next steps:${NC}"
224
+ echo " 1. Edit .planning/${TASK_SLUG}/task_plan.md to define your phases"
225
+ echo " 2. As you work, update the Status section"
226
+ echo " 3. Save findings to .planning/${TASK_SLUG}/notes.md"
227
+ echo " 4. Re-read task_plan.md before major decisions"
228
+ echo ""
229
+
230
+ echo -e "${BLUE}Cleanup:${NC}"
231
+ echo " rm -rf .planning/${TASK_SLUG}/ # Remove this task"
232
+ echo " rm -rf .planning/ # Remove all tasks"
233
+ echo ""
@@ -0,0 +1,118 @@
1
+ #!/bin/bash
2
+ ###############################################################################
3
+ # init-task.sh - Create a new task under a phase in lg-mode persistent-planning
4
+ #
5
+ # Usage:
6
+ # bash scripts/init-task.sh "Task Name" --parent <phase-slug>
7
+ #
8
+ # Creates:
9
+ # .planning/<phase-slug>/<task-slug>/task.md
10
+ # .planning/<phase-slug>/<task-slug>/notes.md
11
+ # .planning/<phase-slug>/<task-slug>/atoms/ (empty dir for future atoms)
12
+ #
13
+ # Refuses if mode is not lg, or if --parent doesn't reference an existing phase.
14
+ ###############################################################################
15
+ set -e
16
+
17
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
18
+ source "${SCRIPT_DIR}/lib/planning.sh"
19
+
20
+ # Parse arguments
21
+ TASK_NAME=""
22
+ PARENT_PHASE=""
23
+ while [[ $# -gt 0 ]]; do
24
+ case "$1" in
25
+ --parent)
26
+ PARENT_PHASE="$2"
27
+ shift 2
28
+ ;;
29
+ -h|--help)
30
+ cat <<EOF
31
+ Usage: bash scripts/init-task.sh "Task Name" --parent <phase-slug>
32
+
33
+ Examples:
34
+ bash scripts/init-task.sh "HEWTD schema extension" --parent foundation
35
+ bash scripts/init-task.sh "Multi-corpus refactor" --parent semantic-memory-core
36
+ EOF
37
+ exit 0
38
+ ;;
39
+ *)
40
+ if [[ -z "$TASK_NAME" ]]; then
41
+ TASK_NAME="$1"
42
+ fi
43
+ shift
44
+ ;;
45
+ esac
46
+ done
47
+
48
+ if [[ -z "$TASK_NAME" || -z "$PARENT_PHASE" ]]; then
49
+ planning_err "Both task name and --parent <phase-slug> are required."
50
+ echo "Usage: bash scripts/init-task.sh \"Task Name\" --parent <phase-slug>"
51
+ exit 1
52
+ fi
53
+
54
+ TASK_SLUG=$(planning_slugify "$TASK_NAME")
55
+
56
+ if [[ -z "$TASK_SLUG" ]]; then
57
+ planning_err "Task name must contain at least one alphanumeric character."
58
+ exit 1
59
+ fi
60
+
61
+ # Refuse non-lg
62
+ MODE=$(planning_mode)
63
+ if [[ "$MODE" != "lg" ]]; then
64
+ planning_err "Current mode is '$MODE' but init-task.sh requires lg mode."
65
+ exit 1
66
+ fi
67
+
68
+ ROOT=$(planning_root)
69
+ PLANNING="$(planning_dir)"
70
+ TODAY=$(planning_today)
71
+ PHASE_DIR="${PLANNING}/${PARENT_PHASE}"
72
+ TASK_DIR="${PHASE_DIR}/${TASK_SLUG}"
73
+ TEMPLATE_DIR="${ROOT}/templates/lg"
74
+
75
+ if [[ ! -d "$TEMPLATE_DIR" ]]; then
76
+ TEMPLATE_DIR="${SCRIPT_DIR}/../templates/lg"
77
+ fi
78
+ if [[ ! -d "$TEMPLATE_DIR" ]]; then
79
+ planning_err "Cannot locate templates/lg directory."
80
+ exit 1
81
+ fi
82
+
83
+ # Validate parent phase exists
84
+ if [[ ! -f "${PHASE_DIR}/phase.md" ]]; then
85
+ planning_err "Parent phase not found: .planning/${PARENT_PHASE}/phase.md"
86
+ echo "Create the phase first with:"
87
+ echo " /start-planning \"<phase name>\" (which runs init-phase.sh in lg mode)"
88
+ exit 1
89
+ fi
90
+
91
+ planning_log "Initializing task: ${TASK_NAME} (parent: ${PARENT_PHASE})"
92
+
93
+ mkdir -p "${TASK_DIR}/atoms"
94
+
95
+ planning_render_and_log \
96
+ "${TEMPLATE_DIR}/task.md" \
97
+ "${TASK_DIR}/task.md" \
98
+ "task.md at ${TASK_DIR}/task.md" \
99
+ "TASK_TITLE_PLACEHOLDER=${TASK_NAME}" \
100
+ "TASK_SLUG_PLACEHOLDER=${TASK_SLUG}" \
101
+ "PHASE_SLUG_PLACEHOLDER=${PARENT_PHASE}" \
102
+ "TASK_DATE_PLACEHOLDER=${TODAY}"
103
+
104
+ planning_render_and_log \
105
+ "${TEMPLATE_DIR}/notes.md" \
106
+ "${TASK_DIR}/notes.md" \
107
+ "notes.md at ${TASK_DIR}/notes.md" \
108
+ "NOTES_TITLE_PLACEHOLDER=${TASK_NAME} — Notes" \
109
+ "NOTES_SCOPE_PLACEHOLDER=${PARENT_PHASE}/${TASK_SLUG}" \
110
+ "NOTES_DATE_PLACEHOLDER=${TODAY}"
111
+
112
+ echo ""
113
+ planning_ok "Task '${TASK_NAME}' ready at .planning/${PARENT_PHASE}/${TASK_SLUG}/"
114
+ echo ""
115
+ echo "Next steps:"
116
+ echo " 1. Edit .planning/${PARENT_PHASE}/${TASK_SLUG}/task.md to describe the goal"
117
+ echo " 2. Add atoms with: /start-atom \"<atom name>\" --parent ${TASK_SLUG}"
118
+ echo " (or add inline atom checkboxes in task.md for simple atoms)"
@@ -0,0 +1,161 @@
1
+ #!/bin/bash
2
+ ###############################################################################
3
+ # scripts/lib/planning.sh - Shared helpers for persistent-planning init scripts
4
+ #
5
+ # Source this file from init-phase.sh, init-task.sh, init-atom.sh, and any
6
+ # other planning-related script that needs slug, root, mode, or template
7
+ # rendering helpers.
8
+ #
9
+ # Usage:
10
+ # #!/bin/bash
11
+ # set -e
12
+ # SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+ # source "${SCRIPT_DIR}/lib/planning.sh"
14
+ #
15
+ # Provides:
16
+ # - planning_slugify "Some Name" → "some-name" (echoed)
17
+ # - planning_root → prints project root (CLAUDE_PROJECT_DIR or pwd)
18
+ # - planning_dir → prints "<root>/.planning"
19
+ # - planning_meta_dir → prints "<root>/.planning/.meta"
20
+ # - planning_workspace_json → prints "<meta>/workspace.json"
21
+ # - planning_mode → prints active mode (sm | lg) via detect-mode.sh
22
+ # - planning_today → prints today's date as YYYY-MM-DD
23
+ # - planning_render_template "<src>" "<dest>" "PLACEHOLDER1=value1" "PLACEHOLDER2=value2" ...
24
+ # Renders a template file by sed-substituting PLACEHOLDER tokens.
25
+ # Refuses to overwrite existing dest unless PLANNING_FORCE=1 in env.
26
+ # - planning_color_<name> → ANSI color codes (green, blue, yellow, cyan, red, reset)
27
+ # (only set when stdout is a tty; empty otherwise)
28
+ # - Color-coded log helpers: planning_log, planning_ok, planning_warn, planning_err
29
+ ###############################################################################
30
+
31
+ # Color codes (only when stdout is a tty)
32
+ if [[ -t 1 ]]; then
33
+ planning_color_green='\033[0;32m'
34
+ planning_color_blue='\033[0;34m'
35
+ planning_color_yellow='\033[1;33m'
36
+ planning_color_cyan='\033[0;36m'
37
+ planning_color_red='\033[0;31m'
38
+ planning_color_reset='\033[0m'
39
+ else
40
+ planning_color_green=''
41
+ planning_color_blue=''
42
+ planning_color_yellow=''
43
+ planning_color_cyan=''
44
+ planning_color_red=''
45
+ planning_color_reset=''
46
+ fi
47
+
48
+ planning_log() { printf "${planning_color_blue}[planning]${planning_color_reset} %s\n" "$*"; }
49
+ planning_ok() { printf "${planning_color_green}[planning]${planning_color_reset} %s\n" "$*"; }
50
+ planning_warn() { printf "${planning_color_yellow}[planning]${planning_color_reset} %s\n" "$*"; }
51
+ planning_err() { printf "${planning_color_red}[planning]${planning_color_reset} %s\n" "$*" >&2; }
52
+
53
+ planning_slugify() {
54
+ local name="$1"
55
+ name=$(echo "$name" | tr '[:upper:]' '[:lower:]')
56
+ name=$(echo "$name" | sed 's/[[:space:]_]\+/-/g')
57
+ name=$(echo "$name" | sed 's/[^a-z0-9-]//g')
58
+ name=$(echo "$name" | sed 's/^-\+\|-\+$//g')
59
+ name=$(echo "$name" | sed 's/-\+/-/g')
60
+ echo "$name"
61
+ }
62
+
63
+ planning_root() {
64
+ echo "${CLAUDE_PROJECT_DIR:-$(pwd)}"
65
+ }
66
+
67
+ planning_dir() {
68
+ echo "$(planning_root)/.planning"
69
+ }
70
+
71
+ planning_meta_dir() {
72
+ echo "$(planning_dir)/.meta"
73
+ }
74
+
75
+ planning_workspace_json() {
76
+ echo "$(planning_meta_dir)/workspace.json"
77
+ }
78
+
79
+ planning_today() {
80
+ date '+%Y-%m-%d'
81
+ }
82
+
83
+ planning_mode() {
84
+ # Resolve via detect-mode.sh (in the same scripts/ dir as the caller's library).
85
+ local lib_dir
86
+ lib_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
87
+ local detect="${lib_dir}/../detect-mode.sh"
88
+ if [[ -x "$detect" ]]; then
89
+ bash "$detect"
90
+ else
91
+ echo "sm"
92
+ fi
93
+ }
94
+
95
+ # planning_render_template <template_src> <dest_path> <PLACEHOLDER1=value1> ...
96
+ # Renders a template file by sed-substituting placeholders.
97
+ #
98
+ # Return codes:
99
+ # 0 → rendered fresh
100
+ # 2 → skipped (dest already exists; pass PLANNING_FORCE=1 to overwrite)
101
+ # 1 → error (template not found, etc.)
102
+ #
103
+ # Callers can branch on the return code to log accurately.
104
+ planning_render_template() {
105
+ local src="$1"
106
+ local dest="$2"
107
+ shift 2
108
+
109
+ if [[ ! -f "$src" ]]; then
110
+ planning_err "Template not found: $src"
111
+ return 1
112
+ fi
113
+
114
+ if [[ -f "$dest" && "${PLANNING_FORCE:-0}" != "1" ]]; then
115
+ planning_warn "Destination already exists, skipping: $dest"
116
+ planning_warn " (re-run with PLANNING_FORCE=1 to overwrite)"
117
+ return 2
118
+ fi
119
+
120
+ # Copy template to dest
121
+ cp "$src" "$dest"
122
+
123
+ # Apply substitutions
124
+ for kv in "$@"; do
125
+ local key="${kv%%=*}"
126
+ local value="${kv#*=}"
127
+ # Use a safe delimiter (~) since values may contain /
128
+ # Escape & and ~ in value
129
+ local escaped_value
130
+ escaped_value=$(printf '%s\n' "$value" | sed -e 's/[\&~]/\\&/g')
131
+ sed -i "s~${key}~${escaped_value}~g" "$dest"
132
+ done
133
+ return 0
134
+ }
135
+
136
+ # planning_render_and_log <template_src> <dest_path> <relative_label> <PLACEHOLDER=val> ...
137
+ # Wraps planning_render_template with accurate logging:
138
+ # - Prints "Created <relative_label>" only when the template was actually rendered
139
+ # - Prints nothing extra when skipped (the warn from render_template already covered it)
140
+ # - Lets the script continue (set -e tolerant) regardless of skip vs render
141
+ planning_render_and_log() {
142
+ local src="$1"
143
+ local dest="$2"
144
+ local label="$3"
145
+ shift 3
146
+
147
+ local rc=0
148
+ planning_render_template "$src" "$dest" "$@" || rc=$?
149
+ case $rc in
150
+ 0)
151
+ planning_ok "Created ${label}"
152
+ ;;
153
+ 2)
154
+ # Already covered by the warn inside planning_render_template
155
+ ;;
156
+ *)
157
+ planning_err "Failed to render ${label} (rc=$rc)"
158
+ return $rc
159
+ ;;
160
+ esac
161
+ }
@@ -0,0 +1,45 @@
1
+ ---
2
+ title: ATOM_TITLE_PLACEHOLDER
3
+ tier: plan
4
+ domains:
5
+ - planning
6
+ status: ready
7
+ last_updated: "ATOM_DATE_PLACEHOLDER"
8
+ plan_kind: atom
9
+ parent: TASK_SLUG_PLACEHOLDER
10
+ sequence: ATOM_SEQUENCE_PLACEHOLDER
11
+ ---
12
+
13
+ # Atom: ATOM_TITLE_PLACEHOLDER
14
+
15
+ **Task**: `TASK_SLUG_PLACEHOLDER`
16
+ **Sequence**: `ATOM_SEQUENCE_PLACEHOLDER` (atoms within a task are processed sequentially)
17
+
18
+ ## What to do
19
+ [Describe the atomic action a subagent should take. Single focused step. If the work
20
+ spans more than one logical operation, split into multiple atoms with sequential ordering.
21
+
22
+ This file IS the contract a subagent reads to know exactly what to do. Be specific.]
23
+
24
+ ## Inputs
25
+ [Files, data, or prior atom outputs this atom depends on.]
26
+
27
+ ## Expected outputs
28
+ [Files modified, files created, commands run, or state changed.]
29
+
30
+ ## Acceptance criteria
31
+ [How a subagent (or human reviewer) confirms this atom is done. Should be concrete
32
+ and verifiable.]
33
+
34
+ ## Status
35
+ **Currently ready** — waiting for a subagent to claim it.
36
+
37
+ Status enum: `ready | in_progress | done | blocked`
38
+
39
+ Status transitions:
40
+ - `ready → in_progress`: a subagent claims this atom
41
+ - `in_progress → done`: the subagent completes the work and verifies acceptance criteria
42
+ - `in_progress → blocked`: the subagent hits an obstacle (add a note explaining why
43
+ in a `## Blocker` section)
44
+ - `done → in_progress` (reopen): allowed when a follow-up correction is needed; adds
45
+ `reopened_at: <iso-timestamp>` field to frontmatter for audit
@@ -0,0 +1,40 @@
1
+ ---
2
+ title: NOTES_TITLE_PLACEHOLDER
3
+ tier: plan
4
+ domains:
5
+ - planning
6
+ status: active
7
+ last_updated: "NOTES_DATE_PLACEHOLDER"
8
+ plan_kind: notes
9
+ scope: NOTES_SCOPE_PLACEHOLDER
10
+ ---
11
+
12
+ # Notes: NOTES_TITLE_PLACEHOLDER
13
+
14
+ **Scope**: `NOTES_SCOPE_PLACEHOLDER` (which phase / task this notes file is attached to)
15
+
16
+ ## Key Findings
17
+ [Findings that emerged during plan implementation. Things that didn't fit cleanly into
18
+ a task or atom but matter for context.]
19
+
20
+ ## Research Sources
21
+ [External references, internal docs, conversations that informed decisions.]
22
+
23
+ ## Synthesized Findings
24
+ [Patterns, themes, distilled understanding from the research.]
25
+
26
+ ## Decisions Made
27
+ [Notes-level decisions that affect the parent task or phase. Promote to the parent's
28
+ Decisions Made section if they have wider impact.]
29
+
30
+ ## Errors & Solutions
31
+ [Errors encountered + how they were resolved. Useful for future similar work.]
32
+
33
+ ---
34
+
35
+ ## Append-Only Log
36
+ [Chronological record of progress. Each entry is dated. Useful for handoff and
37
+ reconstructing context after time away.]
38
+
39
+ ### NOTES_DATE_PLACEHOLDER — Initialized
40
+ - Notes file created
@@ -0,0 +1,42 @@
1
+ ---
2
+ title: PHASE_TITLE_PLACEHOLDER
3
+ tier: plan
4
+ domains:
5
+ - planning
6
+ status: draft
7
+ last_updated: "PHASE_DATE_PLACEHOLDER"
8
+ plan_kind: phase
9
+ parent: null
10
+ ---
11
+
12
+ # Phase: PHASE_TITLE_PLACEHOLDER
13
+
14
+ ## Goal
15
+ [One sentence describing what this phase achieves and the strategic boundary it represents.]
16
+
17
+ ## Tasks
18
+ [Tasks created with `/start-task --parent PHASE_SLUG_PLACEHOLDER` will be tracked here.
19
+ Each task is a bounded deliverable. Tasks default to dependencies-first scheduling.
20
+ Tasks with no inter-dependencies can be marked `parallelizable: true` in their frontmatter
21
+ so subagent teams can pick them up concurrently.]
22
+
23
+ - [ ] (no tasks yet — run `/start-task "Task name" --parent PHASE_SLUG_PLACEHOLDER`)
24
+
25
+ ## Decisions Made
26
+ [Phase-level decisions that affect multiple tasks. Format: `**Decision**: rationale`.]
27
+
28
+ ## Status
29
+ **Currently draft** — phase has been initialized but no tasks defined.
30
+
31
+ Status enum: `draft | active | paused | done | archived`
32
+
33
+ When all tasks are `done`, mark this phase `done`. When archived, this directory and
34
+ its tasks/atoms move to `.planning/archive/PHASE_SLUG_PLACEHOLDER/`.
35
+
36
+ ---
37
+
38
+ ## Layer reference (lg mode)
39
+ - **Phase** (this file): strategic grouping of related tasks
40
+ - **Task** (`.planning/PHASE_SLUG_PLACEHOLDER/<task-slug>/task.md`): bounded deliverable
41
+ - **Atom** (`.planning/PHASE_SLUG_PLACEHOLDER/<task-slug>/atoms/<atom-slug>.md`): subagent hand-off unit
42
+ - **Notes** (`.planning/PHASE_SLUG_PLACEHOLDER/notes.md` or per-task `notes.md`): cross-cutting references
@@ -0,0 +1,54 @@
1
+ ---
2
+ title: TASK_TITLE_PLACEHOLDER
3
+ tier: plan
4
+ domains:
5
+ - planning
6
+ status: draft
7
+ last_updated: "TASK_DATE_PLACEHOLDER"
8
+ plan_kind: task
9
+ parent: PHASE_SLUG_PLACEHOLDER
10
+ depends_on: []
11
+ parallelizable: false
12
+ ---
13
+
14
+ # Task: TASK_TITLE_PLACEHOLDER
15
+
16
+ **Phase**: `PHASE_SLUG_PLACEHOLDER`
17
+
18
+ ## Goal
19
+ [One sentence describing the deliverable end-state for this task.]
20
+
21
+ ## Atoms
22
+ [Atomic checkbox items that will be picked up by subagents. Each atom should be
23
+ something a single subagent can complete in one focused pass.
24
+
25
+ For complex atoms that need explicit subagent context, spawn a standalone atom file
26
+ via `/start-atom "Atom name" --parent TASK_SLUG_PLACEHOLDER` — these become files
27
+ under `atoms/` that subagents read via the planning MCP.
28
+
29
+ Inline checkbox vs. standalone atom file — see anti-pattern doc:
30
+ docs/atom-granularity.md.]
31
+
32
+ - [ ] (no atoms yet — add inline checkboxes here for simple atoms,
33
+ or run `/start-atom "Atom name" --parent TASK_SLUG_PLACEHOLDER` for complex ones)
34
+
35
+ ## Decisions Made
36
+ [Task-level decisions. Format: `**Decision**: rationale`.]
37
+
38
+ ## Status
39
+ **Currently draft** — task has been initialized but no atoms defined.
40
+
41
+ Status enum: `draft | active | paused | done | archived`
42
+
43
+ ## Dependencies
44
+ This task does not currently depend on other tasks. Edit `depends_on:` in frontmatter
45
+ to declare dependencies on other tasks within the same phase. Tasks with no
46
+ inter-dependencies should set `parallelizable: true`.
47
+
48
+ ---
49
+
50
+ ## Layer reference
51
+ - **Phase** (`../phase.md`): the strategic grouping this task belongs to
52
+ - **This task**: the bounded deliverable
53
+ - **Atoms** (`atoms/<atom-slug>.md`): subagent hand-off units (sequential within this task)
54
+ - **Notes** (`notes.md`): cross-cutting references for this task's implementation