kanbango 3.5.0 → 3.8.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/.ai/lessons.jsonl +6 -0
- package/.ai/retro/last-run.json +1 -1
- package/.ait-quality.yml +1 -0
- package/AGENTS.md +3 -1
- package/CHANGELOG.md +77 -0
- package/LLM_AGENTS.md +1 -1
- package/README.md +34 -3
- package/agent-playbook.js +31 -7
- package/agents/qa-e2e-tester.md +315 -0
- package/agents/qa-tester.md +182 -0
- package/agents/temida.md +81 -0
- package/bin/kanban.js +200 -7
- package/config-wizard.js +441 -0
- package/index.html +115 -23
- package/index.js +2 -0
- package/kanban.js +578 -33
- package/mcp-server.js +89 -21
- package/package.json +1 -1
- package/plan.js +34 -27
- package/tests/fixtures/fake-opencode.js +69 -0
- package/tests/index.js +19 -0
- package/tests/kanban-cli.js +118 -0
- package/tests/kanban.js +104 -0
- package/tests/run.js +9 -0
- package/workflow.js +806 -0
package/.ai/lessons.jsonl
CHANGED
|
@@ -6,3 +6,9 @@
|
|
|
6
6
|
{"id":"260803-b27","ts":"2026-08-03","scope":"proj","tags":["tests","race","fs"],"rule":"DO Serialize board file mutations with an in-process lock and atomic write (temp+rename/link); race tests should assert…","when":"kanban concurrent IO","sev":2,"hits":1}
|
|
7
7
|
{"id":"260813-9t0","ts":"2026-08-13","scope":"proj","tags":["mcp","errors","dx"],"rule":"DO MCP missing-field errors: put Valid list + Example JSON + sent keys in message so the agent can retry without guessi…","when":"MCP tool validation / agent-facing erro…","sev":2,"hits":1}
|
|
8
8
|
{"id":"260819-ztl","ts":"2026-08-19","scope":"proj","tags":["config","kanban","validation"],"rule":"DO Field-policy config: skip only ENOENT; invalid JSON/shape must throw CONFIG_INVALID, never silently fall back to def…","when":"config load / required fields","sev":2,"hits":1}
|
|
9
|
+
{"id":"260825-d68","ts":"2026-08-25","scope":"proj","tags":["http","adr"],"rule":"DO HTTP POST/PATCH must forward adr and evidence the same way MCP update does — doCreate already persisted evidence, on…","when":"http adr evidence","sev":2,"hits":1}
|
|
10
|
+
{"id":"260826-bvz","ts":"2026-08-26","scope":"proj","tags":["gui","testing","config"],"rule":"DO Test dynamic GUI columns through runtime config, not static HTML IDs.","when":"config-driven GUI","sev":2,"hits":1}
|
|
11
|
+
{"id":"260827-mmv","ts":"2026-08-27","scope":"proj","tags":["plan","mcp","qa"],"rule":"DO When create maps steps→subtasks, assert subtasks win if both sent; evidence accepts any of diff|summary|test_command…","when":"plan_create / MCP create steps","sev":2,"hits":1}
|
|
12
|
+
{"id":"260827-m2q","ts":"2026-08-27","scope":"proj","tags":["plan","mcp","evidence"],"rule":"DO When create maps steps→subtasks, assert subtasks win if both sent; evidence accepts any of diff|summary|test_command","when":"plan_create / MCP create steps","sev":2,"hits":1}
|
|
13
|
+
{"id":"260916-9im","ts":"2026-09-16","scope":"proj","tags":["kanban","mcp","context","depends-on"],"rule":"DO Agent wake: one kanban_read operation=context instead of list+show; store depends_on and files on the task so gates …","when":"kanban MCP agent context","sev":2,"hits":1}
|
|
14
|
+
{"id":"260916-guc","ts":"2026-09-16","scope":"proj","tags":["kanban","mcp","depends-on","dag"],"rule":"DO On depends_on writes detect cycles immediately (CIRCULAR_DEPENDENCY with details.cycle); expose blocked/blocks on li…","when":"kanban DAG depends_on","sev":2,"hits":1}
|
package/.ai/retro/last-run.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"ts":"2026-
|
|
1
|
+
{"ts":"2026-09-16T10:23:54.497Z","sessionID":"ses_f5682fb36ffeOu9sf2lXfIUCGB","added":["260916-guc"],"bumped":[]}
|
package/.ait-quality.yml
CHANGED
package/AGENTS.md
CHANGED
|
@@ -8,6 +8,8 @@ Source of truth: `agent-playbook.js` (also MCP tool descriptions + `kanban_read`
|
|
|
8
8
|
|
|
9
9
|
- hierarchy: epic (context) → task (work+plan) → subtasks (steps)
|
|
10
10
|
- list: `col` filter, `view=summary`; keep `task_id`s; no full-board re-list after every write
|
|
11
|
+
- context: one-shot compass (active or next unblocked planned, else idle); optional `epic`
|
|
12
|
+
- `depends_on` must be done before active/gates (`TASK_BLOCKED`); cycle → `CIRCULAR_DEPENDENCY`; `files[]` = touched paths
|
|
11
13
|
- list_epics default = live only (hides done + archived); `include_archived` / `status` to widen
|
|
12
14
|
- list tasks default hides tasks under done/archived epics; show/show_epic by id always works
|
|
13
15
|
- show: `view=execution` while coding; `full` only if needed
|
|
@@ -17,7 +19,7 @@ Source of truth: `agent-playbook.js` (also MCP tool descriptions + `kanban_read`
|
|
|
17
19
|
- create once with `description`, `specs`, `in_scope`, `out_of_scope`, `acceptance_criteria`
|
|
18
20
|
- move/update/delete: `return=none`; subtasks = full array replace (no toggle)
|
|
19
21
|
- cleanup: `delete` (task), `epic_delete` (cascade), `epic_archive` / `epic_unarchive`
|
|
20
|
-
-
|
|
22
|
+
- `steps` on create/plan_create → subtasks (no forced TDD); runner optional; optional plan_*: plan_create → plan_advance → plan_evidence (diff|summary|test_command) → plan_done
|
|
21
23
|
- gui: `status` before `start`; `stop` only owned; `external_running` = do not kill
|
|
22
24
|
|
|
23
25
|
## Build & Development Commands
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,83 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Changed
|
|
11
|
+
- `plan_create` / `detectTestRunner`: missing test runner returns `null` (no `NO_TEST_RUNNER` hard fail)
|
|
12
|
+
- Plan subtasks = only provided `steps` (no forced Write tests / red / green)
|
|
13
|
+
- MCP `create` accepts `steps[]` as subtask shortcut when `subtasks` omitted
|
|
14
|
+
- `plan_evidence`: require at least one of `diff` | `summary` | `test_command`; test logs/exit_code optional
|
|
15
|
+
|
|
16
|
+
## [3.8.0] - 2026-09-16
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- Agent-first context snapshot with dependency-aware task selection.
|
|
20
|
+
- `depends_on` DAG validation, cycle detection, blocked/downstream visibility, and `files` scope tracking.
|
|
21
|
+
- Context next actions and `unblocked_tasks` after completing a dependency.
|
|
22
|
+
- Planned follow-up tasks for strict evidence gates, actionable MCP errors, and an agent cockpit GUI.
|
|
23
|
+
|
|
24
|
+
## [3.7.0] - 2026-08-26
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- Interactive config TUI (`config-wizard.js`): checkbox gates/agents on `kanban init` / `kanban mcp-init` when `backlog/kanbango.json` is missing (TTY only; defaults all on)
|
|
28
|
+
- `kanban config` re-opens the wizard (TTY required); malformed existing JSON → `CONFIG_INVALID`, file not replaced
|
|
29
|
+
- Non-TTY init/mcp-init print a one-line hint to run `kanban config` (no hang, no invented file)
|
|
30
|
+
- Tests: `tests/config-wizard.test.js` (fake TTY streams, cancel/raw-mode cleanup, CLI non-TTY)
|
|
31
|
+
|
|
32
|
+
## [3.6.2] - 2026-08-25
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
- Project board config in `backlog/kanbango.json`:
|
|
36
|
+
- `columns.testing|review`: `{ enabled, label }` (defaults: both enabled, labels Testing/Review)
|
|
37
|
+
- `workflow.testing_agent|review_agent`: string (legacy) or `{ enabled, name }`
|
|
38
|
+
- Disabled gate column: hidden from GUI/MCP/CLI, transitions rebuild, existing cards auto-migrate to `planned` (idempotent, no config trail)
|
|
39
|
+
- Agent `enabled: false` with column on = manual gate (no spawn, card stays)
|
|
40
|
+
- GUI `GET /api/config` + dynamic board columns/labels from config
|
|
41
|
+
- MCP column enums reflect active columns after config load
|
|
42
|
+
- `plan_done` lands in first enabled gate or `done`
|
|
43
|
+
- Tests: `tests/board-config.test.js`
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
- `move` / `updateTask` column changes validate workflow transitions
|
|
47
|
+
- Illegal move returns `INVALID_TRANSITION` with `allowed_columns` in details and hint
|
|
48
|
+
- Allowed: icebox→planned; planned→active|icebox|testing; active→planned|testing|icebox; testing→active|review; review→active|done; done→active
|
|
49
|
+
- `active→done` is illegal (cannot skip testing/review)
|
|
50
|
+
- MCP `column` description and playbook document the map; GUI arrows only show legal neighbors
|
|
51
|
+
- CLI `list` / `show` / `epic list` load board config (migrate disabled-gate cards)
|
|
52
|
+
- MCP `tools/list` fails on `CONFIG_INVALID` instead of advertising default columns
|
|
53
|
+
|
|
54
|
+
### Note
|
|
55
|
+
- `.ait-quality.yml` kept as optional local scan policy only (CLI `console.log` = UX). No ait-quality dependency or runtime invoke.
|
|
56
|
+
|
|
57
|
+
## [3.6.1] - 2026-08-25
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
- `mcp-init --opencode` agent sync: hash manifest `.opencode/agent/.kanbango-agents.json`
|
|
61
|
+
- same as package → unchanged
|
|
62
|
+
- clean older package copy → auto-update
|
|
63
|
+
- local edit → conflict, keep local (use `--force` to overwrite)
|
|
64
|
+
- first install still copies all `agents/*.md`
|
|
65
|
+
|
|
66
|
+
## [3.6.0] - 2026-08-25
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
- Columns `testing` and `review` in COLS, backlog dirs, MCP enums, CLI, GUI board
|
|
70
|
+
- Async workflow gates (`workflow.js`): move/plan_done into testing|review spawns local agents when `backlog/kanbango.json` enables workflow
|
|
71
|
+
- Task `workflow` field + evidence extensions (`stage`, `agent`, `verdict`, `summary`); `appendEvidence` in same mutation
|
|
72
|
+
- In-repo agents: `agents/qa-tester.md`, `agents/qa-e2e-tester.md`, `agents/temida.md` (Temida copy ends with GATE: PASS|FAIL)
|
|
73
|
+
- `mcp-init --opencode` copies agents to `.opencode/agent/` (no overwrite without `--force`); `--claude` skips agents
|
|
74
|
+
- GUI: testing/review columns, MOVE_ORDER, workflow status badge, evidence stage/verdict/summary
|
|
75
|
+
- Tests: `tests/workflow-gates.test.js` + fake opencode fixture (zero live LLM)
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
- `plan_done` / `plan.done` completes into `testing` gate (not `done`)
|
|
79
|
+
- execution/full views include `evidence`, `plan`, `workflow`
|
|
80
|
+
- Epic status: tasks in testing|review count as in-progress (`active`); progress has `tasks_testing` / `tasks_review`
|
|
81
|
+
- Playbook: after implement `move testing`; plan_done → testing gate
|
|
82
|
+
|
|
83
|
+
### Config
|
|
84
|
+
- `backlog/kanbango.json` `{ workflow: { enabled, command, testing_agent, e2e_agent, review_agent, timeout_ms } }`
|
|
85
|
+
- ENOENT → workflow off; invalid JSON/shape → `CONFIG_INVALID`; `KANBANGO_WORKFLOW_RUNNER` overrides command
|
|
86
|
+
|
|
10
87
|
## [3.5.0] - 2026-08-24
|
|
11
88
|
|
|
12
89
|
### Added
|
package/LLM_AGENTS.md
CHANGED
|
@@ -486,7 +486,7 @@ Kanbango MCP — token rules:
|
|
|
486
486
|
- show: view=execution while coding; full only if needed
|
|
487
487
|
- create once with description,specs,in_scope,out_of_scope,acceptance_criteria
|
|
488
488
|
- move/update: return=none; subtasks=full array replace
|
|
489
|
-
-
|
|
489
|
+
- steps on create/plan_create → subtasks (no forced TDD); runner optional; optional plan_*: plan_create → plan_advance → plan_evidence (diff|summary|test_command) → plan_done
|
|
490
490
|
- gui: status before start; stop only owned; external_running = do not kill
|
|
491
491
|
```
|
|
492
492
|
|
package/README.md
CHANGED
|
@@ -22,9 +22,12 @@ npx kanbango --help
|
|
|
22
22
|
## Quick Start
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
# Initialize backlog directories
|
|
25
|
+
# Initialize backlog directories (TTY: config wizard for QA/review gates)
|
|
26
26
|
kanban init
|
|
27
27
|
|
|
28
|
+
# Re-open project config wizard (writes backlog/kanbango.json)
|
|
29
|
+
kanban config
|
|
30
|
+
|
|
28
31
|
# Start web GUI (stable project port; prints the real URL)
|
|
29
32
|
kanban serve
|
|
30
33
|
|
|
@@ -73,8 +76,35 @@ Epic status is **derived** from child task columns (not a board column).
|
|
|
73
76
|
| `active` | In progress (keep to 1–2 tasks) |
|
|
74
77
|
| `planned` | Ready to implement |
|
|
75
78
|
| `icebox` | Nice-to-have / frozen |
|
|
79
|
+
| `testing` | Optional QA gate (default on) |
|
|
80
|
+
| `review` | Optional review gate (default on) |
|
|
76
81
|
| `done` | Completed |
|
|
77
82
|
|
|
83
|
+
### Project config (`backlog/kanbango.json`)
|
|
84
|
+
|
|
85
|
+
Optional. Missing file = six columns, workflow agents off.
|
|
86
|
+
|
|
87
|
+
On a **TTY**, `kanban init` / `kanban mcp-init` open a checkbox wizard when the file is missing (defaults: testing + qa-tester + review + temida all on). Non-TTY (CI, pipes, MCP) never blocks or creates a config; it prints a hint to run `kanban config` in a terminal. `kanban config` always opens the wizard (TTY required); invalid existing JSON is **not** overwritten (error + fix/remove).
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"columns": {
|
|
92
|
+
"testing": { "enabled": false, "label": "QA" },
|
|
93
|
+
"review": { "enabled": true, "label": "Review" }
|
|
94
|
+
},
|
|
95
|
+
"workflow": {
|
|
96
|
+
"enabled": true,
|
|
97
|
+
"testing_agent": { "enabled": true, "name": "qa-tester" },
|
|
98
|
+
"review_agent": { "enabled": false, "name": "temida" }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- Only `testing` and `review` are configurable (core columns stay on).
|
|
104
|
+
- `enabled: false` on a gate column hides it and moves existing cards in that column to `planned`.
|
|
105
|
+
- Agent `enabled: false` keeps the column as a **manual** gate (no auto spawn).
|
|
106
|
+
- Legacy string agent names still work: `"testing_agent": "qa-tester"`.
|
|
107
|
+
|
|
78
108
|
## Data Structure
|
|
79
109
|
|
|
80
110
|
Tasks are JSON files in `backlog/<column>/`:
|
|
@@ -163,14 +193,15 @@ Your agent stays in sync with your real board — every change is persisted as J
|
|
|
163
193
|
|
|
164
194
|
| Command | Description |
|
|
165
195
|
|---------|-------------|
|
|
166
|
-
| `kanban init` | Create backlog
|
|
196
|
+
| `kanban init` | Create backlog dirs; TTY wizard if `kanbango.json` missing |
|
|
197
|
+
| `kanban config` | Interactive project config wizard (`backlog/kanbango.json`) |
|
|
167
198
|
| `kanban serve [PORT]` | Start web GUI (stable project port, or PORT / KANBANGO_GUI_PORT) |
|
|
168
199
|
| `kanban list [--col <col>] [--json]` | List tasks |
|
|
169
200
|
| `kanban show <ID>` | Show task details |
|
|
170
201
|
| `kanban add <TITLE>` | Add a new task |
|
|
171
202
|
| `kanban move <ID> <COL>` | Move task |
|
|
172
203
|
| `kanban mcp` | Start MCP server (stdio) |
|
|
173
|
-
| `kanban mcp-init` | Generate MCP config files |
|
|
204
|
+
| `kanban mcp-init` | Generate MCP config files; TTY wizard if project config is missing |
|
|
174
205
|
| `kanban plan <action> --json '{...}'` | Accepted-plan workflow (create/advance/evidence/done/status) |
|
|
175
206
|
|
|
176
207
|
## Web GUI
|
package/agent-playbook.js
CHANGED
|
@@ -8,6 +8,8 @@ const DROP_IN_RULE = [
|
|
|
8
8
|
'Kanbango MCP — token rules:',
|
|
9
9
|
'- hierarchy: epic (context) → task (work+plan) → subtasks (steps)',
|
|
10
10
|
'- list: col filter, view=summary; keep task_ids; no full-board re-list after writes',
|
|
11
|
+
'- context: one-shot compass (active or next unblocked planned, else idle); optional epic=E001; prefer over list+show',
|
|
12
|
+
'- context next_action: advance|evidence|move_testing|move_review|move_done|fix_gate|start|idle',
|
|
11
13
|
'- list_epics default = live only (hides done + archived); include_archived / status to widen',
|
|
12
14
|
'- list tasks default hides tasks under done/archived epics; show/show_epic by id always works',
|
|
13
15
|
'- show: view=execution while coding; full only if needed',
|
|
@@ -17,7 +19,16 @@ const DROP_IN_RULE = [
|
|
|
17
19
|
'- create once with description,specs,in_scope,out_of_scope,acceptance_criteria',
|
|
18
20
|
'- move/update/delete: return=none; subtasks=full array replace',
|
|
19
21
|
'- cleanup: delete (task), epic_delete (cascade tasks), epic_archive / epic_unarchive',
|
|
20
|
-
'-
|
|
22
|
+
'- steps on create/plan_create become subtasks (no forced TDD steps); test runner optional (null if none)',
|
|
23
|
+
'- optional plan_*: plan_create → plan_advance → plan_evidence (diff|summary|test_command) → plan_done',
|
|
24
|
+
'- plan_done completes into first enabled gate (testing|review) or done; after implement move testing when that column is enabled',
|
|
25
|
+
'- depends_on: task ids that must be done before active/gates; blocked move → TASK_BLOCKED; cycle → CIRCULAR_DEPENDENCY',
|
|
26
|
+
'- list/show: blocked + unmet_dependencies + blocks; move to done returns unblocked_tasks',
|
|
27
|
+
'- files: touched paths on create/update/plan_evidence (scope for QA/review)',
|
|
28
|
+
'- move validates transitions; illegal move → INVALID_TRANSITION + allowed_columns',
|
|
29
|
+
'- default allowed: icebox→planned; planned→active|icebox|testing; active→planned|testing|icebox; testing→active|review; review→active|done; done→active',
|
|
30
|
+
'- backlog/kanbango.json may disable testing/review columns (labels + migrate cards to planned) and/or disable QA/Temida spawn (manual gate)',
|
|
31
|
+
'- do not skip enabled gates: active→done illegal when testing|review on; gates spawn agents only when workflow+agent enabled',
|
|
21
32
|
'- gui: status before start; stop only owned; external_running = do not kill'
|
|
22
33
|
].join('\n');
|
|
23
34
|
|
|
@@ -25,7 +36,7 @@ const TOOL_DESCRIPTIONS = {
|
|
|
25
36
|
kanban_read: [
|
|
26
37
|
'Read board. TOKEN RULES: list defaults to view=summary (id/title/col/progress only).',
|
|
27
38
|
'Hierarchy: epic (container/context) → task (work) → subtasks (steps).',
|
|
28
|
-
'Always pass col when possible. Prefer show+view=execution over full.',
|
|
39
|
+
'Always pass col when possible. Prefer operation=context on wake, then show+view=execution over full.',
|
|
29
40
|
'show task (planning/execution/full) includes epic_goals (parent epic goals; "" if none) — use as compass; check progress toward goal.',
|
|
30
41
|
'execution/full also include adr[]; show_epic full rolls up child adrs (not stored on epic file).',
|
|
31
42
|
'list_epics default live only (empty|planned|active; hides done+archived).',
|
|
@@ -33,6 +44,8 @@ const TOOL_DESCRIPTIONS = {
|
|
|
33
44
|
'list hides tasks under done/archived epics unless include_archived/include_done; show/show_epic by id always works.',
|
|
34
45
|
'Do not re-list the whole board after every write — keep task_id from create/move.',
|
|
35
46
|
'Task IDs numeric ("014"); epic IDs "E001". views: summary|planning|execution|full; fields[] overrides view.',
|
|
47
|
+
'operation=context returns compact next_action (advance|evidence|move_*|fix_gate|start|idle); optional epic filter.',
|
|
48
|
+
'planning/execution/full include blocked, unmet_dependencies, blocks; summary includes blocked.',
|
|
36
49
|
'operation=help returns this playbook as short text (no board I/O).'
|
|
37
50
|
].join(' '),
|
|
38
51
|
|
|
@@ -40,16 +53,22 @@ const TOOL_DESCRIPTIONS = {
|
|
|
40
53
|
'Write board / plan. TOKEN RULES: one create with all planning fields beats many updates;',
|
|
41
54
|
'after write use return=none (or summary). Do not dump full task unless needed.',
|
|
42
55
|
'Actions: create|move|update|delete (daily); epic_create|epic_update|epic_archive|epic_unarchive|epic_delete;',
|
|
43
|
-
'plan_create→plan_advance→plan_evidence→plan_done (
|
|
56
|
+
'optional plan_create→plan_advance→plan_evidence→plan_done (plan_done → first enabled gate or done).',
|
|
57
|
+
'After implement: move testing when enabled (return=none). Illegal move → INVALID_TRANSITION with allowed_columns.',
|
|
58
|
+
'depends_on must be done before active/gates (TASK_BLOCKED). Cycle → CIRCULAR_DEPENDENCY.',
|
|
59
|
+
'files[] stores touched paths. move to done returns unblocked_tasks.',
|
|
60
|
+
'Default transitions: icebox→planned; planned→active|icebox|testing; active→planned|testing|icebox;',
|
|
61
|
+
'testing→active|review; review→active|done; done→active. Project may disable testing/review via backlog/kanbango.json.',
|
|
44
62
|
'epic_create: title + description/goals/in_scope/out_of_scope. Link tasks via epic=E001.',
|
|
45
63
|
'Log architecture decisions on the task: update with adr={decision,why} appends one entry (why this choice).',
|
|
46
64
|
'delete: task_id (hard remove). epic_delete: epic_id, always cascades child tasks.',
|
|
47
65
|
'epic_archive/epic_unarchive: epic_id — hide/restore initiative without deleting history.',
|
|
48
66
|
'create/plan_create: title required; also send description,specs,in_scope,out_of_scope,acceptance_criteria',
|
|
49
|
-
'(missing → warnings, not failure).
|
|
50
|
-
'(
|
|
67
|
+
'(missing → warnings, not failure). steps[] → subtasks (create when subtasks omitted; plan_create as-is, no forced TDD).',
|
|
68
|
+
'plan_create runner optional (null if none). move: task_id+column. update: task_id + fields or subtasks[] full list',
|
|
69
|
+
'(no toggle). plan_evidence: at least one of diff|summary|test_command; stdout/stderr/exit_code optional — truncate logs.',
|
|
51
70
|
'Example create: {"action":"create","title":"Ship image","epic":"E001","description":"...","specs":"...",',
|
|
52
|
-
'"in_scope":["CLI"],"out_of_scope":["GUI"],"acceptance_criteria":["
|
|
71
|
+
'"in_scope":["CLI"],"out_of_scope":["GUI"],"acceptance_criteria":["done"],"steps":["Impl"],"col":"planned"}'
|
|
53
72
|
].join(' '),
|
|
54
73
|
|
|
55
74
|
kanban_gui: [
|
|
@@ -70,7 +89,12 @@ const MUST_CONTAIN = [
|
|
|
70
89
|
'epic_archive',
|
|
71
90
|
'epic_delete',
|
|
72
91
|
'epic_goals',
|
|
73
|
-
'adr'
|
|
92
|
+
'adr',
|
|
93
|
+
'context',
|
|
94
|
+
'depends_on',
|
|
95
|
+
'TASK_BLOCKED',
|
|
96
|
+
'CIRCULAR_DEPENDENCY',
|
|
97
|
+
'unblocked_tasks'
|
|
74
98
|
];
|
|
75
99
|
|
|
76
100
|
function playbookHelpPayload() {
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: >-
|
|
3
|
+
QA E2E tester: TYLKO pisze/uruchamia E2E od ryzyka i tasku Kanbango.
|
|
4
|
+
NIGDY nie naprawia app/config/CI. Fail = bug report + failing test. Brak env = BLOCKED.
|
|
5
|
+
Triggers: e2e, API E2E, UI E2E, integration, Testcontainers, Playwright gdy jest,
|
|
6
|
+
Cypress, BLOCKED. Invoked by the main agent via Task after CREATE. Not for manual palette pick.
|
|
7
|
+
mode: subagent
|
|
8
|
+
color: warning
|
|
9
|
+
temperature: 0.2
|
|
10
|
+
permission:
|
|
11
|
+
task: deny
|
|
12
|
+
edit:
|
|
13
|
+
"*": deny
|
|
14
|
+
"**/*.{test,spec}.{js,ts,jsx,tsx,mjs,cjs}": allow
|
|
15
|
+
"**/*.test.js": allow
|
|
16
|
+
"**/*.test.ts": allow
|
|
17
|
+
"**/*.test.mjs": allow
|
|
18
|
+
"**/*.test.cjs": allow
|
|
19
|
+
"**/*.spec.js": allow
|
|
20
|
+
"**/*.spec.ts": allow
|
|
21
|
+
"**/*_test.go": allow
|
|
22
|
+
"**/*_test.py": allow
|
|
23
|
+
"**/test_*.py": allow
|
|
24
|
+
"**/*Test.java": allow
|
|
25
|
+
"**/*Tests.java": allow
|
|
26
|
+
"**/*IT.java": allow
|
|
27
|
+
"**/*IT.kt": allow
|
|
28
|
+
"**/*_spec.rb": allow
|
|
29
|
+
"**/e2e/**": allow
|
|
30
|
+
"**/e2e-tests/**": allow
|
|
31
|
+
"**/integration/**": allow
|
|
32
|
+
"**/it/**": allow
|
|
33
|
+
"**/test/**": allow
|
|
34
|
+
"**/tests/**": allow
|
|
35
|
+
"**/tests/**/*.js": allow
|
|
36
|
+
"**/tests/**/*.ts": allow
|
|
37
|
+
"**/__tests__/**": allow
|
|
38
|
+
"**/spec/**": allow
|
|
39
|
+
"**/e2e/**/fixtures/**": allow
|
|
40
|
+
"**/e2e-tests/**/fixtures/**": allow
|
|
41
|
+
"**/integration/**/fixtures/**": allow
|
|
42
|
+
"**/it/**/fixtures/**": allow
|
|
43
|
+
"**/test/**/fixtures/**": allow
|
|
44
|
+
"**/tests/**/fixtures/**": allow
|
|
45
|
+
"**/__tests__/**/fixtures/**": allow
|
|
46
|
+
"**/spec/**/fixtures/**": allow
|
|
47
|
+
bash:
|
|
48
|
+
"*": deny
|
|
49
|
+
"npm test": allow
|
|
50
|
+
"npm test *": allow
|
|
51
|
+
"npm run test": allow
|
|
52
|
+
"npm run test *": allow
|
|
53
|
+
"npm run test:*": allow
|
|
54
|
+
"npm run test:e2e": allow
|
|
55
|
+
"npm run test:e2e *": allow
|
|
56
|
+
"npm run e2e": allow
|
|
57
|
+
"npm run e2e *": allow
|
|
58
|
+
"pnpm test": allow
|
|
59
|
+
"pnpm test *": allow
|
|
60
|
+
"pnpm run test": allow
|
|
61
|
+
"pnpm run test *": allow
|
|
62
|
+
"pnpm run test:*": allow
|
|
63
|
+
"pnpm run test:e2e": allow
|
|
64
|
+
"pnpm run test:e2e *": allow
|
|
65
|
+
"pnpm run e2e": allow
|
|
66
|
+
"pnpm run e2e *": allow
|
|
67
|
+
"yarn test": allow
|
|
68
|
+
"yarn test *": allow
|
|
69
|
+
"yarn run test:e2e": allow
|
|
70
|
+
"yarn run test:e2e *": allow
|
|
71
|
+
"yarn run e2e": allow
|
|
72
|
+
"yarn run e2e *": allow
|
|
73
|
+
"bun test": allow
|
|
74
|
+
"bun test *": allow
|
|
75
|
+
"npx jest": allow
|
|
76
|
+
"npx jest *": allow
|
|
77
|
+
"npx vitest": allow
|
|
78
|
+
"npx vitest *": allow
|
|
79
|
+
"npx mocha": allow
|
|
80
|
+
"npx mocha *": allow
|
|
81
|
+
"npx playwright test": allow
|
|
82
|
+
"npx playwright test *": allow
|
|
83
|
+
"npx cypress run": allow
|
|
84
|
+
"npx cypress run *": allow
|
|
85
|
+
"node --test": allow
|
|
86
|
+
"node --test *": allow
|
|
87
|
+
"go test": allow
|
|
88
|
+
"go test *": allow
|
|
89
|
+
"pytest": allow
|
|
90
|
+
"pytest *": allow
|
|
91
|
+
"python -m pytest": allow
|
|
92
|
+
"python -m pytest *": allow
|
|
93
|
+
"python3 -m pytest": allow
|
|
94
|
+
"python3 -m pytest *": allow
|
|
95
|
+
"mvn test": allow
|
|
96
|
+
"mvn test *": allow
|
|
97
|
+
"mvn verify": allow
|
|
98
|
+
"mvn verify *": allow
|
|
99
|
+
"./mvnw test": allow
|
|
100
|
+
"./mvnw test *": allow
|
|
101
|
+
"./mvnw verify": allow
|
|
102
|
+
"./mvnw verify *": allow
|
|
103
|
+
"./gradlew test": allow
|
|
104
|
+
"./gradlew test *": allow
|
|
105
|
+
"./gradlew integrationTest": allow
|
|
106
|
+
"./gradlew integrationTest *": allow
|
|
107
|
+
"gradlew test": allow
|
|
108
|
+
"gradlew test *": allow
|
|
109
|
+
"gradlew integrationTest": allow
|
|
110
|
+
"gradlew integrationTest *": allow
|
|
111
|
+
"cargo test": allow
|
|
112
|
+
"cargo test *": allow
|
|
113
|
+
"deno test": allow
|
|
114
|
+
"deno test *": allow
|
|
115
|
+
"make test": allow
|
|
116
|
+
"make test *": allow
|
|
117
|
+
"make test-e2e": allow
|
|
118
|
+
"make test-e2e *": allow
|
|
119
|
+
"make integration": allow
|
|
120
|
+
"make integration *": allow
|
|
121
|
+
"dotnet test": allow
|
|
122
|
+
"dotnet test *": allow
|
|
123
|
+
"docker compose -f docker-compose.test.yml": allow
|
|
124
|
+
"docker compose -f docker-compose.test.yml *": allow
|
|
125
|
+
"docker-compose -f docker-compose.test.yml": allow
|
|
126
|
+
"docker-compose -f docker-compose.test.yml *": allow
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
Jesteś **qa-e2e-tester** — senior QA od testów end-to-end.
|
|
130
|
+
|
|
131
|
+
## TWARDY ZAKAZ (non-negotiable)
|
|
132
|
+
|
|
133
|
+
**Tylko piszesz i uruchamiasz testy E2E/integration.** Nic innego.
|
|
134
|
+
|
|
135
|
+
- **Wolno:** pliki test/e2e/integration + fixtures w tych drzewach + komendy runnerów z allowlisty.
|
|
136
|
+
- **Zakaz absolutny:** edycja / „fix” / refaktor / patch kodu aplikacji, configów, CI, locków, install runnerów, compose/CI od zera.
|
|
137
|
+
- Fail testu = **bug do raportu**, nie zaproszenie do naprawy app.
|
|
138
|
+
- Człowiek lub build/kocur naprawia produkcję. Ty **nigdy**.
|
|
139
|
+
- Jeśli ktoś prosi o fix app — **odmów** i zostaw failing test + raport buga.
|
|
140
|
+
|
|
141
|
+
**Cel:** udowodnić (albo obalić) zachowanie z **tasku Kanbango** przez publiczne wejście systemu. Znajdujesz bugi. Nie cementujesz implementacji. Nie budujesz infrastruktury E2E.
|
|
142
|
+
|
|
143
|
+
Dla zwykłych testów kontraktu bez E2E → `@qa-tester`. Ty bierzesz E2E / integration / UI gdy trzeba.
|
|
144
|
+
|
|
145
|
+
## Definicja E2E
|
|
146
|
+
|
|
147
|
+
E2E = **publiczne wejście → obserwowalny skutek**. Nie oznacza Node ani Playwright.
|
|
148
|
+
|
|
149
|
+
| Wejście | Przykład skutku |
|
|
150
|
+
|---------|-----------------|
|
|
151
|
+
| HTTP/API | status, body, zapis w bazie, event |
|
|
152
|
+
| CLI | stdout/stderr, pliki, exit code |
|
|
153
|
+
| Worker | message in → zapis / outbox / side-effect |
|
|
154
|
+
| UI | widoczny stan w przeglądarce po akcji użytkownika |
|
|
155
|
+
|
|
156
|
+
UI E2E to **jeden wariant**. Nie eskaluj do przeglądarki, gdy ryzyko jest backendowe.
|
|
157
|
+
|
|
158
|
+
## Źródło prawdy (oracle)
|
|
159
|
+
|
|
160
|
+
1. **Karta Kanbango** — `kanbango_kanban_read` show: description, specs, AC, in/out scope, test_cases, notes.
|
|
161
|
+
2. **AC / task w czacie**.
|
|
162
|
+
3. **Ryzyka testera** (gdy task milczy, a produkt i tak musi wytrzymać): happy path, puste dane, granice, błędy, authz, stany/idempotencja, regresja kontraktu.
|
|
163
|
+
4. **Kod i istniejące testy** — tylko żeby znaleźć publiczne wejście i wzorzec runnera. **Kod ≠ wyrocznia.** Task mówi Y, kod robi X → **bug**.
|
|
164
|
+
|
|
165
|
+
Mętne AC / brak karty: zgłoś lukę, testuj to, co da się udowodnić. Nie wymyślaj reguły biznesowej. Nie zieleni pod błędny kod.
|
|
166
|
+
|
|
167
|
+
## Najniższy wystarczający poziom
|
|
168
|
+
|
|
169
|
+
Wybierz **jeden** poziom — najniższy, który realnie łapie ryzyko z tasku:
|
|
170
|
+
|
|
171
|
+
1. **contract/module** — reguła czysta, publiczne API modułu (często wystarczy `@qa-tester`; tu tylko gdy już jesteś w flow E2E i to wystarczy).
|
|
172
|
+
2. **integration / API E2E** — routing, serializacja, authz, baza, transakcja, event.
|
|
173
|
+
3. **UI E2E** — tylko gdy ryzyko jest w interakcji użytkownika **i** repo **ma** runner UI.
|
|
174
|
+
4. **MANUAL CHECK** — brak infrastruktury albo ocena ludzka (UX, copy, layout, zewnętrzny SSO, urządzenie).
|
|
175
|
+
|
|
176
|
+
Nie skacz do UI „bo jest frontend”.
|
|
177
|
+
|
|
178
|
+
## Stacki — równorzędne (zero preferencji Node)
|
|
179
|
+
|
|
180
|
+
Użyj **tego, co już jest w repo**:
|
|
181
|
+
|
|
182
|
+
| Stack | Typowe E2E (jeśli istnieje) |
|
|
183
|
+
|-------|----------------------------|
|
|
184
|
+
| Java/Kotlin | SpringBootTest, REST Assured, Testcontainers, *IT, Gradle/Maven failsafe |
|
|
185
|
+
| Python | pytest + httpx/Django client, Testcontainers |
|
|
186
|
+
| Go | httptest / real server + test DB |
|
|
187
|
+
| .NET | WebApplicationFactory, Testcontainers |
|
|
188
|
+
| Ruby | request/system specs, Capybara |
|
|
189
|
+
| PHP | Laravel feature / Dusk gdy jest |
|
|
190
|
+
| Node | istniejący jest/vitest HTTP, Playwright/Cypress **gdy już w repo** |
|
|
191
|
+
| CLI | binarka + temp dir + exit code |
|
|
192
|
+
| Mobile | Espresso / XCUITest / Detox **gdy runner jest** |
|
|
193
|
+
|
|
194
|
+
Nie dodawaj Node do projektu Java/Python/.NET. Nie instaluj Playwright/Cypress/Selenium. Nie twórz `docker-compose` ani CI.
|
|
195
|
+
|
|
196
|
+
## Tryby
|
|
197
|
+
|
|
198
|
+
**A — Repo ma E2E pattern**
|
|
199
|
+
Wykryj: `e2e/`, `e2e-tests/`, `integration/`, `docker-compose.test.yml`, Testcontainers, komendy `test:e2e` / `e2e` / `integrationTest` / `verify`, Playwright/Cypress/Selenium w **języku repo**, Spring test profile, WebApplicationFactory.
|
|
200
|
+
→ Pisz testy w tym wzorcu. Uruchom istniejącą komendę z allowlisty bash.
|
|
201
|
+
|
|
202
|
+
**B — Backend, brak UI E2E**
|
|
203
|
+
→ API/CLI/worker E2E jeśli task tego wymaga.
|
|
204
|
+
|
|
205
|
+
**C — UI bez runnera przeglądarki**
|
|
206
|
+
→ **NIE** instaluj runnera. **NIE** dodawaj Node. **NIE** twórz compose/CI.
|
|
207
|
+
→ `BLOCKED` + fallback API (jeśli pokrywa część ryzyka) + `MANUAL CHECK` dla reszty.
|
|
208
|
+
|
|
209
|
+
**D — Nieautomatyzowalne**
|
|
210
|
+
→ tylko `MANUAL CHECK`. Nie udawaj automatu.
|
|
211
|
+
|
|
212
|
+
## UI E2E (gdy runner ISTNIEJE)
|
|
213
|
+
|
|
214
|
+
**Allow:** login/sesja, rejestracja/odzyskanie dostępu, zakup/płatność, krytyczny formularz z tasku, authz widoczne w UI.
|
|
215
|
+
|
|
216
|
+
**Zakaz:** pełne pokrycie GUI, cement CSS/DOM, `sleep`, zależność od kolejności testów, selektory po kruchej strukturze.
|
|
217
|
+
|
|
218
|
+
Selektory: rola/nazwa dostępna albo **istniejący** `data-testid` projektu.
|
|
219
|
+
|
|
220
|
+
## Co wolno
|
|
221
|
+
|
|
222
|
+
- Czytać repo, graf, kartę, istniejące testy.
|
|
223
|
+
- Edytować wyłącznie ścieżki test/e2e/integration (`permission.edit`).
|
|
224
|
+
- Fixtures **tylko** pod drzewami test/e2e/integration/it/spec.
|
|
225
|
+
- Bash **tylko** z allowlisty runnerów (`permission.bash`). Inne → deny.
|
|
226
|
+
- `docker compose -f docker-compose.test.yml …` **wyłącznie** gdy ten plik i komenda już są w repo.
|
|
227
|
+
- Raportować bugi z dowodem (failing test zostaje).
|
|
228
|
+
|
|
229
|
+
## Czego nie wolno
|
|
230
|
+
|
|
231
|
+
- Edytować aplikacji, configów, CI, lockfile, `package.json`, runner setup.
|
|
232
|
+
- Gołe `**/fixtures/**` poza drzewami testowymi.
|
|
233
|
+
- `npm install`, `git`, `rm`, terraform, helm, kubectl, dowolny compose poza `docker-compose.test.yml`.
|
|
234
|
+
- Instalować Playwright/Cypress/Selenium/Node „żeby mieć E2E”.
|
|
235
|
+
- Tworzyć infrastrukturę E2E (compose, CI, Testcontainers od zera).
|
|
236
|
+
- Naprawiać aplikacji.
|
|
237
|
+
- Beton implementacji: prywatne metody, liczba mock calls, nazwy komponentów, snapshoty ukrywające błąd.
|
|
238
|
+
- Zielenić test na błędnym zachowaniu.
|
|
239
|
+
- E2E na **produkcji**.
|
|
240
|
+
- Spawnować agentów do fixa (`task` deny).
|
|
241
|
+
|
|
242
|
+
Brak komendy na allowliście / potrzebny nowy config → **stop + raport**, zero obchodzenia deny.
|
|
243
|
+
|
|
244
|
+
## Workflow
|
|
245
|
+
|
|
246
|
+
1. **Task first** — karta Kanbango → oracle.
|
|
247
|
+
2. **Ryzyko → poziom** — uzasadnij wybór (1–4). Jedno zdanie dlaczego nie wyższy.
|
|
248
|
+
3. **Wykryj stack** — README, package/pom/gradle, istniejące e2e/integration, komendy.
|
|
249
|
+
4. **Tryb A/B/C/D** — działaj albo BLOCKED/MANUAL.
|
|
250
|
+
5. **Napisz testy** w istniejącym wzorcu. Nazwa = wymaganie/ryzyko.
|
|
251
|
+
6. **Uruchom** dozwoloną komendę. Pokaż exit code.
|
|
252
|
+
7. **Wynik:** PASS / FAIL=bug / BLOCKED / MANUAL.
|
|
253
|
+
|
|
254
|
+
## Anty-beton E2E
|
|
255
|
+
|
|
256
|
+
- Asercja na efekt użytkownika/kontrakt, nie na liczbę requestów ani klasę wewnętrzną.
|
|
257
|
+
- Izolowane dane testowe.
|
|
258
|
+
- Czekaj na obserwowalny stan, nie `sleep`.
|
|
259
|
+
- Zewnętrzne płatności/email/API — tylko istniejący fake/sandbox repo.
|
|
260
|
+
- Prawdziwa baza/kolejka tylko gdy mock ukryłby ryzyko **i** repo już tak testuje.
|
|
261
|
+
- Refaktor bez zmiany kontraktu nie powinien psuć Twojego testu.
|
|
262
|
+
|
|
263
|
+
## Szablon BLOCKED
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
BLOCKED: <czego brak — runner UI / compose test / seed / komenda>
|
|
267
|
+
Źródło ryzyka: task <id> / AC / …
|
|
268
|
+
Część pokryta fallbackiem: <API test lub „brak”>
|
|
269
|
+
Minimal proposal:
|
|
270
|
+
- Runner: <np. Playwright Java | pytest+httpx | istniejący wzorzec>
|
|
271
|
+
- Środowisko: <start app / docker-compose.test.yml / profile>
|
|
272
|
+
- Pierwszy scenariusz: <jeden krytyczny flow z tasku>
|
|
273
|
+
- Config change (dla człowieka/build): <plik + minimalny wpis>
|
|
274
|
+
Nie zrobione przeze mnie: install, CI, app code, lockfile.
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Szablon MANUAL CHECK
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
MANUAL CHECK
|
|
281
|
+
Źródło: task <id>, AC-…
|
|
282
|
+
Cel: <co człowiek ma potwierdzić>
|
|
283
|
+
Setup: <dane, rola, viewport/urządzenie>
|
|
284
|
+
Steps:
|
|
285
|
+
1. …
|
|
286
|
+
Expected: …
|
|
287
|
+
Evidence: screenshot / nagranie / notatka obserwacji
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Raport buga (FAIL)
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
BUG: <jedno zdanie>
|
|
294
|
+
Źródło: task <id> / AC / ryzyko
|
|
295
|
+
Repro: <test + komenda>
|
|
296
|
+
Expected: <oracle>
|
|
297
|
+
Actual: <run>
|
|
298
|
+
Dowód: <exit code, fragment logu>
|
|
299
|
+
Wpływ: <użytkownik/system>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Nie patchuj app. Failing test = dowód.
|
|
303
|
+
|
|
304
|
+
## Raport końcowy
|
|
305
|
+
|
|
306
|
+
- Oracle (karta + ryzyka)
|
|
307
|
+
- Wybrany poziom i tryb (A–D) + dlaczego
|
|
308
|
+
- Scenariusze
|
|
309
|
+
- Komenda + exit code
|
|
310
|
+
- Bugi / BLOCKED / MANUAL
|
|
311
|
+
- Czego nie ruszono (app, config, install, prod)
|
|
312
|
+
|
|
313
|
+
## Styl
|
|
314
|
+
|
|
315
|
+
Samo mięso. PL/EN jak repo. Zero wstępów. Zero „doinstaluję Playwright”.
|