monkeyshape 0.0.0-stage → 0.2.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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +54 -2
  3. package/config/biome.base.json +71 -0
  4. package/config/tsconfig.base.json +31 -0
  5. package/docs/workflow.md +131 -0
  6. package/package.json +68 -4
  7. package/skills/handoff/SKILL.md +54 -0
  8. package/skills/milestone/SKILL.md +107 -0
  9. package/skills/review-pr/SKILL.md +135 -0
  10. package/skills/roadmap/SKILL.md +66 -0
  11. package/skills/track/SKILL.md +75 -0
  12. package/src/adapters/baseline.ts +55 -0
  13. package/src/adapters/config.ts +25 -0
  14. package/src/adapters/init.ts +176 -0
  15. package/src/adapters/process.ts +38 -0
  16. package/src/adapters/reviews.ts +170 -0
  17. package/src/adapters/skills.ts +113 -0
  18. package/src/adapters/tracks.ts +616 -0
  19. package/src/adapters/workspace.ts +281 -0
  20. package/src/api/monkeyshape.ts +8 -0
  21. package/src/cli/main.ts +359 -0
  22. package/src/core/arch.ts +224 -0
  23. package/src/core/budgets.ts +187 -0
  24. package/src/core/check.ts +122 -0
  25. package/src/core/coverage.ts +118 -0
  26. package/src/core/decisions.ts +65 -0
  27. package/src/core/garden.ts +41 -0
  28. package/src/core/glob.ts +22 -0
  29. package/src/core/handoff.ts +183 -0
  30. package/src/core/hooks.ts +60 -0
  31. package/src/core/jsonc.ts +26 -0
  32. package/src/core/layout.ts +123 -0
  33. package/src/core/markdown.ts +93 -0
  34. package/src/core/model.ts +100 -0
  35. package/src/core/parse.ts +41 -0
  36. package/src/core/paths.ts +19 -0
  37. package/src/core/ratchet.ts +75 -0
  38. package/src/core/refs.ts +214 -0
  39. package/src/core/report.ts +67 -0
  40. package/src/core/rules/ast.ts +50 -0
  41. package/src/core/rules/decodeStrict.ts +60 -0
  42. package/src/core/rules/effectRunAtEdge.ts +33 -0
  43. package/src/core/rules/engine.ts +150 -0
  44. package/src/core/rules/noErrorSpread.ts +28 -0
  45. package/src/core/rules/noNondeterminism.ts +65 -0
  46. package/src/core/rules/noThrow.ts +79 -0
  47. package/src/core/rules/registry.ts +15 -0
  48. package/src/core/scaffold.ts +90 -0
  49. package/src/core/scope.ts +120 -0
  50. package/src/core/skills.ts +291 -0
  51. package/src/core/tracks.ts +358 -0
  52. package/src/helpers/decodeStrict.ts +8 -0
  53. package/src/schemas/config.ts +221 -0
  54. package/src/schemas/errors.ts +31 -0
  55. package/template/.github/pull_request_template.md +11 -0
  56. package/template/.github/workflows/ci.yml +22 -0
  57. package/template/AGENTS.md +37 -0
  58. package/template/CLAUDE.md +1 -0
  59. package/template/DECISIONS.md +8 -0
  60. package/template/README.md +14 -0
  61. package/template/docs/roadmap.md +14 -0
  62. package/template/gitignore +7 -0
  63. package/template/notes/.gitkeep +0 -0
  64. package/template/plan/.gitkeep +0 -0
  65. package/template/shape.config.ts +26 -0
  66. package/template/test/toolchain.test.ts +7 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 clinsky
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,55 @@
1
- # Temporary Holding Version
1
+ # monkeyshape
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Opinionated checks, configs and conventions for humans and coding agents building software
4
+ together on **Bun**, **TypeScript**, **Effect** and **beads**.
5
+
6
+ Agents write a lot of prose and forget most of it. A rule written in `AGENTS.md` works only if
7
+ it is loaded and noticed; a check works every time and costs no context until it fires.
8
+ monkeyshape turns lessons into checks, keeps everything loaded automatically on a budget,
9
+ and treats real-world results as the judge of done.
10
+
11
+ ```console
12
+ $ mshape check
13
+ src/core/cache.ts:1 rules/no-nondeterminism
14
+ reads the wall clock. Use Clock or DateTime.now so tests control time.
15
+
16
+ src/core/client.ts arch/host-access
17
+ imports 'node:fs/promises', but module 'core' has no hostAccess. Reach the host through a service in an adapter module.
18
+
19
+ mshape check failed: 2 problems
20
+ ```
21
+
22
+ ## Quick start
23
+
24
+ ```sh
25
+ bunx --package monkeyshape mshape init my-app
26
+ ```
27
+
28
+ A new repo whose gate (`bun run check`) passes, with one starter test: Bun, TypeScript, Effect,
29
+ beads, the configs, CI, and five skills for your coding agent. Then the working loop, one chat each:
30
+
31
+ 1. `/roadmap` with a brain-dump: the direction, and one deferred epic per goal.
32
+ 2. `/milestone` with your priorities: a plan with acceptance on real data, beads, and
33
+ tracks, each its own worktree from `mshape track new`.
34
+ 3. `/track` in each track's worktree: the agent works its queue and opens PRs.
35
+ 4. `/handoff` when a chat's context runs low; a fresh chat runs `/track` to continue.
36
+ 5. `/review-pr <n>` in its own chat; you merge.
37
+
38
+ The conventions in full: [docs/workflow.md](docs/workflow.md). An existing repo:
39
+ [docs/adopting.md](docs/adopting.md).
40
+
41
+ ## What `mshape check` enforces
42
+
43
+ | Check | Removes |
44
+ |---|---|
45
+ | `arch` | Layering drift, host access from pure code (common paths, statically; not a sandbox), unvetted packages, import cycles |
46
+ | `rules` | Silent decoding, hidden clocks/env/timers, thrown errors, nested runtimes, spread errors |
47
+ | `refs` | Docs and comments that point at paths, scripts or decisions that don't exist |
48
+ | `budgets` | Bloated `AGENTS.md`, decision logs and memories; oversized files |
49
+ | `coverage` | Code that escaped the typechecker or the linter and rots silently |
50
+ | `skills` | Installed skills that agents can't see (a broken `.claude/skills` link) or that lag the package |
51
+
52
+ Existing violations can be grandfathered with `mshape baseline --init`; counts may then only
53
+ go down. Every escape hatch (`// shape-ignore <rule>: <reason>`, config allowances) needs a reason.
54
+
55
+ Early (0.x). What ships and what's next: [docs/roadmap.md](docs/roadmap.md). MIT licensed.
@@ -0,0 +1,71 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.5.15/schema.json",
3
+ "root": false,
4
+ "vcs": {
5
+ "enabled": true,
6
+ "clientKind": "git",
7
+ "useIgnoreFile": true
8
+ },
9
+ "formatter": {
10
+ "enabled": true,
11
+ "indentStyle": "space",
12
+ "indentWidth": 2,
13
+ "lineWidth": 100
14
+ },
15
+ "javascript": {
16
+ "formatter": {
17
+ "quoteStyle": "double",
18
+ "semicolons": "always"
19
+ }
20
+ },
21
+ "linter": {
22
+ "enabled": true,
23
+ "rules": {
24
+ "preset": "recommended",
25
+ "correctness": {
26
+ "useImportExtensions": "error"
27
+ },
28
+ "suspicious": {
29
+ "noExplicitAny": "error",
30
+ "noConsole": "error"
31
+ },
32
+ "style": {
33
+ "noNonNullAssertion": "error",
34
+ "noEnum": "error",
35
+ "noNamespace": "error",
36
+ "noParameterAssign": "error",
37
+ "useImportType": "error",
38
+ "useExportType": "error"
39
+ },
40
+ "performance": {
41
+ "noBarrelFile": "error",
42
+ "noReExportAll": "error"
43
+ },
44
+ "nursery": {
45
+ "noFloatingPromises": "error",
46
+ "noMisusedPromises": "error"
47
+ },
48
+ "complexity": {
49
+ "useLiteralKeys": "off"
50
+ }
51
+ }
52
+ },
53
+ "assist": {
54
+ "enabled": true,
55
+ "actions": {
56
+ "source": {
57
+ "organizeImports": "on"
58
+ }
59
+ }
60
+ },
61
+ "overrides": [
62
+ {
63
+ "includes": ["src/api/**"],
64
+ "linter": { "rules": { "performance": { "noBarrelFile": "off" } } }
65
+ },
66
+ {
67
+ "includes": ["src/cli/**", "tools/**", "**/*.test.ts", "**/*.test.tsx"],
68
+ "linter": { "rules": { "suspicious": { "noConsole": "off" } } }
69
+ }
70
+ ]
71
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "compilerOptions": {
4
+ "target": "ESNext",
5
+ "lib": ["ESNext"],
6
+ "module": "Preserve",
7
+ "moduleResolution": "bundler",
8
+ "moduleDetection": "force",
9
+ "types": ["bun"],
10
+ "noEmit": true,
11
+ "allowImportingTsExtensions": true,
12
+ "verbatimModuleSyntax": true,
13
+ "erasableSyntaxOnly": true,
14
+ "isolatedModules": true,
15
+ "skipLibCheck": true,
16
+ "forceConsistentCasingInFileNames": true,
17
+
18
+ "strict": true,
19
+ "noUncheckedIndexedAccess": true,
20
+ "exactOptionalPropertyTypes": true,
21
+ "noImplicitOverride": true,
22
+ "noImplicitReturns": true,
23
+ "noFallthroughCasesInSwitch": true,
24
+ "noPropertyAccessFromIndexSignature": true,
25
+ "noUnusedLocals": true,
26
+ "noUnusedParameters": true,
27
+ "noUncheckedSideEffectImports": true,
28
+ "allowUnreachableCode": false,
29
+ "allowUnusedLabels": false
30
+ }
31
+ }
@@ -0,0 +1,131 @@
1
+ # The working loop
2
+
3
+ How a repo made by `mshape init` is worked, by a human and coding agents together. Read this
4
+ once after `init`; the skills it names carry the detail, so you don't need it again.
5
+
6
+ The split: **skills carry judgement, the `mshape` CLI carries everything deterministic.** A
7
+ skill interviews, proposes, writes prose and grooms beads; it never builds a worktree or a
8
+ file layout by hand, because the CLI does that and is tested. Each skill is started by name
9
+ in a fresh chat, so your message can be just the skill and your intent.
10
+
11
+ ## Three horizons, three files
12
+
13
+ Plan in detail only what is near. Each horizon has one home and one way of staying true.
14
+
15
+ | Horizon | Home | Written by | Kept true by |
16
+ |---|---|---|---|
17
+ | Direction: months | docs/roadmap.md, plus one deferred beads epic per goal | `/roadmap` | Rewritten in place at each milestone boundary |
18
+ | Milestone: several PRs from several agents | plan/MILESTONE.md | `/milestone` | Frozen for the milestone, replaced at the next |
19
+ | Track state: today | the track's handoff, in `.handoffs` | `/track`, `/handoff` | Overwritten at every handoff |
20
+
21
+ - **The roadmap** opens with a status table, so nobody reads the design as a spec. It is
22
+ never cited by code or by normative docs (AGENTS.md, DECISIONS.md, skills): name the file,
23
+ but the refs check rejects links into its sections. Its goals are deferred epics with no children until a milestone pulls them
24
+ in, so they never crowd `bd ready`.
25
+ - **The milestone plan** says the goal and how you'll know it is met on real data, where
26
+ things stand, the tracks with their beads and acceptance, the interfaces between tracks,
27
+ decision points and what is deferred. When a track diverges from it, the track says so in
28
+ its handoff; a divergence that changes another track's work is a conversation with the
29
+ human, not an edit to the plan. Only handoffs and beads cite it.
30
+ - **A handoff** is what a fresh chat reads to continue a track, and what the human reads to
31
+ decide what to relay. Handoffs live inside git's directory and are linked into every
32
+ checkout as `.handoffs`; they are never committed, so there is one live copy.
33
+
34
+ What a change did and what it showed goes in the **PR body**, which is the narrative the
35
+ human actually reads. Long investigations go in a dated note under `notes/`, which nothing
36
+ normative may cite.
37
+
38
+ Everything else has one home too:
39
+
40
+ - A rule a machine can check is **a check**, whose message gives the reason and the fix. A
41
+ domain invariant is **a test named after it**. The local reason for some code is **a
42
+ comment at that code**.
43
+ - **DECISIONS.md** holds only live decisions worth their budget: a surprising external fact
44
+ that was measured, or a choice between real alternatives that would be expensive to undo.
45
+ The best entries name the tempting wrong fix. A feature design isn't one; it goes in the
46
+ code.
47
+ - **Notes** are immutable: write a new one instead of updating an old one. A lesson that
48
+ should apply going forward is promoted to a check, a test or a decision.
49
+
50
+ ## The loop
51
+
52
+ | Step | Started by | What happens |
53
+ |---|---|---|
54
+ | Init | you: `mshape init <name>` | A new repo whose gate passes, with one starter test: template, toolchain, beads, the five skills, the handoffs store. |
55
+ | Long term | chat: `/roadmap` + a brain-dump | Interview until goals are clear; write docs/roadmap.md; one deferred epic per goal; open a PR. |
56
+ | Mid term | chat: `/milestone` + priorities | Retrospective on the last milestone; agree a goal with acceptance on real data; write plan/MILESTONE.md; groom beads and the roadmap; garden; create the tracks with `mshape track new`; remove finished ones. |
57
+ | Short term | chat in a track's worktree: `/track` | Read the handoff and the track's queue; work; open PRs. |
58
+ | Hand off | you, near 75% of a chat's context: `/handoff` | The handoff is rewritten so a fresh chat can continue; open one in the same worktree and run `/track`. |
59
+ | Review | chat: `/review-pr <number>` | Review against real data in a scratch worktree (`mshape review <n>`); findings go on the PR; you merge. |
60
+
61
+ A first repo goes: `mshape init`, then `/roadmap`, then `/milestone`, then one chat per track
62
+ running `/track`. The first milestone of a new repo is "a first result on a real target".
63
+
64
+ ## Tracks
65
+
66
+ A track is one line of parallel work: a name, a git worktree, a branch, a beads label and a
67
+ handoff, all derived from the name by `mshape track`:
68
+
69
+ - `mshape track new <name>` creates the worktree `.agents/worktrees/<repo>@<name>`, the branch
70
+ `track/<name>` and the handoff, and links the shared paths from `shape.config.ts`
71
+ (gitignored data such as a dataset) into the worktree.
72
+ - `mshape track list` shows the tracks and each one's open beads; `mshape track current`
73
+ names the track of the current directory, and fails with a reason anywhere else.
74
+ - `mshape track rm <name>` removes a finished track. It refuses while the worktree has
75
+ uncommitted work or the branch has unmerged commits, and says which; `--force` discards
76
+ them. Merged means in `main` or in its upstream, which `rm` fetches first, so a PR merged
77
+ on the remote counts before anyone pulls; a merge commit, a rebase and a squash all count. It also refuses while any bead labelled `track:<name>` isn't closed, and `--force`
78
+ doesn't override that: close each one, or move it to the track that will do it.
79
+
80
+ Its beads carry the label `track:<name>`; its queue is `bd ready --label track:<name>`. An
81
+ empty queue doesn't mean the track is done: `bd ready` leaves out beads in progress or blocked.
82
+ The track is done when `mshape track list` shows it with 0 open beads and `merged: yes`.
83
+
84
+ **Ad-hoc tracks.** For work that didn't come from a milestone, run `mshape track new <name>`
85
+ yourself, open a chat in the worktree it prints and run `/track`. The handoff starts as a
86
+ stub, so `/track` interviews you about the work and writes the charter and its beads.
87
+ `mshape track rm <name>` when it's merged.
88
+
89
+ **When to hand off.** At a natural break, around 75% of the context window. A handoff
90
+ records state, lessons not yet promoted, traps and messages for other tracks; you relay
91
+ those messages by pasting them where they belong, or by asking the track's next chat to read
92
+ the other handoff.
93
+
94
+ ## Pull requests and review
95
+
96
+ - Agents commit, push and open PRs; the human merges. A track has one PR open at a time, from
97
+ its branch. Batch a track's beads into PRs of one theme, typically 1k to 2.5k changed
98
+ lines: many small PRs cost more review than a few large ones. That is a default for
99
+ batching, not a gate: a small PR is fine when it unblocks work or keeps docs in step with
100
+ code.
101
+ - The PR body says what changed and why, the evidence on real data, the gate output, the bug
102
+ class a new check closes, what is not done, and the beads closed or filed.
103
+ - `bun run check` is the gate, the same locally and in CI. It is green before every PR.
104
+ - `/review-pr` runs in its own chat, in a detached worktree at the PR's head that
105
+ `mshape review <n>` makes and `mshape review rm <n>` removes. A review is not a track: it
106
+ has no handoff, and everything about it lives on the PR. A review holds the PR to 95%,
107
+ not 100%: a blocker is a defect the PR would ship, and the skill says what counts. It
108
+ takes as many rounds as that needs, and LGTM means nothing is open. You merge, and can
109
+ step in at any point.
110
+
111
+ ## Beads
112
+
113
+ - A bead points to intent; it isn't a spec. Keep it short: the intent, why, and an outcome
114
+ as acceptance.
115
+ - Three kinds: deferred direction epics (no children), milestone stories labelled by track,
116
+ and interface beads between tracks with an owner and a consumer.
117
+ - **Process beads.** When the process itself gets in the way, file a bead labelled
118
+ `process` saying what broke (`bd create --labels process ...`). `/milestone` reviews them
119
+ at the boundary, and fixes that are general land upstream in monkeyshape.
120
+
121
+ ## The milestone boundary
122
+
123
+ The only ceremony, and `/milestone` runs all of it; the skill holds the steps. Between
124
+ boundaries, tracks just work their queues.
125
+
126
+ ## Who decides
127
+
128
+ AGENTS.md has a decision-authority section; fill it in for your repo. The default: humans
129
+ own priorities, milestones, merging, spend above a cap and anything that leaves the machine.
130
+ Agents decide design, refactors, docs, checks and beads within the milestone, and explain
131
+ what they did in the PR body. When in doubt, an agent acts and explains.
package/package.json CHANGED
@@ -1,6 +1,70 @@
1
1
  {
2
2
  "name": "monkeyshape",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "Opinionated checks, configs and conventions for humans and coding agents building together on Bun, TypeScript, Effect and beads.",
5
+ "keywords": [
6
+ "bun",
7
+ "typescript",
8
+ "effect",
9
+ "effect-ts",
10
+ "static-analysis",
11
+ "linter",
12
+ "quality-gate",
13
+ "coding-agents",
14
+ "ai-agents",
15
+ "developer-tools",
16
+ "beads"
17
+ ],
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/clinsky/monkeyshape.git"
22
+ },
23
+ "homepage": "https://github.com/clinsky/monkeyshape#readme",
24
+ "bugs": {
25
+ "url": "https://github.com/clinsky/monkeyshape/issues"
26
+ },
27
+ "type": "module",
28
+ "packageManager": "bun@1.4.2",
29
+ "engines": {
30
+ "bun": ">=1.4.2"
31
+ },
32
+ "bin": {
33
+ "mshape": "./src/cli/main.ts"
34
+ },
35
+ "exports": {
36
+ ".": "./src/api/monkeyshape.ts",
37
+ "./tsconfig.base.json": "./config/tsconfig.base.json",
38
+ "./biome": "./config/biome.base.json"
39
+ },
40
+ "files": [
41
+ "src",
42
+ "config",
43
+ "template",
44
+ "skills",
45
+ "!src/**/*.test.ts",
46
+ "README.md",
47
+ "docs/workflow.md",
48
+ "LICENSE"
49
+ ],
50
+ "scripts": {
51
+ "typecheck": "tsc -p .",
52
+ "lint": "biome ci --error-on-warnings .",
53
+ "fix": "biome check --write .",
54
+ "mshape": "bun src/cli/main.ts",
55
+ "shape": "bun src/cli/main.ts check",
56
+ "check": "bun run typecheck && bun run lint && bun run shape && bun test"
57
+ },
58
+ "dependencies": {
59
+ "oxc-parser": "0.156.0"
60
+ },
61
+ "peerDependencies": {
62
+ "effect": "4.0.0"
63
+ },
64
+ "devDependencies": {
65
+ "@biomejs/biome": "2.5.15",
66
+ "@types/bun": "1.4.2",
67
+ "effect": "4.0.0",
68
+ "typescript": "7.0.2"
69
+ }
70
+ }
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: handoff
3
+ description: Use when the human says /handoff, or asks to wrap up a track's chat because the context is running out or the session is ending. Rewrites the track's handoff so a fresh chat running /track can continue with nothing else.
4
+ ---
5
+
6
+ # Handoff: hand a track to a fresh chat
7
+
8
+ The next session knows only the repo, the beads and the handoff you write now. Write for an
9
+ agent as capable as you who wasn't here: what it needs to continue, not what you did. What a
10
+ change did belongs in its PR body and commits, not here.
11
+
12
+ ## 1. Which track
13
+
14
+ Run `mshape track current`. If it exits 1, tell the human its reason and stop: a handoff
15
+ belongs to a track.
16
+
17
+ ## 2. Leave nothing only in this chat
18
+
19
+ - **Uncommitted work:** if no PR is open from the track branch, commit it there, as a WIP
20
+ commit if it isn't finished, and push. If one is open, a push would add it to the PR:
21
+ leave it uncommitted (the next chat opens in this same worktree) and list it in State.
22
+ Never stash: the stash is shared by every worktree.
23
+ - **Beads:** close what merged; claim what is half done; file what you found and didn't do.
24
+ - **Open PRs:** note each one's number and what it waits on.
25
+
26
+ ## 3. Rewrite the handoff
27
+
28
+ Overwrite `.handoffs/<name>.md`; don't append. Other tracks write to its Messages while you
29
+ work, so read the file again just before writing, and keep every message you hadn't seen.
30
+
31
+ Keep its format: the title, `Status:` and `Queue:` lines, then exactly the sections Charter,
32
+ State (with today's date), Lessons not yet promoted, Traps, Messages, in that order, with
33
+ `###` for headings inside them. About 120 lines at most.
34
+
35
+ - **Charter:** leave it unless the work changed what the track is for; then rewrite it, and
36
+ say in State that it changed and why.
37
+ - **State:** done (PRs and beads, by number), in flight (the branch, the PR, what is half
38
+ done and the next command to run), and next. Concrete enough to act on without asking.
39
+ - **Lessons not yet promoted:** what you learned that should become a check, a test, an
40
+ AGENTS.md gotcha or a decision. If promoting one is quick, do it now instead and delete
41
+ it here. A lesson that is really a bead becomes one.
42
+ - **Traps:** what will bite the next session. Delete traps that are no longer true.
43
+ - **Messages:** delete the answered ones and keep the open ones. Your messages to other
44
+ tracks go in their handoffs, not here.
45
+
46
+ ## 4. Check it and hand over
47
+
48
+ Run `mshape track list`: this track must show `stub` (if the charter isn't agreed yet:
49
+ leave it empty, never write one the human hasn't agreed) or `active`, never `invalid`. If it
50
+ shows `invalid`, each problem is printed under its row: fix them all and run it again. Then
51
+ tell the human, in a few lines: what is done and in flight, any messages they need to relay to another track or decide on, and "open a
52
+ fresh chat in this worktree and run `/track`".
53
+
54
+ Review this skill when a fresh chat had to rediscover something the last one knew.
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: milestone
3
+ description: Use at a milestone boundary, when the human brings priorities for the next stretch of work, or when the repo has a roadmap but no milestone plan yet. Runs the retrospective, agrees a goal with acceptance on real data, writes plan/MILESTONE.md, grooms beads and the roadmap, gardens, and creates the tracks with mshape track.
4
+ ---
5
+
6
+ # Milestone: the mid horizon and the boundary
7
+
8
+ A milestone is the next significant delivery: several PRs from each of several parallel
9
+ tracks. The boundary is the repo's only ceremony, and this skill runs all of it, in order.
10
+ The human owns priorities and approves the plan; you bring the evidence and the proposal.
11
+
12
+ Run this in the main checkout, on an up-to-date `main`, in a fresh chat.
13
+
14
+ ## 1. Gather
15
+
16
+ - plan/MILESTONE.md (the milestone ending), docs/roadmap.md, AGENTS.md.
17
+ - `mshape track list`, and every track's handoff in `.handoffs`: state, lessons not yet
18
+ promoted, messages nobody answered.
19
+ - The milestone's epic and its children (`bd list --parent <epic> --all`), and
20
+ `bd list --label process` for what got in the way.
21
+ - Merged PRs since the plan was written (`gh pr list --state merged`), and their bodies'
22
+ "not done" sections.
23
+ - `mshape garden`.
24
+
25
+ On a repo's first milestone there is nothing to look back on: skip to step 3.
26
+
27
+ ## 2. Retrospective
28
+
29
+ Tell the human, briefly: what shipped against each acceptance line, what slipped and why,
30
+ what the process beads and handoff lessons say, and what you would change. Facts with
31
+ links (PRs, beads), not a story. Ask what they saw that you didn't.
32
+
33
+ ## 3. Agree the goal
34
+
35
+ Propose one goal, from the human's priorities and the roadmap, with **acceptance on real
36
+ data**: a run on a named real target, or a real repo or user doing the thing, never "tests
37
+ pass". A new repo's first milestone is "a first result on a real target". Say what you
38
+ would defer to make it fit, and why. Iterate until the human agrees; don't write the plan
39
+ before that.
40
+
41
+ ## 4. Write plan/MILESTONE.md
42
+
43
+ First move the old plan to notes/, named with today's date (YYYY-MM-DD-milestone-<n>.md).
44
+ Then write the new one, about 500 lines at most:
45
+
46
+ - **Goal, and how we'll know:** the acceptance agreed above.
47
+ - **Where we are:** a gap table, measured where it can be.
48
+ - **What changed since the last milestone, and why.**
49
+ - **Interfaces the tracks share:** every path, command, format or schema two tracks both
50
+ touch, with its owner and consumer, settled before anyone starts. This is the section
51
+ that keeps parallel work from colliding; spend the effort here.
52
+ - **Tracks:** a table of name, charter, beads and acceptance. Split into as many parallel
53
+ tracks as the work allows: each touches disjoint files and meets the others only at the
54
+ interfaces. Derive the number from the work, not a habit: up to about five is usual, and
55
+ one is fine when the work is sequential. When a track ends up holding far more than the
56
+ others, or the riskiest work alongside everything else, split it.
57
+ - **Decision points**, **spend** for big runs, and **deferred items, each with a reason**.
58
+
59
+ The plan is frozen once tracks start. Say so at its top.
60
+
61
+ ## 5. Groom
62
+
63
+ - Create the milestone epic, and its stories as children labelled `track:<name>`, with
64
+ dependencies (`bd dep add`). An interface gets its own bead, owned by one track. A bead
65
+ is intent and an outcome as acceptance, about 1,500 characters at most, not a spec.
66
+ - Pull roadmap epics in with `bd undefer`; close epics whose work is done.
67
+ - Close, defer or rewrite every open story the milestone doesn't need, with a reason. A
68
+ story deferred out of the milestone drops its `track:` label.
69
+ - P1 is the critical path only.
70
+ - Re-verify each bd memory (`bd memories`) against the code; rewrite or delete stale ones.
71
+ - Every `TODO(<bead id>)` in code whose bead is now closed: fix it or re-point it.
72
+
73
+ ## 6. Garden
74
+
75
+ Act on `mshape garden`: anything over budget or grown since the last boundary gets pruned,
76
+ not waived. Promote each handoff lesson to a check, a test, an AGENTS.md gotcha or a
77
+ decision, or delete it. Try to turn each prose rule into a check, and each review finding
78
+ that recurred into one. A process bead whose fix is general belongs upstream in monkeyshape:
79
+ tell the human; filing outside the repo is theirs to approve.
80
+
81
+ ## 7. Roadmap and PR
82
+
83
+ Update docs/roadmap.md: the status table, and what this milestone taught. Then one PR with
84
+ the plan, the roadmap and the garden changes, gate green, the body saying what was decided
85
+ and why. The human merges.
86
+
87
+ ## 8. Tracks
88
+
89
+ Once the PR is merged (or the human says to start):
90
+
91
+ - `mshape track rm <name>` for each finished track whose `beads` column in
92
+ `mshape track list` shows 0. A `-` means beads weren't counted, and `rm` may then remove
93
+ the track with only a note. So first get `bd` working, or check by hand that
94
+ `bd list --label track:<name> --limit 0` lists nothing (it hides only closed beads).
95
+ If `rm` refuses, report the reason; never reach for `--force` without the human. If the
96
+ reason is open beads, `--force` won't help, and grooming has already decided each one:
97
+ move it to the track the new plan gives it, or close it if it's done, and list what you
98
+ did in your report. Ask the human only when the plan doesn't say.
99
+ - `mshape track new <name>` for each new track. Fill its handoff: `Status: active`, the
100
+ charter (its beads, the interfaces it owns or consumes), the state ("not started", and
101
+ how to start), the traps you already know, and messages from the plan.
102
+
103
+ Finish by telling the human what to launch: for each track, the worktree path and "open a
104
+ chat there and run `/track`".
105
+
106
+ Review this skill after each boundary it runs: what the retrospective found about the
107
+ process applies to this file too.