k0-board 0.4.0 → 0.6.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 (77) hide show
  1. package/.claude/skills/k0-changelog/SKILL.md +2 -2
  2. package/.claude/skills/k0-discuss/SKILL.md +105 -0
  3. package/.claude/skills/k0-discuss/references/rounds.md +280 -0
  4. package/.claude/skills/k0-epic/SKILL.md +196 -0
  5. package/.claude/skills/k0-links/.claude-plugin/plugin.json +6 -0
  6. package/.claude/skills/k0-links/hooks/hooks.json +1 -0
  7. package/.claude/skills/k0-links/hooks/links.js +128 -0
  8. package/.claude/skills/k0-links/hooks/register.js +204 -0
  9. package/.claude/skills/k0-next/SKILL.md +82 -0
  10. package/.claude/skills/k0-order/SKILL.md +123 -0
  11. package/.claude/skills/k0-plan/SKILL.md +156 -0
  12. package/.claude/skills/k0-split/SKILL.md +169 -0
  13. package/.claude/skills/k0-story/SKILL.md +108 -0
  14. package/.claude/skills/k0-ultracode/SKILL.md +251 -0
  15. package/.claude/skills/k0-ultracode/references/agent-brief.md +71 -0
  16. package/.claude/skills/k0-ultracode/references/modes.md +49 -0
  17. package/.claude/skills/k0-verify/SKILL.md +219 -0
  18. package/.claude/skills/k0-whatsnew/SKILL.md +95 -0
  19. package/.claude/skills/k0-work/SKILL.md +212 -0
  20. package/CHANGELOG.md +426 -1
  21. package/LICENSE +83 -18
  22. package/README.md +1141 -119
  23. package/bin/k0-board.js +127 -12
  24. package/menubar/K0MenuBar.swift +35 -5
  25. package/package.json +14 -2
  26. package/platform/contract.js +30 -5
  27. package/platform/darwin/terminal.js +230 -56
  28. package/platform/index.js +2 -1
  29. package/platform/linux/index.js +3 -0
  30. package/platform/linux/tray.py +10 -10
  31. package/platform/shared/command.js +19 -3
  32. package/platform/shared/tmux.js +32 -14
  33. package/platform/win32/index.js +5 -2
  34. package/platform/win32/terminal.js +24 -8
  35. package/platform/win32/tray.ps1 +13 -13
  36. package/server/backlog.js +618 -0
  37. package/server/changelog.js +13 -13
  38. package/server/cloud.js +355 -0
  39. package/server/db.js +2117 -146
  40. package/server/files.js +60 -21
  41. package/server/git.js +53 -14
  42. package/server/idle.js +15 -13
  43. package/server/index.js +1341 -186
  44. package/server/launcher.js +122 -14
  45. package/server/machine.js +10 -1
  46. package/server/mirror.js +1069 -0
  47. package/server/prices.js +59 -0
  48. package/server/projects.js +57 -12
  49. package/server/servers.js +22 -1
  50. package/server/sessions.js +5 -5
  51. package/server/settings.js +25 -2
  52. package/server/sync.js +383 -0
  53. package/server/update.js +325 -0
  54. package/server/usage.js +642 -0
  55. package/server/watcher.js +67 -13
  56. package/server/worktree.js +600 -0
  57. package/server/writer.js +98 -26
  58. package/web/account.js +265 -0
  59. package/web/awake.js +62 -0
  60. package/web/base.css +97 -0
  61. package/web/board.css +396 -16
  62. package/web/board.js +1182 -152
  63. package/web/changelog.js +3 -3
  64. package/web/files.js +73 -16
  65. package/web/index.html +110 -12
  66. package/web/list.css +536 -0
  67. package/web/list.js +1015 -0
  68. package/web/mentions.js +27 -9
  69. package/web/recency.js +10 -10
  70. package/web/units.js +1 -1
  71. package/web/usage.css +169 -0
  72. package/web/usage.html +78 -0
  73. package/web/usage.js +447 -0
  74. package/web/view.js +22 -3
  75. package/web/whatsnew.css +211 -0
  76. package/web/whatsnew.html +49 -0
  77. package/web/whatsnew.js +339 -0
