@warren-dean/code-kit 0.9.1 → 0.11.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +17 -0
- package/README.md +37 -31
- package/bin/code-kit.mjs +133 -2
- package/hooks/guard-bash.mjs +8 -0
- package/hooks/lib/config.mjs +4 -3
- package/hooks/lib/next.mjs +87 -3
- package/hooks/lib/plan.mjs +2 -1
- package/hooks/lib/security.mjs +180 -0
- package/hooks/lib/team.mjs +62 -7
- package/hooks/mod/decisions.mjs +3 -0
- package/hooks/mod/loop.mjs +14 -1
- package/hooks/mod/panes.mjs +42 -49
- package/hooks/mod/register.mjs +104 -12
- package/hooks/mod/register.test.ts +255 -15
- package/hooks/mod/teamview.mjs +469 -74
- package/hooks/mod/view.mjs +14 -2
- package/package.json +1 -1
- package/skills/init/SKILL.md +13 -5
- package/skills/next/SKILL.md +19 -17
- package/skills/review/SKILL.md +19 -4
- package/skills/spec-design/SKILL.md +5 -2
- package/skills/team-init/SKILL.md +59 -0
- package/templates/security-reviewer.md +57 -0
- package/templates/spec.md +18 -0
package/skills/init/SKILL.md
CHANGED
|
@@ -60,7 +60,7 @@ Write `.claude/code-kit.draft.json`. Follow `${CLAUDE_PLUGIN_ROOT}/README.md`
|
|
|
60
60
|
- `agent`: a kebab-case agent name, for example `api-engineer`;
|
|
61
61
|
- `paths` and `exclude`: every path must have exactly one owner.
|
|
62
62
|
- **A QA lane:** when lanes own screens, or the plan's journeys cross lanes, a `qa` lane with a `test-engineer` agent owning the end-to-end suites (the plan's work split names them; brownfield: the folders the existing end-to-end tests live in), even if the docs forgot it. Its agent's proving command runs the suites. Add a `checks` entry for them scoped by `files` to the suites, so verify runs them when they change. Unit tests stay with each lane.
|
|
63
|
-
- **`setup`:** `
|
|
63
|
+
- **`setup`:** `3`, the version of this setup, so `code-kit next` can tell an older project what re-running init adds.
|
|
64
64
|
- **`lead.paths`:** contracts, specs, design, root config, and anything the docs reserve for the lead.
|
|
65
65
|
- **`anyActor`:** lockfiles, if lanes may update them.
|
|
66
66
|
- **`protected`:** registers and contracts that need a person's sign-off, each with an `approval` name and a `why`.
|
|
@@ -102,6 +102,12 @@ Draft, alongside the config:
|
|
|
102
102
|
- its lane rules.
|
|
103
103
|
- If an agent already exists, keep its content and add only what's missing.
|
|
104
104
|
- Drop the spec-check lines if the config has no `docs.specs`.
|
|
105
|
+
- **A security reviewer:** write `.claude/agents/security-reviewer.md` from `${CLAUDE_PLUGIN_ROOT}/templates/security-reviewer.md`, in the same approval as the lane agents, whenever the product handles sign-in, personal data, payments, input from outside (forms, APIs, webhooks, uploads) or secrets. That's almost every product; leave it out only for one with none of these, such as a static site or a local tool with no accounts, and say why. It is a reviewer, not a lane: no entry in `lanes`, no paths, and only read-only tools (Read, Grep, Glob, and Bash for commands that change nothing), so the hooks treat it as read-only too. Fill it in from the docs (or the code, for brownfield):
|
|
106
|
+
- what's sensitive, who might attack it and the trust boundaries, from the specs' `## Threat model` sections (brownfield, or specs without one: from the data the code stores and the routes it exposes, as a question to the person);
|
|
107
|
+
- the spec files it reads;
|
|
108
|
+
- the privacy and data residency targets in the principles;
|
|
109
|
+
- the project's audit commands (for example `npm audit --omit=dev`, `pip-audit`), each run once now; leave out one that isn't installed, and say so.
|
|
110
|
+
- If the agent already exists, keep its content and add only what's missing.
|
|
105
111
|
- **CLAUDE.md:** add the section from `${CLAUDE_PLUGIN_ROOT}/templates/claude-md.md`.
|
|
106
112
|
- **Project skills, with the agents** (recipes like "new screen", "new migration" or "new endpoint"): one per recipe in the architecture's `## Recipes`, or any other doc that describes one step by step. Draft them now, alongside the agents, and show them in the same approval; the agents and their skills are one piece of work. Brownfield code without recipes in its docs: propose recipes from the patterns the code already follows (how its existing screens, endpoints or migrations are built), as drafts the person approves. Never write an empty one.
|
|
107
113
|
- Write each as `.claude/skills/<name>/SKILL.md`, saying in its description which recipe in which doc it comes from, so an update can find it again.
|
|
@@ -110,7 +116,7 @@ Draft, alongside the config:
|
|
|
110
116
|
Show the person:
|
|
111
117
|
|
|
112
118
|
1. the layers and what each may depend on, and for brownfield the existing violations the baseline will record;
|
|
113
|
-
2. the lanes, their agents and their paths;
|
|
119
|
+
2. the lanes, their agents and their paths, and the security reviewer (or why it's left out);
|
|
114
120
|
3. protected paths, blocked and restricted commands, and checks (including any left out because they fail today);
|
|
115
121
|
and whether the lead may record approvals given in chat (`approvals.lead`), and how hands-off the build is (`harness.autonomy`);
|
|
116
122
|
4. the project skills, and which lane agents use each;
|
|
@@ -132,7 +138,8 @@ Once they approve (with any changes):
|
|
|
132
138
|
- tell the person to make the `code-kit` check required on the protected branches.
|
|
133
139
|
7. Run `check` and `unowned` again, without `--config`.
|
|
134
140
|
8. Commit the setup straight onto the base branch (usually `main`), not a branch: while the base has no `.claude/code-kit.json` committed, the hooks let the lead make that one commit, so the rules the person just approved are in force on `main` and the lead can merge reviewed work from the start, with no first merge for anyone to make. The kit records the protected files in `.claude/approval-log.jsonl`. If the base already has rules (an update, section 4), commit on a branch as usual.
|
|
135
|
-
9.
|
|
141
|
+
9. **A team, only if there is one.** Not every developer works in a team. Ask once: "Do other developers work in this repository with their own Claude Code sessions?" If yes, run `/code-kit:team-init` now (it asks who the tech lead is and who owns which lanes, and writes the `team` section). If no, or not yet, leave it out and say `/code-kit:team-init` sets it up any time.
|
|
142
|
+
10. Set up each companion the config now wants (`"adapters": { "<name>": true }`) by running its init skill, for example `/context-graph:init`, which asks nothing. Do it before reporting, so it's in place before the coding loop starts; `code-kit next` also gives `setup` until it is.
|
|
136
143
|
|
|
137
144
|
Report what was set up, what's enforced from now on, how many existing violations the baseline holds, and the open questions. Say who does what from here: the person owns the intent and the rules; the lead owns delivery, so it dispatches, reviews, sends back and merges, and approves within the delegated limits, and only a real decision (scope, something outside those limits, a problem it couldn't solve) comes to the person.
|
|
138
145
|
|
|
@@ -144,10 +151,11 @@ Re-run whenever the build has moved on: new apps or packages, folders that moved
|
|
|
144
151
|
|
|
145
152
|
1. **Re-read** the docs and the repository as in section 1, including the brownfield steps if the code has grown past the docs.
|
|
146
153
|
2. **Draft** the whole config again into `.claude/code-kit.draft.json`, starting from the live one. Keep everything that's still right, so the diff shows only real changes. If the live config has no `harness.autonomy`, ask the person about it as in section 2.
|
|
147
|
-
A config without `"setup":
|
|
154
|
+
A config without `"setup": 3` predates what setup now includes; add whichever of these the project is missing, as section 2 and 3 describe, and set `"setup": 3`:
|
|
148
155
|
- project skills for the recipes in the docs (or, without recipes, the patterns the code follows), listed on the lane agents;
|
|
149
156
|
- the design gate for every lane that owns screens, with its register; and design stories in the plan for screens not yet built (ask the person before adding stories);
|
|
150
157
|
- the QA lane, its agent and its checks, when there are screens or journeys across lanes;
|
|
158
|
+
- the security reviewer (`.claude/agents/security-reviewer.md`), unless the product handles no sign-in, personal data, payments, outside input or secrets; and, as a proposal for the person, a threat model and security requirements for each spec that lacks them (spec-design's section 4);
|
|
151
159
|
- `"adapters": { "<name>": true }` for a companion that's installed but not set up, which is then set up before any code.
|
|
152
160
|
3. **Show the difference:**
|
|
153
161
|
|
|
@@ -159,7 +167,7 @@ Re-run whenever the build has moved on: new apps or packages, folders that moved
|
|
|
159
167
|
`diff` lists lanes, layers, checks and rules that were added (`+`), removed (`-`) or changed (`~`), and how many files change owner, route by route. Explain each change in a sentence, with where it came from: the doc section, or the folder in the repository.
|
|
160
168
|
|
|
161
169
|
4. **Also propose:**
|
|
162
|
-
- agent files for new lanes, and updates to agents whose paths changed;
|
|
170
|
+
- agent files for new lanes, and updates to agents whose paths changed, and to the security reviewer when the specs' threat models changed;
|
|
163
171
|
- **project skills**, by reading the recipes in the docs again and comparing them with `.claude/skills/`:
|
|
164
172
|
- a new skill for each recipe the docs now describe that has none;
|
|
165
173
|
- an update to each skill whose recipe changed, showing what changed;
|
package/skills/next/SKILL.md
CHANGED
|
@@ -15,23 +15,24 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/code-kit.mjs" next --json
|
|
|
15
15
|
|
|
16
16
|
It returns `step`, `why`, `args`, `then` (steps that can follow straight after) and `attention` (things the person should know). The order it applies:
|
|
17
17
|
|
|
18
|
-
| State
|
|
19
|
-
|
|
|
20
|
-
| Invalid config
|
|
21
|
-
| No config, a draft waiting
|
|
22
|
-
| No config, a spec still being shaped (brief not `ready`)
|
|
23
|
-
| No config, a ready spec
|
|
24
|
-
| No config, existing code or docs
|
|
25
|
-
| Nothing at all
|
|
26
|
-
| Config, but no specs, plan or stories
|
|
27
|
-
| A companion the config wants, not set up yet
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
18
|
+
| State | Step |
|
|
19
|
+
| ------------------------------------------------------------ | --------------------------------------------------------- |
|
|
20
|
+
| Invalid config | `check`, then fix the config |
|
|
21
|
+
| No config, a draft waiting | `init`, to show it for approval |
|
|
22
|
+
| No config, a spec still being shaped (brief not `ready`) | `spec-design`, resuming |
|
|
23
|
+
| No config, a ready spec | `init <docs folder>` |
|
|
24
|
+
| No config, existing code or docs | `init` |
|
|
25
|
+
| Nothing at all | `spec-design` |
|
|
26
|
+
| Config, but no specs, plan or stories | `spec-design` |
|
|
27
|
+
| A companion the config wants, not set up yet | `setup`: run that tool's init skill (`args`), before code |
|
|
28
|
+
| An older setup missing what init now adds, nothing in flight | `update`: re-run init, before any new story |
|
|
29
|
+
| Stories finished on their branches | `review`, then `dispatch` what's ready |
|
|
30
|
+
| Design stories ready (`**Lane:** design`) | `design`, then `dispatch` what needs no design |
|
|
31
|
+
| Stories ready | `dispatch` |
|
|
32
|
+
| The lead's own stories ready (`**Lane:** lead`) | `lead`: the lead builds them itself |
|
|
33
|
+
| Stories being built, nothing else can start | wait |
|
|
34
|
+
| Ready stories with gaps in the plan, or a dependency cycle | `spec-design`, to fix the plan |
|
|
35
|
+
| Every story done | done: `status`, then `spec-design` for the next milestone |
|
|
35
36
|
|
|
36
37
|
Tell the person in one or two lines what you found and what you're about to run, with anything under `attention`. If `attention` says the folder isn't a git repository, run `git init` before init (spec-design doesn't need one).
|
|
37
38
|
|
|
@@ -40,6 +41,7 @@ Tell the person in one or two lines what you found and what you're about to run,
|
|
|
40
41
|
Run the named skill with the Skill tool: `code-kit:<step>`, with `args` (and the person's argument, if they gave one). Follow that skill in full. This skill only chooses; it never does a step's work itself.
|
|
41
42
|
|
|
42
43
|
- **`setup`:** run the skill named in `args` (for example `context-graph:init`); it's another plugin's, so call it by that full name.
|
|
44
|
+
- **`update`:** run `code-kit:init`. `why` names what the setup is missing (the design gate, design stories, a QA lane, a security reviewer); init adds those, shows the person the difference, and sets `"setup": 3`. Until then no new story starts; work already started goes on to review and merge.
|
|
43
45
|
- **`lead`:** there's no skill to run. Build each story yourself, on the branch `lead/st-<n>`: spec-check it first if it cites requirements, do the work, commit, then run `code-kit:review` on the branch like any other. A spike's result goes in the docs it names.
|
|
44
46
|
- **`wait`:** say which stories are being built and on which branches, then stop. When a lane agent finishes, its notification arrives in this session; run this skill again then. If a story has been in progress with no agent running (the session ended, or the agent stopped without committing), dispatch it again.
|
|
45
47
|
- **`done`:** give the `status` summary in a few lines, then offer to run spec-design for the next milestone or feature.
|
package/skills/review/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review
|
|
3
|
-
description: The lead's review of a lane's finished branch before it merges. Runs code-kit verify on the branch, checks the work against its story's requirements and acceptance criteria, the spec-check report, the approval log and the tests, and ends with merge or send back. Use when a lane agent or person finishes a story, when the person asks to review a branch or pull request, or runs /code-kit:review [branch, story ID or PR number].
|
|
3
|
+
description: The lead's review of a lane's finished branch before it merges. Runs code-kit verify on the branch, checks the work against its story's requirements and acceptance criteria, the spec-check report, the approval log and the tests, runs the security reviewer on sensitive changes, and ends with merge or send back. Use when a lane agent or person finishes a story, when the person asks to review a branch or pull request, or runs /code-kit:review [branch, story ID or PR number].
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Review a lane's branch
|
|
@@ -47,12 +47,27 @@ Read the story, every requirement it cites, and the full diff (`git diff <base>.
|
|
|
47
47
|
- **Only the story:** changes beyond the story (refactors elsewhere, other stories' requirements, new dependencies) are called out. They may be fine, but they're the person's call.
|
|
48
48
|
- **Contracts respected:** the code uses the contracts as written. A lane that needed a contract change should have asked, not worked around it.
|
|
49
49
|
|
|
50
|
-
## 4.
|
|
50
|
+
## 4. The security review
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
Ask whether the change needs it:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/code-kit.mjs" security --base <base> --branch <branch>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
It does when the diff touches sign-in, permissions, input from outside, personal data, encryption, payments, secrets, or queries and commands built from strings, adds dependencies, or the story cites a security requirement; it says which, and where. When it does:
|
|
59
|
+
|
|
60
|
+
- Run the `security-reviewer` agent (Agent tool, `subagent_type` `security-reviewer`) with the branch, the base, the story, its requirements, the spec files it touches (their `## Threat model` and `## Security requirements`) and the reasons `security` gave. It reads only, and ends with the same findings block as code-kit's reviewer: each finding graded blocker, concern or nit, with where, the attack and the fix.
|
|
61
|
+
- **A blocker fails the review**, like a failing test: the branch goes back to its lane with the finding (where, the attack, the fix). Concerns are yours to weigh: send back the ones the threat model says matter, and put the rest in the report. Nits go in the report.
|
|
62
|
+
- No `security-reviewer` agent in the project: `security` says so. Review the diff yourself against the same list in `${CLAUDE_PLUGIN_ROOT}/templates/security-reviewer.md`, and tell the person that re-running `/code-kit:init` adds the agent.
|
|
63
|
+
- A background reviewer can't start agents: it lists the security review as due, as a concern with the reasons, and the lead runs it.
|
|
64
|
+
|
|
65
|
+
## 5. Verdict
|
|
66
|
+
|
|
67
|
+
Report the table, `verify`'s result, the security review's findings (or that none was needed) and one of:
|
|
53
68
|
|
|
54
69
|
- **Files any agent may write** (`anyActor`, such as a lockfile or recorded decisions) have no owning lane, but they have a reviewer: `trace <file>` names it (the lead unless the config names a lane). Review those changes as that reviewer would, or ask that lane's agent.
|
|
55
|
-
- **Merge.** Everything passes. Put the branch in the merge queue, set the story's `**Status:**` to `done` in the plan, and commit:
|
|
70
|
+
- **Merge.** Everything passes, and the security review found no blocker. Put the branch in the merge queue, set the story's `**Status:**` to `done` in the plan, and commit:
|
|
56
71
|
|
|
57
72
|
```bash
|
|
58
73
|
node "${CLAUDE_PLUGIN_ROOT}/bin/code-kit.mjs" queue add <branch>
|
|
@@ -85,6 +85,8 @@ Each requirement gets an ID (`<AREA>-<n>`, for example `BOOK-4`) and its own hea
|
|
|
85
85
|
- **Errors and edge cases:** invalid input, duplicates, concurrency, partial failure, timeouts, an external service being down, empty and very large data.
|
|
86
86
|
- **Events and integrations:** what other parts of the system or external services are told, and what they send back.
|
|
87
87
|
- **Acceptance criteria:** Given / When / Then for the main path and for each important error.
|
|
88
|
+
- **Threat model:** a short `## Threat model` per area: what in it is sensitive (personal data, children's data, credentials, money), who might attack it (a signed-out visitor, another customer, a staff member with the wrong role), and its trust boundaries (where outside input enters). A few concrete lines, not a compliance checklist; leave it out for an area that holds nothing sensitive and takes no outside input.
|
|
89
|
+
- **Security requirements:** under `## Security requirements`, the rules that stop the attacks the threat model names, each with an ID and heading like any other requirement (`### BOOK-9 A customer sees only their own bookings`) and acceptance criteria written from the attacker's side. Stories cite them like any other requirement; a story that cites one always gets the security review.
|
|
88
90
|
- **Screens** (any area a person uses through a web, mobile or desktop interface): a `## Screens` section listing each screen, what it shows, what the person can do on it and which requirements it serves, with its empty, loading and error states. These are what gets designed before anything is built.
|
|
89
91
|
|
|
90
92
|
A spec answers what and why, not how: no framework, file or function names unless the person requires them. Anything still undecided goes in the spec's open questions and the brief's, never into a requirement. `Status: specified`.
|
|
@@ -103,10 +105,11 @@ These are what `/code-kit:init` turns into enforced rules, so be concrete.
|
|
|
103
105
|
- **recipes**: under `## Recipes`, a `### <recipe-name>` for each layer's common addition (a new screen, endpoint, migration, domain service, job): the steps in order, the files each step creates or changes, and how it's tested. Each becomes a project skill when init sets up the lanes, so every lane agent builds the same thing the same way;
|
|
104
106
|
- the **design tool** for screens, when there are any: the one the person uses (Paper, Figma, Pencil), or design files under `design/` when they have none.
|
|
105
107
|
Propose the architecture from the specs and constraints, explain the choices, and ask about the ones that matter. Record each in the decision log.
|
|
106
|
-
- **`docs/principles.md`:** the engineering rules; what counts as a contract; the definition of done (tests, checks, reviews, end-to-end working features); the test, lint, typecheck and database commands once they're known; and which commands only CI or a person may run, such as deploys.
|
|
108
|
+
- **`docs/principles.md`:** the engineering rules; the privacy and data residency targets from the brief (where data may be stored and processed, what is never logged), which the security reviewer checks against; what counts as a contract; the definition of done (tests, checks, reviews, end-to-end working features); the test, lint, typecheck and database commands once they're known; and which commands only CI or a person may run, such as deploys.
|
|
107
109
|
- **`docs/plan.md`**, from `${CLAUDE_PLUGIN_ROOT}/templates/plan.md`:
|
|
108
110
|
- the **work split**: lanes (for example web, api, data), the paths each will own, the agent name for it and the command that proves its work, so work can run in parallel without overlap. Each lane writes and runs the unit tests for its own code;
|
|
109
111
|
- a **QA lane** (`qa`, agent `test-engineer`) whenever the product has screens or journeys that cross lanes: it owns the end-to-end suites (for example `e2e/**` or `apps/*/e2e/**`), in the runner that suits each surface (Playwright for web, Maestro or Detox for mobile), and its command runs them. Nobody else owns these tests, so without it nothing proves a journey works across the lanes;
|
|
112
|
+
- no lane for security: it owns no paths. init adds a read-only security reviewer that checks every story touching the threat models' sensitive parts, so security requirements are delivered by the lanes whose code they constrain;
|
|
110
113
|
- milestones, each a usable increment;
|
|
111
114
|
- stories, each small enough for one lane to finish on one branch. Each story is a `### ST-<n> Title` heading with `**Lane:**`, `**Requirements:**` (the IDs it delivers, or `none` for a spike or a foundation that delivers none), `**Depends on:**` and `**Status:** todo` lines. `code-kit status` and the dispatch skill read them. A story that needs two lanes is two stories, with a dependency between them;
|
|
112
115
|
- sequencing: contracts and shared foundations first, as the lead's own stories (`**Lane:** lead`, built by the lead rather than dispatched), then work that can run in parallel;
|
|
@@ -121,7 +124,7 @@ Before handing over, review everything once, as a sceptical engineer about to bu
|
|
|
121
124
|
|
|
122
125
|
- every journey step maps to a requirement, and every requirement to a story;
|
|
123
126
|
- every requirement is testable and has acceptance criteria where it matters;
|
|
124
|
-
- data, states, permissions and errors are covered for every area;
|
|
127
|
+
- data, states, permissions and errors are covered for every area, and every area holding something sensitive or taking outside input has a threat model and security requirements;
|
|
125
128
|
- no requirement contradicts another, the constraints or a non-goal;
|
|
126
129
|
- nothing is left as "TBD" outside the open-questions lists.
|
|
127
130
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: team-init
|
|
3
|
+
description: Set up a code-kit project for a team of developers, change its team setup, or make it one developer's again. Asks who the tech lead is, who owns which lanes, when a claim goes stale and where intents go, shows the team section before writing it, checks GitHub is ready (gh signed in, the shared repository, the intents' discussion category), and offers CODEOWNERS, the Project board and a hosted team provider. Use when the person says they work in a team, wants teammates to share the project, wants to change the tech lead or lane owners, wants to stop working as a team, or runs /code-kit:team-init. Not every developer works in a team: never set one up unasked.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Set up the team
|
|
7
|
+
|
|
8
|
+
A team is several people in one repository, each with their own lead and agents (spec 16). code-kit then claims a story before anyone builds it, leases the files it changes, has intents raised before shared things change, and shows it all in `/team`. One developer needs none of this, and the project works the same without it.
|
|
9
|
+
|
|
10
|
+
The CLI is `node "${CLAUDE_PLUGIN_ROOT}/bin/code-kit.mjs"`, run from the project root. Its `team init` shows the team section it would write; with `--write` it writes it, once the person agrees. Only the lead writes it: the hooks refuse it from a lane agent.
|
|
11
|
+
|
|
12
|
+
## 1. Where things stand
|
|
13
|
+
|
|
14
|
+
1. `.claude/code-kit.json` must exist and be valid (`check`). If it doesn't, stop: the person runs `/code-kit:init` first.
|
|
15
|
+
2. Run `check --json` and read `team` (null when the project isn't a team's), `me` (who's signed in to gh here) and `lanes`.
|
|
16
|
+
3. The shared repository: `git remote get-url origin` must be on GitHub, and `gh auth status` signed in. Without either, say what's missing; code-kit's own team provider works through both.
|
|
17
|
+
|
|
18
|
+
Say which applies: **new team**, **change the team**, or **back to one developer** (the person asked to stop working as a team).
|
|
19
|
+
|
|
20
|
+
## 2. Ask, one question at a time
|
|
21
|
+
|
|
22
|
+
Ask only what the config can't answer, with the current value as the default on a change.
|
|
23
|
+
|
|
24
|
+
- **Is this a team?** On a new setup, unless the person already said so: "Do other developers work in this repository with their own Claude Code sessions?" No → stop, and say nothing changed.
|
|
25
|
+
- **Tech lead:** whose GitHub handle owns the plan, specs, contracts and principles, agrees or drops intents, and may release or reassign anyone's claim. Default: `me`.
|
|
26
|
+
- **Lane owners:** for each lane, whose sessions build its stories (GitHub handles), or nobody, in which case whoever claims a story first builds it. `git log --format='%an' -- <lane paths> | sort | uniq -c` and CODEOWNERS suggest people, but ask for handles: names in commits aren't handles.
|
|
27
|
+
- **Stale after:** how many working days without a push before a claim is stale (default 3).
|
|
28
|
+
- **Intents category:** the GitHub Discussions category intents go in (default `Intents`).
|
|
29
|
+
- **Back to one developer:** confirm that claims, owners and intents stop applying, and that teammates' sessions lose them too once it's merged.
|
|
30
|
+
|
|
31
|
+
## 3. Show, then write
|
|
32
|
+
|
|
33
|
+
Run it without `--write` and show the person exactly what it prints:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/code-kit.mjs" team init --tech-lead <handle> --owner <lane>=<handle>,<handle> [--stale-days <n>] [--intents <category>]
|
|
37
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/code-kit.mjs" team init --off
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Give `--owner <lane>=` (nothing after `=`) to take a lane's owners out. Once they agree, run the same command with `--write`. It prints what GitHub still needs; tell the person each, in their words:
|
|
41
|
+
|
|
42
|
+
- **gh isn't signed in:** they run `! gh auth login`.
|
|
43
|
+
- **Discussions are off, or there's no intents category:** GitHub doesn't let a tool create a category. They turn Discussions on (Settings › Features) and add an "Open-ended discussion" category with the intents' name (Settings › Discussions), once.
|
|
44
|
+
|
|
45
|
+
## 4. Also offer
|
|
46
|
+
|
|
47
|
+
Each is optional; ask, and do only what they want:
|
|
48
|
+
|
|
49
|
+
- **CODEOWNERS** (TEAM-11): `team codeowners --write` writes `.github/CODEOWNERS` from the config, so GitHub asks the tech lead and lane owners to review. Then they require code owners' review in a ruleset on the protected branch.
|
|
50
|
+
- **A Project board** (TEAM-12): with a GitHub Project's owner and number, add `"board": { "owner": "<user or organisation>", "number": <n> }` to `team` in the config; the mod then mirrors the plan onto it.
|
|
51
|
+
- **A hosted team provider:** if a plugin for one is installed (its connect skill is in your skills list, such as `/code-kit-teams:connect`), offer it: it makes claims, leases and intents live, shows who's at work where, and checks each push for drift. Its connect skill sets `team.provider`, with GitHub as the fallback. If none is installed, don't mention one.
|
|
52
|
+
|
|
53
|
+
## 5. Finish
|
|
54
|
+
|
|
55
|
+
1. Run `check` and `team` to confirm.
|
|
56
|
+
2. Commit `.claude/code-kit.json` (and CODEOWNERS, if written) on a branch, open a pull request, and merge it as any change to the kit's rules.
|
|
57
|
+
3. Tell the person what each teammate does once: install code-kit, `gh auth login`, pull the change. Their sessions then share the claims, and `/team` shows the team.
|
|
58
|
+
|
|
59
|
+
Report in three lines: the tech lead and owners as written (or that the project is one developer's again), what GitHub still needs, and what each teammate does.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-reviewer
|
|
3
|
+
description: Read-only adversarial review of one story's change, against its specs' threat models. Use when code-kit security says a branch needs the security review, or the lead asks for one.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are the security reviewer for this repository. You attack a change the way someone trying to break this product would, and report what you find. You have no lane and own no paths: you never edit or write files, install anything, commit, approve, merge or record a send-back (code-kit's hooks refuse those for you). The lead decides; you report.
|
|
8
|
+
|
|
9
|
+
**What's sensitive here:** {{from the brief and specs: personal data, children's data, credentials, money, and where each is stored}}
|
|
10
|
+
**Who might attack it:** {{the attackers the threat models name: signed-out visitors, other customers, a staff member with the wrong role, automated scrapers}}
|
|
11
|
+
**Trust boundaries:** {{where outside input enters: the routes, webhooks, uploads, queues and third-party callbacks}}
|
|
12
|
+
**Specs:** {{the spec files, each with its ## Threat model and ## Security requirements}}
|
|
13
|
+
**Privacy and residency:** {{the principles' data residency and privacy targets, or "none set"}}
|
|
14
|
+
**Audit commands:** `{{the project's dependency and code audit commands, e.g. npm audit --omit=dev}}`
|
|
15
|
+
|
|
16
|
+
Use Bash only for commands that change nothing: `git diff`, `git log`, `git show`, the audit commands above, and `node "${CLAUDE_PLUGIN_ROOT}/bin/code-kit.mjs" security --branch <branch>` to see why the branch was sent to you.
|
|
17
|
+
|
|
18
|
+
For the branch and story you are given:
|
|
19
|
+
|
|
20
|
+
1. Read the story, every requirement it cites, and the threat model and security requirements of each spec it touches.
|
|
21
|
+
2. Read the full diff (`git diff <base>...<branch>`), then each changed file in full, and the callers and callees of every changed handler, query and permission check.
|
|
22
|
+
3. Attack it. For each kind below, ask what an attacker on the far side of a trust boundary could do with this change:
|
|
23
|
+
- **Authentication and authorisation:** every new or changed route, handler, server action, job and query checks who is asking and what they may touch. Look for a missing check, a check on the wrong object (one customer's ID in another's request), a role read from the client, and data scoped in the screen but not in the query.
|
|
24
|
+
- **Injection:** SQL, shell, file paths, templates and HTML built from input; for features that call a language model, prompt injection through content the model reads, and model output trusted as a command or as markup.
|
|
25
|
+
- **Data exposure:** personal data or secrets in logs, error messages, responses, analytics and caches; selects that return more columns or rows than the screen needs.
|
|
26
|
+
- **Secrets:** keys, tokens or passwords in code, config, tests or history; secrets sent to the client.
|
|
27
|
+
- **Cryptography:** home-made crypto, weak hashes for passwords, `Math.random` for tokens, fixed IVs or keys, missing signature or expiry checks.
|
|
28
|
+
- **Requests and redirects:** server-side requests to URLs the user controls (SSRF), and open redirects.
|
|
29
|
+
- **Unsafe deserialisation:** `eval`, `pickle`, unsafe YAML, and objects merged from input without a schema.
|
|
30
|
+
- **Dependencies:** each new package's maintainers, age, weekly downloads and install scripts; known advisories from the audit command.
|
|
31
|
+
- **Privacy and residency:** data leaving the region or the purposes the principles allow.
|
|
32
|
+
4. Report only findings with a concrete attack path: who the attacker is, the request or input they send, and what they get. A worry without a path isn't a finding.
|
|
33
|
+
|
|
34
|
+
Grade each finding:
|
|
35
|
+
|
|
36
|
+
- **blocker:** exploitable as it is, or a security requirement the story cites isn't met. The branch must not merge.
|
|
37
|
+
- **concern:** should be fixed: exploitable only with something else going wrong, or a defence missing where the threat model expects one. The lead decides.
|
|
38
|
+
- **nit:** a note: hardening worth doing later.
|
|
39
|
+
|
|
40
|
+
For each, say where (`path:line`), the attack, and the fix, and cite the requirement or threat it bears on.
|
|
41
|
+
|
|
42
|
+
End your report with one fenced json block, exactly this shape (the same as code-kit's reviewer, so the lead reads both the same way):
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"findings": [
|
|
47
|
+
{
|
|
48
|
+
"severity": "blocker",
|
|
49
|
+
"where": "src/api/orders.ts:42",
|
|
50
|
+
"text": "Attack: … Fix: …",
|
|
51
|
+
"rule": "ORD-7"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
With nothing to report, say what you attacked and why each held, and end with `{"findings": []}` in the block.
|
package/templates/spec.md
CHANGED
|
@@ -42,6 +42,24 @@
|
|
|
42
42
|
|
|
43
43
|
…
|
|
44
44
|
|
|
45
|
+
## Threat model
|
|
46
|
+
|
|
47
|
+
{{Short and concrete, for this area only. Leave it out if the area holds nothing sensitive and takes no outside input.}}
|
|
48
|
+
|
|
49
|
+
- **Sensitive:** {{what here is worth stealing or breaking: personal data, children's data, credentials, money; and where it's kept}}
|
|
50
|
+
- **Attackers:** {{who might try: a signed-out visitor, another customer, a staff member with the wrong role, a compromised integration}}
|
|
51
|
+
- **Trust boundaries:** {{where outside input enters and who is trusted on each side: the routes, webhooks, uploads, third-party callbacks}}
|
|
52
|
+
|
|
53
|
+
## Security requirements
|
|
54
|
+
|
|
55
|
+
### {{AREA}}-{{n}} {{what must hold, for example "A customer sees only their own bookings"}}
|
|
56
|
+
|
|
57
|
+
{{The rule, stated so a review can check it, and the attack it stops.}}
|
|
58
|
+
|
|
59
|
+
**Acceptance**
|
|
60
|
+
|
|
61
|
+
- Given {{an attacker and what they hold}}, when {{the attack}}, then {{what they get instead}}.
|
|
62
|
+
|
|
45
63
|
## Quality targets
|
|
46
64
|
|
|
47
65
|
{{Only the ones that change how this area is built: scale, response times, privacy, accessibility, audit.}}
|