kataster 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/.claude/THIRD_PARTY_NOTICES.md +4 -0
  2. package/.claude/agents/domain-architect.md +7 -3
  3. package/.claude/agents/researcher.md +77 -0
  4. package/.claude/hooks/validate-docs.ts +15 -0
  5. package/.claude/lib/architecture.ts +3 -33
  6. package/.claude/lib/backlog.ts +2 -0
  7. package/.claude/lib/config.ts +48 -0
  8. package/.claude/lib/discovery.ts +71 -1
  9. package/.claude/lib/engineering.ts +6 -0
  10. package/.claude/lib/gaps.ts +179 -0
  11. package/.claude/lib/glob.ts +39 -0
  12. package/.claude/lib/repo.ts +143 -19
  13. package/.claude/lib/research.ts +303 -0
  14. package/.claude/lib/slices.ts +529 -0
  15. package/.claude/settings.json +1 -0
  16. package/.claude/skills/adopt/SKILL.md +106 -31
  17. package/.claude/skills/adopt/scripts/gap-register.ts +61 -0
  18. package/.claude/skills/adopt/scripts/repo-map.ts +34 -2
  19. package/.claude/skills/adopt/scripts/slice-doc.ts +117 -0
  20. package/.claude/skills/adopt/scripts/slice.ts +163 -0
  21. package/.claude/skills/adopt/templates/context-map.as-is.md +22 -0
  22. package/.claude/skills/architect/SKILL.md +6 -1
  23. package/.claude/skills/domain-model/CONTEXT-FORMAT.md +1 -1
  24. package/.claude/skills/domain-model/SKILL.md +23 -3
  25. package/.claude/skills/event-storming/SKILL.md +3 -2
  26. package/.claude/skills/event-storming/schema/events.schema.json +2 -0
  27. package/.claude/skills/event-storming/templates/events.example.yaml +6 -0
  28. package/.claude/skills/feature/SKILL.md +8 -5
  29. package/.claude/skills/grilling/SKILL.md +15 -0
  30. package/.claude/skills/implement/SKILL.md +39 -3
  31. package/.claude/skills/implement/scripts/characterize.ts +252 -0
  32. package/.claude/skills/implement/scripts/story-context.ts +64 -0
  33. package/.claude/skills/implement/scripts/verify.ts +3 -0
  34. package/.claude/skills/improve-codebase-architecture/SKILL.md +4 -1
  35. package/.claude/skills/research/SKILL.md +149 -0
  36. package/.claude/skills/research/scripts/research-check.ts +105 -0
  37. package/.claude/skills/research/templates/research.md +29 -0
  38. package/.claude/skills/review-stories/SKILL.md +15 -5
  39. package/.claude/skills/shape/SKILL.md +24 -5
  40. package/.claude/skills/tdd/SKILL.md +10 -0
  41. package/.claude/skills/user-stories/SKILL.md +21 -2
  42. package/.claude/skills/user-stories/schema/story.schema.json +4 -0
  43. package/.claude/skills/user-stories/templates/story-template.md +1 -0
  44. package/.opencode/agents/domain-architect.md +7 -3
  45. package/.opencode/agents/researcher.md +91 -0
  46. package/.opencode/commands/adopt.md +1 -1
  47. package/.opencode/commands/feature.md +1 -1
  48. package/.opencode/commands/research.md +7 -0
  49. package/.opencode/commands/shape.md +1 -1
  50. package/AGENTS.md +14 -1
  51. package/CHANGELOG.md +49 -0
  52. package/README.md +78 -19
  53. package/guide/brownfield.md +41 -12
  54. package/guide/concepts.md +12 -1
  55. package/package.json +1 -1
  56. package/src/detect.mjs +9 -0
  57. package/src/install.mjs +4 -0
  58. package/templates/docs/domain/context-map.md +5 -1
  59. package/templates/docs/domain/events.yaml +3 -0
  60. package/templates/docs/research/README.md +70 -0
  61. package/templates/docs/stories/README.md +2 -0
  62. package/templates/docs/workflow.md +54 -13
@@ -17,13 +17,16 @@ is what to read when you are unsure where something belongs.
17
17
  | Vision, user groups, scope | `docs/product/vision.md` | user + main session |
18
18
  | Initiative briefs (proposals, no stories) | `docs/product/initiatives/<slug>.md` | `/shape`; user accepts |
19
19
  | UI/UX decisions (yardstick) | `docs/product/ux-guidelines.md` | `ux-designer` (user approves) |
