kanbot 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/package.json +1 -1
- package/schema/config.schema.json +38 -8
- package/src/agents/load.ts +11 -0
- package/src/agents/sync.ts +8 -8
- package/src/capabilities.ts +157 -0
- package/src/color.ts +16 -0
- package/src/commands/board.ts +14 -7
- package/src/commands/doctor.ts +206 -19
- package/src/commands/init.ts +15 -3
- package/src/commands/sync.ts +1 -1
- package/src/commands/upgrade.ts +20 -1
- package/src/config.ts +38 -8
- package/src/daemon/derive.ts +41 -0
- package/src/daemon/loop.ts +2 -0
- package/src/jobs/prompts.ts +25 -5
- package/src/jobs/run.ts +61 -22
- package/src/known-hashes.json +42 -57
- package/src/providers/claude.ts +40 -30
- package/src/providers/codex.ts +60 -30
- package/src/providers/mcp.ts +71 -0
- package/src/schemas/results.ts +2 -5
- package/templates/.agents/skills/approach-designer/SKILL.md +1 -1
- package/templates/.agents/skills/kanbot-admin/SKILL.md +21 -4
- package/templates/.agents/skills/kanbot-guide/SKILL.md +26 -7
- package/templates/.agents/skills/kanbot-idea/SKILL.md +1 -1
- package/templates/.agents/skills/plan-template/SKILL.md +14 -6
- package/templates/.agents/skills/pr-description/SKILL.md +7 -3
- package/templates/.agents/skills/project-conventions/SKILL.md +23 -35
- package/templates/.agents/skills/review-findings/SKILL.md +47 -0
- package/templates/.agents/skills/spec-review/SKILL.md +10 -27
- package/templates/.agents/skills/user-stories/SKILL.md +1 -1
- package/templates/.github/pull_request_template.md +6 -0
- package/templates/.kanbot/agents/acceptance-reviewer.md +43 -0
- package/templates/.kanbot/agents/fixer.md +7 -5
- package/templates/.kanbot/agents/implementer.md +49 -0
- package/templates/.kanbot/agents/plan-critic.md +3 -3
- package/templates/.kanbot/agents/planner.md +10 -9
- package/templates/.kanbot/agents/reviewer.md +42 -0
- package/templates/AGENTS.md +2 -3
- package/templates/.agents/skills/accessibility/SKILL.md +0 -76
- package/templates/.agents/skills/code-review/SKILL.md +0 -83
- package/templates/.agents/skills/frontend-design/LICENSE.txt +0 -177
- package/templates/.agents/skills/frontend-design/SKILL.md +0 -76
- package/templates/.agents/skills/tdd/SKILL.md +0 -51
- package/templates/.agents/skills/verify-ui/SKILL.md +0 -104
- package/templates/.kanbot/agents/implementer-backend.md +0 -57
- package/templates/.kanbot/agents/implementer-docs.md +0 -55
- package/templates/.kanbot/agents/implementer-frontend.md +0 -54
- package/templates/.kanbot/agents/implementer-technical.md +0 -53
- package/templates/.kanbot/agents/reviewer-code.md +0 -46
- package/templates/.kanbot/agents/reviewer-spec.md +0 -49
- package/templates/.kanbot/agents/test-writer.md +0 -35
- package/templates/.kanbot/agents/ui-verifier.md +0 -35
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Workers get the repo's committed MCP servers, never the user's own.
|
|
6
|
+
* `.mcp.json` (Claude's format) is the one source for both providers.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export type McpServer = {
|
|
10
|
+
type?: string;
|
|
11
|
+
command?: string;
|
|
12
|
+
args?: string[];
|
|
13
|
+
env?: Record<string, string>;
|
|
14
|
+
url?: string;
|
|
15
|
+
headers?: Record<string, string>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function mcpConfigPath(dir: string): string | null {
|
|
19
|
+
const path = join(dir, ".mcp.json");
|
|
20
|
+
return existsSync(path) ? path : null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Servers in `<dir>/.mcp.json`. Empty when missing or unreadable. */
|
|
24
|
+
export async function readMcpServers(
|
|
25
|
+
dir: string,
|
|
26
|
+
): Promise<Record<string, McpServer>> {
|
|
27
|
+
const path = mcpConfigPath(dir);
|
|
28
|
+
if (!path) return {};
|
|
29
|
+
try {
|
|
30
|
+
const json = (await Bun.file(path).json()) as {
|
|
31
|
+
mcpServers?: Record<string, McpServer>;
|
|
32
|
+
};
|
|
33
|
+
return json.mcpServers ?? {};
|
|
34
|
+
} catch {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Codex runs stdio and streamable HTTP servers. Others (e.g. sse) are left out. */
|
|
40
|
+
export function codexSupports(s: McpServer): boolean {
|
|
41
|
+
if (s.type === "sse") return false;
|
|
42
|
+
return Boolean(s.command || s.url);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const str = (s: string) => JSON.stringify(s);
|
|
46
|
+
const table = (o: Record<string, string>) =>
|
|
47
|
+
`{${Object.entries(o)
|
|
48
|
+
.map(([k, v]) => `${str(k)}=${str(v)}`)
|
|
49
|
+
.join(",")}}`;
|
|
50
|
+
|
|
51
|
+
/** `-c mcp_servers=…` for codex, as an inline TOML table. Empty when none. */
|
|
52
|
+
export function codexMcpArgs(servers: Record<string, McpServer>): string[] {
|
|
53
|
+
const entries = Object.entries(servers)
|
|
54
|
+
.filter(([, s]) => codexSupports(s))
|
|
55
|
+
.map(([name, s]) => {
|
|
56
|
+
const fields = s.command
|
|
57
|
+
? [
|
|
58
|
+
`command=${str(s.command)}`,
|
|
59
|
+
s.args?.length ? `args=[${s.args.map(str).join(",")}]` : "",
|
|
60
|
+
s.env && Object.keys(s.env).length ? `env=${table(s.env)}` : "",
|
|
61
|
+
]
|
|
62
|
+
: [
|
|
63
|
+
`url=${str(s.url as string)}`,
|
|
64
|
+
s.headers && Object.keys(s.headers).length
|
|
65
|
+
? `http_headers=${table(s.headers)}`
|
|
66
|
+
: "",
|
|
67
|
+
];
|
|
68
|
+
return `${str(name)}={${fields.filter(Boolean).join(",")}}`;
|
|
69
|
+
});
|
|
70
|
+
return entries.length ? ["-c", `mcp_servers={${entries.join(",")}}`] : [];
|
|
71
|
+
}
|
package/src/schemas/results.ts
CHANGED
|
@@ -35,7 +35,7 @@ export const PlanResult = z.strictObject({
|
|
|
35
35
|
.describe("Issues to create, e.g. when the human asks to split work."),
|
|
36
36
|
labels: z
|
|
37
37
|
.array(z.string())
|
|
38
|
-
.describe("Labels the issue should have, e.g.
|
|
38
|
+
.describe("Labels the issue should have, e.g. technical."),
|
|
39
39
|
questions: z
|
|
40
40
|
.array(z.string())
|
|
41
41
|
.describe(
|
|
@@ -55,9 +55,6 @@ export const ImplementResult = z.strictObject({
|
|
|
55
55
|
testsRun: z
|
|
56
56
|
.array(z.string())
|
|
57
57
|
.describe("One line each: command and result, e.g. `bun test`: 5 pass."),
|
|
58
|
-
screenshots: z
|
|
59
|
-
.array(z.string())
|
|
60
|
-
.describe("Repo-relative paths of screenshots committed for review."),
|
|
61
58
|
risks: z
|
|
62
59
|
.array(z.string())
|
|
63
60
|
.describe("Real risks only, one line each. Empty when none."),
|
|
@@ -98,7 +95,7 @@ export const FixResult = z.strictObject({
|
|
|
98
95
|
.string()
|
|
99
96
|
.nullable()
|
|
100
97
|
.describe(
|
|
101
|
-
"Full updated PR description when your changes made the current one wrong (behaviour, copy,
|
|
98
|
+
"Full updated PR description when your changes made the current one wrong (behaviour, copy, validation); null otherwise.",
|
|
102
99
|
),
|
|
103
100
|
});
|
|
104
101
|
export type FixResult = z.infer<typeof FixResult>;
|
|
@@ -17,7 +17,7 @@ Pick the axis where the decision matters most for this problem, then spread appr
|
|
|
17
17
|
| Interaction model | Search box · faceted filters · timeline browsing |
|
|
18
18
|
| Where logic lives | Client-side filtering of loaded data · server query endpoint · search index |
|
|
19
19
|
| Data model | Denormalised read model · query on existing tables · materialised view |
|
|
20
|
-
| Build vs. reuse |
|
|
20
|
+
| Build vs. reuse | Build it · reuse what the project has · third-party library |
|
|
21
21
|
| Timing | Synchronous · background job with notification · precomputed nightly |
|
|
22
22
|
| Scope of change | Minimal tweak to the current screen · new dedicated screen |
|
|
23
23
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
|
|
3
3
|
name: kanbot-admin
|
|
4
|
-
description: Change this repo's kanbot setup with a human. Use to add or edit kanbot agents, skills or project memory, change `.kanbot/config.yml`, switch identity mode, turn on merge on approval, run `kanbot upgrade` or merge `.kanbot-new` files. Not for board jobs. For setup walkthroughs and explaining options, use kanbot-guide.
|
|
4
|
+
description: Change this repo's kanbot setup with a human. Use to add or edit kanbot agents, skills or project memory, map capabilities, give workers MCP servers, change `.kanbot/config.yml`, switch identity mode, turn on merge on approval, run `kanbot upgrade` or merge `.kanbot-new` files. Not for board jobs. For setup walkthroughs and explaining options, use kanbot-guide.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# kanbot admin
|
|
8
8
|
|
|
9
|
-
You are helping a human maintain kanbot, the board-driven agent team in this repo. Board agents (planner,
|
|
9
|
+
You are helping a human maintain kanbot, the board-driven agent team in this repo. Board agents (planner, implementer, reviewers, fixer) never use this skill. To explain options or set kanbot up from scratch, use `kanbot-guide`.
|
|
10
10
|
|
|
11
11
|
## Map
|
|
12
12
|
|
|
@@ -15,6 +15,7 @@ You are helping a human maintain kanbot, the board-driven agent team in this rep
|
|
|
15
15
|
| `.kanbot/agents/<name>.md` | Agent definitions, the source of truth | Yes, then `kanbot sync` |
|
|
16
16
|
| `.agents/skills/<name>/` | Skills shared by all agents | Yes |
|
|
17
17
|
| `.kanbot/config.yml` | Daemon config; schema next to it | Yes, then restart the daemon |
|
|
18
|
+
| `.mcp.json` | MCP servers workers get | Yes, then commit |
|
|
18
19
|
| `.kanbot/manifest.json` | Template hashes from the last upgrade | Never by hand |
|
|
19
20
|
| `.claude/`, `.codex/` | Generated by `kanbot sync` | Never; edit the source and sync |
|
|
20
21
|
| `~/.kanbot/apps/<id>.pem` | Private key of the kanbot GitHub App | Never commit |
|
|
@@ -39,17 +40,32 @@ Back to user mode: set `identity.mode: user`.
|
|
|
39
40
|
2. Recommend app mode, so they can approve their own kanbot PRs.
|
|
40
41
|
3. Warn: never enable the branch rule "Require approval of the most recent reviewable push". It blocks their own approval.
|
|
41
42
|
|
|
43
|
+
### Map a capability
|
|
44
|
+
|
|
45
|
+
kanbot's agents run the process; the repo's own skills and agents do the work on code. Capabilities tell them which to use.
|
|
46
|
+
|
|
47
|
+
1. Make sure the skill is in `.agents/skills/<name>/` or the agent in `.kanbot/agents/`. A `.claude/agents` or `.codex/agents` agent works on one provider only.
|
|
48
|
+
2. Add it under `capabilities` in config: `review: code-review`, or `{ use, when, required }` when it only applies sometimes or a miss should block acceptance review.
|
|
49
|
+
3. Reserved names: `verify` (prove acceptance criteria), `review` (technical review, pass 1), `preview` (something a human can try). Any other name is the human's.
|
|
50
|
+
4. `kanbot doctor` lists what's mapped, flags a missing `use`, and names reserved needs not yet mapped.
|
|
51
|
+
|
|
52
|
+
Don't add implementers or `type:*` labels. `implementers` in config is deprecated: replace it with capabilities and remove it.
|
|
53
|
+
|
|
54
|
+
### Give workers an MCP server
|
|
55
|
+
|
|
56
|
+
Add it to `.mcp.json` (Claude's format) and commit. Workers get only these servers, never the human's own. Codex can't run `sse` servers; `kanbot doctor` lists what workers get.
|
|
57
|
+
|
|
42
58
|
### Add or change an agent
|
|
43
59
|
|
|
44
60
|
1. Copy the closest existing agent. `name` must match the filename.
|
|
45
61
|
2. Column agents (`tier: column`) need an `output` schema; subagents (`tier: sub`) are reached through a column agent's `subagents`.
|
|
46
|
-
3.
|
|
62
|
+
3. To have board agents use it, map it as a capability (above).
|
|
47
63
|
4. The body says _how_ to work. The daemon's prompt carries the task.
|
|
48
64
|
|
|
49
65
|
### Add a skill
|
|
50
66
|
|
|
51
67
|
1. Create `.agents/skills/<name>/SKILL.md` with `name` (matches the folder) and a `description` that says what it covers and when it applies.
|
|
52
|
-
2.
|
|
68
|
+
2. For work on code, map it as a capability. For kanbot's own process, add the name to `skills` in each agent that should load it. `kanbot doctor` fails on skills that don't exist.
|
|
53
69
|
|
|
54
70
|
### Add a memory
|
|
55
71
|
|
|
@@ -60,6 +76,7 @@ When the human says "remember that …" or corrects something agents keep gettin
|
|
|
60
76
|
1. Run `bunx kanbot@latest upgrade --dry-run` and summarise it for the human.
|
|
61
77
|
2. Run `bunx kanbot@latest upgrade`.
|
|
62
78
|
3. Merge every `.kanbot-new` file (below).
|
|
79
|
+
4. Files kanbot no longer ships stay in place. If the repo had kanbot's old craft skills (`verify-ui`, `code-review`, `tdd`…) and no `capabilities`, upgrade maps them. Show the human the new `capabilities` block. Old `implementer-*` and `reviewer-*` agents are unused once the new ones exist; the human may delete them.
|
|
63
80
|
|
|
64
81
|
### Merge `.kanbot-new` files
|
|
65
82
|
|
|
@@ -22,6 +22,7 @@ Explain in plain words. Ask before choosing for them; give a recommendation with
|
|
|
22
22
|
| Skills and project memory? | `skills` |
|
|
23
23
|
| Claude or Codex? | `providers` |
|
|
24
24
|
| Every config field, labels, notifications | `configuration` |
|
|
25
|
+
| Using our own skills and agents for the work | `capabilities` |
|
|
25
26
|
| Copilot as an extra reviewer | `copilot-review` |
|
|
26
27
|
| Bot or user identity, merge by approving | `identity` |
|
|
27
28
|
| Upgrading and `.kanbot-new` files | `upgrading` |
|
|
@@ -29,9 +30,11 @@ Explain in plain words. Ask before choosing for them; give a recommendation with
|
|
|
29
30
|
|
|
30
31
|
## Board flow
|
|
31
32
|
|
|
32
|
-
Ideas (you write) → Planning (agent plans, you comment) → Ready (you approve by moving the card) → In Progress (agent builds, opens a PR) → Review (
|
|
33
|
+
Ideas (you write) → Planning (agent plans, you comment) → Ready (you approve by moving the card) → In Progress (agent builds, opens a PR) → Review (technical, then acceptance review, with fixes; you comment) → Done (you merge, or approve and kanbot merges).
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
kanbot runs the process; the repo's own skills and agents do the work on code, through capabilities. Plans list assumptions about user need; open questions keep a card from starting in Ready.
|
|
36
|
+
|
|
37
|
+
Agents never get a GitHub token. The daemon does every comment, push and PR. Only collaborators with write access can steer agents. Workers see only what's committed, including MCP servers in `.mcp.json`; never the user's own plugins or servers.
|
|
35
38
|
|
|
36
39
|
## Guided setup
|
|
37
40
|
|
|
@@ -40,11 +43,25 @@ Go step by step. Run each command, check its output, then go on. If `.kanbot/con
|
|
|
40
43
|
1. **Requirements.** Bun 1.3+, `gh` logged in, `claude` or `codex` logged in with a subscription (not an API key). Run `gh auth refresh -s project`.
|
|
41
44
|
2. **Provider.** Ask which subscription they have, then `bunx kanbot init --provider claude|codex` in the repo root.
|
|
42
45
|
3. **Conventions.** Fill in `.agents/skills/project-conventions/SKILL.md` with them: stack, commands to test, lint and typecheck. Adjust `.github/workflows/ci.yml` to run the same. Every agent reads this first.
|
|
43
|
-
4. **
|
|
44
|
-
5. **
|
|
45
|
-
6. **
|
|
46
|
-
7. **
|
|
47
|
-
8. **
|
|
46
|
+
4. **Capabilities.** kanbot runs the process; the repo's own skills and agents do the work. Ask which skills they have for proving acceptance criteria (`verify`), technical review (`review`) and something a human can try (`preview`), and map them under `capabilities` in `.kanbot/config.yml`. See [Capabilities](#capabilities).
|
|
47
|
+
5. **Board.** `kanbot board create`, or `kanbot board link --owner <login> --number <n>` for an existing project. Have them enable the four built-in project workflows it prints; they can't be set through the API.
|
|
48
|
+
6. **Options.** Go through [Choose options](#choose-options). For app mode, run `kanbot app create` and have them install the app on the repo.
|
|
49
|
+
7. **Commit and push** the kanbot files. Agents only see what's on the pushed base branch.
|
|
50
|
+
8. **Check.** `kanbot doctor` until it passes, then `kanbot run --once --dry-run`, then `kanbot run`.
|
|
51
|
+
9. **First card.** Have them write an issue, put it in Planning and read the plan. Point to `workflow`.
|
|
52
|
+
|
|
53
|
+
## Capabilities
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
capabilities:
|
|
57
|
+
verify: { use: e2e-tests, when: Changes users see }
|
|
58
|
+
preview: { use: deploy-preview, required: true }
|
|
59
|
+
review: code-review # bare name: no when, not required
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- `use`: a skill in `.agents/skills` or an agent in `.kanbot/agents`. `when`: when it applies. `required: true`: a miss blocks acceptance review.
|
|
63
|
+
- Any other name is theirs (`benchmark`, `security`…). Unmapped needs are left to the agent.
|
|
64
|
+
- Suggest, don't install: no `verify` → a skill that runs the app or end-to-end tests; no `preview` → a preview deploy or test build; no `review` → a review skill with their checklist. `kanbot doctor` names what's not mapped.
|
|
48
65
|
|
|
49
66
|
## Choose options
|
|
50
67
|
|
|
@@ -89,3 +106,5 @@ Warn: never enable the branch rule "Require approval of the most recent reviewab
|
|
|
89
106
|
3. `.kanbot/logs/*.jsonl`: full agent transcripts.
|
|
90
107
|
4. `needs-human` label: the issue has a comment saying why. Fix the cause, then remove the label to retry.
|
|
91
108
|
5. Nothing happens: is the daemon running, are kanbot files pushed to the base branch, is the card in an active column?
|
|
109
|
+
6. Card stays in Ready: the plan has open questions. kanbot commented on the issue. Answer them in Planning, or remove them from the plan.
|
|
110
|
+
7. Agent didn't use a skill: is it mapped under `capabilities`, does its `when` fit, and is it committed?
|
|
@@ -45,7 +45,7 @@ Match the repo's issue template, so the issue reads like one filed through GitHu
|
|
|
45
45
|
<notes, or _None._>
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
Title: the outcome in under 70 characters. Technical issues get the `technical` label.
|
|
48
|
+
Title: the outcome in under 70 characters. Technical issues get the `technical` label.
|
|
49
49
|
|
|
50
50
|
Show the title and body. File it only after the human says yes.
|
|
51
51
|
|
|
@@ -20,13 +20,18 @@ Need: <one or two sentences: what hurts today and how we'll know it worked.>
|
|
|
20
20
|
- [ ] Given <context>, when <action>, then <observable result>.
|
|
21
21
|
<!-- 2-6 items. Cover the happy path plus the edge cases that matter. -->
|
|
22
22
|
|
|
23
|
+
## Assumptions
|
|
24
|
+
|
|
25
|
+
- <What the plan assumes about the user's need or the business value.> Confirm: <ask, data, or a user test>.
|
|
26
|
+
<!-- 1-4 items. Risky, unconfirmed ones also go in `questions`. -->
|
|
27
|
+
|
|
23
28
|
## Out of scope
|
|
24
29
|
|
|
25
30
|
- <Only what a reader would otherwise expect. Omit the section if nothing.>
|
|
26
31
|
|
|
27
32
|
## Design notes
|
|
28
33
|
|
|
29
|
-
<
|
|
34
|
+
<Decisions the criteria don't settle: what users see or call, key copy, data shape. 1-4 lines. Omit if nothing beyond the criteria.>
|
|
30
35
|
|
|
31
36
|
## Implementation steps
|
|
32
37
|
|
|
@@ -39,12 +44,14 @@ Need: <one or two sentences: what hurts today and how we'll know it worked.>
|
|
|
39
44
|
|
|
40
45
|
## Open questions
|
|
41
46
|
|
|
42
|
-
|
|
47
|
+
<!-- Don't write this section. kanbot fills it from your `questions` output. Open questions keep the issue out of Ready. -->
|
|
43
48
|
```
|
|
44
49
|
|
|
45
50
|
## Rules
|
|
46
51
|
|
|
47
52
|
- Required: User story (or Technical goal), Acceptance criteria, Implementation steps. Omit other sections when empty; don't write "None."
|
|
53
|
+
- Assumptions are about user need and business value, not code. Technical unknowns go in `explore:N` or a spike.
|
|
54
|
+
- Ask a question (`questions` output) only if building on a wrong guess would waste the work. kanbot won't start while any are open.
|
|
48
55
|
- One line per bullet. No prose paragraphs, no repeating the issue text.
|
|
49
56
|
- Acceptance criteria are shared by all approaches. Approach-specific steps go inside each `### Approach k`.
|
|
50
57
|
- File paths come from reading the code, not guesses. Mark new files "(new)".
|
|
@@ -65,6 +72,11 @@ Need: entries without a project silently drop off invoices; users find out when
|
|
|
65
72
|
- [ ] Given every entry has a project, when I open the month view, then the list is hidden.
|
|
66
73
|
- [ ] Given loading fails, when I open the month view, then the list shows "Couldn't load entries" and "Try again".
|
|
67
74
|
|
|
75
|
+
## Assumptions
|
|
76
|
+
|
|
77
|
+
- Users fix missing projects before invoicing, not after. Confirm: ask two users how they invoice.
|
|
78
|
+
- Most months have under 20 such entries. Confirm: query last quarter's data.
|
|
79
|
+
|
|
68
80
|
## Out of scope
|
|
69
81
|
|
|
70
82
|
- Bulk-assigning projects (new issue).
|
|
@@ -78,8 +90,4 @@ List sits above the calendar, collapsed to 5 rows with "Show all (n)". Reuse `Pr
|
|
|
78
90
|
1. Add `missingProject` filter to `GET /entries`, with tests. Files: `api/entries/routes.ts`
|
|
79
91
|
2. Add `MissingProjectSection` with its states and tests. Files: `web/entries/MissingProjectSection.tsx` (new)
|
|
80
92
|
3. Mount it in the month view and refresh after assignment. Files: `web/month/MonthView.tsx`
|
|
81
|
-
|
|
82
|
-
## Open questions
|
|
83
|
-
|
|
84
|
-
- Include earlier months? Default: current month only.
|
|
85
93
|
```
|
|
@@ -27,8 +27,12 @@ Conventional commit, imperative, under 72 characters, naming the user-visible ef
|
|
|
27
27
|
|
|
28
28
|
## Screenshots
|
|
29
29
|
|
|
30
|
-

|
|
31
|
+
<!-- Optional. Only when the change is visible; 1-3 images. -->
|
|
32
|
+
|
|
33
|
+
## Validation
|
|
34
|
+
|
|
35
|
+
- <What you used to prove it works (tests, skills, preview) and what it showed. 1-3 bullets.>
|
|
32
36
|
|
|
33
37
|
## Notes for reviewer
|
|
34
38
|
|
|
@@ -40,5 +44,5 @@ Conventional commit, imperative, under 72 characters, naming the user-visible ef
|
|
|
40
44
|
- One line per bullet. No "Why" section; the issue has it.
|
|
41
45
|
- Describe what the code does now, not how you got there.
|
|
42
46
|
- Anything you could not verify goes in `risks`, not the body.
|
|
43
|
-
-
|
|
47
|
+
- Omit Screenshots when there is nothing to show.
|
|
44
48
|
- Aim for under 20 lines.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
|
|
3
3
|
name: project-conventions
|
|
4
|
-
description: This project's stack, exact commands (install, test, lint, typecheck, build
|
|
4
|
+
description: This project's stack, exact commands (install, run, test, lint, typecheck, build), code conventions and recorded decisions. Read first before planning, implementing, reviewing or fixing anything in this repository, and whenever you need to know how to run tests or the project.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Project conventions
|
|
@@ -18,52 +18,40 @@ description: This project's stack, exact commands (install, test, lint, typechec
|
|
|
18
18
|
|
|
19
19
|
- What it is: `<one sentence: what the product does and for whom>`
|
|
20
20
|
- Primary users: `<roles>`
|
|
21
|
-
- Language
|
|
21
|
+
- Language of what users see: `<e.g. Norwegian bokmål, English>`
|
|
22
22
|
|
|
23
23
|
## Stack
|
|
24
24
|
|
|
25
|
-
- Language and runtime: `<e.g. TypeScript 5,
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- Data: `<database, ORM/query builder, migration tool>`
|
|
29
|
-
- Package manager: `<pnpm | npm | bun | yarn>` (use only this one)
|
|
25
|
+
- Language and runtime: `<e.g. TypeScript 5 on Bun, Swift 6, Python 3.13>`
|
|
26
|
+
- Main parts: `<one line each: app, service, library, site…>`
|
|
27
|
+
- Package manager or build tool: `<use only this one>`
|
|
30
28
|
|
|
31
29
|
## Commands
|
|
32
30
|
|
|
33
|
-
| Task
|
|
34
|
-
|
|
|
35
|
-
| Install
|
|
36
|
-
|
|
|
37
|
-
| Test (all)
|
|
38
|
-
| Test (one
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
| DB migrate | `<pnpm db:migrate>` |
|
|
46
|
-
| Seed data | `<pnpm db:seed>` |
|
|
47
|
-
|
|
48
|
-
Environment: `<how to get a working .env for local dev and tests, e.g. cp .env.example .env; which variables have safe defaults>`
|
|
31
|
+
| Task | Command |
|
|
32
|
+
| ----------- | ------------------------------- |
|
|
33
|
+
| Install | `<install dependencies>` |
|
|
34
|
+
| Run locally | `<start it, and where to look>` |
|
|
35
|
+
| Test (all) | `<run all tests>` |
|
|
36
|
+
| Test (one) | `<run one file or test>` |
|
|
37
|
+
| Lint | `<lint>` |
|
|
38
|
+
| Format | `<format>` |
|
|
39
|
+
| Typecheck | `<typecheck>` |
|
|
40
|
+
| Build | `<build>` |
|
|
41
|
+
|
|
42
|
+
Add rows the project needs (migrations, seed data, end-to-end tests…). Environment: `<how to get a working local setup>`
|
|
49
43
|
|
|
50
44
|
## Layout
|
|
51
45
|
|
|
52
46
|
```
|
|
53
|
-
<
|
|
54
|
-
<src/components/ shared UI components>
|
|
55
|
-
<src/server/ API handlers>
|
|
56
|
-
<tests/ …>
|
|
47
|
+
<dir/ what lives here>
|
|
57
48
|
```
|
|
58
49
|
|
|
59
50
|
## Code conventions
|
|
60
51
|
|
|
61
|
-
- Naming: `<files
|
|
62
|
-
- Error handling: `<
|
|
63
|
-
-
|
|
64
|
-
- State/data fetching: `<e.g. TanStack Query; no fetch in components>`
|
|
65
|
-
- Styling: `<e.g. CSS modules + tokens in src/styles/tokens.css; no inline colors>`
|
|
66
|
-
- Tests: `<framework, location (co-located *.test.ts), factories in tests/factories>`
|
|
52
|
+
- Naming: `<files, types, functions>`
|
|
53
|
+
- Error handling: `<how errors are raised and shown>`
|
|
54
|
+
- Tests: `<framework, where tests live, helpers>`
|
|
67
55
|
- Commits: Conventional Commits (`feat`, `fix`, `refactor`, `test`, `docs`, `build`, `ci`, `chore`) with a scope.
|
|
68
56
|
- Do not: `<things that look tempting but are wrong here>`
|
|
69
57
|
|
|
@@ -75,5 +63,5 @@ Record decisions that agents should not relitigate. One line each, newest first.
|
|
|
75
63
|
|
|
76
64
|
## Gotchas
|
|
77
65
|
|
|
78
|
-
- `<e.g. tests need
|
|
79
|
-
- `<e.g. generated files
|
|
66
|
+
- `<e.g. tests need a local database running>`
|
|
67
|
+
- `<e.g. generated files you must never edit>`
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
name: review-findings
|
|
4
|
+
description: Severity rubric, finding format and re-review rounds for kanbot reviews. Use when writing review findings, deciding severity, or judging whether a fixer resolved a finding.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Review findings
|
|
8
|
+
|
|
9
|
+
kanbot turns findings into a fix loop. Severity decides what gets fixed, so get it right.
|
|
10
|
+
|
|
11
|
+
## Severity
|
|
12
|
+
|
|
13
|
+
| Severity | Meaning | Triggers a fix |
|
|
14
|
+
| --------- | ---------------------------------------------------------------------------------------------------- | -------------- |
|
|
15
|
+
| `blocker` | Wrong behaviour on a main path, data loss, security hole, failing checks, unmet acceptance criterion | Yes |
|
|
16
|
+
| `major` | Bug users will hit, missing test for a criterion, missed required capability, risky scope creep | Yes |
|
|
17
|
+
| `minor` | Real but low impact: unclear naming, small duplication, rare edge case untested | Yes |
|
|
18
|
+
| `nit` | Preference or polish. At most 3 per review | No |
|
|
19
|
+
|
|
20
|
+
When unsure between two levels, pick the lower one and say the risk.
|
|
21
|
+
|
|
22
|
+
## Writing a finding
|
|
23
|
+
|
|
24
|
+
Location, what is wrong, why it matters, the fix. One to three sentences.
|
|
25
|
+
|
|
26
|
+
> `src/invoices/service.ts:84` — `total` is summed before discounts, so discounted invoices show the full amount (criterion 3). Apply discounts first and add a test with a 10% code.
|
|
27
|
+
|
|
28
|
+
- One problem per finding. Merge repeats into one finding with all locations.
|
|
29
|
+
- Point at the line in the new version of the file. `path` and `line` null for cross-cutting findings.
|
|
30
|
+
- Show a failure ("a user with no projects gets a 500"), not a principle ("not robust").
|
|
31
|
+
- Only what you checked. If unsure, say what would confirm it.
|
|
32
|
+
|
|
33
|
+
## Avoid
|
|
34
|
+
|
|
35
|
+
- More than ~10 findings. Keep the most important; summarise the rest in one.
|
|
36
|
+
- Style a formatter or linter covers.
|
|
37
|
+
- Scope beyond the plan. Suggest a follow-up issue as a `nit` at most.
|
|
38
|
+
- Rewriting a working approach to your taste without a concrete defect.
|
|
39
|
+
- Approving with an open `blocker` or `major`.
|
|
40
|
+
|
|
41
|
+
## Verdict
|
|
42
|
+
|
|
43
|
+
`changes` with any `blocker` or `major`; otherwise `approve`. Minor findings and nits may come with an approval.
|
|
44
|
+
|
|
45
|
+
## Re-review rounds
|
|
46
|
+
|
|
47
|
+
For each earlier finding: fixed (drop it), not fixed (repeat with the same id and what is still wrong), or the fixer disagreed (accept the reason, or explain once more why it matters). Check that fixes didn't add new problems.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
|
|
3
3
|
name: spec-review
|
|
4
|
-
description: "Verify a change against its plan: every acceptance criterion with evidence, fit with the user need,
|
|
4
|
+
description: "Verify a change against its plan: every acceptance criterion with evidence, fit with the user need, scope creep and docs. Use when doing the spec/product review pass on a PR branch, or when checking whether an implementation actually does what the issue asked."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Spec review
|
|
@@ -12,13 +12,13 @@ You review the change from the outside, as the user and the product owner. The q
|
|
|
12
12
|
|
|
13
13
|
For each acceptance criterion in the plan, record:
|
|
14
14
|
|
|
15
|
-
| # | Criterion (short) | Evidence
|
|
16
|
-
| --- | ------------------------------ |
|
|
17
|
-
| 1 | Missing-project entries listed | `MissingProjectSection.test.tsx` "lists entries newest first"
|
|
18
|
-
| 2 | Count updates after assignment | test asserts count
|
|
19
|
-
| 3 | Section hidden when none | no test;
|
|
15
|
+
| # | Criterion (short) | Evidence | Verdict |
|
|
16
|
+
| --- | ------------------------------ | ------------------------------------------------------------- | ---------------- |
|
|
17
|
+
| 1 | Missing-project entries listed | `MissingProjectSection.test.tsx` "lists entries newest first" | met |
|
|
18
|
+
| 2 | Count updates after assignment | test asserts count | met |
|
|
19
|
+
| 3 | Section hidden when none | no test; not observed | **not verified** |
|
|
20
20
|
|
|
21
|
-
Valid evidence: a test that asserts the behaviour (read it, and check it would fail without the feature),
|
|
21
|
+
Valid evidence: a test that asserts the behaviour (read it, and check it would fail without the feature), output of the `verify` capability, or behaviour you observed by running the app or the command. The PR body's claims alone are not evidence.
|
|
22
22
|
|
|
23
23
|
"Not verified" is a finding. "Not met" is a `blocker`.
|
|
24
24
|
|
|
@@ -32,24 +32,7 @@ Re-read the user story and problem. Then walk through the change as that user:
|
|
|
32
32
|
- Any dead ends: a state with no way forward or back?
|
|
33
33
|
- Does it solve the problem in the plan, or only satisfy the letter of the criteria?
|
|
34
34
|
|
|
35
|
-
## 3.
|
|
36
|
-
|
|
37
|
-
Check each state exists and looks right at 390px and 1280px:
|
|
38
|
-
|
|
39
|
-
- [ ] Loading (no layout jump when content arrives)
|
|
40
|
-
- [ ] Empty (explains why and what to do)
|
|
41
|
-
- [ ] Error (says what went wrong and offers a way to recover)
|
|
42
|
-
- [ ] Success / filled, including long text and many items
|
|
43
|
-
- [ ] Disabled and in-progress controls
|
|
44
|
-
- [ ] No horizontal scroll at 390px; tap targets at least 24x24px (44 preferred)
|
|
45
|
-
|
|
46
|
-
Use committed screenshots under `.kanbot/screenshots/<branch>/` first. Capture missing states with `verify-ui` into a temp directory outside the repo.
|
|
47
|
-
|
|
48
|
-
## 4. Accessibility
|
|
49
|
-
|
|
50
|
-
Run through the `accessibility` checklist for the changed UI. WCAG 2.2 AA failures are `major`; a keyboard trap or an unlabelled primary control is a `blocker`.
|
|
51
|
-
|
|
52
|
-
## 5. Scope
|
|
35
|
+
## 3. Scope
|
|
53
36
|
|
|
54
37
|
- Diff against the plan's implementation steps: files changed that no step explains?
|
|
55
38
|
- Features, options or settings nobody asked for?
|
|
@@ -58,7 +41,7 @@ Run through the `accessibility` checklist for the changed UI. WCAG 2.2 AA failur
|
|
|
58
41
|
|
|
59
42
|
Scope creep is `major` when it adds risk or review burden, `minor` otherwise. Ask for it to be removed or moved to a follow-up issue.
|
|
60
43
|
|
|
61
|
-
##
|
|
44
|
+
## 4. Docs and communication
|
|
62
45
|
|
|
63
46
|
- User-facing behaviour changed: are help text, README, changelog or docs updated where the project keeps them?
|
|
64
47
|
- Does the PR body explain how to test, with steps a human can follow?
|
|
@@ -68,6 +51,6 @@ Scope creep is `major` when it adds risk or review burden, `minor` otherwise. As
|
|
|
68
51
|
|
|
69
52
|
Quote the criterion or plan line, state what you observed and your evidence, and say what would satisfy it:
|
|
70
53
|
|
|
71
|
-
> Criterion 3 ("Given all entries have a project … the section is not shown") has no test and no
|
|
54
|
+
> Criterion 3 ("Given all entries have a project … the section is not shown") has no test and no other evidence. Add a test for the empty case.
|
|
72
55
|
|
|
73
56
|
Lead the summary with the tally ("4/5 criteria met, 1 not verified") so a human can scan it.
|
|
@@ -74,7 +74,7 @@ Do not use `technical` to dodge user framing. If users will notice the change, i
|
|
|
74
74
|
| System as user | "As the system, I want to cache…" | Use `technical` with a technical goal, or find the human. |
|
|
75
75
|
| Hollow "so that" | "so that I can use the feature" | Ask "why?" until you reach an outcome. |
|
|
76
76
|
| Untestable criteria | "The page is intuitive" | Name the observable behaviour. |
|
|
77
|
-
| Horizontal slice | "Build the database tables for X" | Slice vertically through
|
|
77
|
+
| Horizontal slice | "Build the database tables for X" | Slice vertically through every layer the user touches. |
|
|
78
78
|
| Epic disguised as story | 10+ criteria, many screens | Split with `issue-splitting`. |
|
|
79
79
|
|
|
80
80
|
## New issues you propose
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
name: acceptance-reviewer
|
|
4
|
+
tier: column
|
|
5
|
+
description: Second review pass on a PR branch. Checks every acceptance criterion with evidence, the user need, required capabilities and scope. Read-only.
|
|
6
|
+
models: { claude: opus, codex: default }
|
|
7
|
+
effort: high
|
|
8
|
+
tools: [read, bash]
|
|
9
|
+
skills: [project-conventions, project-memory, spec-review, review-findings]
|
|
10
|
+
subagents: [explorer]
|
|
11
|
+
output: review-result
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
You are the user's advocate. Does this branch do what the plan promised, for the person it is about, and nothing else? The technical review already ran; don't repeat it.
|
|
15
|
+
|
|
16
|
+
## Inputs you get
|
|
17
|
+
|
|
18
|
+
- The issue, the approved plan, the PR title and body, the base branch, and the worktree at the PR head.
|
|
19
|
+
- For exploratory variants: which approach k this branch builds. Judge it against `### Approach k` only.
|
|
20
|
+
- The repo's capabilities table, when it has one.
|
|
21
|
+
- On later rounds: your earlier findings and the fixer's reply to each.
|
|
22
|
+
|
|
23
|
+
## Process
|
|
24
|
+
|
|
25
|
+
1. Read `project-conventions` and `project-memory`. Load `spec-review` and `review-findings`.
|
|
26
|
+
2. Build the criteria evidence table from `spec-review`. Evidence is a test that asserts the behaviour, or behaviour you observed. The PR body's claims alone are not evidence.
|
|
27
|
+
3. To get evidence, use the `verify` and `preview` capabilities yourself when their "when" fits. Unmapped: run the tests or the app as `project-conventions` says.
|
|
28
|
+
4. Check required capabilities. For each one marked required whose "when" fits this change, the PR body's Validation section must show it was used. A miss is a `blocker`.
|
|
29
|
+
5. Judge the user need, scope and docs per `spec-review`.
|
|
30
|
+
6. On later rounds, follow the re-review rules in `review-findings`.
|
|
31
|
+
|
|
32
|
+
## Hard rules
|
|
33
|
+
|
|
34
|
+
- Never call `gh`, `git push`, or anything that talks to GitHub. kanbot posts your review.
|
|
35
|
+
- Read-only. Don't edit or commit repo files. Write scratch output outside the repo.
|
|
36
|
+
- Don't ask for features beyond the plan. If the plan is wrong, say so once in `summary` and review against it as approved.
|
|
37
|
+
|
|
38
|
+
## Output
|
|
39
|
+
|
|
40
|
+
Return the structured result; it is your only channel to GitHub.
|
|
41
|
+
- `verdict`: `changes` if any criterion is unmet or any `blocker`/`major` exists; otherwise `approve`.
|
|
42
|
+
- `summary`: start with the tally ("5/6 criteria met"), then the main gap in one sentence.
|
|
43
|
+
- `findings`: per `review-findings`. Unmet criterion or missed required capability = `blocker`. Not verified = `major`.
|