goalbuddy 0.3.6 → 0.3.7
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/README.md +17 -8
- package/RELEASE-0.3.5.md +4 -4
- package/RELEASE-0.3.7.md +127 -0
- package/goalbuddy/SKILL.md +19 -10
- package/goalbuddy/scripts/check-goal-state.mjs +53 -0
- package/goalbuddy/scripts/render-task-prompt.mjs +22 -1
- package/{plugins/goalbuddy/skills/goalbuddy/extend → goalbuddy/surfaces}/local-goal-board/README.md +7 -9
- package/{plugins/goalbuddy/skills/goalbuddy/extend → goalbuddy/surfaces}/local-goal-board/examples/sample-goal/state.yaml +5 -5
- package/{plugins/goalbuddy/skills/goalbuddy/extend → goalbuddy/surfaces}/local-goal-board/examples/subgoal-parent/state.yaml +3 -3
- package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/state.yaml +3 -3
- package/goalbuddy/{extend → surfaces}/local-goal-board/scripts/lib/goal-board.mjs +2 -2
- package/goalbuddy/{extend → surfaces}/local-goal-board/scripts/local-goal-board.mjs +4 -4
- package/goalbuddy/{extend → surfaces}/local-goal-board/test/local-goal-board.test.mjs +8 -8
- package/goalbuddy/templates/goal.md +9 -0
- package/goalbuddy/templates/state.yaml +7 -6
- package/internal/assets/goalbuddy-v0.3.7-release.png +0 -0
- package/internal/cli/goal-maker.mjs +9 -711
- package/package.json +4 -4
- package/plugins/goalbuddy/.claude-plugin/plugin.json +3 -4
- package/plugins/goalbuddy/.codex-plugin/plugin.json +5 -6
- package/plugins/goalbuddy/README.md +4 -3
- package/plugins/goalbuddy/skills/goalbuddy/SKILL.md +19 -10
- package/plugins/goalbuddy/skills/goalbuddy/scripts/check-goal-state.mjs +53 -0
- package/plugins/goalbuddy/skills/goalbuddy/scripts/render-task-prompt.mjs +22 -1
- package/{goalbuddy/extend → plugins/goalbuddy/skills/goalbuddy/surfaces}/local-goal-board/README.md +7 -9
- package/{goalbuddy/extend → plugins/goalbuddy/skills/goalbuddy/surfaces}/local-goal-board/examples/sample-goal/state.yaml +5 -5
- package/{goalbuddy/extend → plugins/goalbuddy/skills/goalbuddy/surfaces}/local-goal-board/examples/subgoal-parent/state.yaml +3 -3
- package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/state.yaml +3 -3
- package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/scripts/lib/goal-board.mjs +2 -2
- package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/scripts/local-goal-board.mjs +4 -4
- package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/test/local-goal-board.test.mjs +8 -8
- package/plugins/goalbuddy/skills/goalbuddy/templates/goal.md +9 -0
- package/plugins/goalbuddy/skills/goalbuddy/templates/state.yaml +7 -6
- package/examples/extend-catalog-workflow/goal.md +0 -53
- package/examples/extend-catalog-workflow/notes/T001-extension-model-map.md +0 -47
- package/examples/extend-catalog-workflow/notes/T002-architecture-decision.md +0 -48
- package/examples/extend-catalog-workflow/notes/T003-implementation-summary.md +0 -43
- package/examples/extend-catalog-workflow/notes/T004-root-extend-folder.md +0 -24
- package/examples/extend-catalog-workflow/notes/T005-layout-cleanup.md +0 -46
- package/examples/extend-catalog-workflow/notes/T006-catalog-location.md +0 -50
- package/examples/extend-catalog-workflow/notes/T999-completion-audit.md +0 -36
- package/examples/extend-catalog-workflow/state.yaml +0 -327
- package/examples/github-pr-workflow-extension/pr-handoff.md +0 -46
- package/goalbuddy/extend/github-projects/README.md +0 -105
- package/goalbuddy/extend/github-projects/examples/goal-board-sync/state.yaml +0 -63
- package/goalbuddy/extend/github-projects/extension.yaml +0 -43
- package/goalbuddy/extend/github-projects/scripts/lib/github-projects.mjs +0 -728
- package/goalbuddy/extend/github-projects/scripts/lib/goal-state.mjs +0 -362
- package/goalbuddy/extend/github-projects/scripts/sync-github-project.mjs +0 -193
- package/goalbuddy/extend/github-projects/test/github-projects.test.mjs +0 -267
- package/goalbuddy/extend/local-goal-board/extension.yaml +0 -39
- package/internal/assets/extend-release.png +0 -0
- package/internal/assets/extend-release.svg +0 -83
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/README.md +0 -105
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/examples/goal-board-sync/state.yaml +0 -63
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/extension.yaml +0 -43
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/scripts/lib/github-projects.mjs +0 -728
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/scripts/lib/goal-state.mjs +0 -362
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/scripts/sync-github-project.mjs +0 -193
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/test/github-projects.test.mjs +0 -267
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/extension.yaml +0 -39
- /package/goalbuddy/{extend → surfaces}/local-goal-board/assets/goalbuddy-mark.png +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/sample-goal/notes/T001-scout.md +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/goal.md +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/notes/.gitkeep +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/goal.md +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/notes/.gitkeep +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/assets/goalbuddy-mark.png +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/sample-goal/notes/T001-scout.md +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/goal.md +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/notes/.gitkeep +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/goal.md +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/notes/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
<a href="https://goalbuddy.dev"><img alt="goalbuddy.dev" src="https://img.shields.io/badge/site-goalbuddy.dev-684cff?style=flat-square"></a>
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
|
-
GoalBuddy helps Codex and Claude Code stay oriented during long coding tasks
|
|
19
|
+
GoalBuddy helps Codex and Claude Code stay oriented during long coding tasks by giving native `/goal` a finish line, a live work surface, and a proof loop.
|
|
20
20
|
|
|
21
|
-
It gives `/goal` a small local workspace: a charter, a board, notes, receipts, and a clear next task. The work stays in your repo, so a run can pause, resume, verify, and keep going without re-inventing the plan every turn.
|
|
21
|
+
It gives `/goal` a small local workspace: a charter, a goal oracle, a board, notes, receipts, and a clear next task. The work stays in your repo, so a run can pause, resume, verify, and keep going without re-inventing the plan every turn.
|
|
22
22
|
|
|
23
23
|
## Start Here
|
|
24
24
|
|
|
@@ -70,6 +70,7 @@ docs/goals/<your-goal>/
|
|
|
70
70
|
goal.md
|
|
71
71
|
state.yaml
|
|
72
72
|
notes/
|
|
73
|
+
.goalbuddy-board/ # generated local board files
|
|
73
74
|
subgoals/ # optional depth-1 child boards
|
|
74
75
|
```
|
|
75
76
|
|
|
@@ -84,16 +85,22 @@ docs/goals/<your-goal>/
|
|
|
84
85
|
## How It Thinks
|
|
85
86
|
|
|
86
87
|
```text
|
|
87
|
-
|
|
88
|
+
Intent -> Oracle -> Surface -> Loop -> Proof
|
|
88
89
|
```
|
|
89
90
|
|
|
91
|
+
The oracle is the observable signal that says whether the original owner outcome is actually true: a test suite, browser walkthrough, demo transcript, generated artifact, benchmark, source-backed answer, release check, or final human decision.
|
|
92
|
+
|
|
93
|
+
No oracle, no serious goal.
|
|
94
|
+
|
|
95
|
+
The local board is the default work surface. It is not an extension marketplace; it is the built-in view of the `state.yaml` truth.
|
|
96
|
+
|
|
90
97
|
Scout maps the repo.
|
|
91
98
|
|
|
92
99
|
Judge chooses the largest safe useful slice.
|
|
93
100
|
|
|
94
101
|
Worker completes the whole assigned slice and leaves a receipt.
|
|
95
102
|
|
|
96
|
-
`/goal` keeps the loop honest until the
|
|
103
|
+
`/goal` keeps the loop honest until a final Judge/PM audit maps receipts and verification back to the oracle and records the full outcome complete.
|
|
97
104
|
|
|
98
105
|
## Slice Sizing
|
|
99
106
|
|
|
@@ -101,7 +108,7 @@ Safe does not mean small. Safe means bounded, explicit, verified, and reversible
|
|
|
101
108
|
|
|
102
109
|
GoalBuddy should not optimize for tiny safe tasks. It should optimize for the largest safe useful slice: a working screen, working API path, data pipeline step, backend vertical slice, real bug fix, or milestone review. The board warns when it sees safe-looking work that keeps adding helpers, contracts, proof files, or doc notes without moving the outcome.
|
|
103
110
|
|
|
104
|
-
##
|
|
111
|
+
## Goalmaxxed
|
|
105
112
|
|
|
106
113
|
GoalBuddy keeps the model small:
|
|
107
114
|
|
|
@@ -115,7 +122,7 @@ Use subgoals for bounded child work that belongs to a parent task. Use multiple
|
|
|
115
122
|
|
|
116
123
|
## Execution Quality
|
|
117
124
|
|
|
118
|
-
GoalBuddy can prepare safe parallel work; it does not run a parallel org chart.
|
|
125
|
+
GoalBuddy can prepare safe parallel work; it does not run a parallel org chart or install arbitrary extension packs.
|
|
119
126
|
|
|
120
127
|
Use `goalbuddy prompt docs/goals/<slug>` to render a compact prompt for the active task without dumping the whole state file. The prompt includes a mandatory `required_spawn_agent_type`; Codex PMs should use that exact GoalBuddy agent (`goal_scout`, `goal_worker`, or `goal_judge`) instead of a generic role agent. Use `goalbuddy parallel-plan docs/goals/<slug>` to inspect read-only or disjoint write-scope work that can be handed to native Codex or Claude Code agent flows. The command reports recommendations only; it does not mutate state or spawn agents.
|
|
121
128
|
|
|
@@ -131,11 +138,13 @@ That updates both Codex and Claude Code.
|
|
|
131
138
|
|
|
132
139
|
## Live Boards
|
|
133
140
|
|
|
134
|
-
GoalBuddy
|
|
141
|
+
GoalBuddy opens a local board while the work is running, so you can see the plan, active task, receipts, subgoals, and verification status without digging through the chat.
|
|
135
142
|
|
|
136
143
|
Multiple local boards reuse one readable `goalbuddy.localhost` hub with an in-header board switcher. When sharing a board in chat or docs, use a real Markdown link such as `[Open GoalBuddy board](http://goalbuddy.localhost:41737/<slug>/)` so the URL is clickable. The viewer also supports dark mode, compact mode, completed-task collapse, active-work motion, and reduced-motion handling.
|
|
137
144
|
|
|
138
|
-
|
|
145
|
+
Custom external integrations should be built as ordinary repo work with a concrete implementation plan, not installed from a GoalBuddy catalog.
|
|
146
|
+
|
|
147
|
+
See [GoalBuddy 0.3.7: Goalmaxxed](RELEASE-0.3.7.md) for the latest release notes.
|
|
139
148
|
|
|
140
149
|
<p align="center">
|
|
141
150
|
<img src="internal/assets/goalbuddy-live-board.jpg" alt="GoalBuddy local live board open next to Codex while Scout, Judge, and Worker tasks populate." width="100%">
|
package/RELEASE-0.3.5.md
CHANGED
|
@@ -256,8 +256,8 @@ The board renderer also fails closed on invalid child paths, so a malformed subg
|
|
|
256
256
|
Run the bundled parent/child board:
|
|
257
257
|
|
|
258
258
|
```bash
|
|
259
|
-
node goalbuddy/
|
|
260
|
-
--goal goalbuddy/
|
|
259
|
+
node goalbuddy/surfaces/local-goal-board/scripts/local-goal-board.mjs \
|
|
260
|
+
--goal goalbuddy/surfaces/local-goal-board/examples/subgoal-parent
|
|
261
261
|
```
|
|
262
262
|
|
|
263
263
|
Then try:
|
|
@@ -265,8 +265,8 @@ Then try:
|
|
|
265
265
|
- switch to dark mode from the gear menu
|
|
266
266
|
- open task `T004` to see the embedded child board
|
|
267
267
|
- launch another board and use the header selector
|
|
268
|
-
- run `goalbuddy parallel-plan goalbuddy/
|
|
269
|
-
- run `goalbuddy prompt goalbuddy/
|
|
268
|
+
- run `goalbuddy parallel-plan goalbuddy/surfaces/local-goal-board/examples/subgoal-parent`
|
|
269
|
+
- run `goalbuddy prompt goalbuddy/surfaces/local-goal-board/examples/subgoal-parent`
|
|
270
270
|
|
|
271
271
|
## Tests
|
|
272
272
|
|
package/RELEASE-0.3.7.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# GoalBuddy 0.3.7: Goalmaxxed
|
|
2
|
+
|
|
3
|
+
Release date: 2026-05-19
|
|
4
|
+
|
|
5
|
+
Goalmaxxed is the release where GoalBuddy stops trying to become a workflow catalog and commits to one sharper job:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Give /goal enough pressure that it keeps working until the original outcome is actually true.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This release is heavily inspired by the Codex maxxing playbook: keep the goal visible, preserve context in local files, use subagents deliberately, demand evidence, and resist the temptation to declare victory because a plausible slice finished.
|
|
12
|
+
|
|
13
|
+
Update with:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx goalbuddy update
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## The Headline
|
|
20
|
+
|
|
21
|
+
GoalBuddy now centers the native `/goal` loop around five small ideas:
|
|
22
|
+
|
|
23
|
+
- **Intent**: capture what the owner actually wants.
|
|
24
|
+
- **Oracle**: define the observable signal that proves the outcome is real.
|
|
25
|
+
- **Surface**: keep one local board visible while the run moves.
|
|
26
|
+
- **Loop**: Scout maps facts, Judge chooses the largest safe useful slice, Worker completes the whole slice.
|
|
27
|
+
- **Proof**: final completion requires receipts mapped back to the oracle.
|
|
28
|
+
|
|
29
|
+
That is the product. Everything else got judged against that loop.
|
|
30
|
+
|
|
31
|
+
## Goal Pressure
|
|
32
|
+
|
|
33
|
+
GoalBuddy now treats the goal oracle as first-class state. A serious goal needs an observable signal before the board can pretend it knows what done means:
|
|
34
|
+
|
|
35
|
+
- a passing test suite
|
|
36
|
+
- a browser walkthrough
|
|
37
|
+
- a demo transcript
|
|
38
|
+
- a generated artifact
|
|
39
|
+
- a benchmark
|
|
40
|
+
- a source-backed answer
|
|
41
|
+
- a release check
|
|
42
|
+
- a final human decision
|
|
43
|
+
|
|
44
|
+
No oracle, no serious goal.
|
|
45
|
+
|
|
46
|
+
The checker also rejects weak final completion. A goal should not be marked done just because the active task ended. Done means a final Judge or PM audit records that the receipts and verification satisfy the oracle.
|
|
47
|
+
|
|
48
|
+
## Larger Useful Slices
|
|
49
|
+
|
|
50
|
+
This release sharpens the slice policy:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
Safe does not mean small. Safe means bounded, explicit, verified, and reversible.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
GoalBuddy now pushes Judge and Worker toward the largest safe useful slice: a working screen, working API path, backend vertical slice, real bug fix, data pipeline step, or milestone review.
|
|
57
|
+
|
|
58
|
+
The board warns when it sees micro-slicing: helper files, contracts, proof notes, or tiny prep tasks that are safe but do not move the owner outcome.
|
|
59
|
+
|
|
60
|
+
## Built-In Local Board
|
|
61
|
+
|
|
62
|
+
The local board is now a core surface, not an extension.
|
|
63
|
+
|
|
64
|
+
The bundled surface lives at:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
goalbuddy/surfaces/local-goal-board/
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
It remains the default way to watch a GoalBuddy run: active task, blocked state, receipts, verification status, subgoals, and board switching all point back to the same `state.yaml` truth.
|
|
71
|
+
|
|
72
|
+
## No Extension Catalog
|
|
73
|
+
|
|
74
|
+
GoalBuddy no longer ships a public extension catalog.
|
|
75
|
+
|
|
76
|
+
The old catalog made the product look bigger while making the core loop blurrier. Goalmaxxed chooses the smaller invariant:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
GoalBuddy prepares and pressures /goal runs. Custom integrations are ordinary repo work.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If a team wants a GitHub, Linear, Slack, or release integration, they should prepare a concrete implementation plan in their repo and build it as normal software. GoalBuddy should not install arbitrary workflow packs as a side channel.
|
|
83
|
+
|
|
84
|
+
## Simpler Public Surface
|
|
85
|
+
|
|
86
|
+
The public copy now says what GoalBuddy actually does:
|
|
87
|
+
|
|
88
|
+
- prepares `/goal`
|
|
89
|
+
- writes `goal.md` and `state.yaml`
|
|
90
|
+
- creates a goal oracle
|
|
91
|
+
- opens a local board
|
|
92
|
+
- keeps Scout/Judge/Worker handoffs receipt-shaped
|
|
93
|
+
- prevents early completion
|
|
94
|
+
- leaves custom integrations outside the core
|
|
95
|
+
|
|
96
|
+
The Codex and Claude Code plugin manifests are aligned with the package description, and the test suite now checks that the Claude manifest stays in sync.
|
|
97
|
+
|
|
98
|
+
## Release Boundaries
|
|
99
|
+
|
|
100
|
+
This release intentionally does not add:
|
|
101
|
+
|
|
102
|
+
- an extension marketplace
|
|
103
|
+
- automatic parallel-agent spawning
|
|
104
|
+
- hosted board state
|
|
105
|
+
- automatic receipt application
|
|
106
|
+
- UI controls that mutate board state
|
|
107
|
+
- a replacement for native `/goal`
|
|
108
|
+
|
|
109
|
+
GoalBuddy stays local, file-backed, and boring in the parts that should be boring.
|
|
110
|
+
|
|
111
|
+
## Package Notes
|
|
112
|
+
|
|
113
|
+
This release updates:
|
|
114
|
+
|
|
115
|
+
- npm package version: `0.3.7`
|
|
116
|
+
- Codex plugin version: `0.3.7`
|
|
117
|
+
- Claude Code plugin version: `0.3.7`
|
|
118
|
+
- package contents to include `goalbuddy/surfaces/`
|
|
119
|
+
- mirrored GoalBuddy skill files under `plugins/goalbuddy/skills/goalbuddy/`
|
|
120
|
+
|
|
121
|
+
Before publishing, verify:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm run check
|
|
125
|
+
npm run pack:dry-run
|
|
126
|
+
node internal/cli/check-publish-version.mjs
|
|
127
|
+
```
|
package/goalbuddy/SKILL.md
CHANGED
|
@@ -12,9 +12,17 @@ GoalBuddy is for autonomous, long-running Codex or Claude Code work where the PM
|
|
|
12
12
|
The loop is:
|
|
13
13
|
|
|
14
14
|
```text
|
|
15
|
-
raw user intent -> intake compiler ->
|
|
15
|
+
raw user intent -> intake compiler -> goal oracle -> local work surface -> one active task -> receipt -> proof loop -> repeat
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
GoalBuddy's core invariant is:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
Intent -> Oracle -> Surface -> Loop -> Proof
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
No oracle, no serious goal. A goal oracle is the observable signal that tells the PM whether the original owner outcome is actually true yet. It may be a test suite, browser walkthrough, demo transcript, generated artifact, benchmark, source-backed answer, release check, or final human decision. Weak proof creates weak goals, so record the oracle before shaping tasks and keep testing against it until final completion.
|
|
25
|
+
|
|
18
26
|
## Invocation Boundary
|
|
19
27
|
|
|
20
28
|
There are two different modes:
|
|
@@ -31,7 +39,7 @@ Allowed `$goal-prep` actions:
|
|
|
31
39
|
- run the bundled GoalBuddy update checker and mention a newer version if one is available;
|
|
32
40
|
- ask diagnostic intake questions and wait when required;
|
|
33
41
|
- create or repair only `docs/goals/<slug>/goal.md`, `docs/goals/<slug>/state.yaml`, `docs/goals/<slug>/notes/`, and the generated `.goalbuddy-board/` visual board artifact;
|
|
34
|
-
- create and open the
|
|
42
|
+
- create and open the built-in local GoalBuddy board surface for the goal unless the user opts out;
|
|
35
43
|
- optionally run the GoalBuddy board checker against that `state.yaml`;
|
|
36
44
|
- verify GoalBuddy agent availability, if this can be done without touching implementation work, and record `installed`, `bundled_not_installed`, `missing`, or `unknown` truthfully;
|
|
37
45
|
- print exactly `/goal Follow docs/goals/<slug>/goal.md.`;
|
|
@@ -69,25 +77,25 @@ Extract:
|
|
|
69
77
|
- authority: `requested | approved | inferred | needs_approval | blocked`;
|
|
70
78
|
- proof type: `test | demo | artifact | metric | review | source_backed_answer | decision`;
|
|
71
79
|
- completion proof: the observable signal for full outcome completion;
|
|
80
|
+
- goal oracle: the live check, walkthrough, artifact, metric, or decision that will keep pressure on the goal and prevent early completion;
|
|
72
81
|
- likely misfire: how `/goal` could succeed at the wrong thing;
|
|
73
82
|
- blind spots: important risks, choices, or success dimensions the user may not have named yet;
|
|
74
83
|
- existing plan facts: user-provided steps, files, constraints, or sequencing that must be preserved but still validated.
|
|
75
84
|
|
|
76
|
-
|
|
85
|
+
Use the local GoalBuddy board as the default work surface for broad GoalBuddy runs. Ask only when the user has not already implied they want the default local surface, the goal is unusually quick/private, or board setup would materially distract from the requested prep:
|
|
77
86
|
|
|
78
87
|
```text
|
|
79
|
-
Do you want
|
|
88
|
+
Do you want the local GoalBuddy board for this goal?
|
|
80
89
|
```
|
|
81
90
|
|
|
82
91
|
Recommended options:
|
|
83
92
|
|
|
84
93
|
1. Local live board (Recommended) - starts immediately, requires no credentials, and lets the user watch tasks populate inside Codex or Claude Code.
|
|
85
|
-
2.
|
|
86
|
-
3. No visual board - best for quick or private goals where the file board is enough.
|
|
94
|
+
2. No visual board - best for quick or private goals where the file board is enough.
|
|
87
95
|
|
|
88
96
|
If the user chooses the local live board, create the goal directory, `notes/`, and an initial minimal `state.yaml` as soon as the slug is known, then run `npx goalbuddy board docs/goals/<slug>` and open the printed local URL in the AI coding agent's in-app browser (the Codex in-app Browser, the Claude Code preview, or the user's regular browser). The default local hub is `http://goalbuddy.localhost:41737/`, and board URLs normally look like `http://goalbuddy.localhost:41737/<slug>/`. In short: start the local board before filling the task list so the board pops up right away and cards populate live as `state.yaml` changes. Include the printed board URL in the final prep response as an actual clickable Markdown link, for example `[Open GoalBuddy board](http://goalbuddy.localhost:41737/<slug>/)`. Do not put the board URL only in a code block, quote, HTML comment, or prose that the UI cannot click.
|
|
89
97
|
|
|
90
|
-
If the user
|
|
98
|
+
If the user wants an external board, GitHub sync, Slack digest, Linear handoff, or any other custom integration, do not install a GoalBuddy catalog item. Treat it as normal implementation work: create a concrete task that designs and verifies that integration inside the target repo or asks the operator for the required credentials and scope.
|
|
91
99
|
|
|
92
100
|
Ask before board creation when the request is vague, strategic, improvement-oriented, or open-ended and the user has not explicitly said to use defaults. Ask one guided question at a time with 2-3 options and a recommended default, then wait. Continue the diagnostic intake until the user's answers are sufficient to choose the board shape. Do not create or repair `docs/goals/<slug>/` until the diagnostic intake is complete or the user explicitly accepts defaults.
|
|
93
101
|
|
|
@@ -134,7 +142,7 @@ Stop after each question. Do not create files, repair an existing board, run che
|
|
|
134
142
|
|
|
135
143
|
Minimum diagnostic ladder for vague, strategic, or improvement-oriented goals:
|
|
136
144
|
|
|
137
|
-
1.
|
|
145
|
+
1. Goal surface: use the local live board by default, or ask "Do you want the local GoalBuddy board for this goal?" when board handling is unresolved.
|
|
138
146
|
2. Intent target: what kind of improvement or outcome matters most?
|
|
139
147
|
3. Success proof: what evidence would convince the user this worked?
|
|
140
148
|
4. Scope and non-goals: what should remain untouched or explicitly out of scope?
|
|
@@ -173,7 +181,7 @@ Do:
|
|
|
173
181
|
- classify the goal as `specific`, `open_ended`, `existing_plan`, `recovery`, or `audit`;
|
|
174
182
|
- create or repair `docs/goals/<slug>/`;
|
|
175
183
|
- create `goal.md`, `state.yaml`, and `notes/`;
|
|
176
|
-
-
|
|
184
|
+
- start the local board immediately and open it in the AI coding agent's in-app browser (Codex in-app Browser, Claude Code preview, or the user's regular browser) before filling the task list, unless the user opts out;
|
|
177
185
|
- seed a role-tagged task board that matches the input shape;
|
|
178
186
|
- make the first active task safe;
|
|
179
187
|
- verify Scout, Worker, and Judge agent availability or record an explicit truthful state;
|
|
@@ -234,7 +242,7 @@ Use this skill for goals that are broad, multi-hour, ambiguous, high-risk, alrea
|
|
|
234
242
|
|
|
235
243
|
For a one-change task, do not create a GoalBuddy board.
|
|
236
244
|
|
|
237
|
-
Scout and Judge tasks may identify optional
|
|
245
|
+
Scout and Judge tasks may identify optional publishing, reporting, integration, plugin, or channel opportunities as improvement candidates. Treat those as normal board tasks with concrete implementation plans. `state.yaml` remains board truth.
|
|
238
246
|
|
|
239
247
|
## The Four Primitives
|
|
240
248
|
|
|
@@ -274,6 +282,7 @@ The charter answers:
|
|
|
274
282
|
What did the user originally ask for?
|
|
275
283
|
What are we trying to improve?
|
|
276
284
|
What input shape did the intake identify?
|
|
285
|
+
What is the goal oracle?
|
|
277
286
|
What constraints are non-negotiable?
|
|
278
287
|
Is this goal specific, open-ended, existing-plan, recovery, or audit?
|
|
279
288
|
What likely misfire must the PM avoid?
|
|
@@ -53,6 +53,38 @@ function nestedScalar(section, key) {
|
|
|
53
53
|
return null;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
function pathScalar(path, key) {
|
|
57
|
+
const lines = text.split(/\r?\n/);
|
|
58
|
+
let depth = 0;
|
|
59
|
+
for (const line of lines) {
|
|
60
|
+
if (!line.trim()) continue;
|
|
61
|
+
const indent = line.match(/^ */)[0].length;
|
|
62
|
+
if (indent < depth * 2) depth = Math.floor(indent / 2);
|
|
63
|
+
|
|
64
|
+
if (depth < path.length && indent === depth * 2 && new RegExp(`^\\s{${indent}}${path[depth]}:\\s*$`).test(line)) {
|
|
65
|
+
depth += 1;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (depth === path.length && indent === depth * 2) {
|
|
70
|
+
const match = line.match(new RegExp(`^\\s{${indent}}${key}:\\s*(.*?)\\s*$`));
|
|
71
|
+
if (match) return clean(match[1]);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isWeakProof(value) {
|
|
78
|
+
if (value === null || value === undefined) return true;
|
|
79
|
+
const normalized = String(value).trim().toLowerCase();
|
|
80
|
+
return normalized === ""
|
|
81
|
+
|| normalized === "unknown"
|
|
82
|
+
|| normalized === "tbd"
|
|
83
|
+
|| normalized === "todo"
|
|
84
|
+
|| normalized === "none"
|
|
85
|
+
|| /^<.*>$/.test(normalized);
|
|
86
|
+
}
|
|
87
|
+
|
|
56
88
|
function sectionText(section) {
|
|
57
89
|
const lines = text.split(/\r?\n/);
|
|
58
90
|
const start = lines.findIndex((line) => new RegExp(`^${section}:\\s*$`).test(line));
|
|
@@ -225,6 +257,11 @@ const allowedAgentStatuses = new Set(["installed", "bundled_not_installed", "mis
|
|
|
225
257
|
const continuousUntilFullOutcome = nestedScalar("rules", "continuous_until_full_outcome") === true;
|
|
226
258
|
const missingInputOrCredentialsDoNotStopGoal =
|
|
227
259
|
nestedScalar("rules", "missing_input_or_credentials_do_not_stop_goal") === true;
|
|
260
|
+
const goalPressureRequiresOracle = nestedScalar("rules", "goal_pressure_requires_oracle") !== false;
|
|
261
|
+
const noCompletionOnWeakProof = nestedScalar("rules", "no_completion_on_weak_proof") !== false;
|
|
262
|
+
const completionProof = pathScalar(["goal", "intake"], "completion_proof");
|
|
263
|
+
const oracleSignal = pathScalar(["goal", "oracle"], "signal");
|
|
264
|
+
const oracleFinalProof = pathScalar(["goal", "oracle"], "final_proof");
|
|
228
265
|
const legacySignals = [
|
|
229
266
|
/^gate:\s*$/m,
|
|
230
267
|
/^artifact_policy:\s*$/m,
|
|
@@ -244,6 +281,19 @@ if (!["active", "blocked", "done"].includes(goalStatus)) {
|
|
|
244
281
|
errors.push(`goal.status must be active, blocked, or done; got ${goalStatus || "<missing>"}`);
|
|
245
282
|
}
|
|
246
283
|
|
|
284
|
+
if (goalPressureRequiresOracle) {
|
|
285
|
+
if (isWeakProof(oracleSignal)) {
|
|
286
|
+
warnings.push("goal.oracle.signal is missing or placeholder-like; weak oracles make /goal finish too early.");
|
|
287
|
+
}
|
|
288
|
+
if (isWeakProof(oracleFinalProof)) {
|
|
289
|
+
warnings.push("goal.oracle.final_proof is missing or placeholder-like; final completion needs receipt-backed proof.");
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (isWeakProof(completionProof)) {
|
|
294
|
+
warnings.push("goal.intake.completion_proof is missing or placeholder-like; record the observable signal that proves the full original outcome.");
|
|
295
|
+
}
|
|
296
|
+
|
|
247
297
|
function agentStatusWarning(agent, status) {
|
|
248
298
|
const agentLabel = agent[0].toUpperCase() + agent.slice(1);
|
|
249
299
|
if (status === "bundled_not_installed") {
|
|
@@ -532,6 +582,9 @@ function escapeRegExp(value) {
|
|
|
532
582
|
}
|
|
533
583
|
|
|
534
584
|
if (goalStatus === "done") {
|
|
585
|
+
if (noCompletionOnWeakProof && (isWeakProof(completionProof) || isWeakProof(oracleSignal) || isWeakProof(oracleFinalProof))) {
|
|
586
|
+
errors.push("done goals require concrete completion proof, goal.oracle.signal, and goal.oracle.final_proof; weak proof cannot close a goal");
|
|
587
|
+
}
|
|
535
588
|
const finalAudit = tasks.some((task) => {
|
|
536
589
|
if (!["judge", "pm"].includes(task.type) || task.status !== "done") return false;
|
|
537
590
|
if (!task.receipt.present || task.receipt.value === null) return false;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import { basename, dirname, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { parseGoalStateText } from "../
|
|
5
|
+
import { parseGoalStateText } from "../surfaces/local-goal-board/scripts/lib/goal-board.mjs";
|
|
6
6
|
|
|
7
7
|
const ROLE_DEFAULTS = {
|
|
8
8
|
scout: { agent: "goal_scout", reasoning: "low", sandbox: "read-only" },
|
|
@@ -45,6 +45,7 @@ export function renderTaskPrompt(options) {
|
|
|
45
45
|
fork_context_allowed: role !== "worker",
|
|
46
46
|
board_path: board.path,
|
|
47
47
|
child_board_paths: childBoardPaths(board),
|
|
48
|
+
goal_oracle: board.goal.oracle || null,
|
|
48
49
|
slice_policy: board.document.rules?.slice_policy || null,
|
|
49
50
|
warnings,
|
|
50
51
|
},
|
|
@@ -141,6 +142,12 @@ function promptWarnings(board, task) {
|
|
|
141
142
|
const warnings = [];
|
|
142
143
|
const role = normalizeRole(task.type);
|
|
143
144
|
if (task.id !== board.activeTask) warnings.push(`Task ${task.id} is not the active task on this board.`);
|
|
145
|
+
if (isWeakProof(board.goal.oracle?.signal)) {
|
|
146
|
+
warnings.push("goal.oracle.signal is missing or placeholder-like; keep the goal pressured by a concrete completion oracle.");
|
|
147
|
+
}
|
|
148
|
+
if (isWeakProof(board.goal.oracle?.final_proof)) {
|
|
149
|
+
warnings.push("goal.oracle.final_proof is missing or placeholder-like; do not mark the goal complete without receipt-backed proof.");
|
|
150
|
+
}
|
|
144
151
|
if (role === "worker") {
|
|
145
152
|
if (stringList(task.allowed_files).length === 0) warnings.push(`Worker task ${task.id} has no allowed_files.`);
|
|
146
153
|
if (stringList(task.verify).length === 0) warnings.push(`Worker task ${task.id} has no verify commands.`);
|
|
@@ -211,6 +218,17 @@ function isTrue(value) {
|
|
|
211
218
|
return value === true || String(value).toLowerCase() === "true";
|
|
212
219
|
}
|
|
213
220
|
|
|
221
|
+
function isWeakProof(value) {
|
|
222
|
+
if (value === null || value === undefined) return true;
|
|
223
|
+
const normalized = String(value).trim().toLowerCase();
|
|
224
|
+
return normalized === ""
|
|
225
|
+
|| normalized === "unknown"
|
|
226
|
+
|| normalized === "tbd"
|
|
227
|
+
|| normalized === "todo"
|
|
228
|
+
|| normalized === "none"
|
|
229
|
+
|| /^<.*>$/.test(normalized);
|
|
230
|
+
}
|
|
231
|
+
|
|
214
232
|
function stringList(value) {
|
|
215
233
|
return Array.isArray(value) ? value.filter((item) => item !== null && item !== undefined).map(String) : [];
|
|
216
234
|
}
|
|
@@ -261,6 +279,9 @@ function formatPrompt(payload) {
|
|
|
261
279
|
lines.push("- child_board_paths:");
|
|
262
280
|
for (const path of payload.metadata.child_board_paths) lines.push(` - ${path}`);
|
|
263
281
|
}
|
|
282
|
+
if (payload.metadata.goal_oracle) {
|
|
283
|
+
lines.push(`- goal_oracle: ${JSON.stringify(payload.metadata.goal_oracle)}`);
|
|
284
|
+
}
|
|
264
285
|
if (payload.metadata.slice_policy) {
|
|
265
286
|
lines.push(`- slice_policy: ${JSON.stringify(payload.metadata.slice_policy)}`);
|
|
266
287
|
}
|
package/{plugins/goalbuddy/skills/goalbuddy/extend → goalbuddy/surfaces}/local-goal-board/README.md
RENAMED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Generate a small local GoalBuddy board for a goal directory and watch it update live while agents work.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The surface keeps `state.yaml` authoritative. It writes static web app files into the goal directory and serves them from a local-only Node server. The browser subscribes to Server-Sent Events, so cards update as `state.yaml`, `notes/`, or linked depth-1 sub-goal state changes without a manual reload.
|
|
6
6
|
|
|
7
7
|
## Use When
|
|
8
8
|
|
|
@@ -14,11 +14,10 @@ The extension keeps `state.yaml` authoritative. It writes static web app files i
|
|
|
14
14
|
## Generate And Serve
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
|
|
18
|
-
--goal docs/goals/<slug>
|
|
17
|
+
npx goalbuddy board docs/goals/<slug>
|
|
19
18
|
```
|
|
20
19
|
|
|
21
|
-
The generated app includes the bundled `assets/goalbuddy-mark.png`, so the board keeps the GoalBuddy mark
|
|
20
|
+
The generated app includes the bundled `assets/goalbuddy-mark.png`, so the board keeps the GoalBuddy mark anywhere the package is installed.
|
|
22
21
|
|
|
23
22
|
The command writes:
|
|
24
23
|
|
|
@@ -34,8 +33,7 @@ Then it starts or reuses the shared local board hub at `http://goalbuddy.localho
|
|
|
34
33
|
## Check Without A Long-Running Server
|
|
35
34
|
|
|
36
35
|
```bash
|
|
37
|
-
|
|
38
|
-
--goal docs/goals/<slug> \
|
|
36
|
+
npx goalbuddy board docs/goals/<slug> \
|
|
39
37
|
--once \
|
|
40
38
|
--json
|
|
41
39
|
```
|
|
@@ -63,9 +61,9 @@ Clicking a card opens a detail modal with the task objective, status, assignee,
|
|
|
63
61
|
## Verification
|
|
64
62
|
|
|
65
63
|
```bash
|
|
66
|
-
node --test
|
|
67
|
-
node
|
|
68
|
-
--goal
|
|
64
|
+
node --test goalbuddy/surfaces/local-goal-board/test/*.test.mjs
|
|
65
|
+
node goalbuddy/surfaces/local-goal-board/scripts/local-goal-board.mjs \
|
|
66
|
+
--goal goalbuddy/surfaces/local-goal-board/examples/sample-goal \
|
|
69
67
|
--once \
|
|
70
68
|
--json
|
|
71
69
|
```
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
version: 2
|
|
2
2
|
|
|
3
3
|
goal:
|
|
4
|
-
title: "Local
|
|
5
|
-
slug: "local-
|
|
4
|
+
title: "Local Goal Board Surface"
|
|
5
|
+
slug: "local-goal-board-surface"
|
|
6
6
|
kind: specific
|
|
7
7
|
tranche: "Demonstrate local GoalBuddy board rendering."
|
|
8
8
|
status: active
|
|
@@ -30,7 +30,7 @@ tasks:
|
|
|
30
30
|
type: worker
|
|
31
31
|
assignee: Worker
|
|
32
32
|
status: blocked
|
|
33
|
-
objective: "Catalog and document the local board
|
|
33
|
+
objective: "Catalog and document the local board surface."
|
|
34
34
|
receipt:
|
|
35
35
|
result: blocked
|
|
36
36
|
summary: "T003 is blocked during the progressive board motion demo."
|
|
@@ -78,7 +78,7 @@ tasks:
|
|
|
78
78
|
type: scout
|
|
79
79
|
assignee: Scout
|
|
80
80
|
status: done
|
|
81
|
-
objective: "List the
|
|
81
|
+
objective: "List the board launch paths."
|
|
82
82
|
receipt:
|
|
83
83
|
result: done
|
|
84
84
|
summary: "T009 completed during the progressive board motion demo."
|
|
@@ -118,7 +118,7 @@ tasks:
|
|
|
118
118
|
type: worker
|
|
119
119
|
assignee: Worker
|
|
120
120
|
status: done
|
|
121
|
-
objective: "Prepare final
|
|
121
|
+
objective: "Prepare final board packaging check."
|
|
122
122
|
receipt:
|
|
123
123
|
result: done
|
|
124
124
|
summary: "T014 completed during the progressive board motion demo."
|
|
@@ -31,10 +31,10 @@ tasks:
|
|
|
31
31
|
status: active
|
|
32
32
|
objective: "Build the sub-goal board view."
|
|
33
33
|
allowed_files:
|
|
34
|
-
- goalbuddy/
|
|
35
|
-
- goalbuddy/
|
|
34
|
+
- goalbuddy/surfaces/local-goal-board/scripts/lib/goal-board.mjs
|
|
35
|
+
- goalbuddy/surfaces/local-goal-board/test/local-goal-board.test.mjs
|
|
36
36
|
verify:
|
|
37
|
-
- node --test goalbuddy/
|
|
37
|
+
- node --test goalbuddy/surfaces/local-goal-board/test/local-goal-board.test.mjs
|
|
38
38
|
stop_if:
|
|
39
39
|
- "Need files outside allowed_files."
|
|
40
40
|
subgoal:
|
|
@@ -24,16 +24,16 @@ tasks:
|
|
|
24
24
|
result: done
|
|
25
25
|
summary: "Child board payload needs normal columns and task details."
|
|
26
26
|
evidence:
|
|
27
|
-
- goalbuddy/
|
|
27
|
+
- goalbuddy/surfaces/local-goal-board/scripts/lib/goal-board.mjs
|
|
28
28
|
- id: T002
|
|
29
29
|
type: worker
|
|
30
30
|
assignee: Worker
|
|
31
31
|
status: active
|
|
32
32
|
objective: "Render the read-only embedded child board."
|
|
33
33
|
allowed_files:
|
|
34
|
-
- goalbuddy/
|
|
34
|
+
- goalbuddy/surfaces/local-goal-board/scripts/lib/goal-board.mjs
|
|
35
35
|
verify:
|
|
36
|
-
- node --test goalbuddy/
|
|
36
|
+
- node --test goalbuddy/surfaces/local-goal-board/test/local-goal-board.test.mjs
|
|
37
37
|
stop_if:
|
|
38
38
|
- "Need files outside allowed_files."
|
|
39
39
|
receipt: null
|
|
@@ -6,8 +6,8 @@ import { fileURLToPath } from "node:url";
|
|
|
6
6
|
const VALID_STATUSES = new Set(["queued", "active", "blocked", "done"]);
|
|
7
7
|
const COLUMN_ORDER = ["todo", "in-progress", "blocked", "completed"];
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const
|
|
10
|
-
const logoAssetPath = join(
|
|
9
|
+
const surfaceRoot = resolve(__dirname, "../..");
|
|
10
|
+
const logoAssetPath = join(surfaceRoot, "assets", "goalbuddy-mark.png");
|
|
11
11
|
|
|
12
12
|
export class GoalBoardError extends Error {
|
|
13
13
|
constructor(message) {
|
|
@@ -527,9 +527,9 @@ function serveStatic(appDir, pathname, response) {
|
|
|
527
527
|
return;
|
|
528
528
|
}
|
|
529
529
|
|
|
530
|
-
const
|
|
530
|
+
const fileExtension = cleanPath.match(/\.[^.]+$/)?.[0] || "";
|
|
531
531
|
response.writeHead(200, {
|
|
532
|
-
"Content-Type": textTypes[
|
|
532
|
+
"Content-Type": textTypes[fileExtension] || "application/octet-stream",
|
|
533
533
|
"Cache-Control": "no-store",
|
|
534
534
|
});
|
|
535
535
|
response.end(readFileSync(file));
|
|
@@ -580,8 +580,8 @@ function usage() {
|
|
|
580
580
|
console.log(`GoalBuddy Local Goal Board
|
|
581
581
|
|
|
582
582
|
Usage:
|
|
583
|
-
|
|
584
|
-
|
|
583
|
+
npx goalbuddy board docs/goals/<slug>
|
|
584
|
+
npx goalbuddy board docs/goals/<slug> --once --json
|
|
585
585
|
|
|
586
586
|
Options:
|
|
587
587
|
--goal <path> Goal directory containing state.yaml.
|