20
+ | Research evidence (expiry) | `docs/research/<topic>.md` | `researcher` (read-only); main session writes; user confirms findings |
20
21
  | Prototypes (throwaway, on branch `prototype/<slug>`) | `docs/prototypes/<slug>/` | `ux-designer`; verdict in the story and `ux-guidelines.md` |
21
22
  | Glossary (ubiquitous language) | `CONTEXT.md` | `domain-model` skill |
22
23
  | Event storming model | `docs/domain/events.yaml` | event storming / `domain-architect` |
24
+ | Gap register (as-is ↔ target) | `docs/domain/gap-register.md` | `gap-register.ts` (generated rows) + user decisions outside the block |
23
25
  | Visualization (generated!) | `docs/domain/event-storming.md` | hook – never edit manually |
24
- | Context map | `docs/domain/context-map.md` | `domain-architect` |
26
+ | Target context map | `docs/domain/context-map.md` | `domain-architect`, `/bootstrap`, `/shape`, `/feature`, `/improve-codebase-architecture`; `/adopt` never writes it |
27
+ | As-is context map | `docs/domain/context-map.as-is.md` | `/adopt` only |
25
28
  | Logical data model | `docs/architecture/data-model.md` | `domain-architect` |
26
- | Repository map (generated!) | `docs/architecture/repo-map.json`, `docs/architecture/repo-map.md` | `repo-map.ts` – never edit manually |
29
+ | Repository map (generated!) | `docs/architecture/repo-map.json`, `docs/architecture/repo-map.md` | `repo-map.ts` – packages, roles, concept slices; never edit manually |
27
30
  | Package docs (loaded on demand) | `<package>/AGENTS.md` + `<package>/CLAUDE.md` | `/adopt`, user confirms the prose |
28
31
  | Path-scoped rules | `.claude/rules/*.md` (both harnesses) | `/adopt`, user approves |
29
32
  | Architecture boundaries | `docs/architecture/boundaries.yaml` | user confirms; checked by `boundary-check.ts` |
@@ -44,13 +47,17 @@ is what to read when you are unsure where something belongs.
44
47
  | Command | Covers |
45
48
  |---|---|
46
49
  | `/bootstrap` | greenfield: vision → event storming → model → architecture → UX → stories |
47
- | `/adopt [scope] [--stories]` | brownfield: repo map → one slice (domain + shared library) → evidence → domain draft → package docs → grilling → gap register; stories only with `--stories`; repeat per slice |
50
+ | `/adopt [scope] [--stories]` | brownfield: repo map → one concept or package slice (+ shared library) → evidence → domain draft → context docs → grilling → gap register; scope may be a package path, `--paths`, `--route`, `--table`, `--event`, `--cluster` or a term; stories only with `--stories` |
48
51
  | `/shape <idea \| ticket>` | before a large feature: frame, place (existing/new context, shared library), impact, slices, rough cost range, recommendation; creates no stories; `--dry-run` writes nothing |
49
52
  | `boundary-check.ts` | architecture boundaries: `--init`, `--update-baseline`, `--changed`, `--json` |
50
53
  | `affected.ts` | monorepo fast loop: changed files or `--base` → affected packages + native test command |
54
+ | `slice.ts` | concept scope (`--paths`/`--route`/`--table`/`--event`/`--cluster`/`--term`) → candidate files across layers |
55
+ | `slice-doc.ts` | cross-cutting concept slice → `.claude/rules/<context>.md` with `paths:` frontmatter |
56
+ | `characterize.ts` | affected story/paths → existing tests and files with no test; the input for characterization tests |
51
57
  | `grilling` (`/grill-me`) | relentless interview in rounds with recommended answers – how we ask questions |
58
+ | `/research <question>` | one cross-cutting question as evidence: check existing research and expiry, read-only researcher, findings in `docs/research/<topic>.md`, cited in grilling and stories |
52
59
  | `/grill-with-docs` | grilling + `domain-model` + `architect`: writes glossary and ADRs as it goes |
53
- | `/event-storming [process]`, `/feature <idea \| ST-NNN \| ticket>` | discovery entry points; both start by grilling. `/feature` resolves a story or ticket read-only and routes bugs to a regression story; `--prototype` adds a throwaway prototype before the stories |
60
+ | `/event-storming [process]`, `/feature <idea \| ST-NNN \| ticket>` | discovery entry points; both start by grilling. `/feature` resolves a story or ticket read-only and routes bugs to a regression story; `--prototype` adds a throwaway prototype before the stories; `--research` forces the research step |
54
61
  | `user-stories`, `/review-stories` | story format, 1-command rule, spec linter, human approval |