@@ -0,0 +1,251 @@
1
+ ---
2
+ name: k0-ultracode
3
+ description: Runs a whole epic — or one story — as a manager with agents under it: it takes what the board already knows, cuts the plan into assignments, hands each one to an agent working in an isolated copy of the repository, brings the work back one piece at a time, and closes every story with the tests, a fresh pair of eyes and the counter-check before moving to the next. Use this skill when the user types "/k0-ultracode" or "/k0-ultracode K7", or says "run the whole epic", "take this and go", "do it with agents", "hand it to the manager", "fallo tutto tu", "porta avanti l'epica", "usa gli agenti", "vai fino in fondo". Do not use it to talk a story through (that is /k0-discuss), to write a plan and stop (/k0-plan), to do one story by hand in one session (/k0-work), or to push, tag or release anything (/commit-push-deploy).
4
+ ---
5
+
6
+ # /k0-ultracode [key]
7
+
8
+ One manager, several agents, and a board that says at every moment where the work is.
9
+
10
+ `[key]` is an epic such as `K7` or a story such as `K42`. With no argument, the story is the one
11
+ this session is attached to. With something that is not a key — a sentence, a file — there is
12
+ nothing on the board yet, and §2 puts it there before anything else happens.
13
+
14
+ Three words are used here and nowhere else in k0. The **manager** is you, this session. An
15
+ **assignment** is one slice of a plan. An **agent** is a subagent that carries out exactly one
16
+ assignment in a copy of the repository of its own. Agents never speak to the user: everything the
17
+ user hears comes from the manager.
18
+
19
+ ## 1. Find what you were pointed at
20
+
21
+ ```bash
22
+ PORT="${K0_PORT:-4319}"
23
+ REPO="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null)"; REPO="${REPO%/.git}"
24
+ [ -d "$REPO" ] || REPO="$(git rev-parse --show-toplevel 2>/dev/null)"
25
+ curl -sS --max-time 30 --get --data-urlencode "repo=$REPO" \
26
+ "http://127.0.0.1:$PORT/api/backlog" -o "$SCRATCH/k0-backlog.json"
27
+ ```
28
+
29
+ `127.0.0.1`, not `k0.localhost`: browsers resolve that name by themselves, `curl` does not.
30
+ `--get --data-urlencode`, not `?repo=$REPO`: a repository path with a space in it makes `curl`
31
+ refuse the address outright, and one with a `#` in it quietly sends half. `$SCRATCH` is the
32
+ session's scratch directory, and nothing is written outside it and the worktrees of §6.
33
+
34
+ - `curl` cannot connect → the k0 server is not running. Say so (`k0-board start`, or the tray
35
+ icon → *Restart*) and **stop**.
36
+ - `{"enabled": false}` → say in one line that the k0 backlog is switched off and **stop**.
37
+ - `REPO` empty → this is not a git repository. Ask once which repository this belongs to and take
38
+ the path he gives.
39
+
40
+ An epic key gives the epic and the stories under it, in the order the board already has them and
41
+ with the dependencies it already knows. A story key gives one story. If two things could be meant,
42
+ ask once, showing both.
43
+
44
+ ## 2. Nothing on the board yet
45
+
46
+ A sentence said out loud, a document, an idea: it goes onto the board first, because everything
47
+ after this reads the board and nothing else.
48
+
49
+ - Something big — a feature, an area of the product → `/k0-epic`: its rounds, its decisions, its
50
+ tree of stories, approved before a line is written.
51
+ - One thing he already knows he wants → `/k0-story`, and carry on here.
52
+
53
+ Follow those skills rather than paraphrasing them. When they are done there is a key, and §3 starts
54
+ on it.
55
+
56
+ ## 3. Ask once: how much rope, and how hard
57
+
58
+ One `AskUserQuestion`, two questions, and **never a `preview` on an option** — the free-text box
59
+ disappears when there is one, and this is the moment he is most likely to want it.
60
+
61
+ **How much rope** — `interactive`, `checkpoint` or `autonomous`. **How hard** — `light`, `medium`
62
+ (the default) or `hard`. What each one means, how many agents it allows at once, how many repair
63
+ attempts it buys and where it stops is in `references/modes.md`. Read it now and hold it for the
64
+ whole run; the path is relative to the folder this skill was loaded from.
65
+
66
+ Say the answer back in one line — "autonomous, medium: three agents at a time, two repair
67
+ attempts, and I come back when the epic is done or when something is genuinely stuck" — and write
68
+ that same line into the Log of the epic, or of the story when there is no epic. That line is the
69
+ contract, and §9 reads it back after a crash.
70
+
71
+ ## 4. One story at a time
72
+
73
+ Stories are taken in the board's order, and a story whose dependencies are not `Done` waits for
74
+ them. A story is finished — merged, tested, counter-checked — before the next one starts. On an
75
+ epic that is the whole point: a mistake caught in the first story is a mistake the other six never
76
+ inherit.
77
+
78
+ For each story, §5 to §8, then a Log entry saying it is closed, then the next one.
79
+
80
+ ## 5. Decisions, a plan, and the cut
81
+
82
+ ```bash
83
+ curl -sS --max-time 30 "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" -o "$SCRATCH/k0-story.json"
84
+ ```
85
+
86
+ `$STORY_ID` is the `id` of the story, not its key.
87
+
88
+ - **No decisions** → the rounds of `../k0-discuss/references/rounds.md`, which is also where the
89
+ shape of a decision and the collision rule live. In `autonomous` only the questions that would
90
+ change the work get asked; the rest you settle yourself and write down as assumptions (§8), never
91
+ as decisions.
92
+ - **No plan** → write one in the shape `/k0-plan` gives it: `## What you get`, then
93
+ `## Constraints — already decided` listing every standing decision verbatim **by `label`**, then
94
+ steps that each end with the labels they serve. Store it and move the story on:
95
+
96
+ ```bash
97
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/plan" \
98
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-plan.json" # {"text": "…"}
99
+ curl -sS --max-time 30 -X PATCH "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" \
100
+ -H 'content-type: application/json' -d '{"state": "Planned"}'
101
+ ```
102
+
103
+ - **The decisions that are still standing** are the constraints every agent works under. Leave out
104
+ any with `superseded_by` set, and call each one by its `label` and never by its number: an
105
+ inherited one is `K7·D3`, and the story may have a `D3` of its own saying something else entirely.
106
+
107
+ Then cut the plan into **assignments**, and cut it by file:
108
+
109
+ - two assignments that would write the same file are one assignment, or they are done one after the
110
+ other — never at the same time;
111
+ - an assignment that cannot be described without naming another one is not ready to be cut;
112
+ - where the repository's own `CLAUDE.md` asks for documentation with every change — k0's does — the
113
+ last assignment of every story is the documentation and the changelog line.
114
+
115
+ One `TaskCreate` per assignment, in order, plus one for the merge and one for the counter-check;
116
+ exactly one `in_progress` at a time. If `TaskCreate` is not among your tools, say so in one line and
117
+ carry on with the Log alone — never call it again to see whether it has come back.
118
+
119
+ Write the cut into the Log before an agent is spawned: what each assignment is, which files it
120
+ owns, which of them run together. In `interactive` and `checkpoint`, show it and wait.
121
+
122
+ ## 6. The worktrees
123
+
124
+ Every agent writes in a copy of the repository of its own, and the manager owns all of them.
125
+
126
+ ```
127
+ <the branch you are on>
128
+ └─ k0u-K42 the story's own branch → $SCRATCH/k0u/K42
129
+ ├─ k0u-K42-a1 assignment 1 → $SCRATCH/k0u/K42-a1
130
+ └─ k0u-K42-a2 assignment 2 → $SCRATCH/k0u/K42-a2
131
+ ```
132
+
133
+ ```bash
134
+ git -C "$REPO" worktree add -b "k0u-$KEY" "$SCRATCH/k0u/$KEY" HEAD
135
+ git -C "$REPO" worktree add -b "k0u-$KEY-a1" "$SCRATCH/k0u/$KEY-a1" "k0u-$KEY"
136
+ ```
137
+
138
+ From the branch you are on — not `main`, not `origin`. No `git pull`, no `git fetch`, no checking
139
+ out anything else first: if the user is on a feature branch, that is the branch this work belongs
140
+ to and the branch the merge goes back into.
141
+
142
+ They live in the session's scratch directory rather than in `.claude/worktrees/`, which belongs to
143
+ k0 and is swept by the server. They have no `.env` and no `node_modules`, and that is not an
144
+ oversight: it is the physical reason an agent cannot start a server or run a suite even if it
145
+ forgets it was told not to.
146
+
147
+ k0's own `POST /api/backlog/worktree` is not used here. It records one worktree against one
148
+ session, and `POST /api/backlog/story/:id/start` opens a real terminal window — on an epic of eight
149
+ stories that would be eight windows. The board stays honest all the same, because the state and the
150
+ Log are written by the manager.
151
+
152
+ ## 7. The agents
153
+
154
+ One agent per assignment, `general-purpose`, on the model this session is already running. How many
155
+ run at once is the number `references/modes.md` gave you in §3 and no more: a fourth agent waits for
156
+ a free slot rather than starting.
157
+
158
+ What an agent is handed and what it owes back is `references/agent-brief.md` — the assignment, the
159
+ standing decisions verbatim by label, the path of its worktree as the only place on disk it may
160
+ write, and the shape of its report. Read it before spawning the first one.
161
+
162
+ An agent cannot ask the user anything. It comes back with its questions written down, and they are
163
+ the manager's to answer: in `interactive` they go to the user as they arrive; in `checkpoint` they
164
+ are held to the next stop; in `autonomous` you answer them yourself unless the answer would
165
+ contradict a standing decision — that one always comes back to the user — and each answer becomes
166
+ an assumption in the Log.
167
+
168
+ An agent that comes back empty, or that says it could not do the assignment, is not retried on the
169
+ spot. That is a repair, and repairs are counted and spent in §8.
170
+
171
+ ## 8. Back together, then the only things that are ever run
172
+
173
+ The agents' branches come into the story's branch one at a time, in the order the assignments were
174
+ cut:
175
+
176
+ ```bash
177
+ git -C "$SCRATCH/k0u/$KEY" merge --no-ff "k0u-$KEY-a1"
178
+ ```
179
+
180
+ A conflict here means the cut was wrong. In `interactive` and `checkpoint`: stop, show which files,
181
+ let the user decide. In `autonomous`: resolve it only where the conflict is inside the files that
182
+ assignment owned and a standing decision says which side wins; otherwise leave that assignment out,
183
+ say so plainly, and carry on with the rest — the good work still goes in.
184
+
185
+ Then the story goes into the branch the run started on:
186
+
187
+ ```bash
188
+ git -C "$SCRATCH/k0u/$KEY" add -A && git -C "$SCRATCH/k0u/$KEY" commit -m "…" # if anything is pending
189
+ git -C "$REPO" merge --no-ff "k0u-$KEY"
190
+ ```
191
+
192
+ One line, Conventional Commits, English, written from the diff, saying what changed for the person
193
+ using this project rather than which function moved. The base repository must be clean first: if it
194
+ is not, stop and say so rather than committing somebody else's work.
195
+
196
+ **Never `git push`. Never a pull request.** Not with a flag, not because the branch tracks a remote,
197
+ not to be helpful. What leaves this machine leaves it through `/commit-push-deploy`, and only when
198
+ the user asks.
199
+
200
+ Then, in the base repository and nowhere else:
201
+
202
+ 1. **The tests.** `npm test` in k0, and whatever the repository says its gate is anywhere else.
203
+ This is the only thing this skill ever runs, and it runs here because here the code on the disk
204
+ is the code that was merged. Inside a worktree it would be a green run against the wrong code.
205
+ 2. **A fresh pair of eyes.** An agent that wrote none of it reads this story's diff against the plan
206
+ and the standing decisions and tries to knock it down. On `hard`, two of them with a lens each —
207
+ one on the decisions, one on correctness — and a third asking what the plan forgot.
208
+ 3. **The repairs.** Red tests, or a finding worth acting on: one agent, in the base repository,
209
+ committing `fix: …`. Two attempts on `medium` and `hard`, one on `light`. After the last one,
210
+ stop. Say in one line what is still broken and leave everything else merged — work that passes
211
+ is not held hostage by work that does not.
212
+ 4. **The counter-check.** `/k0-verify` on this story: the state goes to `Review`, every standing
213
+ decision gets `kept`, `violated` or `na` with its evidence, and the run goes in one call. Do not
214
+ set `Done`: `Done` is the button the user presses, and nothing else may press it.
215
+
216
+ Last, put the worktrees away — whatever happened, including after a failure:
217
+
218
+ ```bash
219
+ git -C "$REPO" worktree remove --force "$SCRATCH/k0u/$KEY-a1"
220
+ git -C "$REPO" branch -D "k0u-$KEY-a1"
221
+ ```
222
+
223
+ A run that ends with a `k0u-*` branch still standing is a run that lied about being finished.
224
+
225
+ ## 9. Picking it up cold
226
+
227
+ The Log is the state of this run and there is no second copy of it. Each of these gets an entry the
228
+ moment it happens — on the story, and on the epic when a story closes:
229
+
230
+ - the line from §3 saying which mode and how hard;
231
+ - the cut into assignments, before any agent starts;
232
+ - each assignment as it lands, with the files it touched;
233
+ - each assumption taken alone;
234
+ - the merge, the tests, the counter-check, and anything left out.
235
+
236
+ So a session that runs out of context, or a terminal somebody closed, costs nothing but the
237
+ assignment that was in flight. Running `/k0-ultracode` again on the same key reads the Log, says in
238
+ one line where the last run got to, and starts from the first assignment that never landed. Nothing
239
+ the Log records as merged is ever done twice.
240
+
241
+ ## 10. Close
242
+
243
+ To the user, in his language, and nothing after it:
244
+
245
+ **Cosa ho fatto** — what is different now, story by story: whether the tests were green, what the
246
+ fresh pair of eyes said, how the counter-check came out.
247
+
248
+ **Cosa resta a te** — the assumptions taken alone, so he can overturn any of them with
249
+ `/k0-discuss`; the assignments left out and what they needed; whatever the repairs did not fix; and
250
+ that the stories are sitting in `Review` waiting for him to press `Done`, which is his and nobody
251
+ else's.
@@ -0,0 +1,71 @@
1
+ # What an agent is told, and what it owes back
2
+
3
+ One agent, one assignment, one worktree. The brief is written by the manager and sent with the
4
+ `Agent` tool; the agent type is `general-purpose` and the model is the one the session is already
5
+ running. Nothing below is optional: a brief missing the decisions is a brief that produces work
6
+ somebody has to throw away.
7
+
8
+ ## The brief
9
+
10
+ ```
11
+ You are one of several agents working on <KEY> — <story title>.
12
+
13
+ Your assignment
14
+ <what this assignment finishes, in two or three lines, from the plan step it came from>
15
+
16
+ Write only here
17
+ <the worktree path>
18
+ Every path you touch is absolute and under it. Nothing is written in the base repository —
19
+ not a file, not a note, not a scratch script. The repository has no .env and no node_modules
20
+ on purpose.
21
+
22
+ The files that are yours
23
+ <the files this assignment owns>
24
+ Another agent owns the rest right now. Needing a file that is not on this list is a question,
25
+ not a decision: report it and stop touching it.
26
+
27
+ The constraints — already decided
28
+ D2 — <the decision, verbatim>
29
+ K7·D3 — <the decision, verbatim>
30
+ These are not advice. Work that contradicts one of them is wrong work, however well written.
31
+ If the assignment cannot be done without breaking one, stop and report it.
32
+
33
+ Never
34
+ no tests, no build, no dev server, no npm run of any kind;
35
+ no git commit, no git merge, no branch, no push, no pull request;
36
+ no call to the k0 API and nothing written to .k0/;
37
+ no work outside your worktree.
38
+
39
+ When you are done, your final message is the report below and nothing else — no preamble, no
40
+ summary for a human. It is read by a program.
41
+ ```
42
+
43
+ ## The report
44
+
45
+ The last message is JSON and nothing else:
46
+
47
+ ```json
48
+ {
49
+ "done": "what is now true that was not true before, in two or three lines",
50
+ "files": ["path/one.js", "path/two.js"],
51
+ "assumptions": ["a choice taken because nothing decided it, one per line"],
52
+ "questions": ["a question only the user can answer, one per line"],
53
+ "blocked": null
54
+ }
55
+ ```
56
+
57
+ - `done` is written for whoever reads the Log, not for the user: names of files are welcome.
58
+ - `assumptions` is the list the manager turns into Log entries and, at the end, into the things the
59
+ user is told he can overturn. An agent that took no choices returns an empty list — never a
60
+ reassuring sentence.
61
+ - `questions` is what the agent could not settle by itself. Where it went ahead anyway it says so
62
+ in `assumptions` as well, so the manager knows which questions have code behind them already.
63
+ - `blocked` is a sentence when the assignment could not be finished, and `null` when it could. An
64
+ agent that half-finished says so here rather than in `done`.
65
+
66
+ ## What the manager does with it
67
+
68
+ The report is not committed and not shown raw to the user. It becomes: a Log entry, an assumption
69
+ list, the questions of §7, and — when `blocked` is set — one of the repair attempts of §8. An agent
70
+ is never asked to try again on the spot: the budget is counted in one place, and that place is the
71
+ manager.
@@ -0,0 +1,49 @@
1
+ # How much rope, and how hard
2
+
3
+ Two questions, asked once, in §3 of `/k0-ultracode`. One `AskUserQuestion` with both of them in it,
4
+ and no `preview` on any option — a single-choice question with a preview loses the free-text box,
5
+ and this is the moment the user is most likely to want to type something of his own.
6
+
7
+ ## How much rope
8
+
9
+ **`interactive`** — everything passes the user. Each assignment is shown as it lands, each question
10
+ an agent brings back is asked while it is still warm, each conflict is his to settle. The slowest,
11
+ and the one to offer when the work touches something he cares about.
12
+
13
+ **`checkpoint`** — three stops and no others: the cut into assignments before any agent starts,
14
+ the moment before the story goes into the branch, and a red test run. Questions from agents are
15
+ held and asked in a batch at the next stop.
16
+
17
+ **`autonomous`** — no stops. Assumptions are taken and written down, and the run comes back when
18
+ the epic is finished. It stops early for three things and nothing else:
19
+
20
+ - an answer that would contradict a decision that is still standing;
21
+ - a conflict that cannot be resolved inside the files one assignment owned;
22
+ - the tests still red after the last repair attempt.
23
+
24
+ Autonomous means autonomous. A mode that asks anyway is the mode the user did not choose, and the
25
+ question that could have waited for the final block should have waited for it.
26
+
27
+ ## How hard
28
+
29
+ | | agents at once | repair attempts | the fresh pair of eyes |
30
+ |---|---|---|---|
31
+ | `light` | 2 | 1 | one agent |
32
+ | `medium` (default) | 3 | 2 | one agent |
33
+ | `hard` | 5 | 2 | two agents, a lens each — the decisions, correctness — and a third asking what the plan forgot |
34
+
35
+ The numbers are ceilings, not targets: three slots do not mean three assignments, and a plan that
36
+ cuts into two is done by two. A fourth agent waits for a slot rather than starting.
37
+
38
+ Nothing here loops until it runs out of things to find. The repair attempts are spent and then the
39
+ run says what is still broken — that is the difference between this and a run that never ends.
40
+
41
+ ## Saying it back
42
+
43
+ One line to the user, and the same line into the Log, before anything starts:
44
+
45
+ > autonomous, medium: three agents at a time, two repair attempts, and I come back when the epic is
46
+ > done or when something is genuinely stuck.
47
+
48
+ A run picked up cold reads that line first and keeps the contract the user agreed to, rather than
49
+ choosing a new one on his behalf.
@@ -0,0 +1,219 @@
1
+ ---
2
+ name: k0-verify
3
+ description: The counter-check on a story whose work is finished — it takes every decision that was made about that story one at a time, not as a group, and records kept, violated or not applicable with the evidence, the file and the line or a sentence saying why it does not apply. Then it runs the checklist, doing itself everything a machine can do (the project's tests, and the browser through Chrome DevTools when the thing is a web application) and leaving the user only what genuinely needs a person. Use this skill when the user types "/k0-verify" or says "check it against what we decided", "verify this story", "did it do what we agreed", "controlla se ha rispettato le decisioni", "verifica la storia", "fai il controllo finale". Do not use it to review code in general, to run the tests on their own, or to mark a story Done: it proposes closing, it never closes.
4
+ ---
5
+
6
+ # /k0-verify [story key]
7
+
8
+ A discussion is only worth what somebody later checks. This is the check. One decision, one
9
+ verdict, one piece of evidence — and no summary standing in for the row.
10
+
11
+ ## Before anything
12
+
13
+ ```bash
14
+ PORT="${K0_PORT:-4319}"
15
+ REPO="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null)"; REPO="${REPO%/.git}"
16
+ [ -d "$REPO" ] || REPO="$(git rev-parse --show-toplevel 2>/dev/null)"
17
+ curl -sS --max-time 30 --get --data-urlencode "repo=$REPO" \
18
+ "http://127.0.0.1:$PORT/api/backlog" -o "$SCRATCH/k0-board.json"
19
+ ```
20
+
21
+ `127.0.0.1`, not `k0.localhost`: browsers resolve that name by themselves, `curl` does not.
22
+ `--get --data-urlencode`, not `?repo=$REPO`: a repository path with a space in it makes `curl`
23
+ refuse the address outright, and one with a `#` in it quietly sends half.
24
+ `$SCRATCH` is the session's scratch directory; nothing is written outside it. `REPO` is the
25
+ repository the stories are filed under — the main one, even when this session sits in a
26
+ subdirectory of it or inside a session's worktree. That last case is the reason it is not `$PWD`:
27
+ `/k0-verify` is typed exactly where `/k0-work` has just been working.
28
+
29
+ - `curl` cannot connect → the k0 server is not running. Say so (`k0-board start`, or the tray
30
+ icon → *Restart*) and **stop**.
31
+ - `{"enabled": false}` → say in one line that the backlog is switched off in k0's settings and
32
+ **stop**.
33
+ - `REPO` empty, or an answer with no `stories` in it at all → this is not a checkout, and the
34
+ server said so rather than answering with a board. Say that, ask once which repository the
35
+ story is in, and take the path he gives. It is not an empty backlog: reporting it as one sends
36
+ him looking for stories that were never missing.
37
+ - **A listing with `stories: []`** → say that plainly and stop. There is nothing here to check
38
+ against, and it is not a reason to ask the user for what the board would have told you.
39
+
40
+ That answer holds every story in this repository with its key, state and title, so work
41
+ out which story is meant from it — never ask the user for a key you can look up. With no
42
+ argument, take the story of the session you are in, or the one in `Working`; if two could be
43
+ meant, ask once, showing both.
44
+
45
+ Then fetch the story and read all of it — rounds, decisions, checks, plan, log:
46
+
47
+ ```bash
48
+ curl -sS --max-time 30 "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" -o "$SCRATCH/k0-story.json"
49
+ curl -sS --max-time 30 -X PATCH "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" \
50
+ -H 'content-type: application/json' -d '{"state": "Review"}'
51
+ ```
52
+
53
+ A run of checks is what puts a story in `Review`.
54
+
55
+ **The run number comes out of that file, not out of your head.** It carries `latest_run`, and the
56
+ run you are about to write is **`latest_run + 1`** — `0` there means nothing has ever been checked
57
+ and this is run 1. `runs` beside it lists what each earlier run found. Do not count anything
58
+ yourself: a run that collides with an earlier one quietly rewrites what was checked last time.
59
+
60
+ **Put the whole run on tasks before looking at anything.** One task per standing decision, its
61
+ subject the label and a few words of the sentence; then one per checklist item — or a single
62
+ *write the checklist* when there is none — and a last one for the outcome. A decision's task goes
63
+ `in_progress` when you start looking and `completed` when its verdict is written down, with the
64
+ verdict and the evidence in its description. Nothing is marked completed on the strength of a
65
+ group: the tasks exist so that a skipped decision shows up as a task still open. If `TaskCreate`
66
+ is not among your tools, say so in one line and carry on; never call it again to see whether it
67
+ has come back.
68
+
69
+ ## 1. Every decision, one at a time
70
+
71
+ Walk the decisions in the order the file has them. **Never in a group, never as a summary, never
72
+ "the rest were all respected".** A decision skipped is the whole failure this feature exists
73
+ to prevent.
74
+
75
+ Each one carries a `label` and an `owner`, and both matter:
76
+
77
+ - `owner: "story"` — labelled `D3`. Decided about this story.
78
+ - `owner: "epic"` — labelled `K7·D3`. Decided about the whole epic, before this story existed,
79
+ and inherited by every story under it. It is checked here exactly like the story's own, and the
80
+ verdict is about **this** story: the same epic decision can be kept in one story and violated in
81
+ another, and that is right, not a contradiction to resolve.
82
+
83
+ Use the label when you talk about a decision, always. `D3` and `K7·D3` are two different
84
+ sentences and a story usually has both.
85
+
86
+ For each one, go and look. Read the code, the interface, the file it says will exist — do not
87
+ answer from what you remember writing.
88
+
89
+ | verdict | when | evidence |
90
+ |---|---|---|
91
+ | `kept` | the finished work does what the sentence says | `server/db.js:120` — the file and the line where it is true |
92
+ | `violated` | it does not, or it does something else | the file and line where it goes wrong, and one sentence saying how |
93
+ | `na` | the sentence cannot apply to this work | one sentence saying why, in the user's language |
94
+
95
+ `na` is for a decision about something that was never built in this story, and for one that was
96
+ **superseded**: the evidence is *superseded by* the label of whatever replaced it, and that one is
97
+ what gets checked.
98
+
99
+ `na` is not an escape hatch. If you cannot find where a decision landed, that is `violated`,
100
+ not `na` — "I could not find it" is a finding, not an exemption.
101
+
102
+ Post the whole run in one call, all decisions together, once you have looked at all of them:
103
+
104
+ ```bash
105
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/verify" \
106
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-verify.json"
107
+ ```
108
+
109
+ with `{ "run": 2, "results": [{ "decision_id": 41, "verdict": "kept", "evidence": "…" }, …] }`.
110
+ **Name each decision by its `id`**, the row id from the file — not by its number. A story's `D3`
111
+ and its epic's `K7·D3` are both "3", and a number would attach half the run to the wrong
112
+ sentences. Write the JSON to a file and send it with `-d @file`: evidence sentences carry quotes
113
+ and newlines and do not survive being pasted inline.
114
+
115
+ **A run is the whole set.** The server answers `409` and writes nothing if a decision that is
116
+ still standing has no verdict in it, and names the ones it did not find — look at those and send
117
+ the whole run again. Nothing is half-recorded, so there is no half-run to repair.
118
+
119
+ ## 2. The checklist
120
+
121
+ The checklist is what somebody would do to convince themselves the story is finished. If the
122
+ story has one, use the items already in `$SCRATCH/k0-story.json` — each carries the `id` you will
123
+ mark it with.
124
+
125
+ If it has none, write one — one line per thing, plain language — post it, and then **fetch the
126
+ story again**, because posting replaces the whole checklist and the items you are about to mark
127
+ are new rows with ids that did not exist a moment ago:
128
+
129
+ ```bash
130
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/check" \
131
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-checks.json" # { "items": [{ "text": "…" }] }
132
+
133
+ curl -sS --max-time 30 "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID" -o "$SCRATCH/k0-story.json"
134
+ ```
135
+
136
+ Never `PATCH` a check by an id you have not just read back. A stale id either fails or marks the
137
+ wrong line passed, and a checklist that says something was proved when it was not is worse than
138
+ no checklist.
139
+
140
+ **Do yourself everything a machine can do.** The user's time is the scarce thing here; leaving
141
+ him a checklist you could have run is handing back your own work.
142
+
143
+ - **The project's tests** — run them the way the repository runs them, on the branch that holds
144
+ the merged work, never inside a session worktree: the worktree's copied `.env` carries the
145
+ base repository's port, and a runner that reuses a live server goes green against the wrong
146
+ code.
147
+ - **The browser, through Chrome DevTools MCP**, when the thing has an interface: open the page,
148
+ do the gesture the decision describes, look at it. A screenshot is evidence; "it should work"
149
+ is not.
150
+ - **Anything else with an exit code** — a build, a linter, a script the repository already has.
151
+
152
+ Record each one as you go, so a terminal that dies keeps what was already proved:
153
+
154
+ ```bash
155
+ curl -sS --max-time 30 -X PATCH "http://127.0.0.1:$PORT/api/backlog/check/$CHECK_ID" \
156
+ -H 'content-type: application/json' -d '{"state": "pass", "evidence": "npm test — 214/214", "by": "claude"}'
157
+ ```
158
+
159
+ `$CHECK_ID` is the `id` of that item as it came back from the story. `state` is `pass`, `fail` or
160
+ `skip`; `by` is `claude` for what you ran.
161
+
162
+ **What is left for the user** is only what genuinely needs a person: a judgement about how
163
+ something feels, a device or an account you do not have, an action with a consequence outside
164
+ this machine. Leave those `todo`, list them as a short numbered list with what to look at and
165
+ what would count as passing, and mark them `pass` or `fail` with `"by": "user"` from what he
166
+ answers. Never mark them yourself.
167
+
168
+ ## 3. The outcome
169
+
170
+ Present it in the user's language, in this order and nothing more:
171
+
172
+ 1. one line: how many decisions, how many kept, how many violated, how many not applicable;
173
+ 2. **every `violated` decision in full** — the sentence, quoted, and where it went wrong;
174
+ 3. **the kept ones, one line each** — the number and the sentence, short. Not a count standing in
175
+ for them: those sentences are the reason he sat through the discussion, and *"the other nine
176
+ were fine"* is exactly the summary this skill exists to refuse. Say where the full record with
177
+ the evidence lives, in one line: the story's page on the board, and the *Verification* section
178
+ of `<repo>/.k0/stories/K42-….md`, which is a plain file he can open six months from now;
179
+ 4. the checks that failed;
180
+ 5. the checks still waiting on him.
181
+
182
+ Then, and only then, the proposal. **You never close anything.** `Done` is the button on the
183
+ board, pressed by the user, and nothing else may set it.
184
+
185
+ - Everything kept, every check passed → say the story looks finished and that pressing **Done**
186
+ on the post-it is what closes it.
187
+ - **A `violated` verdict standing unacknowledged → do not propose closing at all.** Not softly,
188
+ not with a caveat. Say what is broken and offer to fix it, or wait for him to say the verdict
189
+ is wrong or that he accepts it — an acknowledged violation is one he has answered, and his
190
+ answer becomes a decision of its own through `/k0-discuss`. Write it the way
191
+ `../k0-discuss/references/rounds.md` says decisions are written — the path is relative to the
192
+ folder this skill was loaded from, and the two skills are siblings wherever k0 is installed —
193
+ and then verify again as a new run.
194
+ - Checks still waiting on him → say what you need from him and stop there.
195
+
196
+ Last, append what happened to the story's log:
197
+
198
+ ```bash
199
+ curl -sS --max-time 30 -X POST "http://127.0.0.1:$PORT/api/backlog/story/$STORY_ID/log" \
200
+ -H 'content-type: application/json' -d @"$SCRATCH/k0-log.json" # { "text": "…", "session_id": "…" }
201
+ ```
202
+
203
+ ## Rules
204
+
205
+ - **Talk to the user in his language, and store what he says in his language.** The evidence
206
+ strings that are file and line stay as they are; the sentences around them are his.
207
+ - **Never ask for what the API can tell you** — the key, the state, the decisions,
208
+ what is blocked. It is all in the two calls at the top.
209
+ - **Do not invent evidence.** A line number you did not open is worse than no verdict.
210
+ - **Do not edit or delete a decision.** Verdicts are recorded against it; the sentence itself
211
+ only ever changes by being superseded, and that is `/k0-discuss`'s job.
212
+ - **No files outside the scratch directory.**
213
+ - A second run never overwrites the first. Runs stack, and reading them in order is how
214
+ somebody sees that the thing was actually fixed — which is why the run number is read off the
215
+ story rather than assumed.
216
+ - **A violation is never cleared by silence, and never by `na`.** It stands until a later run
217
+ finds that decision `kept`, or until the decision itself is superseded because it was the
218
+ decision that was wrong. Those are the two answers, and the board holds you to them: a story
219
+ cannot be marked Done while one is open, whatever any later run says about anything else.