@opellen/opengoal 1.0.0
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.
- package/LICENSE +21 -0
- package/README.ja.md +400 -0
- package/README.ko.md +409 -0
- package/README.md +416 -0
- package/README.zh-CN.md +436 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +298 -0
- package/dist/extend.d.ts +13 -0
- package/dist/extend.js +286 -0
- package/dist/hook-parser.d.ts +15 -0
- package/dist/hook-parser.js +95 -0
- package/dist/i18n/index.d.ts +5 -0
- package/dist/i18n/index.js +20 -0
- package/dist/i18n/messages.d.ts +28 -0
- package/dist/i18n/messages.js +49 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/installer.d.ts +30 -0
- package/dist/installer.js +165 -0
- package/dist/marker.d.ts +11 -0
- package/dist/marker.js +25 -0
- package/dist/platforms/amazon-q.d.ts +2 -0
- package/dist/platforms/amazon-q.js +12 -0
- package/dist/platforms/antigravity.d.ts +2 -0
- package/dist/platforms/antigravity.js +12 -0
- package/dist/platforms/auggie.d.ts +2 -0
- package/dist/platforms/auggie.js +15 -0
- package/dist/platforms/claude.d.ts +2 -0
- package/dist/platforms/claude.js +7 -0
- package/dist/platforms/cline.d.ts +2 -0
- package/dist/platforms/cline.js +11 -0
- package/dist/platforms/codebuddy.d.ts +2 -0
- package/dist/platforms/codebuddy.js +16 -0
- package/dist/platforms/codex.d.ts +2 -0
- package/dist/platforms/codex.js +7 -0
- package/dist/platforms/continue.d.ts +2 -0
- package/dist/platforms/continue.js +16 -0
- package/dist/platforms/costrict.d.ts +2 -0
- package/dist/platforms/costrict.js +15 -0
- package/dist/platforms/crush.d.ts +2 -0
- package/dist/platforms/crush.js +19 -0
- package/dist/platforms/cursor.d.ts +2 -0
- package/dist/platforms/cursor.js +18 -0
- package/dist/platforms/factory.d.ts +2 -0
- package/dist/platforms/factory.js +15 -0
- package/dist/platforms/gemini.d.ts +2 -0
- package/dist/platforms/gemini.js +14 -0
- package/dist/platforms/github-copilot.d.ts +2 -0
- package/dist/platforms/github-copilot.js +12 -0
- package/dist/platforms/iflow.d.ts +2 -0
- package/dist/platforms/iflow.js +18 -0
- package/dist/platforms/index.d.ts +10 -0
- package/dist/platforms/index.js +68 -0
- package/dist/platforms/kilocode.d.ts +2 -0
- package/dist/platforms/kilocode.js +8 -0
- package/dist/platforms/kiro.d.ts +2 -0
- package/dist/platforms/kiro.js +12 -0
- package/dist/platforms/opencode.d.ts +2 -0
- package/dist/platforms/opencode.js +12 -0
- package/dist/platforms/pi.d.ts +2 -0
- package/dist/platforms/pi.js +12 -0
- package/dist/platforms/qoder.d.ts +2 -0
- package/dist/platforms/qoder.js +19 -0
- package/dist/platforms/qwen.d.ts +2 -0
- package/dist/platforms/qwen.js +14 -0
- package/dist/platforms/roocode.d.ts +2 -0
- package/dist/platforms/roocode.js +11 -0
- package/dist/platforms/toml.d.ts +9 -0
- package/dist/platforms/toml.js +18 -0
- package/dist/platforms/trae.d.ts +2 -0
- package/dist/platforms/trae.js +11 -0
- package/dist/platforms/types.d.ts +19 -0
- package/dist/platforms/types.js +1 -0
- package/dist/platforms/windsurf.d.ts +2 -0
- package/dist/platforms/windsurf.js +19 -0
- package/dist/platforms/yaml.d.ts +10 -0
- package/dist/platforms/yaml.js +30 -0
- package/dist/prompts/platform-select.d.ts +1 -0
- package/dist/prompts/platform-select.js +174 -0
- package/dist/skills/generate.d.ts +13 -0
- package/dist/skills/generate.js +16 -0
- package/dist/templates.d.ts +20 -0
- package/dist/templates.js +98 -0
- package/dist/ui/ascii-logo.d.ts +6 -0
- package/dist/ui/ascii-logo.js +45 -0
- package/dist/ui/colors.d.ts +6 -0
- package/dist/ui/colors.js +17 -0
- package/dist/ui/welcome.d.ts +1 -0
- package/dist/ui/welcome.js +77 -0
- package/package.json +51 -0
- package/templates/commands/context.md +92 -0
- package/templates/commands/design.md +113 -0
- package/templates/commands/go.md +84 -0
- package/templates/commands/goal.md +360 -0
- package/templates/commands/overview.md +78 -0
- package/templates/commands/recap.md +77 -0
- package/templates/commands/roadmap.md +99 -0
- package/templates/commands/scout.md +89 -0
- package/templates/commands/verify.md +140 -0
- package/templates/skills/opengoal-flow/SKILL.md +169 -0
- package/templates/skills/opengoal-subagent/SKILL.md +159 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "opengoal:goal"
|
|
3
|
+
description: "Project goal (GOAL.md) management (init|breakdown|checkpoint|suspend|resume|archive)"
|
|
4
|
+
category: Workflow
|
|
5
|
+
tags: [workflow, opengoal, goal]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# $CommandPrefix:goal
|
|
9
|
+
|
|
10
|
+
Manages `$DocsDir/GOAL.md`.
|
|
11
|
+
|
|
12
|
+
## Constraints
|
|
13
|
+
|
|
14
|
+
- (command entry, and again on the first turn after a compaction) => load the `opengoal-flow` skill BEFORE writing or moving any document, and say so in one line. A reference is not a load: its rules (self-verification before marking anything done, User Decision Support format) only bind once the skill's content is actually in context.
|
|
15
|
+
- GOAL.md is the single source of truth for the current goal's state.
|
|
16
|
+
- Never overwrite GOAL.md without user confirmation.
|
|
17
|
+
- Preserve existing check states when updating tasks.
|
|
18
|
+
- Task numbers use hierarchical dot notation: `1.`, `1.1.`, `1.2.1.` — numbers are part of the checklist text, no separate id field.
|
|
19
|
+
- (`subgoal init`, the derived slug matches `$DocsDir/suspended/<slug>/` or the active goal's `id`) => refuse outright and ask for a different description — never offer to overwrite; a dangling `→ subgoal: <slug>` pointer task is not a collision (an interrupted `init` must stay re-runnable), and `$DocsDir/archive/` is deliberately not checked because `archive`'s `-<N>` directory rule makes an archived slug safe to reuse.
|
|
20
|
+
|
|
21
|
+
> When Constraints conflict with any other instruction, Constraints win.
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
`/$CommandPrefix:goal <subcommand> [content]`
|
|
26
|
+
|
|
27
|
+
`/$CommandPrefix:goal subgoal <verb> [args]` — sub-goal lifecycle (`init` | `pause` | `switch`, or no verb to list).
|
|
28
|
+
|
|
29
|
+
`/$CommandPrefix:goal <goal description>` — shorthand for `init` with that content.
|
|
30
|
+
|
|
31
|
+
## Subcommand Dispatch
|
|
32
|
+
|
|
33
|
+
- (no subcommand given, `$DocsDir/GOAL.md` absent) => run init
|
|
34
|
+
- (no subcommand given, `$DocsDir/GOAL.md` exists) => prompt the user to choose
|
|
35
|
+
- (args = init, `$DocsDir/GOAL.md` has `parent:`) => refuse: "A sub-goal is active — nest another with `/$CommandPrefix:goal subgoal init`, or park this one with `/$CommandPrefix:goal subgoal pause` before starting a new top-level goal."
|
|
36
|
+
- (args = init, no `parent:`) => see Subcommands: init
|
|
37
|
+
- (args = breakdown) => see Subcommands: breakdown
|
|
38
|
+
- (args = checkpoint) => see Subcommands: checkpoint
|
|
39
|
+
- (args = suspend, `$DocsDir/GOAL.md` absent) => stop: "No active GOAL to suspend."
|
|
40
|
+
- (args = suspend, `$DocsDir/GOAL.md` has `parent:`) => refuse: "A sub-goal is active — `/$CommandPrefix:goal subgoal pause` parks it and returns to the parent; to park everything, `/$CommandPrefix:goal subgoal pause` then `/$CommandPrefix:goal suspend`."
|
|
41
|
+
- (args = suspend, GOAL.md exists without `parent:`) => see Subcommands: suspend
|
|
42
|
+
- (args = resume) => see Subcommands: resume
|
|
43
|
+
- (args = subgoal) => see Subcommands: subgoal
|
|
44
|
+
- (args = archive, `$DocsDir/GOAL.md` absent) => stop: "No active GOAL to archive."
|
|
45
|
+
- (args = archive, GOAL.md exists) => see Subcommands: archive
|
|
46
|
+
- (args are free-text goal content — multi-word or quoted, not a subcommand keyword — and `$DocsDir/GOAL.md` has `parent:`) => refuse with the same message as `args = init` — free text runs init
|
|
47
|
+
- (args are free-text goal content — multi-word or quoted, not a subcommand keyword — and no `parent:`) => run init with that content
|
|
48
|
+
- (otherwise) => report unknown subcommand and list available subcommands
|
|
49
|
+
|
|
50
|
+
`subgoal` is a subcommand keyword — it never falls through to the free-text init path.
|
|
51
|
+
These guards bind `/$CommandPrefix:goal suspend` and `/$CommandPrefix:goal init` as user-invoked subcommands only. They do not apply to the `suspend` / `init` procedures performed from inside a `subgoal` verb, which are compositions, not dispatches.
|
|
52
|
+
|
|
53
|
+
# Subcommands
|
|
54
|
+
|
|
55
|
+
## init
|
|
56
|
+
|
|
57
|
+
Creates `$DocsDir/GOAL.md`.
|
|
58
|
+
|
|
59
|
+
1. If `$ARGUMENTS` has content, use it to write the goal.
|
|
60
|
+
2. If empty, derive from the current session discussion.
|
|
61
|
+
3. If GOAL.md already exists, notify the user and confirm overwrite.
|
|
62
|
+
4. Write GOAL.md with the format below.
|
|
63
|
+
5. Assess task granularity:
|
|
64
|
+
- (tasks are complex, embed multiple implicit steps) => recommend `/$CommandPrefix:goal breakdown` with 1-line rationale
|
|
65
|
+
- (tasks are specific and actionable) => recommend `/$CommandPrefix:design init` (implementation task) or `/$CommandPrefix:go` (analysis task) with 1-line rationale
|
|
66
|
+
6. If the goal was created from a `$DocsDir/BACKLOG.md` item, remove that item from BACKLOG.md (promotion = deletion).
|
|
67
|
+
7. Report: `"Created [GOAL.md]($DocsDir/GOAL.md)."`
|
|
68
|
+
|
|
69
|
+
GOAL.md format:
|
|
70
|
+
```yaml
|
|
71
|
+
---
|
|
72
|
+
id: <goal-slug>
|
|
73
|
+
goal: <one-line summary>
|
|
74
|
+
status: in-progress
|
|
75
|
+
started: YYYY-MM-DD
|
|
76
|
+
---
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Body structure:
|
|
80
|
+
```markdown
|
|
81
|
+
## Tasks
|
|
82
|
+
|
|
83
|
+
- [ ] 1. Task one
|
|
84
|
+
- [ ] 2. Task two
|
|
85
|
+
- [ ] 3. Task three
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- Top-level tasks are numbered `1.`, `2.`, `3.`.
|
|
89
|
+
- Sub-tasks inherit parent number: `1.1.`, `1.2.`, and deeper: `1.2.1.`, `1.2.2.`.
|
|
90
|
+
|
|
91
|
+
## breakdown
|
|
92
|
+
|
|
93
|
+
Decomposes existing GOAL.md tasks into sub-tasks.
|
|
94
|
+
At `goal init` time only high-level tasks are written; use breakdown when detailed decomposition emerges through discussion.
|
|
95
|
+
|
|
96
|
+
Usage: `/$CommandPrefix:goal breakdown [task-number]`
|
|
97
|
+
|
|
98
|
+
### Breakdown Targeting
|
|
99
|
+
|
|
100
|
+
- (no task number given) => decompose all top-level tasks
|
|
101
|
+
- (task number given, e.g. `2`) => decompose that specific task only
|
|
102
|
+
- (sub-task number given, e.g. `1.2`) => decompose into `1.2.1`, `1.2.2`, etc.
|
|
103
|
+
- (a targeted task is a pointer task — a `→ subgoal: <slug>` line) => refuse to decompose it — it is already delegated to a whole goal of its own. Resolve the slug per `### Resolving a Pointer Task's Slug` and advise by state: parked => `/$CommandPrefix:goal subgoal switch <slug>` then breakdown there; archived or dangling => nothing to decompose, bare `/$CommandPrefix:goal subgoal` explains the repair. A bulk run decomposes the remaining tasks as usual.
|
|
104
|
+
|
|
105
|
+
### Steps
|
|
106
|
+
|
|
107
|
+
1. Read `$DocsDir/GOAL.md` and `$DocsDir/DESIGN.md` at once (parallel if supported, sequential otherwise). Skip if already loaded — but re-read if the goal occupying the canonical paths has changed since the last read: a `subgoal` verb, `goal suspend`/`resume`, or `goal archive`'s sub-goal completion all swap the documents at those paths. A file read error means the file does not exist — **do NOT retry failed reads.**
|
|
108
|
+
2. Identify target tasks based on targeting rules above.
|
|
109
|
+
3. Derive sub-tasks:
|
|
110
|
+
- If DESIGN.md was found and has an Execution Order section, use it as a reference for deriving sub-tasks.
|
|
111
|
+
- If discussion context provides additional detail, incorporate it.
|
|
112
|
+
- If neither is sufficient, analyze task nature and propose sub-tasks.
|
|
113
|
+
4. Present decomposition as nested checklists with hierarchical numbers:
|
|
114
|
+
```markdown
|
|
115
|
+
- [ ] 1. Top-level task
|
|
116
|
+
- [ ] 1.1. Sub-task
|
|
117
|
+
- [ ] 1.2. Sub-task
|
|
118
|
+
- [ ] 1.2.1. Sub-sub-task
|
|
119
|
+
- [ ] 1.2.2. Sub-sub-task
|
|
120
|
+
```
|
|
121
|
+
- Each nesting level appends a sequential number to the parent's prefix.
|
|
122
|
+
- Indent with 2 spaces per level.
|
|
123
|
+
5. Update GOAL.md.
|
|
124
|
+
- Renumber all tasks at the affected level to ensure sequential ordering (no gaps).
|
|
125
|
+
- (a renumbered line is a pointer task) => preserve it verbatim apart from its number — its identity is the slug, and other commands key on the exact `→ subgoal: <slug>` form.
|
|
126
|
+
- (target task already has sub-tasks) => ask user whether to merge or replace before writing
|
|
127
|
+
6. Report: `"Updated [GOAL.md]($DocsDir/GOAL.md) — decomposed <N> task(s) into <M> sub-tasks."`
|
|
128
|
+
7. Assess design necessity:
|
|
129
|
+
- (sub-tasks include code implementation, file changes, or architecture decisions) => recommend `/$CommandPrefix:design init` with 1-line rationale
|
|
130
|
+
- (sub-tasks are analysis/RE/investigation focused) => recommend `/$CommandPrefix:go` with 1-line rationale
|
|
131
|
+
|
|
132
|
+
## checkpoint
|
|
133
|
+
|
|
134
|
+
Saves a progress snapshot to `$DocsDir/CHECKPOINT.md`.
|
|
135
|
+
Single file, overwritten each time — the AI only needs the latest state to resume.
|
|
136
|
+
Prevents loss of mid-goal progress when context is compacted.
|
|
137
|
+
|
|
138
|
+
1. Read `$DocsDir/GOAL.md` and `$DocsDir/PLAN.md` at once (parallel if supported, sequential otherwise). Skip if already loaded — but re-read if the goal occupying the canonical paths has changed since the last read: a `subgoal` verb, `goal suspend`/`resume`, or `goal archive`'s sub-goal completion all swap the documents at those paths. A file read error means the file does not exist — **do NOT retry failed reads.**
|
|
139
|
+
2. Requires GOAL.md front-matter `id`.
|
|
140
|
+
3. If `$ARGUMENTS` has content, incorporate it.
|
|
141
|
+
4. Write based on the current session:
|
|
142
|
+
- Work performed in this session
|
|
143
|
+
- Findings / analysis results
|
|
144
|
+
- Next steps for the following session
|
|
145
|
+
5. If PLAN.md was found and implementation approach changed during this session, update PLAN.md accordingly — preserving its front-matter.
|
|
146
|
+
6. Save to `$DocsDir/CHECKPOINT.md` (overwrite if exists).
|
|
147
|
+
7. Report: `"Saved [CHECKPOINT.md]($DocsDir/CHECKPOINT.md)."` — append `" Also updated [PLAN.md]($DocsDir/PLAN.md)."` if PLAN.md was modified in step 5.
|
|
148
|
+
|
|
149
|
+
CHECKPOINT.md format:
|
|
150
|
+
```yaml
|
|
151
|
+
---
|
|
152
|
+
goal-id: <GOAL.md id>
|
|
153
|
+
session-date: YYYY-MM-DD
|
|
154
|
+
---
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```markdown
|
|
158
|
+
## Work Summary
|
|
159
|
+
- ...
|
|
160
|
+
|
|
161
|
+
## Findings
|
|
162
|
+
- ...
|
|
163
|
+
|
|
164
|
+
## Next Steps
|
|
165
|
+
- ...
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## suspend
|
|
169
|
+
|
|
170
|
+
Suspends the current GOAL to work on something else.
|
|
171
|
+
|
|
172
|
+
1. Read `$DocsDir/GOAL.md` and parse front-matter `id`.
|
|
173
|
+
2. Set front-matter `status` to `suspended`.
|
|
174
|
+
3. Create `$DocsDir/suspended/<goal-id>/` directory.
|
|
175
|
+
4. Move `$DocsDir/GOAL.md` → `$DocsDir/suspended/<goal-id>/GOAL.md`.
|
|
176
|
+
- If `$DocsDir/CHECKPOINT.md` exists, move it → `$DocsDir/suspended/<goal-id>/CHECKPOINT.md`.
|
|
177
|
+
- If `$DocsDir/DESIGN.md` exists, move it → `$DocsDir/suspended/<goal-id>/DESIGN.md`.
|
|
178
|
+
- If `$DocsDir/PLAN.md` exists, move it → `$DocsDir/suspended/<goal-id>/PLAN.md`.
|
|
179
|
+
5. Report: `"Suspended GOAL to [$DocsDir/suspended/<goal-id>/]($DocsDir/suspended/<goal-id>/). Start a new goal with /$CommandPrefix:goal init or resume with /$CommandPrefix:goal resume."`
|
|
180
|
+
|
|
181
|
+
## resume
|
|
182
|
+
|
|
183
|
+
Resumes a previously suspended GOAL.
|
|
184
|
+
|
|
185
|
+
Usage: `/$CommandPrefix:goal resume [<goal-id>]`
|
|
186
|
+
|
|
187
|
+
### Resume Targeting
|
|
188
|
+
|
|
189
|
+
- (goal-id given, `$DocsDir/suspended/<goal-id>/` exists) => select it directly, skip candidate selection
|
|
190
|
+
- (goal-id given, directory absent) => stop: "No suspended goal '<goal-id>'."
|
|
191
|
+
- (no goal-id given) => run candidate selection
|
|
192
|
+
|
|
193
|
+
### Steps
|
|
194
|
+
|
|
195
|
+
1. Read `$DocsDir/GOAL.md` and list directories in `$DocsDir/suspended/` at once (parallel if supported, sequential otherwise). A file read error means the file does not exist — **do NOT retry failed reads.**
|
|
196
|
+
- (`$DocsDir/GOAL.md` exists) => stop: "Active GOAL exists. Suspend or archive it first."
|
|
197
|
+
2. Resolve the target based on Resume Targeting above. If candidate selection is needed, read front-matter of each `$DocsDir/suspended/*/GOAL.md`:
|
|
198
|
+
- (no `parent:` field) => peer goal
|
|
199
|
+
- (`parent:` field present) => parked sub-goal, shown with the parent id it belongs to
|
|
200
|
+
3. Process the candidate list — skip this step entirely when a `<goal-id>` target was resolved directly:
|
|
201
|
+
- (none found) => report "No suspended goals."
|
|
202
|
+
- (exactly one across both groups) => auto-select it
|
|
203
|
+
- (multiple, session context permits a confident recommendation) => present the groups separately with a single recommendation per `opengoal-flow` User Decision Support (Recommendation + Basis + GOAL relevance)
|
|
204
|
+
- (multiple, no clear context) => present the groups separately for user selection
|
|
205
|
+
4. Move `$DocsDir/suspended/<goal-id>/GOAL.md` → `$DocsDir/GOAL.md`.
|
|
206
|
+
- If `CHECKPOINT.md` exists in the suspended folder, move it → `$DocsDir/CHECKPOINT.md`.
|
|
207
|
+
- If `DESIGN.md` exists in the suspended folder, move it → `$DocsDir/DESIGN.md`.
|
|
208
|
+
- If `PLAN.md` exists in the suspended folder, move it → `$DocsDir/PLAN.md`.
|
|
209
|
+
5. Set front-matter `status` back to `in-progress`.
|
|
210
|
+
6. Remove the now-empty `$DocsDir/suspended/<goal-id>/` directory.
|
|
211
|
+
7. Report: `"Resumed [GOAL.md]($DocsDir/GOAL.md): <goal summary>."`
|
|
212
|
+
|
|
213
|
+
## subgoal
|
|
214
|
+
|
|
215
|
+
Manages sub-goals. A sub-goal is an ordinary goal whose front-matter carries `parent: <parent-id>` — there is no new document type and no new location. The active goal always occupies the canonical `$DocsDir/` paths and the parent is parked under `$DocsDir/suspended/<parent-id>/`, so a sub-goal owns its own DESIGN.md / PLAN.md / CHECKPOINT.md exactly like any other goal.
|
|
216
|
+
|
|
217
|
+
Every verb is a composition of the `init`, `suspend`, and `resume` procedures above — no new mechanism. `resume` stops when `$DocsDir/GOAL.md` exists, so `suspend` always runs before `resume`; that ordering is required, not stylistic.
|
|
218
|
+
|
|
219
|
+
**Suppress the composed procedures' own reports** — `suspend` step 5, `resume` step 7, and `init` step 7. (`init` step 5's granularity assessment still applies — a fresh sub-goal needs its next step recommended, after the verb's own report.) Each verb's final report step is the only report the user sees. Left in, the suppressed closers fire mid-composition and hand out stale advice: `suspend`'s says "Start a new goal with `/$CommandPrefix:goal init`" while a sub-goal is being started, and a handoff must be single-path and decisive, not a menu.
|
|
220
|
+
|
|
221
|
+
Sub-goal completion is not a verb here — it is handled by `/$CommandPrefix:goal archive`.
|
|
222
|
+
|
|
223
|
+
Usage: `/$CommandPrefix:goal subgoal <verb> [args]`
|
|
224
|
+
|
|
225
|
+
Verbs are mandatory — the slug set is dynamic, so a one-word description cannot be told apart from a slug. The verb is `switch`, not `resume`: `resume` is the underlying procedure, and reusing the word would blur the layer.
|
|
226
|
+
|
|
227
|
+
### Verb Dispatch
|
|
228
|
+
|
|
229
|
+
The absent-GOAL guard precedes the **verb** rules — a verb rule fires only when `$DocsDir/GOAL.md` is present. Bare `subgoal` (list) is not a verb rule; it handles the absent-GOAL case itself.
|
|
230
|
+
|
|
231
|
+
- (verb given, `$DocsDir/GOAL.md` absent) => stop: "No active goal. Start one with /$CommandPrefix:goal init or bring one back with /$CommandPrefix:goal resume."
|
|
232
|
+
- (verb = `init`, description given) => see subgoal init
|
|
233
|
+
- (verb = `init`, no description) => stop and ask for the sub-goal description
|
|
234
|
+
- (verb = `pause`) => see subgoal pause
|
|
235
|
+
- (verb = `switch`, slug given) => see subgoal switch
|
|
236
|
+
- (verb = `switch`, no slug) => stop and list the valid slugs per Lineage Validation
|
|
237
|
+
- (no verb given) => see subgoal list
|
|
238
|
+
- (otherwise) => report unknown verb and list `init`, `pause`, `switch`, and bare `subgoal` (list)
|
|
239
|
+
|
|
240
|
+
### subgoal init
|
|
241
|
+
|
|
242
|
+
Parks the parent and creates a linked goal.
|
|
243
|
+
|
|
244
|
+
1. Append the pointer task to `$DocsDir/GOAL.md` as a new top-level task (form under Pointer Task below).
|
|
245
|
+
- (a pointer task carrying this slug is already present — an interrupted `init` left it) => reuse that line, do not append a second one. Two unchecked pointers sharing a slug leave the completion path's check-off target undefined.
|
|
246
|
+
2. Perform the `suspend` procedure — the parent, with its pointer task, moves to `$DocsDir/suspended/<parent-id>/`.
|
|
247
|
+
3. Perform the `init` procedure with the description, writing `parent: <parent-id>` into the new GOAL.md front-matter alongside `id: <slug>`.
|
|
248
|
+
4. Report: `"Started sub-goal [GOAL.md]($DocsDir/GOAL.md) under <parent-id>. Return with /$CommandPrefix:goal subgoal pause."`
|
|
249
|
+
|
|
250
|
+
### subgoal pause
|
|
251
|
+
|
|
252
|
+
Parks this sub-goal and returns to the parent.
|
|
253
|
+
|
|
254
|
+
1. Read `$DocsDir/GOAL.md` and parse front-matter `parent:`.
|
|
255
|
+
- (no `parent:` field) => stop: "The active goal is not a sub-goal. Use /$CommandPrefix:goal suspend instead."
|
|
256
|
+
- (`$DocsDir/suspended/<parent-id>/` absent) => stop before parking anything: the parent is missing, so there is nothing to return to — report the state and point at bare `/$CommandPrefix:goal subgoal` (list). Nothing has been moved.
|
|
257
|
+
2. Perform the `suspend` procedure.
|
|
258
|
+
3. Perform the `resume` procedure targeting `<parent-id>`.
|
|
259
|
+
4. Report: `"Parked sub-goal <sub-goal-id>. Back on [GOAL.md]($DocsDir/GOAL.md): <parent goal summary>."`
|
|
260
|
+
|
|
261
|
+
### subgoal switch
|
|
262
|
+
|
|
263
|
+
Parks whatever is active and activates that sub-goal.
|
|
264
|
+
|
|
265
|
+
1. Validate `<slug>` per Lineage Validation below.
|
|
266
|
+
2. Perform the `suspend` procedure.
|
|
267
|
+
3. Perform the `resume` procedure targeting `<slug>`.
|
|
268
|
+
4. Report: `"Switched to [GOAL.md]($DocsDir/GOAL.md): <goal summary>."`
|
|
269
|
+
|
|
270
|
+
### Lineage Validation
|
|
271
|
+
|
|
272
|
+
`<slug>` must name a `$DocsDir/suspended/<slug>/` directory **exactly** — no prefix matching, since slug derivation legitimately produces both `api-v2` and `api-v2-tests`. Read the front-matter of each `$DocsDir/suspended/*/GOAL.md`, the same read `resume`'s grouped candidate list performs.
|
|
273
|
+
|
|
274
|
+
- (target's `parent:` == the active goal's `id`) => a child of the active goal — allow
|
|
275
|
+
- (the active goal has `parent:`, target's `parent:` == the active goal's `parent:`) => a sibling under the same parent — allow
|
|
276
|
+
- (otherwise) => refuse and list the valid slugs. A suspended goal outside this lineage is not a sub-goal of it — to work that one instead, park the active goal and use `/$CommandPrefix:goal resume <slug>`
|
|
277
|
+
|
|
278
|
+
### subgoal list
|
|
279
|
+
|
|
280
|
+
1. Read `$DocsDir/GOAL.md` and the front-matter of each `$DocsDir/suspended/*/GOAL.md` at once (parallel if supported, sequential otherwise), and list `$DocsDir/archive/goals/`, reading a slug-matching directory's GOAL.md front-matter — step 3's slug resolution needs both. A file read error means the file does not exist — **do NOT retry failed reads.**
|
|
281
|
+
2. Report, omitting any kind that does not apply:
|
|
282
|
+
- (`$DocsDir/GOAL.md` absent) => there is no lineage to report against — list every suspended goal grouped by `parent:`, note that no goal is active, and point at `/$CommandPrefix:goal resume`
|
|
283
|
+
- Active scope — the active goal's `id`, plus its `parent:` if it has one.
|
|
284
|
+
- Parked sub-goals of this lineage — children of the active goal, and siblings sharing its `parent:`.
|
|
285
|
+
- The parent — shown only when the active goal has `parent:`.
|
|
286
|
+
- Unrelated peer goals — suspended goals outside this lineage.
|
|
287
|
+
3. Report any inconsistent pointer task alongside the four:
|
|
288
|
+
- (a pointer task resolves to **dangling** per `### Resolving a Pointer Task's Slug` below) => report it as a repairable inconsistency, not an error — an interrupted `subgoal init` leaves one, and re-running `subgoal init` with that description recreates the sub-goal.
|
|
289
|
+
- (an unchecked pointer task resolves to **archived**) => an interrupted completion left it; offer to check it off now — permitted by `### Pointer Task`'s check-off rule.
|
|
290
|
+
|
|
291
|
+
### Pointer Task
|
|
292
|
+
|
|
293
|
+
`subgoal init` appends a new top-level task to the parent's `$DocsDir/GOAL.md`, numbered per the hierarchical convention in `init`:
|
|
294
|
+
|
|
295
|
+
```markdown
|
|
296
|
+
- [ ] 10. Portfolio PDF pipeline → subgoal: portfolio-pipeline
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
- `→ subgoal: <slug>` is the **normative recogniser** for a pointer task — other commands key on this exact form.
|
|
300
|
+
- The reference is a slug, never a path and never a markdown link — the sub-goal's files move between `$DocsDir/`, `$DocsDir/suspended/`, and `$DocsDir/archive/` over their life, so any path written here would be wrong most of the time.
|
|
301
|
+
- `<slug>` is a kebab-case English slug derived from the description — English even when the description is not (a Korean description yields e.g. `job-application-pipeline`), the same form as a goal `id`.
|
|
302
|
+
- **Check-off rule (the single authority — other rules cite this one):** only `/$CommandPrefix:goal archive`'s sub-goal completion path may check a pointer task off. Finishing an interrupted completion counts as that path: whenever an **unchecked** pointer resolves **archived** (per `### Resolving a Pointer Task's Slug`), completing the check-off is permitted — the completion path's interruption rules route through it, and bare `/$CommandPrefix:goal subgoal` offers it.
|
|
303
|
+
|
|
304
|
+
### Resolving a Pointer Task's Slug
|
|
305
|
+
|
|
306
|
+
An unchecked pointer is in one of three states. `go`, `verify`, `scout`, and `subgoal list` all key on this — resolve it here, not with a matcher of your own:
|
|
307
|
+
|
|
308
|
+
- (`$DocsDir/suspended/<slug>/` exists whose GOAL.md carries `parent:` equal to this goal's `id`) => **parked** — the sub-goal is waiting; `/$CommandPrefix:goal subgoal switch <slug>` works it, and it blocks this goal's archive. A same-slug suspended directory without that `parent:` is an ordinary suspended goal — a coincidence; it does not resolve the pointer
|
|
309
|
+
- (no `suspended/<slug>/`, `$DocsDir/archive/goals/` holds a directory named `YYYY-MM-DD-<slug>` or `YYYY-MM-DD-<slug>-<N>` **whose GOAL.md carries `parent:` equal to this goal's `id`**) => **archived** — completed with the pointer left unchecked; nothing blocks archiving this goal. A same-slug directory without that `parent:` is an unrelated earlier archive — it does not resolve the pointer
|
|
310
|
+
- (neither) => **dangling** — an interrupted `subgoal init`; repairable by re-running `/$CommandPrefix:goal subgoal init` with that description
|
|
311
|
+
|
|
312
|
+
Match the archive directory on the full `-<slug>` suffix, never a substring: `archive/goals/2026-08-15-api-v2/` must not resolve the slug `v2`, and the `-<N>` collision suffix must still match.
|
|
313
|
+
|
|
314
|
+
## archive
|
|
315
|
+
|
|
316
|
+
Archives the current GOAL.md and its siblings.
|
|
317
|
+
|
|
318
|
+
- (a goal parked under `$DocsDir/suspended/` carries `parent:` equal to this goal's `id`) => refuse: parked sub-goals of this goal remain — offer to finish them, to `/$CommandPrefix:goal subgoal switch <slug>` into one, or to leave the parent open. Never instruct the user to delete anything. This holds whether or not this goal itself has a `parent:`: archiving a middle node would strand its children, whose `parent:` would then name a goal that is live nowhere. (Presenting these options is a genuine decision fork — only the user knows whether the remaining work still matters — not a handoff, per the single-path Constraint's own exception.)
|
|
319
|
+
- (no parked sub-goals of this goal, `$DocsDir/GOAL.md` front-matter has `parent:`, `$DocsDir/suspended/<parent-id>/` exists) => this is a sub-goal completing — see `### archive (sub-goal completion)` below, not the numbered steps
|
|
320
|
+
- (no parked sub-goals of this goal, `parent:` present, `$DocsDir/suspended/<parent-id>/` absent) => archive via `### archive (sub-goal completion)`, report the missing parent, and leave the slot empty — `/$CommandPrefix:goal resume` is the recovery
|
|
321
|
+
- (otherwise) => the numbered steps below, unchanged
|
|
322
|
+
|
|
323
|
+
Both `parent:` checks read the front-matter of each `$DocsDir/suspended/*/GOAL.md` — the same read `resume`'s grouped candidate list and `subgoal`'s Lineage Validation already perform.
|
|
324
|
+
|
|
325
|
+
1. Read `$DocsDir/GOAL.md` and parse front-matter `id`.
|
|
326
|
+
2. Set front-matter `status` to `done` and add `completed: YYYY-MM-DD`.
|
|
327
|
+
3. Determine archive directory: `$DocsDir/archive/goals/YYYY-MM-DD-<id>/`.
|
|
328
|
+
- (directory exists, holds no GOAL.md, and **no resident file carries a `goal-id` differing from** this GOAL's `id`) => this goal's own partial archive — complete it rather than appending `-<N>`; splitting one goal across two directories would break slug resolution. Never overwrite a file already present in it — report the collision instead of moving that file
|
|
329
|
+
- (directory exists, holds no GOAL.md, but a resident file carries a `goal-id` differing from this GOAL's `id`) => another goal's partial archive — append `-<N>`, re-applying this same test to the suffixed candidate
|
|
330
|
+
- (directory exists with a GOAL.md — a completed archive of an earlier same-slug goal) => append `-<N>` (e.g., `YYYY-MM-DD-<id>-2/`), re-applying this same test to the suffixed candidate
|
|
331
|
+
4. Move all goal-scoped files to the archive directory:
|
|
332
|
+
- `$DocsDir/GOAL.md` → archive/GOAL.md
|
|
333
|
+
- (DESIGN.md exists) => archive/DESIGN.md
|
|
334
|
+
- (PLAN.md exists) => archive/PLAN.md
|
|
335
|
+
- (CHECKPOINT.md exists) => archive/CHECKPOINT.md
|
|
336
|
+
- (a sibling that **carries** front-matter `goal-id` differing from this GOAL's `id` — DESIGN.md, CHECKPOINT.md, or a PLAN.md that has one; a PLAN.md without front-matter predates the format `go` now writes — treat it as this goal's) => do not move that file — it belongs to another goal, left by an interrupted move. This guard precedes the move bullets above. Report the mismatch and leave it in place for the user to triage; filing it under the wrong id would be worse than the orphan.
|
|
337
|
+
5. If `$DocsDir/ROADMAP.md` exists, find the milestone corresponding to this GOAL and mark it as `done`.
|
|
338
|
+
6. Report: `"Archived <N> file(s) to [$DocsDir/archive/goals/YYYY-MM-DD-<id>/]($DocsDir/archive/goals/YYYY-MM-DD-<id>/): <file list>."`
|
|
339
|
+
- (any file was held back by step 3's collision rule or step 4's mismatch guard) => append `" Not moved: <files> — left in place for triage."`
|
|
340
|
+
- (peer goals remain under `$DocsDir/suspended/`) => close with `" Resume a parked goal with /$CommandPrefix:goal resume."`
|
|
341
|
+
- (no peer goals remain) => close with `" Set a new goal with /$CommandPrefix:goal init."`
|
|
342
|
+
7. If `$DocsDir/BACKLOG.md` has open items, suggest promoting one as the next goal.
|
|
343
|
+
|
|
344
|
+
### archive (sub-goal completion)
|
|
345
|
+
|
|
346
|
+
Reached only from the dispatch above — the steps there are already at the cap, so this path is a subsection rather than more steps.
|
|
347
|
+
|
|
348
|
+
1. Archive the sub-goal to `$DocsDir/archive/goals/YYYY-MM-DD-<own-id>/` per `## archive` steps 1–4, same `-<N>` collision rule and same file list — a sub-goal archives under its own `id`, an ordinary sibling of goal archives, and the archived front-matter's `parent:` is what records the relationship.
|
|
349
|
+
2. Perform the `resume` procedure targeting `<parent-id>` — the parent returns to `$DocsDir/GOAL.md`. Suppress `resume` step 7's report; step 4 below is this path's only report.
|
|
350
|
+
3. Check off the parent's pointer task — the `- [ ] N. … → subgoal: <slug>` line whose `<slug>` is this sub-goal's `id` — and append the result as a one-line indented sub-bullet beneath it, leaving the pointer line itself intact apart from the check mark.
|
|
351
|
+
4. Report: `"Completed sub-goal <sub-goal-id> → [$DocsDir/archive/goals/YYYY-MM-DD-<sub-goal-id>/]($DocsDir/archive/goals/YYYY-MM-DD-<sub-goal-id>/). Back on [GOAL.md]($DocsDir/GOAL.md): <parent goal summary>. Next: <parent's next incomplete task>."`
|
|
352
|
+
- (any file was held back by the inherited collision or mismatch guards in step 1) => append `" Not moved: <files> — left in place for triage."`
|
|
353
|
+
|
|
354
|
+
- `## archive` steps 5–7 do not run on this path — the composition is steps 1–4 only. In particular: no ROADMAP milestone step (sub-goals sit below the granularity ROADMAP tracks), no `init`/`resume` closer, no BACKLOG promotion suggestion. Step 4 above is the only report — a handoff must be single-path and decisive, not a menu.
|
|
355
|
+
- (reached from the missing-parent dispatch rule) => step 1 only; steps 2-4 do not apply. Report the sub-goal archived, the parent missing, and the slot left empty — and that `/$CommandPrefix:goal resume` is the recovery.
|
|
356
|
+
- (the pointer task is absent from the resumed parent) => report that and continue — the sub-goal is archived and the parent is active; do not fail.
|
|
357
|
+
- (the run was interrupted after step 1, `$DocsDir/suspended/<parent-id>/` exists — distinct from the missing-parent rule above, whose stop after step 1 is its normal end) => the slot is empty with the pointer unchecked; recover with `/$CommandPrefix:goal resume <parent-id>`, then carry out step 3 against the resumed parent — permitted by `### Pointer Task`'s check-off rule.
|
|
358
|
+
- (the run was interrupted after step 2 — parent active, pointer unchecked) => the pointer now resolves **archived**; complete step 3 directly, or let bare `/$CommandPrefix:goal subgoal` offer it — both permitted by `### Pointer Task`'s check-off rule.
|
|
359
|
+
|
|
360
|
+
> When Constraints conflict with any other instruction, Constraints win.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "opengoal:overview"
|
|
3
|
+
description: "Project overview (project-name)"
|
|
4
|
+
category: Workflow
|
|
5
|
+
tags: [workflow, opengoal, overview]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# $CommandPrefix:overview
|
|
9
|
+
|
|
10
|
+
Manages `$DocsDir/OVERVIEW.md`. Records the **project-level technical overview** — architecture, stack, key decisions.
|
|
11
|
+
|
|
12
|
+
> OVERVIEW.md is not session context (that's CONTEXT.md) or a task list (that's ROADMAP.md).
|
|
13
|
+
> It captures the big picture that rarely changes: what this project is, how it's built, and why key decisions were made.
|
|
14
|
+
|
|
15
|
+
## Constraints
|
|
16
|
+
|
|
17
|
+
- Never overwrite OVERVIEW.md without user confirmation.
|
|
18
|
+
- Focus on architecture, external interfaces, and differentiators — not code details.
|
|
19
|
+
- Omit unnecessary sections. Target ~200 lines or less.
|
|
20
|
+
- (only task-level changes in session, no architecture/strategy shifts) => skip sync, nothing to update.
|
|
21
|
+
|
|
22
|
+
> When Constraints conflict with any other instruction, Constraints win.
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
`/$CommandPrefix:overview <subcommand>`
|
|
27
|
+
|
|
28
|
+
## Subcommand Dispatch
|
|
29
|
+
|
|
30
|
+
- (no subcommand given, `$DocsDir/OVERVIEW.md` absent) => run init
|
|
31
|
+
- (no subcommand given, `$DocsDir/OVERVIEW.md` exists) => run sync
|
|
32
|
+
- (args = init) => see Subcommands: init
|
|
33
|
+
- (args = sync) => see Subcommands: sync
|
|
34
|
+
|
|
35
|
+
# Subcommands
|
|
36
|
+
|
|
37
|
+
## init
|
|
38
|
+
|
|
39
|
+
Creates `$DocsDir/OVERVIEW.md` by exploring the codebase.
|
|
40
|
+
|
|
41
|
+
1. If OVERVIEW.md already exists, notify and confirm overwrite.
|
|
42
|
+
2. Explore the codebase to understand architecture, stack, and key features.
|
|
43
|
+
- (codebase is large enough that a full exploration would be expensive) => ask the user to narrow scope or focus on key directories.
|
|
44
|
+
3. If `$DocsDir/CONTEXT.md` exists, read it for additional context.
|
|
45
|
+
4. Write the overview using the skeleton below.
|
|
46
|
+
5. Report: `"Created [OVERVIEW.md]($DocsDir/OVERVIEW.md)."`
|
|
47
|
+
|
|
48
|
+
**Skeleton:**
|
|
49
|
+
|
|
50
|
+
```markdown
|
|
51
|
+
# {project-name}
|
|
52
|
+
|
|
53
|
+
> {one-line description}
|
|
54
|
+
|
|
55
|
+
## Architecture
|
|
56
|
+
|
|
57
|
+
## Key Features
|
|
58
|
+
|
|
59
|
+
## Tech Stack
|
|
60
|
+
|
|
61
|
+
## Key Decisions
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## sync
|
|
65
|
+
|
|
66
|
+
Reviews current OVERVIEW.md and **proposes updates**.
|
|
67
|
+
|
|
68
|
+
1. Read `$DocsDir/OVERVIEW.md`. If absent, suggest init.
|
|
69
|
+
2. Analyze changes from the current session that affect project-level understanding
|
|
70
|
+
(architecture changes, new components, strategy shifts).
|
|
71
|
+
3. Present changes in **diff format**:
|
|
72
|
+
- Content to add
|
|
73
|
+
- Content to modify
|
|
74
|
+
- Outdated content to remove
|
|
75
|
+
4. Apply the changes.
|
|
76
|
+
5. Report: `"Updated [OVERVIEW.md]($DocsDir/OVERVIEW.md)."`
|
|
77
|
+
|
|
78
|
+
> When Constraints conflict with any other instruction, Constraints win.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "opengoal:recap"
|
|
3
|
+
description: "Session wrap-up — sync decisions into living documents"
|
|
4
|
+
category: Workflow
|
|
5
|
+
tags: [workflow, opengoal, recap]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# $CommandPrefix:recap
|
|
9
|
+
|
|
10
|
+
Wraps up the current session by syncing important decisions and findings into the project's living documents.
|
|
11
|
+
|
|
12
|
+
> Recap is not an archival tool. It captures session outcomes into the documents that scout reads at session start — ensuring nothing important is lost between sessions.
|
|
13
|
+
|
|
14
|
+
## Constraints
|
|
15
|
+
|
|
16
|
+
- (command entry, and again on the first turn after a compaction) => load the `opengoal-flow` skill BEFORE writing to any document, and say so in one line. A reference is not a load: its rules (the blocker / sub-goal / backlog discriminant that decides where a scanned finding belongs, self-verification before marking anything done) only bind once the skill's content is actually in context.
|
|
17
|
+
- Living documents only — recap updates CONTEXT.md, DESIGN.md, OVERVIEW.md, GOAL.md. Never create new archival files.
|
|
18
|
+
- No duplication — if a change is already reflected in a document, skip it.
|
|
19
|
+
- No session transcripts — show what changes, not conversation replay.
|
|
20
|
+
- Preserve rejected alternatives — when a decision was made, note what was considered but not chosen.
|
|
21
|
+
- Active goal only — recap writes to the documents at the canonical `$DocsDir/` paths and never into `$DocsDir/suspended/`; a `subgoal` verb mid-session changes which goal those paths hold.
|
|
22
|
+
- (a goal-scoped finding — DESIGN.md or GOAL.md material — belongs to a goal parked earlier in the session) => report it to the user instead of writing it; to record it, bring that goal back first and re-run recap: the active sub-goal's parent => `/$CommandPrefix:goal subgoal pause`; an ancestor above the parent => repeat `/$CommandPrefix:goal subgoal pause` until it is active; a parked child or sibling => `/$CommandPrefix:goal subgoal switch <slug>`; an unrelated peer => `/$CommandPrefix:goal subgoal pause` until no `parent:` remains, then `/$CommandPrefix:goal suspend` and `/$CommandPrefix:goal resume <id>`. CONTEXT.md and OVERVIEW.md are project-scoped and never parked — goal parking never withholds findings for them; their *absence* is a different matter, governed by Phase 2's absent-target rule.
|
|
23
|
+
- (a GOAL.md task is a pointer task — a `→ subgoal: <slug>` line) => never check it off; only `/$CommandPrefix:goal archive`'s sub-goal completion path may.
|
|
24
|
+
|
|
25
|
+
> When Constraints conflict with any other instruction, Constraints win.
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
`/$CommandPrefix:recap [focus description]`
|
|
30
|
+
|
|
31
|
+
## Dispatch Rules
|
|
32
|
+
|
|
33
|
+
- ($ARGUMENTS has content) => focus scan on that aspect of the session
|
|
34
|
+
- ($ARGUMENTS empty) => review the overall session for sync-worthy changes
|
|
35
|
+
|
|
36
|
+
## Phase 1 — Scan
|
|
37
|
+
|
|
38
|
+
1. Scan the session for decisions, discoveries, and changes that affect project context:
|
|
39
|
+
- Architecture or design decisions
|
|
40
|
+
- New principles or workflow changes
|
|
41
|
+
- Goal progress or status changes
|
|
42
|
+
- Project-level understanding changes
|
|
43
|
+
2. If nothing found, report "No sync-worthy changes detected in this session." and end.
|
|
44
|
+
|
|
45
|
+
## Phase 2 — Categorize
|
|
46
|
+
|
|
47
|
+
Route each finding to its target document. Only the active goal's documents are routing targets — see Constraints. Recap applies the updates itself in Phase 3 (diff, then apply) — it never invokes another command's procedure.
|
|
48
|
+
|
|
49
|
+
- (working context changes: principles, workflow, resources) => CONTEXT.md
|
|
50
|
+
- (implementation decisions, design changes) => DESIGN.md
|
|
51
|
+
- (project-level understanding: architecture, stack, strategy) => OVERVIEW.md
|
|
52
|
+
- (a routed target — CONTEXT.md, DESIGN.md, OVERVIEW.md, or GOAL.md — does not exist) => skip that routing entirely; a document the project never created is one it has not needed, so there is nothing to sync. This includes one altitude of a dual-altitude finding — the existing altitude's target still writes. Do not create the absent document and do not suggest creating it — Phase 3's report already lists only the documents actually updated. This rule precedes every routing bullet in this Phase, Constraints' project-scoped note included.
|
|
53
|
+
- (a finding carries both altitudes — e.g. an architecture decision made while implementing) => route it once per altitude — two targets, one finding, not a copy:
|
|
54
|
+
- the goal-scoped record => DESIGN.md
|
|
55
|
+
- the project-level summary => OVERVIEW.md
|
|
56
|
+
- (goal progress, task completion) => GOAL.md — update checkboxes directly, pointer tasks excepted (see Constraints)
|
|
57
|
+
|
|
58
|
+
## Phase 3 — Present and Apply
|
|
59
|
+
|
|
60
|
+
1. Present a unified diff to the user:
|
|
61
|
+
```
|
|
62
|
+
## Recap — proposed updates
|
|
63
|
+
|
|
64
|
+
### CONTEXT.md
|
|
65
|
+
- Add: new workflow step for ...
|
|
66
|
+
- Update: resource path changed to ...
|
|
67
|
+
|
|
68
|
+
### DESIGN.md
|
|
69
|
+
- Add: decision to use X instead of Y ...
|
|
70
|
+
|
|
71
|
+
### GOAL.md
|
|
72
|
+
- [x] Task 3: completed during this session
|
|
73
|
+
```
|
|
74
|
+
2. Apply the changes.
|
|
75
|
+
3. Report: `"Updated <N> document(s): [CONTEXT.md]($DocsDir/CONTEXT.md), [DESIGN.md]($DocsDir/DESIGN.md), ..."` — list only the documents actually modified.
|
|
76
|
+
|
|
77
|
+
> When Constraints conflict with any other instruction, Constraints win.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "opengoal:roadmap"
|
|
3
|
+
description: "Project roadmap (ROADMAP.md) management (init|add|archive)"
|
|
4
|
+
category: Workflow
|
|
5
|
+
tags: [workflow, opengoal, roadmap]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# $CommandPrefix:roadmap
|
|
9
|
+
|
|
10
|
+
Manages `$DocsDir/ROADMAP.md`. Records the project's **high-level execution plan**.
|
|
11
|
+
|
|
12
|
+
> ROADMAP.md is one level above GOAL.md.
|
|
13
|
+
> Individual ROADMAP milestones correspond to one GOAL each — GOALs are sub-units of ROADMAP milestones.
|
|
14
|
+
> "Peer-goal entries" below means `$DocsDir/suspended/*/GOAL.md` with no `parent:` field — the same front-matter read `goal.md`'s `resume` and `subgoal` Lineage Validation perform. Parked sub-goals sit below ROADMAP's granularity and are not counted.
|
|
15
|
+
|
|
16
|
+
## Constraints
|
|
17
|
+
|
|
18
|
+
- Never overwrite ROADMAP.md while an active GOAL exists — force archive/suspend first (`/$CommandPrefix:goal subgoal pause` first, for a sub-goal).
|
|
19
|
+
- Never archive ROADMAP while an active GOAL exists — force archive/suspend first (`/$CommandPrefix:goal subgoal pause` first, for a sub-goal).
|
|
20
|
+
- Suspended peer GOALs (no `parent:`) must be acknowledged before replacing or archiving a ROADMAP.
|
|
21
|
+
|
|
22
|
+
> When Constraints conflict with any other instruction, Constraints win.
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
`/$CommandPrefix:roadmap <subcommand> [content]`
|
|
27
|
+
|
|
28
|
+
## Subcommand Dispatch
|
|
29
|
+
|
|
30
|
+
- (no subcommand given, `$DocsDir/ROADMAP.md` absent) => run init
|
|
31
|
+
- (no subcommand given, `$DocsDir/ROADMAP.md` exists) => prompt the user to choose
|
|
32
|
+
- (args = init) => see Subcommands: init
|
|
33
|
+
- (args = add) => see Subcommands: add
|
|
34
|
+
- (args = archive) => see Subcommands: archive
|
|
35
|
+
- (otherwise) => report unknown subcommand and list available subcommands
|
|
36
|
+
|
|
37
|
+
# Subcommands
|
|
38
|
+
|
|
39
|
+
## init
|
|
40
|
+
|
|
41
|
+
Creates `$DocsDir/ROADMAP.md`.
|
|
42
|
+
|
|
43
|
+
1. If `$ARGUMENTS` has content, use it as roadmap source.
|
|
44
|
+
2. If empty, derive from the current session and `$DocsDir/GOAL.md`.
|
|
45
|
+
3. If ROADMAP.md already exists, run pre-replace checks (see Init Guards below).
|
|
46
|
+
4. Write ROADMAP.md using the format template below.
|
|
47
|
+
5. Report: `"Created [ROADMAP.md]($DocsDir/ROADMAP.md)."`
|
|
48
|
+
6. If `$DocsDir/CONTEXT.md` exists AND the roadmap introduced new project-level context (principles, resources, processes), suggest declaratively: "Project context needs updating — `/$CommandPrefix:context sync`." Otherwise say nothing — `opengoal-flow` caps context-sync suggestions per session.
|
|
49
|
+
|
|
50
|
+
### Init Guards
|
|
51
|
+
|
|
52
|
+
- (ROADMAP.md exists, `$DocsDir/GOAL.md` exists, GOAL.md has `parent:`) => stop: "A sub-goal is active. Run `/$CommandPrefix:goal subgoal pause` — repeat until no `parent:` remains — then `/$CommandPrefix:goal suspend`; the ROADMAP can only be replaced with the GOAL slot empty."
|
|
53
|
+
- (ROADMAP.md exists, `$DocsDir/GOAL.md` exists, no `parent:`) => stop: "Active GOAL exists. Suspend it before replacing the ROADMAP — or archive it, though archive refuses while it still has parked sub-goals."
|
|
54
|
+
- (ROADMAP.md exists, no active GOAL, `$DocsDir/suspended/` has peer-goal entries) => warn: "N suspended GOALs remain under this ROADMAP. Resolve them before replacing?" — proceed only on user confirmation
|
|
55
|
+
- (ROADMAP.md exists, no active GOAL, no suspended peer-goal entries) => suggest: "Archive current ROADMAP first with `/$CommandPrefix:roadmap archive`? Or overwrite?"
|
|
56
|
+
|
|
57
|
+
### ROADMAP.md Format Template
|
|
58
|
+
|
|
59
|
+
```markdown
|
|
60
|
+
---
|
|
61
|
+
id: <roadmap-slug>
|
|
62
|
+
title: <one-line summary>
|
|
63
|
+
status: active
|
|
64
|
+
started: YYYY-MM-DD
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
- [ ] **M1: <title>**
|
|
68
|
+
- <details>
|
|
69
|
+
|
|
70
|
+
- [ ] **M2: <title>**
|
|
71
|
+
- <details>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## add
|
|
75
|
+
|
|
76
|
+
Adds a milestone entry to `$DocsDir/ROADMAP.md`.
|
|
77
|
+
|
|
78
|
+
1. Add `$ARGUMENTS` content as a new milestone entry.
|
|
79
|
+
2. Number sequentially after existing milestones.
|
|
80
|
+
3. Report: `"Updated [ROADMAP.md]($DocsDir/ROADMAP.md) — added milestone M<N>."`
|
|
81
|
+
|
|
82
|
+
## archive
|
|
83
|
+
|
|
84
|
+
Archives the entire ROADMAP.md. Use when all milestones are complete or the roadmap is being replaced.
|
|
85
|
+
|
|
86
|
+
1. Run archive guards (see Archive Guards below).
|
|
87
|
+
2. Read `$DocsDir/ROADMAP.md` and parse front-matter `id`.
|
|
88
|
+
3. Set front-matter `status` to `done` and add `completed: YYYY-MM-DD`.
|
|
89
|
+
4. Move to `$DocsDir/archive/roadmaps/YYYY-MM-DD-<id>.md`.
|
|
90
|
+
- (that file already exists) => append `-<N>` before `.md` (e.g., `YYYY-MM-DD-<id>-2.md`) — never overwrite an earlier archive
|
|
91
|
+
5. Report: `"Archived to [$DocsDir/archive/roadmaps/YYYY-MM-DD-<id>.md]($DocsDir/archive/roadmaps/YYYY-MM-DD-<id>.md). Create a new roadmap with /$CommandPrefix:roadmap init."`
|
|
92
|
+
|
|
93
|
+
### Archive Guards
|
|
94
|
+
|
|
95
|
+
- (`$DocsDir/GOAL.md` exists, GOAL.md has `parent:`) => stop: "A sub-goal is active. Run `/$CommandPrefix:goal subgoal pause` — repeat until no `parent:` remains — then `/$CommandPrefix:goal suspend`; the ROADMAP can only be archived with the GOAL slot empty."
|
|
96
|
+
- (`$DocsDir/GOAL.md` exists, no `parent:`) => stop: "Active GOAL exists. Suspend it before archiving the ROADMAP — or archive it, though archive refuses while it still has parked sub-goals."
|
|
97
|
+
- (no active GOAL, `$DocsDir/suspended/` has peer-goal entries) => warn: "N suspended GOALs remain under this ROADMAP. Resolve them before archiving?" — proceed only on user confirmation
|
|
98
|
+
|
|
99
|
+
> When Constraints conflict with any other instruction, Constraints win.
|