55
62
  | `backlog`, `/backlog-sync` | local / GitHub Issues / Jira mirror, sync and conflict rules |
56
63
  | `ux-design` | how we decide the interface: the UX frontier, what a story says about a screen, review order |
@@ -82,10 +89,23 @@ is what to read when you are unsure where something belongs.
82
89
  - **1-command rule.** One story = one command + its events on one aggregate, at most 4 Gherkin scenarios. A second
83
90
  command is a second story, never a second scenario set. `type: domain` requires `aggregate` and `command` and the
84
91
  linter cross-checks them against `events.yaml`.
92
+ - **Aggregate status is honest.** `target` is the desired boundary (the default when the field is missing);
93
+ `as-is` is the factual boundary recovered from code and needs `evidence`; `unresolved` means the boundary is
94
+ unclear and needs an open hotspot. A story on an `unresolved` aggregate cannot leave `review` – settle the
95
+ boundary first. `/adopt` never writes `target` for something inferred from code.
96
+ - **As-is and target are separate.** `/adopt` writes `docs/domain/context-map.as-is.md` and `as-is` aggregates;
97
+ it never edits the target map `docs/domain/context-map.md`. `/bootstrap`, `/shape`, `/feature`,
98
+ `/event-storming`, `domain-architect` and `/improve-codebase-architecture` write the target. The gap register
99
+ (`docs/domain/gap-register.md`) links both sides; its generated block comes from `events.yaml`.
85
100
  - **Fast lane.** `type: chore` and `type: task` cover UI tweaks, refactorings, dependencies and setup. `/implement`
86
101
  takes the fast lane automatically (or with `--fast`): branch → implement → lint/typecheck/tests → pull request, no
87
102
  Gherkin matching and no formal review pass. `type: tech-task` keeps its checklist and acceptance; `type: spike` is
88
103
  a timeboxed question.
104
+ - **Characterization before test-first.** In a domain story, an affected path with no test for the behaviour that
105
+ is about to change gets a characterization test first: pin the current behaviour, run it green, commit it
106
+ separately (`ST-NNN: characterize <area>`), then start the story tests. If the current behaviour contradicts the
107
+ story, the story goes back to `review` – the test is not adapted to the story. The fast lane skips this except
108
+ for an explicit refactoring.
89
109
  - **The spec linter is the gate.** `node .claude/skills/user-stories/scripts/lint-story.ts <file>` (or
90
110
  `kataster lint-story`) checks frontmatter, required fields, aggregate/command/event references, Gherkin and the
91
111
  scenario limit – deterministically, without an LLM. Green → `ready-for-human-review`; the user approves `ready`.
@@ -99,13 +119,17 @@ is what to read when you are unsure where something belongs.
99
119
  reopened – changes become a new story.
100
120
  - **Never weaken or delete a test to get green.** One branch and one pull request per story; the user merges.
101
121
  - **Subagents don't know the conversation**: when delegating, pass file paths and a clear task.
102
- - **Adopt in slices.** One domain plus at most one shared library per session; never the whole monorepo. The
103
- ranking in `docs/architecture/repo-map.md` suggests where to start.
122
+ - **Adopt in slices, by concept.** One concept or domain plus at most one shared library per session; never the
123
+ whole monorepo. In a layered repository a domain runs through `api/`, `services/` and `repositories/` – a
124
+ generic `services`/`utils` package is a layer, not a domain. The ranking and the concept clusters in
125
+ `docs/architecture/repo-map.md` suggest where to start; `slice.ts` resolves the candidate files.
104
126
  - **The root `AGENTS.md` has no domain.** Structure, commands, hard conventions and links. Domain language lives
105
127
  in `CONTEXT.md`, package reality in `<package>/AGENTS.md` – loaded only when someone works there.
106
128
  - **Directory docs before glob rules.** Rules that apply to a directory belong in its `AGENTS.md`; `.claude/rules/`
107
- with `paths:` is for patterns a directory cannot express. Claude Code scopes it natively, OpenCode's plugin
108
- attaches it when a matching file is read or written – one file, both harnesses.
129
+ with `paths:` is for patterns a directory cannot express. A cross-cutting concept slice documents its domain in
130
+ `.claude/rules/<context>.md` with the slice's globs; a real domain package keeps `<package>/AGENTS.md`. Never
131
+ duplicate the same content in both. Claude Code scopes rules natively, OpenCode's plugin attaches them when a
132
+ matching file is read or written – one file, both harnesses.
109
133
  - **Checks are green on day one.** Brownfield checks start report-only with a baseline and only new violations
