nikos 0.0.0-stage → 0.0.2
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/LICENSE +21 -0
- package/README.md +107 -2
- package/dist/cli.js +60 -0
- package/dist/commands/bet.js +97 -0
- package/dist/commands/clear.js +100 -0
- package/dist/commands/decide.js +60 -0
- package/dist/commands/decisions.js +71 -0
- package/dist/commands/init.js +72 -0
- package/dist/commands/next.js +35 -0
- package/dist/commands/plan.js +64 -0
- package/dist/commands/show.js +82 -0
- package/dist/commands/state.js +104 -0
- package/dist/commands/validate.js +206 -0
- package/dist/commands/verify.js +99 -0
- package/dist/lib/project.js +42 -0
- package/dist/lint/constitution.js +40 -0
- package/dist/lint/gherkin.js +99 -0
- package/dist/lint/portable.js +66 -0
- package/dist/verify/detect.js +21 -0
- package/docs/format.md +296 -0
- package/docs/gherkin.md +81 -0
- package/docs/install.md +72 -0
- package/docs/intentdocs-mapping.md +117 -0
- package/docs/quickstart.md +153 -0
- package/package.json +44 -4
- package/schemas/bet.schema.json +23 -0
- package/schemas/state.schema.json +34 -0
- package/schemas/storymap.schema.json +43 -0
- package/skills/clear/SKILL.md +55 -0
- package/skills/clear-review/SKILL.md +45 -0
- package/skills/decisions/SKILL.md +45 -0
- package/skills/intent/SKILL.md +39 -0
- package/skills/nikos-mode/SKILL.md +61 -0
- package/skills/nikos-mode/playbooks/answer.md +9 -0
- package/skills/nikos-mode/playbooks/bet.md +14 -0
- package/skills/nikos-mode/playbooks/build-a-story.md +14 -0
- package/skills/nikos-mode/playbooks/change.md +12 -0
- package/skills/nikos-mode/playbooks/idea-to-blueprint.md +16 -0
- package/skills/nikos-mode/playbooks/index.md +13 -0
- package/skills/nikos-mode/playbooks/validate.md +17 -0
- package/skills/nikos-mode/principles/index.md +14 -0
- package/skills/verify/SKILL.md +49 -0
- package/templates/intent/constitution.md +19 -0
- package/templates/intent/decisions.md +12 -0
- package/templates/intent/features/getting-started/first-story.feature +12 -0
- package/templates/intent/plans/.gitkeep +0 -0
- package/templates/intent/state.yaml +4 -0
- package/templates/intent/storymap.yaml +10 -0
- package/templates/plan.md +13 -0
- package/templates/verify/js/cucumber.mjs +6 -0
- package/templates/verify/js/test/steps/first-story.steps.mjs +16 -0
- package/templates/verify/python/behave.ini +4 -0
- package/templates/verify/python/steps/first_story_steps.py +19 -0
- package/templates/verify/ts/cucumber.mjs +6 -0
- package/templates/verify/ts/test/steps/first-story.steps.ts +16 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Mapping intent/ to intentdocs
|
|
2
|
+
|
|
3
|
+
`intentdocs push` and `intentdocs pull` translate between the local
|
|
4
|
+
`intent/` folder and an intentdocs project. This table is the contract: every
|
|
5
|
+
local field maps to an intentdocs field, or is marked **local-only**.
|
|
6
|
+
Fields that exist only in intentdocs are listed at the end.
|
|
7
|
+
|
|
8
|
+
## Project and vision
|
|
9
|
+
|
|
10
|
+
| Local | intentdocs | Notes |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| `constitution.md` front matter `name` | project name | |
|
|
13
|
+
| `constitution.md` front matter `idea` | project idea | |
|
|
14
|
+
| `## Users` | vision `users` | |
|
|
15
|
+
| `## Problem` | vision `problem` | |
|
|
16
|
+
| `## Switch` | vision `switch` | |
|
|
17
|
+
| `## First` | vision `first` | |
|
|
18
|
+
| `## Proof` | vision `proof` | |
|
|
19
|
+
| extra `##` sections (e.g. `## Validation`) | **local-only** | pushed as a project note in a later format version |
|
|
20
|
+
| `storymap.yaml` `key` | project story key prefix | e.g. `HT` → `HT-1` |
|
|
21
|
+
| `storymap.yaml` `project` | **local-only** | slug used for paths |
|
|
22
|
+
| `storymap.yaml` `format_version` | **local-only** | |
|
|
23
|
+
|
|
24
|
+
## Activities and releases
|
|
25
|
+
|
|
26
|
+
| Local | intentdocs | Notes |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `activities[].title` | story `activity` | intentdocs groups by activity name |
|
|
29
|
+
| `activities[].id` | **local-only** | folder slug under `features/` |
|
|
30
|
+
| `releases[].number` | release order | |
|
|
31
|
+
| `releases[].title` | release label | |
|
|
32
|
+
| `releases[].stories` order | build sequence within the release | |
|
|
33
|
+
|
|
34
|
+
## Stories (feature files)
|
|
35
|
+
|
|
36
|
+
| Local | intentdocs | Notes |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| story id tag, e.g. `@HT-1` | story `key` | |
|
|
39
|
+
| `Feature:` title | story `title` | |
|
|
40
|
+
| description `As a …` | `as_a` | |
|
|
41
|
+
| description `I want …` | `i_want` | |
|
|
42
|
+
| description `So that …` | `so_that` | |
|
|
43
|
+
| `@must` / `@should` / `@could` on the Feature | story `priority` | |
|
|
44
|
+
| `@release-N` | story `release` | must agree with `storymap.yaml` |
|
|
45
|
+
| `@activity-<id>` | story `activity` | resolved to the activity title |
|
|
46
|
+
| `@effort-XS` … `@effort-XL` (optional) | story `effort` | |
|
|
47
|
+
| file path | **local-only** | |
|
|
48
|
+
|
|
49
|
+
## Acceptance criteria (scenarios)
|
|
50
|
+
|
|
51
|
+
| Local | intentdocs | Notes |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `@AC<n>` tag and scenario title prefix | criterion `label` | |
|
|
54
|
+
| scenario title after the label + its steps | criterion `text` | pushed as one Given/When/Then sentence |
|
|
55
|
+
| `@must` / `@should` / `@could` on the Scenario | criterion `priority` | |
|
|
56
|
+
| scenario pass/fail from `nikos verify` | criterion `last_result` | sent via report_criteria |
|
|
57
|
+
| step definition file and test name | linked tests | sent via save_tests |
|
|
58
|
+
|
|
59
|
+
## Plans
|
|
60
|
+
|
|
61
|
+
| Local | intentdocs | Notes |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| file `plans/<id>.v<N>.md` | plan `version` N | |
|
|
64
|
+
| front matter `summary` | plan `summary` | |
|
|
65
|
+
| `## <n>. <title>` | step `title` | |
|
|
66
|
+
| `**Why:**` | step `why` | |
|
|
67
|
+
| `**Criteria:**` | step `criteria` | labels resolved to criterion ids |
|
|
68
|
+
| `**Files:**` | step `files` | |
|
|
69
|
+
| `**Tests:**` (optional) | step `tests` | |
|
|
70
|
+
| `**Needs you:**` (optional) | step `needs_you.question` | |
|
|
71
|
+
| body text | step `agent_notes` | |
|
|
72
|
+
| front matter `risk` (optional) | plan `risk` | |
|
|
73
|
+
| front matter `introduces` (optional) | plan `introduces` | new dependencies |
|
|
74
|
+
| front matter `supersedes`, `created` | **local-only** | intentdocs keeps its own history |
|
|
75
|
+
|
|
76
|
+
## Decisions
|
|
77
|
+
|
|
78
|
+
| Local | intentdocs | Notes |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| entry heading title | decision `title` | |
|
|
81
|
+
| entry body | decision `description` | |
|
|
82
|
+
| `**Category:**` | decision `category` | |
|
|
83
|
+
| entry date | decision created date | |
|
|
84
|
+
| story id in heading | decision linked story | |
|
|
85
|
+
| `**Supersedes:**` | **local-only** | intentdocs amends instead |
|
|
86
|
+
|
|
87
|
+
## State
|
|
88
|
+
|
|
89
|
+
Status isn't pushed: intentdocs sets it. New stories start as To do,
|
|
90
|
+
existing ones keep theirs, and they move through build and acceptance in
|
|
91
|
+
intentdocs. `intentdocs push` still sends the local status, and says how
|
|
92
|
+
many it ignored.
|
|
93
|
+
|
|
94
|
+
| Local | intentdocs | Notes |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `status: todo` | **not pushed** | intentdocs sets status |
|
|
97
|
+
| `status: in_progress` | **not pushed** | intentdocs sets status |
|
|
98
|
+
| `status: needs_rework` | **not pushed** | intentdocs sets status |
|
|
99
|
+
| `status: done` | **not pushed** | intentdocs sets status; its own done needs acceptance after build |
|
|
100
|
+
| `blockers` | raised blockers | |
|
|
101
|
+
| `plan_version` | current plan version | |
|
|
102
|
+
| `claimed_by` | story claim | |
|
|
103
|
+
| `run.queue` | build run story order | |
|
|
104
|
+
| `updated` | **local-only** | |
|
|
105
|
+
|
|
106
|
+
## Bets
|
|
107
|
+
|
|
108
|
+
| Local | intentdocs | Notes |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| `outreach/*.md`, `## Validation` | **local-only** | intentdocs keeps the vision answers, not outreach drafts or results |
|
|
111
|
+
| `bets/*.md` | **local-only** | intentdocs has no bet object yet |
|
|
112
|
+
|
|
113
|
+
## intentdocs-only (not pulled into files)
|
|
114
|
+
|
|
115
|
+
Comments, design references, plan approvals, story approval after build,
|
|
116
|
+
founder to-dos, releases readiness checks, collaborators and workspace
|
|
117
|
+
settings stay in intentdocs. `intentdocs pull` never writes them to the repo.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Quickstart: your first passing scenario in 10 minutes
|
|
2
|
+
|
|
3
|
+
You'll make a tiny tip calculator in an empty repo and finish with one story
|
|
4
|
+
whose acceptance criterion runs as a test and passes. You need Node 20 or
|
|
5
|
+
later and npm. Nothing is installed globally: every `nikos` command runs
|
|
6
|
+
through `npx`.
|
|
7
|
+
|
|
8
|
+
## 1. Make a repo (1 minute)
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
mkdir tip-calculator && cd tip-calculator
|
|
12
|
+
git init
|
|
13
|
+
npm init -y
|
|
14
|
+
npm pkg set type=module
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 2. Create the intent/ folder (1 minute)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx -y nikos init --name "Tip Calculator" --key TC
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
You should see:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
Created intent/ (6 files)
|
|
27
|
+
✓ intent/ is valid — 1 story, 1 release
|
|
28
|
+
|
|
29
|
+
Next: fill in intent/constitution.md, then write your first story in intent/features/.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`intent/` now holds your story map, a state file, a decision log and one
|
|
33
|
+
starter story, TC-1. [docs/format.md](format.md) explains each file.
|
|
34
|
+
|
|
35
|
+
## 3. Write the story (2 minutes)
|
|
36
|
+
|
|
37
|
+
Replace the starter story with a real one. Save this as
|
|
38
|
+
**`intent/features/getting-started/first-story.feature`**:
|
|
39
|
+
|
|
40
|
+
```gherkin
|
|
41
|
+
@TC-1 @release-1 @must @activity-getting-started
|
|
42
|
+
Feature: Add a tip to the bill
|
|
43
|
+
|
|
44
|
+
As a diner
|
|
45
|
+
I want to add a tip to my bill
|
|
46
|
+
So that I know what to pay
|
|
47
|
+
|
|
48
|
+
@AC1 @must
|
|
49
|
+
Scenario: AC1 — A 20% tip on a 50 bill
|
|
50
|
+
Given a bill of 50
|
|
51
|
+
When I add a 20% tip
|
|
52
|
+
Then the total is 60.00
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The scenario is the acceptance criterion: TC-1 isn't done until it passes.
|
|
56
|
+
Check the folder is still well formed, and start the story:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx -y nikos validate
|
|
60
|
+
npx -y nikos state set TC-1 in_progress
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
✓ intent/ is valid — 1 story, 1 release
|
|
65
|
+
TC-1: todo → in_progress
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 4. Set up the runner (2 minutes)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx -y nikos verify setup
|
|
72
|
+
npm install --save-dev @cucumber/cucumber@^12
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`verify setup` notices this is a JavaScript repo and adds `cucumber.mjs`,
|
|
76
|
+
which runs every story in `intent/` as a test. Now run TC-1:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx -y nikos verify TC-1
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
It fails, and says why: none of the three steps has any code behind it yet.
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
1 scenario (1 undefined)
|
|
86
|
+
3 steps (3 undefined)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 5. Make it pass (3 minutes)
|
|
90
|
+
|
|
91
|
+
Write the code. Save this as **`tip.js`**:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
export function totalWithTip(bill, percent) {
|
|
95
|
+
return (bill * (1 + percent / 100)).toFixed(2);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Connect each step to the code. Save this as **`test/steps/tip.steps.mjs`**:
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
import { Given, When, Then } from "@cucumber/cucumber";
|
|
103
|
+
import assert from "node:assert/strict";
|
|
104
|
+
import { totalWithTip } from "../../tip.js";
|
|
105
|
+
|
|
106
|
+
Given("a bill of {int}", function (bill) {
|
|
107
|
+
this.bill = bill;
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
When("I add a {int}% tip", function (percent) {
|
|
111
|
+
this.total = totalWithTip(this.bill, percent);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
Then("the total is {float}", function (expected) {
|
|
115
|
+
assert.equal(this.total, expected.toFixed(2));
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Run it again:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx -y nikos verify TC-1
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
1 scenario (1 passed)
|
|
127
|
+
3 steps (3 passed)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 6. Call it done (1 minute)
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx -y nikos state set TC-1 done
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
TC-1: in_progress → done
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`state set … done` runs the scenarios first and refuses if any fail, so a
|
|
141
|
+
story can't be marked done on the agent's word alone.
|
|
142
|
+
|
|
143
|
+
That's the whole loop: write the story, run it, make it pass, mark it done.
|
|
144
|
+
|
|
145
|
+
## Next: let your agent do it
|
|
146
|
+
|
|
147
|
+
Install nikOS in your agent tool ([docs/install.md](install.md)), then ask:
|
|
148
|
+
|
|
149
|
+
> Add a story for splitting the bill between people, and build it.
|
|
150
|
+
|
|
151
|
+
The `nikos-mode` skill picks the right playbook: it writes the story,
|
|
152
|
+
checks it, plans it, builds it, and stops at "done" only when the new
|
|
153
|
+
scenario passes.
|
package/package.json
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nikos",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "nikOS \u2014 an open-source agent skill stack for spec-driven development. Specs, plans and Cucumber features live in your repo.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Niko Vijay",
|
|
7
|
+
"homepage": "https://nikos.tools",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/nikovijay/NikOS.git"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"bin": {
|
|
14
|
+
"nikos": "dist/cli.js"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"schemas",
|
|
22
|
+
"templates",
|
|
23
|
+
"skills",
|
|
24
|
+
"docs"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc -p tsconfig.json",
|
|
28
|
+
"prepublishOnly": "npm run build && npm test",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
31
|
+
"test:ci": "vitest run --reporter=default --reporter=junit --outputFile.junit=reports/junit.xml"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@cucumber/cucumber": "^12.9.0",
|
|
35
|
+
"@types/node": "^22.20.5",
|
|
36
|
+
"tsx": "^4.23.15",
|
|
37
|
+
"typescript": "^5.6.3",
|
|
38
|
+
"vitest": "^2.1.9"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@cucumber/gherkin": "^30.0.4",
|
|
42
|
+
"@cucumber/messages": "^26.0.1",
|
|
43
|
+
"ajv": "^8.17.1",
|
|
44
|
+
"yaml": "^2.6.1"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://nikos.tools/schemas/bet.schema.json",
|
|
4
|
+
"title": "nikOS bet card front matter",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["id", "hypothesis", "key_result", "expected_uplift", "time_box", "blockers", "stories", "status"],
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"id": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
|
|
10
|
+
"hypothesis": { "type": "string", "minLength": 1 },
|
|
11
|
+
"key_result": { "type": "string", "minLength": 1 },
|
|
12
|
+
"expected_uplift": { "type": "string", "minLength": 1 },
|
|
13
|
+
"time_box": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
|
|
14
|
+
"blockers": { "type": "array", "items": { "type": "string", "minLength": 1 } },
|
|
15
|
+
"stories": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"minItems": 1,
|
|
18
|
+
"uniqueItems": true,
|
|
19
|
+
"items": { "type": "string", "pattern": "^[A-Z][A-Z0-9]{0,9}-[0-9]+$" }
|
|
20
|
+
},
|
|
21
|
+
"status": { "enum": ["open", "won", "lost", "killed"] }
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://nikos.tools/schemas/state.schema.json",
|
|
4
|
+
"title": "nikOS state",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["format_version", "stories"],
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"format_version": { "const": 1 },
|
|
10
|
+
"stories": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"propertyNames": { "pattern": "^[A-Z][A-Z0-9]{0,9}-[0-9]+$" },
|
|
13
|
+
"additionalProperties": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"required": ["status"],
|
|
16
|
+
"additionalProperties": false,
|
|
17
|
+
"properties": {
|
|
18
|
+
"status": { "enum": ["todo", "in_progress", "needs_rework", "done"] },
|
|
19
|
+
"claimed_by": { "type": "string" },
|
|
20
|
+
"plan_version": { "type": "integer", "minimum": 1 },
|
|
21
|
+
"blockers": { "type": "array", "items": { "type": "string" } },
|
|
22
|
+
"updated": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"run": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"properties": {
|
|
30
|
+
"queue": { "type": "array", "items": { "type": "string" } }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://nikos.tools/schemas/storymap.schema.json",
|
|
4
|
+
"title": "nikOS story map",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["format_version", "project", "key", "activities", "releases"],
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"format_version": { "const": 1 },
|
|
10
|
+
"project": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
|
11
|
+
"key": { "type": "string", "pattern": "^[A-Z][A-Z0-9]{0,9}$" },
|
|
12
|
+
"activities": {
|
|
13
|
+
"type": "array",
|
|
14
|
+
"minItems": 1,
|
|
15
|
+
"items": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["id", "title"],
|
|
18
|
+
"additionalProperties": false,
|
|
19
|
+
"properties": {
|
|
20
|
+
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
|
21
|
+
"title": { "type": "string", "minLength": 1 }
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"releases": {
|
|
26
|
+
"type": "array",
|
|
27
|
+
"minItems": 1,
|
|
28
|
+
"items": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"required": ["number", "title", "stories"],
|
|
31
|
+
"additionalProperties": false,
|
|
32
|
+
"properties": {
|
|
33
|
+
"number": { "type": "integer", "minimum": 1 },
|
|
34
|
+
"title": { "type": "string", "minLength": 1 },
|
|
35
|
+
"stories": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"items": { "type": "string", "pattern": "^[A-Z][A-Z0-9]{0,9}-[0-9]+$" }
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clear
|
|
3
|
+
description: Check a story is Clear, Lean, Executable, Accurate and Responsible before anyone plans or builds it. Use before building any story, or when asked to review or check a spec.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# clear
|
|
7
|
+
|
|
8
|
+
A story must pass all five checks before it's built. Bad specs caught here
|
|
9
|
+
never become bad code.
|
|
10
|
+
|
|
11
|
+
## 1. Run the mechanical checks
|
|
12
|
+
|
|
13
|
+
Run `nikos clear <story-id>` in the repo. It finds the story's `.feature` file
|
|
14
|
+
and decides **Lean** and **Executable**, which a script can check better than
|
|
15
|
+
a person. Use its result for those two checks; don't overrule it.
|
|
16
|
+
|
|
17
|
+
If the command isn't available, check them by hand:
|
|
18
|
+
|
|
19
|
+
- **Executable:** the feature has at least one Scenario, and every Scenario
|
|
20
|
+
has a When step and a Then step.
|
|
21
|
+
- **Lean:** the feature names no file paths, SQL, frameworks, databases or
|
|
22
|
+
storage mechanisms.
|
|
23
|
+
|
|
24
|
+
## 2. Judge the other three
|
|
25
|
+
|
|
26
|
+
Read the story's `.feature` file, `intent/constitution.md` and
|
|
27
|
+
`intent/decisions.md`.
|
|
28
|
+
|
|
29
|
+
- **Clear:** every sentence has one reading. Two people would build the same
|
|
30
|
+
thing from it. Vague words ("fast", "easy", "some", "etc.") fail.
|
|
31
|
+
- **Accurate:** it agrees with the constitution (who it's for, the problem,
|
|
32
|
+
the proof) and with every decision in `decisions.md`. Name the line it
|
|
33
|
+
contradicts.
|
|
34
|
+
- **Responsible:** where the story touches personal data, money, safety,
|
|
35
|
+
outreach to real people or accessibility, a scenario or the description
|
|
36
|
+
covers it. A story that touches none of these passes and says so.
|
|
37
|
+
|
|
38
|
+
## 3. Report all five, in this order
|
|
39
|
+
|
|
40
|
+
One line per check, every time, even when it passes:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Clear: pass. <why>
|
|
44
|
+
Lean: pass. <why>
|
|
45
|
+
Executable: fail. <what's missing>. Fix: <the change to make>
|
|
46
|
+
Accurate: pass. <why>
|
|
47
|
+
Responsible: pass. <why>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Every fail names what's missing and the fix.
|
|
51
|
+
|
|
52
|
+
## 4. Stop on a fail
|
|
53
|
+
|
|
54
|
+
If any check fails, don't plan or build the story. Report the failures and
|
|
55
|
+
the fixes, and wait for the spec to change.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clear-review
|
|
3
|
+
description: Get a sceptical second review of a story's spec before building it, from another model or a fresh agent when one is available. Use when a spec is about to be built and the person wants it challenged, or when CLEAR passed but something feels off.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# clear-review
|
|
7
|
+
|
|
8
|
+
One reviewer misses things. A second one, with no stake in the spec, finds
|
|
9
|
+
more.
|
|
10
|
+
|
|
11
|
+
## 1. Run CLEAR first
|
|
12
|
+
|
|
13
|
+
Check the story with the clear skill. If a check fails, stop and report it.
|
|
14
|
+
There's no point reviewing a spec that already fails.
|
|
15
|
+
|
|
16
|
+
## 2. Ask a second reviewer to attack it
|
|
17
|
+
|
|
18
|
+
If you can hand work to another model or a fresh agent with no memory of this
|
|
19
|
+
conversation, give it only:
|
|
20
|
+
|
|
21
|
+
- the story's `.feature` file,
|
|
22
|
+
- `intent/constitution.md`,
|
|
23
|
+
- the entries from `nikos decisions "<story-id>"`,
|
|
24
|
+
|
|
25
|
+
and this brief: "You are a sceptical reviewer. Find what's ambiguous,
|
|
26
|
+
missing, contradictory, untestable or risky in this spec. For each problem,
|
|
27
|
+
quote the line and say what could go wrong. Don't suggest code."
|
|
28
|
+
|
|
29
|
+
Don't share your own CLEAR results or opinion with it, so its read isn't
|
|
30
|
+
anchored on yours.
|
|
31
|
+
|
|
32
|
+
If you can't hand work off, do the review yourself as a separate pass: reread
|
|
33
|
+
the feature as that sceptical reviewer, line by line, and say in the report
|
|
34
|
+
that it was a single-model review.
|
|
35
|
+
|
|
36
|
+
## 3. Merge into one list
|
|
37
|
+
|
|
38
|
+
Combine your CLEAR results and the reviewer's findings into one list. Drop
|
|
39
|
+
duplicates, and say who raised each finding. For each one, say whether it
|
|
40
|
+
blocks building (the spec is wrong or untestable) or is a note.
|
|
41
|
+
|
|
42
|
+
## 4. Stop for the person
|
|
43
|
+
|
|
44
|
+
Show the list. Change the spec only once the person agrees to each change.
|
|
45
|
+
A finding is a question for them, not a fix for you.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: decisions
|
|
3
|
+
description: Show why something was decided by quoting the decision log, or say plainly that no decision is recorded. Use when someone asks why a choice was made, what was rejected, or whether something was ever decided.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# decisions
|
|
7
|
+
|
|
8
|
+
The reason for a choice is whatever `intent/decisions.md` says. Never invent
|
|
9
|
+
one.
|
|
10
|
+
|
|
11
|
+
## 1. Search the log
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
nikos decisions "<the question or topic>"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
It quotes every entry that mentions the topic, best match first, each with
|
|
18
|
+
its `intent/decisions.md:<first>-<last>` line range. A story id (e.g. HT-1)
|
|
19
|
+
finds the entries tagged with it.
|
|
20
|
+
|
|
21
|
+
If nothing matches, try again with the words the spec would use: the name
|
|
22
|
+
of the feature, the library or the setting, and other spellings (colour and
|
|
23
|
+
color).
|
|
24
|
+
|
|
25
|
+
## 2. Answer from the entries
|
|
26
|
+
|
|
27
|
+
Quote the lines that answer the question, cite them as
|
|
28
|
+
`intent/decisions.md:<lines>`, and give the date and story id. If an entry
|
|
29
|
+
says it supersedes another, quote both and say which one stands.
|
|
30
|
+
|
|
31
|
+
Only cite an entry that actually answers the question. A match on a shared
|
|
32
|
+
word isn't an answer.
|
|
33
|
+
|
|
34
|
+
## 3. When nothing is recorded
|
|
35
|
+
|
|
36
|
+
Say: "No decision about <topic> is recorded in intent/decisions.md." You may
|
|
37
|
+
add what the git history of `intent/` shows (`git log -p -- intent/`), marked
|
|
38
|
+
clearly as history, not a recorded decision. Then offer to log one:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
nikos decide "<title>" --why "<why>" --category <product|architecture|design|process>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Log it only once the person tells you the reason. Don't write a reason for
|
|
45
|
+
them.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: intent
|
|
3
|
+
description: Explain what a story is meant to do and where it stands, from the repo's specs. Use when someone asks what a story is for, what it covers, or what state it's in, by its id (e.g. HT-2) or by topic.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# intent
|
|
7
|
+
|
|
8
|
+
Say what the spec says, not what the code happens to do.
|
|
9
|
+
|
|
10
|
+
## 1. Find the story
|
|
11
|
+
|
|
12
|
+
If you have a story id, use it. If you only have a topic, search the
|
|
13
|
+
`Feature:` lines under `intent/features/` and pick the story that matches.
|
|
14
|
+
If more than one could match, list them and ask which one.
|
|
15
|
+
|
|
16
|
+
## 2. Read everything recorded about it
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
nikos show <story-id>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
It prints the feature (user story and scenarios), its status from
|
|
23
|
+
`intent/state.yaml`, its release, the latest plan, any bets it's linked to,
|
|
24
|
+
and decisions tagged with its id. Open the feature file and the plan it
|
|
25
|
+
names when you need more than the summary.
|
|
26
|
+
|
|
27
|
+
## 3. Answer in plain words
|
|
28
|
+
|
|
29
|
+
Say, in a few sentences:
|
|
30
|
+
|
|
31
|
+
- who it's for and what they get (the "As a / I want / So that" lines),
|
|
32
|
+
- what has to be true for it to be done (each scenario, by its AC label),
|
|
33
|
+
- where it stands: status, who has it (`claimed_by`), blockers, and the latest
|
|
34
|
+
plan. A story in the run queue but unclaimed is waiting, not being worked
|
|
35
|
+
on.
|
|
36
|
+
|
|
37
|
+
Cite each claim as `path:line`, including the bet and plan files `nikos show`
|
|
38
|
+
names. If the spec doesn't say something, say so.
|
|
39
|
+
Don't fill the gap from the code or from guesswork.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nikos-mode
|
|
3
|
+
description: Entry point for nikOS spec-driven work. Use at the start of any request in a repo with an intent/ folder, or when asked to plan, build, change, check or explain a story. Picks the matching playbook and runs every step of it.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# nikos-mode
|
|
7
|
+
|
|
8
|
+
You follow a named playbook for every request instead of improvising. Run
|
|
9
|
+
these five steps in order, every time.
|
|
10
|
+
|
|
11
|
+
The playbooks run the `nikos` command. When it isn't installed (`nikos
|
|
12
|
+
--version` fails), run it as `npx -y nikos` instead: `npx -y nikos validate`
|
|
13
|
+
for `nikos validate`, and so on.
|
|
14
|
+
|
|
15
|
+
## 1. Read the principles
|
|
16
|
+
|
|
17
|
+
Read `principles/index.md` next to this file. Keep each principle in mind for
|
|
18
|
+
the rest of the request. When one applies, say which.
|
|
19
|
+
|
|
20
|
+
## 2. Pick a playbook and say which
|
|
21
|
+
|
|
22
|
+
Read `playbooks/index.md`. Match the request against the "Use when" column and
|
|
23
|
+
pick exactly one playbook. Then tell the person, before doing anything else:
|
|
24
|
+
|
|
25
|
+
> Playbook: **<name>** (`playbooks/<file>`), because <one-line reason>.
|
|
26
|
+
|
|
27
|
+
If two rows match, pick the first and say which other one you passed over. If
|
|
28
|
+
nothing matches, say "No playbook matches", then use `change` when the request
|
|
29
|
+
edits files in the repo and `answer` when it doesn't.
|
|
30
|
+
|
|
31
|
+
## 3. Copy every step into the task list
|
|
32
|
+
|
|
33
|
+
Open the chosen playbook file. Copy each numbered step into your task list,
|
|
34
|
+
word for word and in order, one item per step.
|
|
35
|
+
|
|
36
|
+
- If your tool has a built-in task or todo list, use it.
|
|
37
|
+
- If it has none, write the list in your reply as a Markdown checklist
|
|
38
|
+
(`- [ ] 1. …`) and repeat it, updated, whenever a step changes state.
|
|
39
|
+
|
|
40
|
+
Don't merge, reword, reorder or summarise steps. Don't add steps of your own
|
|
41
|
+
to the playbook's list; put extra work under the step it belongs to.
|
|
42
|
+
|
|
43
|
+
## 4. Never drop a step
|
|
44
|
+
|
|
45
|
+
Every step ends as done or skipped. A step you don't do stays on the list,
|
|
46
|
+
marked skipped, with the reason:
|
|
47
|
+
|
|
48
|
+
> ~~5. Run the story's scenarios~~ skipped: the repo has no Cucumber runner yet.
|
|
49
|
+
|
|
50
|
+
"Not needed" is not a reason. Say what makes it not needed.
|
|
51
|
+
|
|
52
|
+
## 5. Show evidence before you say done
|
|
53
|
+
|
|
54
|
+
Finish with a report that lists every step with its outcome:
|
|
55
|
+
|
|
56
|
+
- **done**, with the evidence: the command you ran and its result, the file
|
|
57
|
+
and line you changed, or the passage you quoted.
|
|
58
|
+
- **skipped**, with the reason from step 4.
|
|
59
|
+
|
|
60
|
+
Never call the request done, fixed or passing without that evidence. If a
|
|
61
|
+
check fails, say so and show the output.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# answer
|
|
2
|
+
|
|
3
|
+
Answer a question from what the repo's specs actually say.
|
|
4
|
+
|
|
5
|
+
1. Restate the question in one sentence.
|
|
6
|
+
2. Find the files in `intent/` that answer it: constitution, story map, features, plans or decisions.
|
|
7
|
+
3. Answer in plain words, citing each claim as `path:line`.
|
|
8
|
+
4. If the specs don't answer it, say so and name the file where the answer belongs.
|
|
9
|
+
5. Report every step with its evidence or its skip reason.
|