openplanr 2.1.1 → 2.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.
- package/CHANGELOG.md +5 -0
- package/dist/cli/commands/planning-artifacts.d.ts.map +1 -1
- package/dist/cli/commands/planning-artifacts.js +6 -18
- package/dist/cli/commands/planning-artifacts.js.map +1 -1
- package/dist/cli/commands/sprint-refinement.d.ts +5 -0
- package/dist/cli/commands/sprint-refinement.d.ts.map +1 -0
- package/dist/cli/commands/sprint-refinement.js +141 -0
- package/dist/cli/commands/sprint-refinement.js.map +1 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +4 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +5 -8
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/dashboard/.vite/manifest.json +1 -1
- package/dist/dashboard/assets/{index-BCvntXFj.js → index-B74ddyXA.js} +2 -2
- package/dist/dashboard/assets/{index-BCvntXFj.js.map → index-B74ddyXA.js.map} +1 -1
- package/dist/dashboard/dashboard-manifest.json +8 -8
- package/dist/dashboard/index.html +1 -1
- package/dist/models/sprint-refinement-schema.d.ts +122 -0
- package/dist/models/sprint-refinement-schema.d.ts.map +1 -0
- package/dist/models/sprint-refinement-schema.js +147 -0
- package/dist/models/sprint-refinement-schema.js.map +1 -0
- package/dist/models/types.d.ts +8 -0
- package/dist/models/types.d.ts.map +1 -1
- package/dist/services/delivery-status-service.d.ts +6 -1
- package/dist/services/delivery-status-service.d.ts.map +1 -1
- package/dist/services/delivery-status-service.js +28 -1
- package/dist/services/delivery-status-service.js.map +1 -1
- package/dist/services/git-service.d.ts +19 -0
- package/dist/services/git-service.d.ts.map +1 -1
- package/dist/services/git-service.js +41 -0
- package/dist/services/git-service.js.map +1 -1
- package/dist/services/graph-service.d.ts.map +1 -1
- package/dist/services/graph-service.js +3 -1
- package/dist/services/graph-service.js.map +1 -1
- package/dist/services/sprint-refinement-service.d.ts +162 -0
- package/dist/services/sprint-refinement-service.d.ts.map +1 -0
- package/dist/services/sprint-refinement-service.js +645 -0
- package/dist/services/sprint-refinement-service.js.map +1 -0
- package/dist/templates/sprints/refinement.md.hbs +94 -0
- package/dist/templates/sprints/sprint-tasks.md.hbs +16 -0
- package/dist/templates/sprints/sprint.md.hbs +17 -12
- package/dist/utils/constants.d.ts +2 -0
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +6 -1
- package/dist/utils/constants.js.map +1 -1
- package/docs/CLI.md +26 -2
- package/lib/host-packages/adapter-registry.json +1 -1
- package/lib/host-packages/capability-map.json +16 -0
- package/lib/host-packages/claude/openplanr/.openplanr-content.json +27 -7
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/claude/openplanr/skills/openplanr/SKILL.md +1 -0
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/claude/openplanr/skills/sprint/SKILL.md +181 -0
- package/lib/host-packages/claude/openplanr/skills/sprint/openplanr.skill.json +59 -0
- package/lib/host-packages/claude/openplanr/skills/sprint/references/refinement-contract.md +154 -0
- package/lib/host-packages/claude/openplanr/skills/sprint/references/sprint-formats.md +146 -0
- package/lib/host-packages/claude/openplanr/skills/sprint/schemas/refinement.schema.json +140 -0
- package/lib/host-packages/cursor/openplanr/.openplanr-content.json +24 -8
- package/lib/host-packages/cursor/openplanr/manifest.json +2 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-openplanr.mdc +1 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-sprint/references/refinement-contract.md +154 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-sprint/references/sprint-formats.md +146 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-sprint/schemas/refinement.schema.json +140 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-sprint.mdc +180 -0
- package/lib/host-packages/openai/openplanr/.openplanr-content.json +31 -7
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/openai/openplanr/skills/openplanr/SKILL.md +1 -0
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/package.json +1 -1
- package/lib/host-packages/openai/openplanr/skills/sprint/SKILL.md +181 -0
- package/lib/host-packages/openai/openplanr/skills/sprint/agents/openai.yaml +6 -0
- package/lib/host-packages/openai/openplanr/skills/sprint/openplanr.skill.json +59 -0
- package/lib/host-packages/openai/openplanr/skills/sprint/references/refinement-contract.md +154 -0
- package/lib/host-packages/openai/openplanr/skills/sprint/references/sprint-formats.md +146 -0
- package/lib/host-packages/openai/openplanr/skills/sprint/schemas/refinement.schema.json +140 -0
- package/package.json +2 -2
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Refinement contract
|
|
2
|
+
|
|
3
|
+
The refinement document is the durable record of one run: what was read, how
|
|
4
|
+
each item was judged, what was selected and what the refuters changed. The CLI
|
|
5
|
+
validates it (`planr sprint refinement <id> --data`), stores it as
|
|
6
|
+
`.planr/sprints/SPRINT-NNN/refinement.json`, renders `refinement.md` from it
|
|
7
|
+
and fills the sprint body from its batches. `planr sprint diff`, `planr sprint
|
|
8
|
+
close` and `planr sprint apply` read it back.
|
|
9
|
+
|
|
10
|
+
## Item record
|
|
11
|
+
|
|
12
|
+
One entry per open item, whether or not it is selected.
|
|
13
|
+
|
|
14
|
+
| Field | Meaning |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| `id` | Artifact id (`BL-012`, `QT-034`, `TASK-007`). Only artifacts; file non-artifact work as a quick task first. |
|
|
17
|
+
| `title` | The item's title as written. |
|
|
18
|
+
| `claim` | What the item says is wrong or wanted, in one sentence. |
|
|
19
|
+
| `evidenceDate` | The latest dated evidence for the claim (`YYYY-MM-DD`), or `null` when none exists. |
|
|
20
|
+
| `codePath` / `codePathExists` | The code path the item names and whether it still exists on the default branch as described. `null` when the item names none. |
|
|
21
|
+
| `stale` | `true` when the evidence is older than the cadence allows or the code has moved on. |
|
|
22
|
+
| `blockedBy` | The named blockers: `partner: …`, `team decision: …`, `BL-045`. Empty when nothing blocks it. |
|
|
23
|
+
| `unblockQuestion` | The one question whose answer unblocks the item. |
|
|
24
|
+
| `effort` | `hours`, `day`, `days` or `week+`. |
|
|
25
|
+
| `score` | Production impact this month × tractability now. Any consistent scale; only the order matters. |
|
|
26
|
+
| `bucket` | `inProgress`, `planNext`, `blocked` or `closeOrDemote`. |
|
|
27
|
+
| `reason` | One clause: why the item sits in that bucket. |
|
|
28
|
+
| `evidence` | For close-or-demote rows: `file:line`, PR number or date. |
|
|
29
|
+
| `targetStatus` / `targetPriority` | What `planr sprint apply` writes, in the repository's own vocabulary (`planr update --help`). Priority applies to backlog items only. |
|
|
30
|
+
|
|
31
|
+
## Scoring
|
|
32
|
+
|
|
33
|
+
Score = production impact this month × tractability now.
|
|
34
|
+
|
|
35
|
+
- Impact counts users hit, money or compliance at stake, and whether the
|
|
36
|
+
release cut depends on it. An item nobody is hit by this month scores low
|
|
37
|
+
regardless of its label.
|
|
38
|
+
- Tractability counts whether the fix is known, whether the code path exists,
|
|
39
|
+
whether a migration or a partner is needed, and whether the item is already
|
|
40
|
+
half done.
|
|
41
|
+
- Evidence date beats priority label. A P0 from months ago with no fresh
|
|
42
|
+
evidence is a candidate for close-or-demote, not for in progress.
|
|
43
|
+
|
|
44
|
+
## Buckets
|
|
45
|
+
|
|
46
|
+
| Bucket | Rule |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `inProgress` | Fits the stated capacity to the cut. Ordered for execution and grouped into `batches` (PR batches by product, or sessions). Includes the release cut itself as work. |
|
|
49
|
+
| `planNext` | Real and tractable, but after the cut. |
|
|
50
|
+
| `blocked` | Blocked on a partner, a team decision or another item. Never in progress. Carries `blockedBy` and `unblockQuestion`. |
|
|
51
|
+
| `closeOrDemote` | Dead, duplicated, overtaken or already delivered. Carries `evidence` and the `targetStatus` or `targetPriority` the write-back applies. |
|
|
52
|
+
|
|
53
|
+
Every item is in exactly one bucket; `buckets.<name>` lists the ids and each
|
|
54
|
+
item's `bucket` field agrees. `batches[].itemIds` partition `buckets.inProgress`
|
|
55
|
+
exactly.
|
|
56
|
+
|
|
57
|
+
## Refuter lenses
|
|
58
|
+
|
|
59
|
+
Run all three over every in-progress pick before the buckets are shown.
|
|
60
|
+
|
|
61
|
+
| Lens | Question | Typical corrections |
|
|
62
|
+
| --- | --- | --- |
|
|
63
|
+
| `evidence` | Is it still real on the default branch? Is the premise true? Was it already fixed? | Dropped picks, moves to close-or-demote |
|
|
64
|
+
| `capacity` | Does the list fit the days? Are migrations, partner dependencies, PR batching and CI cost per PR accounted for? | Splits, reorders, moves to plan-next |
|
|
65
|
+
| `impact` | Who is hit this month if it is not done? Which higher-impact item was omitted for it? | Swaps, moves to plan-next |
|
|
66
|
+
|
|
67
|
+
A pick that fails a lens moves or drops, and the correction is recorded in
|
|
68
|
+
`refuted[]` as `{ itemId, lens, change, from, to }`. Nothing is deleted from
|
|
69
|
+
`items[]`; the item keeps its new bucket and reason.
|
|
70
|
+
|
|
71
|
+
## `refinement.json`
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"schemaVersion": 1,
|
|
76
|
+
"sprintId": "SPRINT-004",
|
|
77
|
+
"refinedAt": "2026-09-17",
|
|
78
|
+
"inputs": {
|
|
79
|
+
"capacityDays": 6,
|
|
80
|
+
"releaseCut": "2026-09-25",
|
|
81
|
+
"gitRevision": "a1b2c3d",
|
|
82
|
+
"previousSprintId": "SPRINT-003",
|
|
83
|
+
"operateCycleId": "OP-2026-09-A",
|
|
84
|
+
"sources": ["backlog", "quick", "git", "release-profile"],
|
|
85
|
+
"defaulted": ["capacity"],
|
|
86
|
+
"notes": "Connector not configured; statuses stay local."
|
|
87
|
+
},
|
|
88
|
+
"items": [
|
|
89
|
+
{
|
|
90
|
+
"id": "BL-345",
|
|
91
|
+
"title": "CRM callback silent since 10 Sep",
|
|
92
|
+
"claim": "Callbacks from the CRM stopped landing on 10 Sep",
|
|
93
|
+
"evidenceDate": "2026-09-16",
|
|
94
|
+
"codePath": "apps/apply/src/crm/callback.ts",
|
|
95
|
+
"codePathExists": true,
|
|
96
|
+
"stale": false,
|
|
97
|
+
"blockedBy": [],
|
|
98
|
+
"effort": "hours",
|
|
99
|
+
"score": 9.5,
|
|
100
|
+
"bucket": "inProgress",
|
|
101
|
+
"reason": "39 applications stuck at Received"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"id": "BL-295",
|
|
105
|
+
"title": "Importer drops trailing rows",
|
|
106
|
+
"evidenceDate": "2026-05-02",
|
|
107
|
+
"stale": true,
|
|
108
|
+
"blockedBy": [],
|
|
109
|
+
"effort": "days",
|
|
110
|
+
"score": 0.5,
|
|
111
|
+
"bucket": "closeOrDemote",
|
|
112
|
+
"reason": "delivered by #569",
|
|
113
|
+
"evidence": "PR #569 merged 2026-09-08",
|
|
114
|
+
"targetStatus": "closed"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "BL-167",
|
|
118
|
+
"title": "Dynamics id for the Austrian Matura",
|
|
119
|
+
"evidenceDate": "2026-08-30",
|
|
120
|
+
"stale": false,
|
|
121
|
+
"blockedBy": ["partner: Dynamics team"],
|
|
122
|
+
"unblockQuestion": "Which Dynamics id represents the Austrian Matura?",
|
|
123
|
+
"effort": "day",
|
|
124
|
+
"score": 4,
|
|
125
|
+
"bucket": "blocked",
|
|
126
|
+
"reason": "needs the partner mapping"
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"buckets": {
|
|
130
|
+
"inProgress": ["BL-345"],
|
|
131
|
+
"planNext": [],
|
|
132
|
+
"blocked": ["BL-167"],
|
|
133
|
+
"closeOrDemote": ["BL-295"]
|
|
134
|
+
},
|
|
135
|
+
"batches": [
|
|
136
|
+
{ "title": "VM read session", "effortDays": 0.5, "itemIds": ["BL-345"] }
|
|
137
|
+
],
|
|
138
|
+
"refuted": [
|
|
139
|
+
{
|
|
140
|
+
"itemId": "BL-295",
|
|
141
|
+
"lens": "evidence",
|
|
142
|
+
"change": "delivered 8 Sep, moved to close",
|
|
143
|
+
"from": "inProgress",
|
|
144
|
+
"to": "closeOrDemote"
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`inputs.sources` names what was read; `inputs.defaulted` names every value
|
|
151
|
+
taken from a default instead of the repository or the user. The CLI adds
|
|
152
|
+
`leftovers[]` on `planr sprint close` and `applied` on `planr sprint apply`;
|
|
153
|
+
never write those yourself. Unknown fields are rejected, so keep notes in
|
|
154
|
+
`inputs.notes` or in the item's `reason`.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Sprint formats
|
|
2
|
+
|
|
3
|
+
Three durable outputs and one chat return. The CLI writes the first three from
|
|
4
|
+
the two JSON inputs below; when it is unavailable, write the same files by hand.
|
|
5
|
+
|
|
6
|
+
## `sprint.json` (input to `planr sprint create --data`)
|
|
7
|
+
|
|
8
|
+
```json
|
|
9
|
+
{
|
|
10
|
+
"title": "Cut 25 Sep 2026",
|
|
11
|
+
"startDate": "2026-09-17",
|
|
12
|
+
"releaseCut": "2026-09-25",
|
|
13
|
+
"capacityDays": 6,
|
|
14
|
+
"goals": ["Unblock stuck applications", "Ship the cut"]
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`endDate` defaults to `releaseCut`, or to `startDate` plus the duration when no
|
|
19
|
+
cut is known. `status` may be `planned` or `active` (default). Omit `taskIds`
|
|
20
|
+
and `batches`; `planr sprint refinement` fills them from the refinement
|
|
21
|
+
document.
|
|
22
|
+
|
|
23
|
+
## Sprint artifact
|
|
24
|
+
|
|
25
|
+
`.planr/sprints/SPRINT-NNN-<slug>.md`: the existing frontmatter plus three
|
|
26
|
+
fields, and the In-progress bucket as checkboxes grouped by batch.
|
|
27
|
+
|
|
28
|
+
```markdown
|
|
29
|
+
---
|
|
30
|
+
id: "SPRINT-004"
|
|
31
|
+
name: "Cut 25 Sep 2026"
|
|
32
|
+
startDate: "2026-09-17"
|
|
33
|
+
endDate: "2026-09-25"
|
|
34
|
+
duration: "8d"
|
|
35
|
+
status: "active"
|
|
36
|
+
releaseCut: "2026-09-25"
|
|
37
|
+
capacityDays: 6
|
|
38
|
+
created: "2026-09-17"
|
|
39
|
+
updated: "2026-09-17"
|
|
40
|
+
taskIds: ["BL-345", "BL-348", "QT-194"]
|
|
41
|
+
refinedAt: "2026-09-17"
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
# SPRINT-004: Cut 25 Sep 2026
|
|
45
|
+
|
|
46
|
+
## Sprint Details
|
|
47
|
+
|
|
48
|
+
- **Duration:** 8d
|
|
49
|
+
- **Start:** 2026-09-17
|
|
50
|
+
- **End:** 2026-09-25
|
|
51
|
+
- **Status:** ACTIVE
|
|
52
|
+
- **Release cut:** 2026-09-25
|
|
53
|
+
- **Capacity:** 6 engineer-days
|
|
54
|
+
|
|
55
|
+
## Tasks
|
|
56
|
+
|
|
57
|
+
### VM read session · 0.5d
|
|
58
|
+
|
|
59
|
+
- [ ] **BL-345** CRM callback silent since 10 Sep · hours · [view](../backlog/BL-345-crm-callback-silent.md)
|
|
60
|
+
|
|
61
|
+
### PR 1 · MUVi Apply · 1d
|
|
62
|
+
|
|
63
|
+
- [ ] **BL-348** rag-api cannot reach the department API · day · [view](../backlog/BL-348-rag-api.md)
|
|
64
|
+
- [ ] **QT-194** Release cut 25 Sep · hours · [view](../quick/QT-194-release-cut-25-sep.md)
|
|
65
|
+
|
|
66
|
+
## Retrospective
|
|
67
|
+
_Complete this section when closing the sprint with `planr sprint close SPRINT-004`._
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Each task line is `- [ ] **ID** title · effort · [view](relative path)`.
|
|
71
|
+
`planr status`, `planr sprint close` and the dashboard read these lines; tick a
|
|
72
|
+
box when the item ships. `releaseCut` is absent when no release profile exists;
|
|
73
|
+
`capacityDays` and `refinedAt` are absent until a refinement is recorded.
|
|
74
|
+
|
|
75
|
+
## Refinement note
|
|
76
|
+
|
|
77
|
+
`.planr/sprints/SPRINT-NNN/refinement.md`, rendered from the JSON so the next
|
|
78
|
+
run can diff against it:
|
|
79
|
+
|
|
80
|
+
- **Inputs**: capacity, release cut, git revision, previous sprint, Operate
|
|
81
|
+
cycle, sources read, values defaulted.
|
|
82
|
+
- **Items**: one table row per open item: `ID · score · evidence date · stale?
|
|
83
|
+
· blocked by · effort · bucket`.
|
|
84
|
+
- **Refuter verdicts**: every correction verbatim, with its lens.
|
|
85
|
+
- **In progress** by batch, then **Plan next**, **Blocked** and **Close or
|
|
86
|
+
demote** in full, since only In progress goes into the sprint.
|
|
87
|
+
- **Leftovers** (after `planr sprint close`) and **Applied** (after
|
|
88
|
+
`planr sprint apply`).
|
|
89
|
+
|
|
90
|
+
## Machine-readable copy
|
|
91
|
+
|
|
92
|
+
`.planr/sprints/SPRINT-NNN/refinement.json`: the document described in
|
|
93
|
+
[the refinement contract](refinement-contract.md), validated against the JSON
|
|
94
|
+
Schema packaged as `schemas/refinement.schema.json` (linked from the skill
|
|
95
|
+
entrypoint). The dashboard, `planr sprint diff` and `planr sprint apply` consume
|
|
96
|
+
it.
|
|
97
|
+
|
|
98
|
+
## Status write-back
|
|
99
|
+
|
|
100
|
+
Only on approval through the structured question. `planr sprint apply
|
|
101
|
+
SPRINT-NNN --yes --commit` writes each close, demote or blocked row's
|
|
102
|
+
`targetStatus`, `targetPriority` and `blockedBy` to the artifacts and commits the
|
|
103
|
+
sprint, the note, the JSON and the changed artifacts as one commit:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
chore(planr): refine backlog for SPRINT-NNN
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Example chat return
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
Outcome: proposed · 5.8 of 6 engineer-days used · SPRINT-004 (cut 25 Sep)
|
|
113
|
+
Sprint: .planr/sprints/SPRINT-004-cut-25-sep-2026.md
|
|
114
|
+
|
|
115
|
+
In progress (execution order)
|
|
116
|
+
VM read session · 0.5d
|
|
117
|
+
BL-345 CRM callback silent since 10 Sep, 39 applications stuck at Received
|
|
118
|
+
BL-348 rag-api cannot reach the department API (+ missing api key)
|
|
119
|
+
PR 1 · MUVi Apply · 1d
|
|
120
|
+
BL-282 self-healing where clause
|
|
121
|
+
BL-229 write-side GUID check only (rest 9 Oct)
|
|
122
|
+
PR 2 · Connect residuals · 0.75d
|
|
123
|
+
BL-360, BL-364, BL-368, BL-056 (D3 only)
|
|
124
|
+
Ops readiness · 1.5d · QT-194 the cut · 0.5d
|
|
125
|
+
|
|
126
|
+
Plan next (9 Oct) BL-224, BL-043, BL-283, BL-014, BL-349 code, … (14 items)
|
|
127
|
+
Blocked BL-167 partner: Dynamics id for Austrian Matura?
|
|
128
|
+
BL-272 team: which English tests carry a score? (31 items)
|
|
129
|
+
Close or demote BL-295 done by #569 · BL-327 done by #590 · BL-197 P1 dead 14 Sep … (42 items)
|
|
130
|
+
|
|
131
|
+
Refuted BL-342 evidence: no server actions in muvi-apply, dropped
|
|
132
|
+
BL-229 impact: no applicant hit this month, split
|
|
133
|
+
BL-295 evidence: delivered 8 Sep, moved to close
|
|
134
|
+
Issues none
|
|
135
|
+
Next approve write-back: planr sprint apply SPRINT-004 --yes --commit
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Hand-written fallback
|
|
139
|
+
|
|
140
|
+
Without the CLI, create the three files above yourself: allocate the next
|
|
141
|
+
`SPRINT-NNN`, write the frontmatter and the batched checkboxes exactly as shown,
|
|
142
|
+
write `refinement.json` to the schema and `refinement.md` from it, and apply the
|
|
143
|
+
status changes with the repository's own vocabulary in one commit with the same
|
|
144
|
+
message. Never store notes as `.planr/sprints/SPRINT-NNN-*.md` siblings; graph
|
|
145
|
+
readers treat every `.md` in `sprints/` as a sprint and skip only the
|
|
146
|
+
`SPRINT-NNN/` directory.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openplanr.dev/schemas/skills/planr-sprint/refinement.schema.json",
|
|
4
|
+
"title": "OpenPlanr sprint refinement document",
|
|
5
|
+
"description": "One backlog refinement run: inputs, every open item's judgement, the four buckets, the in-progress batches and the refuter corrections. Written by the planr-sprint skill and validated by planr sprint refinement.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["schemaVersion", "sprintId", "refinedAt", "inputs", "items", "buckets"],
|
|
9
|
+
"$defs": {
|
|
10
|
+
"isoDate": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
|
|
11
|
+
"artifactId": { "type": "string", "pattern": "^[A-Z]+-\\d+$" },
|
|
12
|
+
"sprintId": { "type": "string", "pattern": "^SPRINT-\\d+$" },
|
|
13
|
+
"text": { "type": "string", "minLength": 1 },
|
|
14
|
+
"bucket": { "enum": ["inProgress", "planNext", "blocked", "closeOrDemote"] },
|
|
15
|
+
"effort": { "enum": ["hours", "day", "days", "week+"] },
|
|
16
|
+
"lens": { "enum": ["evidence", "capacity", "impact"] },
|
|
17
|
+
"idList": { "type": "array", "items": { "$ref": "#/$defs/artifactId" } }
|
|
18
|
+
},
|
|
19
|
+
"properties": {
|
|
20
|
+
"schemaVersion": { "const": 1 },
|
|
21
|
+
"sprintId": { "$ref": "#/$defs/sprintId" },
|
|
22
|
+
"refinedAt": { "$ref": "#/$defs/isoDate" },
|
|
23
|
+
"inputs": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"additionalProperties": false,
|
|
26
|
+
"properties": {
|
|
27
|
+
"capacityDays": { "type": "number", "exclusiveMinimum": 0 },
|
|
28
|
+
"releaseCut": { "$ref": "#/$defs/isoDate" },
|
|
29
|
+
"gitRevision": { "$ref": "#/$defs/text" },
|
|
30
|
+
"previousSprintId": { "$ref": "#/$defs/sprintId" },
|
|
31
|
+
"operateCycleId": { "$ref": "#/$defs/text" },
|
|
32
|
+
"sources": { "type": "array", "items": { "$ref": "#/$defs/text" }, "default": [] },
|
|
33
|
+
"defaulted": { "type": "array", "items": { "$ref": "#/$defs/text" }, "default": [] },
|
|
34
|
+
"notes": { "$ref": "#/$defs/text" }
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"items": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"items": {
|
|
40
|
+
"type": "object",
|
|
41
|
+
"additionalProperties": false,
|
|
42
|
+
"required": ["id", "title", "effort", "score", "bucket", "reason"],
|
|
43
|
+
"properties": {
|
|
44
|
+
"id": { "$ref": "#/$defs/artifactId" },
|
|
45
|
+
"title": { "$ref": "#/$defs/text" },
|
|
46
|
+
"claim": { "$ref": "#/$defs/text" },
|
|
47
|
+
"evidenceDate": { "oneOf": [{ "$ref": "#/$defs/isoDate" }, { "type": "null" }], "default": null },
|
|
48
|
+
"codePath": { "oneOf": [{ "$ref": "#/$defs/text" }, { "type": "null" }] },
|
|
49
|
+
"codePathExists": { "type": ["boolean", "null"] },
|
|
50
|
+
"stale": { "type": "boolean", "default": false },
|
|
51
|
+
"blockedBy": { "type": "array", "items": { "$ref": "#/$defs/text" }, "default": [] },
|
|
52
|
+
"unblockQuestion": { "$ref": "#/$defs/text" },
|
|
53
|
+
"effort": { "$ref": "#/$defs/effort" },
|
|
54
|
+
"score": { "type": "number" },
|
|
55
|
+
"bucket": { "$ref": "#/$defs/bucket" },
|
|
56
|
+
"reason": { "$ref": "#/$defs/text" },
|
|
57
|
+
"evidence": { "$ref": "#/$defs/text" },
|
|
58
|
+
"targetStatus": { "$ref": "#/$defs/text" },
|
|
59
|
+
"targetPriority": { "$ref": "#/$defs/text" }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"buckets": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"required": ["inProgress", "planNext", "blocked", "closeOrDemote"],
|
|
67
|
+
"properties": {
|
|
68
|
+
"inProgress": { "$ref": "#/$defs/idList" },
|
|
69
|
+
"planNext": { "$ref": "#/$defs/idList" },
|
|
70
|
+
"blocked": { "$ref": "#/$defs/idList" },
|
|
71
|
+
"closeOrDemote": { "$ref": "#/$defs/idList" }
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"batches": {
|
|
75
|
+
"type": "array",
|
|
76
|
+
"default": [],
|
|
77
|
+
"items": {
|
|
78
|
+
"type": "object",
|
|
79
|
+
"additionalProperties": false,
|
|
80
|
+
"required": ["title", "itemIds"],
|
|
81
|
+
"properties": {
|
|
82
|
+
"title": { "$ref": "#/$defs/text" },
|
|
83
|
+
"effortDays": { "type": "number", "exclusiveMinimum": 0 },
|
|
84
|
+
"itemIds": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/artifactId" } }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"refuted": {
|
|
89
|
+
"type": "array",
|
|
90
|
+
"default": [],
|
|
91
|
+
"items": {
|
|
92
|
+
"type": "object",
|
|
93
|
+
"additionalProperties": false,
|
|
94
|
+
"required": ["itemId", "lens", "change"],
|
|
95
|
+
"properties": {
|
|
96
|
+
"itemId": { "$ref": "#/$defs/artifactId" },
|
|
97
|
+
"lens": { "$ref": "#/$defs/lens" },
|
|
98
|
+
"change": { "$ref": "#/$defs/text" },
|
|
99
|
+
"from": { "$ref": "#/$defs/bucket" },
|
|
100
|
+
"to": { "enum": ["inProgress", "planNext", "blocked", "closeOrDemote", "dropped"] }
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"leftovers": {
|
|
105
|
+
"description": "Written by planr sprint close.",
|
|
106
|
+
"type": "array",
|
|
107
|
+
"items": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"additionalProperties": false,
|
|
110
|
+
"required": ["id", "reason"],
|
|
111
|
+
"properties": {
|
|
112
|
+
"id": { "$ref": "#/$defs/artifactId" },
|
|
113
|
+
"reason": { "enum": ["unchecked", "not-done"] }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"applied": {
|
|
118
|
+
"description": "Written by planr sprint apply.",
|
|
119
|
+
"type": "object",
|
|
120
|
+
"additionalProperties": false,
|
|
121
|
+
"required": ["at", "updates"],
|
|
122
|
+
"properties": {
|
|
123
|
+
"at": { "$ref": "#/$defs/text" },
|
|
124
|
+
"updates": {
|
|
125
|
+
"type": "array",
|
|
126
|
+
"items": {
|
|
127
|
+
"type": "object",
|
|
128
|
+
"additionalProperties": false,
|
|
129
|
+
"required": ["id", "type", "fields"],
|
|
130
|
+
"properties": {
|
|
131
|
+
"id": { "$ref": "#/$defs/artifactId" },
|
|
132
|
+
"type": { "$ref": "#/$defs/text" },
|
|
133
|
+
"fields": { "type": "object", "additionalProperties": { "type": "string" } }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openplanr",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Deterministic OpenPlanr utilities for planning storage, validation, rendering, setup, diagnostics, and GitHub/Linear synchronization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cli/index.js",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"zod": "^4.3.6"
|
|
116
116
|
},
|
|
117
117
|
"optionalDependencies": {
|
|
118
|
-
"planr-pipeline": "0.45.
|
|
118
|
+
"planr-pipeline": "0.45.2"
|
|
119
119
|
},
|
|
120
120
|
"devDependencies": {
|
|
121
121
|
"@biomejs/biome": "^2.4.9",
|