110
134
  fail; a red hook gets switched off. `docs/engineering/checks.yaml` decides what runs at edit time and at
111
135
  Stop/CI; the `project-check.ts` dispatcher is wired once and never per package.
@@ -116,6 +140,11 @@ is what to read when you are unsure where something belongs.
116
140
  source is recorded in the story (`Source: …`), its acceptance criteria are grilled like any other claim, and
117
141
  `external` is still written only by the backlog sync. A bug is a story with the label `bug`, not a separate type; a
118
142
  change to a documented rule is a feature, because the rule changes.
143
+ - **Research is evidence, not a specification.** Auth/identity, security, payment, privacy, accessibility,
144
+ performance and new technologies are researched before the round that depends on them; `/feature --research`
145
+ forces it. The `researcher` is read-only and the only path to web content. Findings live in
146
+ `docs/research/<topic>.md` with an expiry; only a finding the user confirms becomes a testable criterion. A story
147
+ with `risk: high` or a configured gate label needs a resolvable `sources:` entry before `ready-for-human-review`.
119
148
  - **Prototypes are throwaway.** One question, one self-contained HTML file under `docs/prototypes/<slug>/`,
120
149
  captured on a throwaway branch `prototype/<slug>` and never merged. The decision lands in the story
121
150
  (`Prototype: …`) and, when it is a recurring rule, in `ux-guidelines.md` as a G-number. No tests, no
@@ -134,12 +163,22 @@ larger than one feature goes through `/shape` first and then `/feature` per slic
134
163
  question cannot be settled on paper, `/feature --prototype` adds a throwaway prototype between grilling and the
135
164
  stories; the verdict goes into the story and the UX guidelines.
136
165
 
166
+ Cross-cutting questions – auth, security, payment, privacy, accessibility, performance, a new library or technology –
167
+ are researched before the round that depends on them: `/research` or the research step of `/feature`, with findings
168
+ in `docs/research/<topic>.md`, an expiry and a citation in the story's `sources:`. `/feature --research` forces the
169
+ step. Research is evidence for the grilling, never a decision; an expired file is refreshed before approval.
170
+
137
171
  Engineering, story by story: `/implement [ST-NNN]` (empty = next ready story whose dependencies are done). Domain
138
- lane: prepare → test plan → red/green per scenario → `verify.ts` → review lane scaled to the diff → refactor →
139
- acceptance tester's verdict → `done` + pull request. Fast lane (`chore`/`task`, or `--fast`): prepare → implement →
140
- lint/typecheck/tests → `verify.ts` → pull request. **The user only merges.** `--prototype` settles an open UI
141
- question first; if it changes the story, the story goes back to `review`, through the linter and the user again.
142
- Start the next story in a fresh session.
172
+ lane: prepare → test plan → **characterization net for untested existing behaviour** → red/green per scenario →
173
+ `verify.ts` → review lane scaled to the diff → refactor → acceptance tester's verdict → `done` + pull request.
174
+ Fast lane (`chore`/`task`, or `--fast`): prepare → implement → lint/typecheck/tests → `verify.ts` → pull request.
175
+ **The user only merges.** `--prototype` settles an open UI question first; if it changes the story, the story goes
176
+ back to `review`, through the linter and the user again. Start the next story in a fresh session.
177
+
178
+ In a brownfield domain story, `characterize.ts` names the affected paths with no test. Characterization tests pin
179
+ the current behaviour and are committed separately (`ST-NNN: characterize <area>`) **before** the story's red →
180
+ green loop. If the current behaviour contradicts the story, that is a finding: the story goes back to `review` and
181
+ the code is not silently adjusted. The fast lane skips this except for an explicit refactoring.
143
182
 
144
183
  With a tracker: pull before `/review-stories`, `/groom-backlog` and `/implement`; push after changing or approving
145
184
  stories and after `done`. The tracker leads on conflict; `docs/stories/` is the mirror and `BACKLOG.md` stays
@@ -156,5 +195,7 @@ domain stories – not in between. Progress is measured in done domain stories a
156
195
  MCP tools; the local mirror keeps validation and traceability deterministic.
157
196
  - **Preview provider** (optional, `review.preview` in `.claude/project.json`): with it, acceptance testing uses the
158
197
  branch preview; without it, the reviewers work from the code.
198
+ - **Web access** goes through the read-only `researcher` (web search/fetch only; no write, no shell). The main
199
+ session receives structured findings and never fetches pages itself.
159
200
  - Never work around missing access silently (no token in a file, no login in the background) – report it and let the
160
201
  user decide.