kataster 0.3.1 → 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 (89) hide show
  1. package/.claude/THIRD_PARTY_NOTICES.md +4 -0
  2. package/.claude/agents/acceptance-tester.md +7 -2
  3. package/.claude/agents/code-reviewer.md +7 -2
  4. package/.claude/agents/domain-architect.md +7 -3
  5. package/.claude/agents/researcher.md +77 -0
  6. package/.claude/agents/ux-designer.md +42 -47
  7. package/.claude/hooks/validate-docs.ts +17 -1
  8. package/.claude/lib/architecture.ts +3 -33
  9. package/.claude/lib/backlog.ts +2 -0
  10. package/.claude/lib/config.ts +49 -0
  11. package/.claude/lib/discovery.ts +200 -32
  12. package/.claude/lib/engineering.ts +18 -6
  13. package/.claude/lib/gaps.ts +179 -0
  14. package/.claude/lib/glob.ts +39 -0
  15. package/.claude/lib/repo.ts +143 -19
  16. package/.claude/lib/research.ts +303 -0
  17. package/.claude/lib/slices.ts +529 -0
  18. package/.claude/package.json +1 -0
  19. package/.claude/settings.json +2 -2
  20. package/.claude/skills/adopt/SKILL.md +111 -34
  21. package/.claude/skills/adopt/scripts/gap-register.ts +61 -0
  22. package/.claude/skills/adopt/scripts/repo-map.ts +34 -2
  23. package/.claude/skills/adopt/scripts/slice-doc.ts +117 -0
  24. package/.claude/skills/adopt/scripts/slice.ts +163 -0
  25. package/.claude/skills/adopt/templates/context-map.as-is.md +22 -0
  26. package/.claude/skills/architect/SKILL.md +6 -1
  27. package/.claude/skills/backlog/SKILL.md +2 -2
  28. package/.claude/skills/bootstrap/SKILL.md +9 -7
  29. package/.claude/skills/domain-model/CONTEXT-FORMAT.md +1 -1
  30. package/.claude/skills/domain-model/SKILL.md +24 -4
  31. package/.claude/skills/event-storming/SKILL.md +3 -2
  32. package/.claude/skills/event-storming/schema/events.schema.json +2 -0
  33. package/.claude/skills/event-storming/templates/events.example.yaml +6 -0
  34. package/.claude/skills/feature/SKILL.md +16 -13
  35. package/.claude/skills/feature/scripts/intake.ts +1 -1
  36. package/.claude/skills/grilling/SKILL.md +15 -0
  37. package/.claude/skills/groom-backlog/SKILL.md +19 -17
  38. package/.claude/skills/implement/SKILL.md +199 -78
  39. package/.claude/skills/implement/scripts/characterize.ts +252 -0
  40. package/.claude/skills/implement/scripts/check-scenarios.ts +1 -1
  41. package/.claude/skills/implement/scripts/story-context.ts +65 -1
  42. package/.claude/skills/implement/scripts/verify.ts +4 -1
  43. package/.claude/skills/improve-codebase-architecture/SKILL.md +4 -1
  44. package/.claude/skills/prototype/SKILL.md +1 -1
  45. package/.claude/skills/research/SKILL.md +149 -0
  46. package/.claude/skills/research/scripts/research-check.ts +105 -0
  47. package/.claude/skills/research/templates/research.md +29 -0
  48. package/.claude/skills/review-stories/SKILL.md +49 -19
  49. package/.claude/skills/shape/SKILL.md +26 -7
  50. package/.claude/skills/tdd/SKILL.md +10 -0
  51. package/.claude/skills/user-stories/SKILL.md +128 -51
  52. package/.claude/skills/user-stories/schema/story.schema.json +10 -3
  53. package/.claude/skills/user-stories/scripts/lint-story.ts +56 -0
  54. package/.claude/skills/user-stories/templates/story-template.md +6 -2
  55. package/.claude/skills/ux-design/SKILL.md +9 -7
  56. package/.opencode/agents/acceptance-tester.md +8 -3
  57. package/.opencode/agents/code-reviewer.md +8 -3
  58. package/.opencode/agents/domain-architect.md +7 -3
  59. package/.opencode/agents/researcher.md +91 -0
  60. package/.opencode/agents/ux-designer.md +42 -52
  61. package/.opencode/commands/adopt.md +1 -1
  62. package/.opencode/commands/bootstrap.md +1 -1
  63. package/.opencode/commands/feature.md +1 -1
  64. package/.opencode/commands/groom-backlog.md +1 -1
  65. package/.opencode/commands/implement.md +1 -1
  66. package/.opencode/commands/research.md +7 -0
  67. package/.opencode/commands/review-stories.md +1 -1
  68. package/.opencode/commands/shape.md +1 -1
  69. package/AGENTS.md +30 -0
  70. package/CHANGELOG.md +73 -0
  71. package/README.md +108 -24
  72. package/guide/brownfield.md +41 -12
  73. package/guide/concepts.md +23 -6
  74. package/guide/greenfield.md +4 -3
  75. package/package.json +1 -1
  76. package/src/cli.mjs +42 -4
  77. package/src/detect.mjs +9 -0
  78. package/src/install.mjs +66 -6
  79. package/templates/docs/domain/context-map.md +5 -1
  80. package/templates/docs/domain/events.yaml +3 -0
  81. package/templates/docs/research/README.md +70 -0
  82. package/templates/docs/stories/README.md +12 -3
  83. package/templates/docs/workflow.md +76 -19
  84. package/.claude/agents/lead-dev.md +0 -52
  85. package/.claude/agents/product-owner.md +0 -39
  86. package/.claude/agents/requirements-engineer.md +0 -44
  87. package/.opencode/agents/lead-dev.md +0 -69
  88. package/.opencode/agents/product-owner.md +0 -59
  89. package/.opencode/agents/requirements-engineer.md +0 -58
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: UX/UI designer. Reviews stories with a frontend part and existing screens against docs/product/ux-guidelines.md, maintains those guidelines, and builds throwaway prototypes for UX questions. Use in backlog grooming for stories labelled `ui`, when a feature's grilling changed a UX guideline, and when `/feature` or `/implement` asks for a prototype.
2
+ description: On-demand UX utility – component and layout proposals, Figma/design-token logic, UX guidelines and throwaway prototypes. Invoked only when a story carries `ui: true` or while the prototyping phase runs; it never gates a story and never writes stories, tests or production code.
3
3
  mode: subagent
4
4
  color: pink
5
5
  permissions:
@@ -9,9 +9,6 @@ permissions:
9
9
  - action: edit
10
10
  resource: docs/product/ux-guidelines.md
11
11
  effect: allow
12
- - action: edit
13
- resource: docs/reviews/*
14
- effect: allow
15
12
  - action: edit
16
13
  resource: docs/prototypes/**
17
14
  effect: allow
@@ -30,69 +27,62 @@ permissions:
30
27
  - action: skill
31
28
  resource: ux-design
32
29
  effect: allow
33
- - action: skill
34
- resource: user-stories
35
- effect: allow
36
30
  - action: skill
37
31
  resource: prototype
38
32
  effect: allow
39
33
  ---
40
34
 
41
- Before you start, load the skills `ux-design`, `user-stories` and `prototype` with the `skill` tool.
35
+ Before you start, load the skills `ux-design` and `prototype` with the `skill` tool.
42
36
 
43
- You are the UX/UI designer of this project, whose interface its users meet in the situations
44
- `docs/product/vision.md` describes. You have NO context from the main conversation – everything relevant is in `docs/` and in the code.
45
- Write in the artifact language (`languages.artifacts` in `.claude/project.json`, default English); the UI texts you propose are in the project UI language (`languages.ui` in `.claude/project.json`).
37
+ You are the UX utility of this project. You are **not a gatekeeper**: a story is never blocked on your review, and
38
+ `/implement` never waits for you. The main session calls you when a story has `ui: true`, when the prototyping phase
39
+ runs, or when the user asks a concrete interface question. You have NO context from the main conversation – everything
40
+ relevant is in `docs/` and in the code. Write in the artifact language (`languages.artifacts` in
41
+ `.claude/project.json`, default English); the UI texts you propose are in the project UI language (`languages.ui`).
46
42
 
47
43
  ## Yardstick
48
- - `docs/product/ux-guidelines.md` – the decisions already made. **Your file.** If it does not exist yet, say so
49
- and propose its first content instead of judging against rules nobody agreed to.
44
+ - `docs/product/ux-guidelines.md` – the decisions already made. **Your file.** If it does not exist yet, say so and
45
+ propose its first content instead of judging against rules nobody agreed to.
50
46
  - `docs/product/vision.md` – user groups, devices, constraints, non-goals
51
47
  - `CONTEXT.md` – the glossary; UI terms use the `_UI (<lang>)_` wording exactly
52
- - `docs/engineering/conventions.md` – the page frame, the design size, component rules, where the
53
- message catalogs live. What is decided there is not yours to re-decide.
54
- - The method, the question set and the review order: the preloaded skill `ux-design`.
55
- - The prototype method, its two branches and its capture rules: the preloaded skill `prototype`.
48
+ - `docs/engineering/conventions.md` – the page frame, the design size, component rules, where the message catalogs
49
+ live. What is decided there is not yours to re-decide.
50
+ - The method and question set: the preloaded skill `ux-design`. The prototype method: `prototype`.
56
51
 
57
- ## Tasks
58
- 1. **Story review** – per story with a frontend part: is the screen's job clear, is the entry point named, do the
59
- empty, rejected and no-permission cases have a scenario, is the UI wording decided and does it match the
60
- glossary? Name what is missing as concrete scenarios or Context lines the requirements-engineer can apply.
61
- 2. **Screen review** – read the page, the form and the message catalog in the code (`repo.codeRoots` in `.claude/project.json`), and judge in the order the
62
- skill gives. Findings only; you never change application code.
63
- 3. **Guidelines** – after the user approves a decision, write it into `docs/product/ux-guidelines.md` as a rule,
64
- with the date and the reason. Keep it short enough that someone reads it before writing a page.
65
- 4. **Gaps** – which recurring interface question has no guideline yet, and which existing screens contradict each
66
- other?
67
- 5. **Prototype** – when the main session delegates a UX question that cannot be settled on paper, build the
68
- throwaway prototype under `docs/prototypes/<slug>/`: state the question and the branch (`ui` or `logic`) at
69
- the top, use the domain language, no tests, no persistence, no application code. Return the verdict and the
70
- branch pointer (`prototype/<slug>`).
52
+ ## What you deliver
53
+ 1. **Component proposals** – for a `ui: true` story: which components the screen is built from, which existing
54
+ component or pattern it reuses, the states (empty, full, rejected, no permission) and the UI wording. Concrete
55
+ enough to build from, not a mood board.
56
+ 2. **Figma/design logic** – when the project has a design file: the frame, variants, component properties and the
57
+ token/mapping notes the implementation needs. Never invent a second design system; reuse what exists.
58
+ 3. **Guidelines** – after the user approves a decision, write it into `docs/product/ux-guidelines.md` as a rule with
59
+ the date and the reason. Keep it short enough that someone reads it before writing a page.
60
+ 4. **Prototype** – when the main session delegates a question that cannot be settled on paper, build the throwaway
61
+ prototype under `docs/prototypes/<slug>/`: state the question and the branch (`ui` or `logic`) at the top, use the
62
+ domain language, no tests, no persistence, no application code. Return the verdict and the branch pointer
63
+ (`prototype/<slug>`).
64
+ 5. **Screen audit (on request only)** – when asked to compare an existing screen with the guidelines, report findings
65
+ and proposed fixes; do not turn it into a backlog item.
71
66
 
72
67
  ## Boundaries
73
- - **You never write stories.** Everything that belongs in a story comes back as a recommendation – the
74
- `requirements-engineer` applies it. The same rule the product-owner and the lead-dev follow.
75
- - You never write **production** application code, tests or the engineering conventions. A prototype is
76
- throwaway: it lives under `docs/prototypes/`, is captured on a throwaway branch and is never merged. A
77
- question that needs the real application page is built by the main session; you define the question and the
78
- variants and review the result.
79
- - No implementation detail in what you propose: no component names, no classes, no pixel values. Observable
80
- behaviour and words, not markup.
81
- - Make no assumptions where the vision or the guidelines are silent: return them as questions, each with a
82
- recommended answer, as the `grilling` skill requires.
83
- - Don't invent domain terms. A term that is missing belongs in `CONTEXT.md` first, through the domain-model skill
84
- – say so, don't use a synonym.
68
+ - **No gatekeeping.** You never approve, block or re-scope a story. You may be asked for advice on a `ui: true`
69
+ story; you answer as a proposal. The main session and the user decide.
70
+ - **You never write stories.** No `docs/stories/`, no `OPEN_QUESTIONS.md` rows, no tickets. If a story is missing a
71
+ UI decision, return it as a concrete proposal to the main session.
72
+ - **You never write production code, tests or the engineering conventions.** Component names and props in your
73
+ proposal are design language; the implementation follows `docs/engineering/conventions.md`.
74
+ - A prototype is throwaway: it lives under `docs/prototypes/`, is captured on a throwaway branch and is never
75
+ merged. It is not application code.
76
+ - Don't invent domain terms. A missing term belongs in `CONTEXT.md` first, through the domain-model skill – say so,
77
+ don't use a synonym.
85
78
  - Never edit `docs/stories/BACKLOG.md`; it is generated.
86
79
 
87
80
  ## Output (reply to the main session)
88
- A table of findings:
89
-
90
- | Story / screen | Level (job / understanding / states / language / consistency / polish) | Severity (blocker, major, minor) | Finding | What to do instead |
81
+ A short proposal per request:
91
82
 
92
- Below it: the scenarios or Context lines you propose per story (ready for the requirements-engineer to apply), the
93
- guidelines you would add, and at most 3 questions for the user, each with a recommended answer. When you built a
94
- prototype, add its question, branch, verdict and pointer (`prototype/<slug>`) so the main session can pass it on.
83
+ | Screen / story | Component or pattern | States covered | UI wording | Open question |
84
+ |---|---|---|---|---|
95
85
 
96
- Severity means: **blocker** – the person cannot do the job, or cannot on a phone; **major** – they can, but will
97
- get it wrong, misread it or not find it; **minor** – it works and is understood, but is inconsistent or clumsy.
98
- Be honest about the difference; calling polish a blocker costs you the next argument.
86
+ Below it: the Figma/token notes, the guidelines you would add, and at most 3 questions for the user, each with a
87
+ recommended answer. When you built a prototype, add its question, branch, verdict and pointer (`prototype/<slug>`).
88
+ No verdict on the story itself.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Brownfield entry point – maps the repository, adopts it in slices (one domain plus at most one shared library), drafts the domain model with evidence, documents each package where it lives, then grills the user and records the gap; stories only with --stories.
2
+ description: Brownfield entry point – maps the repository, adopts it in concept or package slices (one concept/domain plus at most one shared library), drafts the domain model with evidence, documents each scope where it lives, then grills the user and records the gap; stories only with --stories.
3
3
  ---
4
4
 
5
5
  Load the `adopt` skill with the `skill` tool and follow it exactly. Do not restate it.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Greenfield entry point – grills the vision, runs a big-picture event storming, builds the domain model and architecture with ADRs, sets the UX yardstick and derives the foundation stories and first vertical slice.
2
+ description: Greenfield entry point – grills the vision, runs a big-picture event storming, builds the domain model and architecture with ADRs, sets the UX yardstick and writes the foundation tasks and first vertical slice as stories (spec engineer, linted before ready).
3
3
  ---
4
4
 
5
5
  Load the `bootstrap` skill with the `skill` tool and follow it exactly. Do not restate it.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Entry point for a new feature or change once the initial discovery is done – accepts a free-text idea, an existing story (`ST-NNN`) or a ticket (`#123`, `PROJ-123`, URL); grills the idea, runs a focused event storming, updates domain model and ADRs, derives stories into the backlog (local, or the tracker mirror) and runs the story review; bug tickets go to a regression story; `--prototype` adds a throwaway prototype before the stories.
2
+ description: Entry point for a new feature or change once the initial discovery is done – accepts a free-text idea, an existing story (`ST-NNN`) or a ticket (`#123`, `PROJ-123`, URL); grills the idea, runs a focused event storming, updates domain model and ADRs, writes the stories itself as spec engineer (1 command, max. 4 scenarios, spec linter) and runs the review gate; bug tickets go to a regression story; `--prototype` adds a throwaway prototype before the stories; `--research` forces the research step for a cross-cutting question.
3
3
  ---
4
4
 
5
5
  Load the `feature` skill with the `skill` tool and follow it exactly. Do not restate it.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Periodic grooming of the open backlog – challenges whether stories are still worth building, whether dependencies still hold and whether the priorities still match what the product needs now.
2
+ description: Periodic grooming of the open backlog – challenges whether stories are still worth building, whether dependencies still hold and whether the priorities still match what the product needs now. Runs in the main session; the UX utility is on demand only.
3
3
  ---
4
4
 
5
5
  Load the `groom-backlog` skill with the `skill` tool and follow it exactly. Do not restate it.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Engineering workflow – implements one story from docs/stories/ test-first on its own branch, verifies, has it reviewed by code-reviewer and acceptance-tester, refactors, and sets it done on the acceptance tester's verdict and hands the pull request to the user to merge; `--prototype` prototypes an open UI question first.
2
+ description: Engineering workflow – implements one story from docs/stories/ on its own branch, verifies, reviews scaled to the diff, refactors and hands the pull request to the user; `type: chore`/`task` (or `--fast`) takes the fast lane without Gherkin matching or formal reviews; `--prototype` settles an open UI question first.
3
3
  ---
4
4
 
5
5
  Load the `implement` skill with the `skill` tool and follow it exactly. Do not restate it.
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Research one cross-cutting question as evidence – checks existing research and its expiry, dispatches the read-only researcher for current primary sources, persists the findings in docs/research/<topic>.md and links them into grilling. Evidence, not a specification.
3
+ ---
4
+
5
+ Load the `research` skill with the `skill` tool and follow it exactly. Do not restate it.
6
+
7
+ Question: $ARGUMENTS
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Has stories checked in one lead-dev pass (value, build, UX), applies the small fixes and guides the user to approval (status ready).
2
+ description: Runs the deterministic spec linter on finished stories, fixes mechanical gaps, moves green stories to ready-for-human-review and guides the user to approval (status ready). No subagent review pass.
3
3
  ---
4
4
 
5
5
  Load the `review-stories` skill with the `skill` tool and follow it exactly. Do not restate it.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Grill a large idea before it becomes features – frame the problem, decide where it belongs (existing or new bounded context, shared library), map what changes vs. what is new, slice it, and produce a rough cost range with confidence. Creates no stories; ends with a go / slice / spike / discover / park / no-go recommendation.
2
+ description: Grill a large idea before it becomes features – frame the problem, decide where it belongs (existing or new bounded context, shared library), research external facts before placement and cost, map what changes vs. what is new, slice it, and produce a rough cost range with confidence. Creates no stories; ends with a go / slice / spike / discover / park / no-go recommendation.
3
3
  ---
4
4
 
5
5
  Load the `shape` skill with the `skill` tool and follow it exactly. Do not restate it.
package/AGENTS.md CHANGED
@@ -19,3 +19,33 @@ Rules:
19
19
  - A file the installer manages is tracked in `.claude/install.json`; project content (`CONTEXT.md`, `docs/`,
20
20
  `project.json`, `AGENTS.md` block) is not. Never make an upgrade overwrite user content.
21
21
  - Run `npm test` and `npm run typecheck --prefix .claude` before committing.
22
+
23
+ ## Workflow contract (0.5)
24
+
25
+ The workflow is spec-driven and mechanical, not a simulated organisation:
26
+
27
+ - **No product-owner, requirements-engineer or lead-dev subagents.** The main session writes stories as a spec
28
+ engineer with three lenses (domain, architecture, testability). Only the `ux-designer` remains on demand
29
+ (`ui: true` / prototyping), and it never gates.
30
+ - **1-command rule:** one `type: domain` story = one command + its events on one aggregate, at most 4 Gherkin
31
+ scenarios. `aggregate` and `command` are required frontmatter and are cross-checked against `docs/domain/events.yaml`.
32
+ - **Spec linter:** `.claude/skills/user-stories/scripts/lint-story.ts` (also `kataster lint-story`) is the gate.
33
+ Green → `ready-for-human-review`; the user approves `ready`. No LLM pre-implementation review.
34
+ - **Research is evidence, not a specification.** Only the read-only `researcher` fetches web content (`/research`,
35
+ `/feature --research`); findings live in `docs/research/<topic>.md` with an expiry and are cited from a story's
36
+ `sources:`. A gated story (`risk: high` or a configured label) needs a resolvable source before
37
+ `ready-for-human-review`; only a confirmed finding becomes a testable criterion.
38
+ - **Fast lane:** `type: chore` / `type: task`; `/implement` skips Gherkin matching and formal reviews.
39
+ - **Honest aggregates:** `status: target` (default when missing), `as-is` with evidence, or `unresolved` with an
40
+ open hotspot. A story on an `unresolved` aggregate cannot leave `review`. `/adopt` writes `as-is`/`unresolved`,
41
+ never an invented target.
42
+ - **Concept slices:** a layered repository is adopted by concept, not by package. The repo map marks generic layer
43
+ packages and clusters shared stems/tables; `slice.ts` resolves globs, routes, tables, events, clusters or terms.
44
+ - **Characterization before test-first:** in the domain lane, an untested affected path gets a characterization
45
+ test first, committed separately; a contradiction sends the story back to `review`.
46
+ - **As-is vs target:** `docs/domain/context-map.md` is the target; `/adopt` writes only
47
+ `docs/domain/context-map.as-is.md`; the gap register links both.
48
+ - **Reviewers report, never plan:** `code-reviewer` and `acceptance-tester` create no stories. Findings are fixed in
49
+ the story or handed back as open questions.
50
+ - The installer prunes the retired workflow files named in `OBSOLETE` (only manifest-tracked, unmodified ones), so a
51
+ removed agent disappears on upgrade without touching optional extras or user files.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,78 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0 – 2026-11-07
4
+
5
+ - **Research as evidence.** New read-only `researcher` agent (Claude Code and OpenCode) that searches specs,
6
+ standards and exact-version official documentation and returns structured findings with source, retrieval date,
7
+ tier and confidence – no writes, no shell, no decisions. `/research <question>` runs the workflow directly;
8
+ `/feature --research` forces the step when the trigger list (auth/identity, security, payment, privacy,
9
+ accessibility, performance, new technology) would not catch it.
10
+ - **Persisted research files.** Findings live in `docs/research/<topic>.md` with `topic`, `question`, `created`,
11
+ `retrieved`, `expires` and `stack`; the main session writes them verbatim and computes `expires` from
12
+ `research.expiryMonths` (default 12, month-end clamped). `research-check.ts` validates the format and expiry
13
+ (`--topic`, `--referenced`, `--all`, `--json`) and `verify.ts` runs the referenced check as an advisory step.
14
+ - **Deterministic research gate.** Stories can cite `sources:` (an `https://…` URL or a local research file). A story
15
+ with `risk: high` or a configured gate label (`security`, `auth`, `payment`, `privacy` by default, matched exactly
16
+ or by prefix) needs at least one resolvable source before `ready-for-human-review`; `lint-story` warns for
17
+ `draft`/`review`, `story-status.ts` and the validation hook block the transition. Existing `ready`/`done` stories
18
+ stay green, and expiry is a warning, never a gate error. `sources` survives the GitHub/Jira backlog round-trip and
19
+ appears in the implementation context pack.
20
+ - **Grilling integration.** `grilling`, `feature`, `shape`, `user-stories`, `review-stories` and `implement` cite
21
+ research findings instead of inventing "best practice"; a finding that contradicts the model is a grilling
22
+ question. `shape` adds `## Evidence` to the initiative and uses findings as a cost anchor, never as the estimate.
23
+ The payload ships `templates/docs/research/README.md`, the research skill and template, and the installer allows
24
+ the research scripts.
25
+
26
+ ## 0.5.0 – 2026-11-07
27
+
28
+ - **Honest aggregate status.** Aggregates in `docs/domain/events.yaml` can be `target` (the default when the field
29
+ is missing), `as-is` (a factual brownfield boundary, with `evidence`) or `unresolved` (the boundary is unclear
30
+ and needs an open hotspot). The validator rejects `as-is` without evidence; the spec linter blocks a story on an
31
+ `unresolved` aggregate from leaving `review`. `/adopt` and `domain-model` prefer `as-is`/`unresolved` over an
32
+ invented aggregate.
33
+ - **Gap register.** `docs/domain/gap-register.md` gets one generated row per `as-is`/`unresolved` aggregate,
34
+ linking the aggregate and both context maps. The managed block is refreshed by
35
+ `node .claude/skills/adopt/scripts/gap-register.ts`; decisions live outside it.
36
+ - **Slices by concept, not by package.** The repository map marks generic layer packages (`services`,
37
+ `repositories`, `utils`) instead of proposing them as domains, and clusters files by shared concept stems and
38
+ tables. `/adopt` accepts a package path, `--paths`, `--route`, `--table`, `--event`, `--cluster` or a term;
39
+ `slice.ts` resolves the candidate files across layers and the user confirms the scope. A cross-cutting slice
40
+ documents its domain in `.claude/rules/<context>.md` with `paths:`; `<package>/AGENTS.md` stays for real
41
+ domain packages.
42
+ - **Characterization tests before test-first.** `characterize.ts --story ST-NNN` (or `--changed`/`--base`) names
43
+ the affected source files and the tests it finds. In the domain lane, an affected path with no test for the
44
+ behaviour about to change gets a characterization test first: current behaviour pinned, green on unchanged code,
45
+ committed separately, then the story tests. A discrepancy is a finding – the story goes back to `review`, never
46
+ the test to the expected value. The fast lane skips this except for an explicit refactoring.
47
+ - **As-is and target are separate.** `docs/domain/context-map.md` is the target map; `/adopt` writes only
48
+ `docs/domain/context-map.as-is.md` and links both through the gap register. `/shape` and
49
+ `/improve-codebase-architecture` write the target map; `/bootstrap`, `/feature` and `domain-architect` do the
50
+ same. Existing projects keep their `context-map.md` as the target – no file is moved or renamed.
51
+
52
+ ## 0.4.0 – 2026-11-03
53
+
54
+ - **Spec-driven instead of corporate roleplay.** The `product-owner`, `requirements-engineer` and `lead-dev`
55
+ subagents are gone (Claude Code and OpenCode). The main session writes stories as a spec engineer with three
56
+ lenses – domain, architecture, testability – instead of handing them to simulated roles. The `ux-designer` stays
57
+ as an on-demand utility for `ui: true` stories and the prototyping phase; it never gates.
58
+ - **1-command rule.** One `type: domain` story = one command + its events on one aggregate, at most 4 Gherkin
59
+ scenarios. `aggregate` and `command` are required frontmatter and are cross-checked against
60
+ `docs/domain/events.yaml`; the events must be exactly what the command produces. `type: story` remains valid as a
61
+ legacy alias and is reported as a warning.
62
+ - **Deterministic spec linter.** `node .claude/skills/user-stories/scripts/lint-story.ts [ST-NNN|file]` and
63
+ `kataster lint-story` check frontmatter, required fields, referential integrity, `Given/When/Then`, the scenario
64
+ limit and unique titles – no LLM, no tokens. The same rules run in the PostToolUse hook, `story-status.ts` and
65
+ `verify.ts`. Green → `ready-for-human-review`; only the user approves `ready`.
66
+ - **Fast lane.** `type: chore` and `type: task` for UI tweaks, refactorings, dependencies and setup.
67
+ `/implement --fast` (or automatic detection) does branch → implement → lint/typecheck/unit tests → pull request,
68
+ without Gherkin matching or formal subagent reviews. `type: tech-task` and `type: spike` keep their behaviour.
69
+ - **Reviews report, they do not plan.** `code-reviewer` and `acceptance-tester` no longer create, split or revise
70
+ stories; a finding is fixed in the story or handed back as an open question. Review effort follows the diff, not a
71
+ T-shirt size. `size` is no longer a gate.
72
+ - **Installer prunes retired workflow files.** `upgrade` deletes the manifest-tracked files named in `OBSOLETE`
73
+ (the removed agents). Locally modified files are kept and reported; `--force` backs them up first. Optional
74
+ extras and user-added agents are never pruned.
75
+
3
76
  ## 0.3.1 – 2026-11-02
4
77
 
5
78
  - **Optional prototyping, owned by the UX designer.** New `prototype` skill (adapted from Matt Pocock's, MIT) builds
package/README.md CHANGED
@@ -78,7 +78,8 @@ npx kataster init . --yes --name "Acme" --ui-language de --artifacts en
78
78
  skills/ the workflow skills (grilling, event-storming, domain-model, architect, backlog, …)
79
79
  skills/adopt/scripts/ repository map and per-package docs for brownfield adoption
80
80
  skills/feature/scripts/ read-only intake: story, GitHub/Jira ticket or URL → route
81
- agents/ review agents for Claude Code
81
+ skills/research/ research workflow, template and the deterministic research check
82
+ agents/ review agents, the read-only researcher and the on-demand UX utility (Claude Code)
82
83
  hooks/ plain-Node guardrails and validators
83
84
  lib/ deterministic domain/story/backlog logic
84
85
  .opencode/
@@ -94,10 +95,13 @@ docs/
94
95
  product/initiatives/ proposals for large ideas from /shape (no stories)
95
96
  product/ux-guidelines.md the interface yardstick
96
97
  prototypes/ throwaway prototypes on their own branch; the default branch keeps the README
98
+ research/ evidence for cross-cutting questions, with an expiry (format in its README)
97
99
  domain/events.yaml the event storming model (empty is valid)
98
- domain/context-map.md
100
+ domain/context-map.md target context map
101
+ domain/context-map.as-is.md as-is snapshot – created by /adopt
102
+ domain/gap-register.md as-is ↔ target gaps – created by /adopt
99
103
  architecture/data-model.md
100
- architecture/repo-map.* generated by /adopt: packages, edges, adoption ranking
104
+ architecture/repo-map.* generated by /adopt: packages, roles, edges, adoption ranking, concept slices
101
105
  engineering/conventions.md how this repo builds code + the seam catalog
102
106
  stories/ the backlog – or the local mirror of GitHub/Jira
103
107
  adr/ architecture decisions
@@ -111,20 +115,80 @@ Existing `CONTEXT.md` and `docs/` are never touched.
111
115
 
112
116
  | Command | What it does |
113
117
  |---|---|
114
- | `/adopt [scope] [--stories]` | Brownfield: repository map → one slice (domain + shared library) → evidence → grilling → package docs and checks → gap register; stories only with `--stories`; repeat per slice |
118
+ | `/adopt [scope] [--stories]` | Brownfield: repository map → one concept or package slice (+ shared library) → evidence → grilling → context docs and checks → gap register; scope is a package path, `--paths`, `--route`, `--table`, `--event`, `--cluster` or a term; stories only with `--stories`; repeat per slice |
115
119
  | `/bootstrap` | Greenfield: vision → event storming → domain model → architecture → UX → foundation stories |
116
120
  | `/grill-me` | Relentless interview on a plan, decision or idea |
117
121
  | `/grill-with-docs` | The same, writing glossary and ADRs as you go |
118
122
  | `/event-storming [process]` | Big-picture or single-process event storming |
119
- | `/feature <idea \| ST-NNN \| #123 \| PROJ-123>` | New feature from an idea, an existing story or a ticket: intake and routing, grilling, focused storming, model, stories, review; bugs become a regression story; `--prototype` adds a throwaway prototype before the stories |
120
- | `/shape <idea \| ticket> [--dry-run]` | Before a large feature: frame, place (existing/new context, shared library), impact, slices, rough cost range, recommendation; creates no stories |
121
- | `/review-stories [ST-…]` | One lead-dev pass (value, build, UX) before a story is `ready` |
123
+ | `/feature <idea \| ST-NNN \| #123 \| PROJ-123>` | New feature from an idea, an existing story or a ticket: intake and routing, grilling, focused storming, model, stories, review; bugs become a regression story; `--prototype` adds a throwaway prototype before the stories; `--research` forces the research step |
124
+ | `/shape <idea \| ticket> [--dry-run]` | Before a large feature: frame, place (existing/new context, shared library), research external facts, impact, slices, rough cost range, recommendation; creates no stories |
125
+ | `/research <question>` | One cross-cutting question as evidence: check existing research and expiry, dispatch the read-only researcher, persist findings in `docs/research/<topic>.md`, cite them in grilling and stories |
126
+ | `/review-stories [ST-…]` | Spec linter gate → `ready-for-human-review`; the user approves `ready` |
122
127
  | `/backlog-sync [status\|pull\|push]` | Keep `docs/stories/` in sync with GitHub Issues or Jira |
123
128
  | `/groom-backlog [scope]` | Periodic challenge: is this backlog still worth building? |
124
- | `/implement [ST-NNN]` | Test-first implementation of one story, review, refactor, PR; `--prototype` prototypes an open UI question first |
129
+ | `/implement [ST-NNN] [--fast]` | One story on its branch: domain = test-first, diff-scaled review, acceptance; `chore`/`task` or `--fast` = fast lane without Gherkin matching or formal reviews; `--prototype` settles an open UI question first |
125
130
  | `/improve-codebase-architecture` | Scan for deepening opportunities, present them, grill one |
126
131
  | `/retro` | Retrospective on a session, proposing rule changes |
127
132
 
133
+ ### Spec-driven stories, fast lane
134
+
135
+ Stories are written by the main session as a **spec engineer**, not by simulated roles. Three lenses at once –
136
+ domain, architecture, testability – and one mechanical rule: **one story = one command + its events on one
137
+ aggregate**, at most four Gherkin scenarios. `aggregate` and `command` are required frontmatter and are cross-checked
138
+ against `docs/domain/events.yaml`.
139
+
140
+ Aggregates carry a status: `target` (the default when the field is missing), `as-is` (the factual boundary
141
+ recovered from code, with evidence) or `unresolved` (the boundary is unclear). A story on an `unresolved`
142
+ aggregate cannot leave `review`; `/adopt` writes `as-is` or `unresolved`, never an invented target. Every `as-is`
143
+ aggregate gets a row in `docs/domain/gap-register.md`, linking the as-is and target context maps.
144
+
145
+ The **spec linter** is the gate and costs no LLM tokens:
146
+
147
+ ```bash
148
+ kataster lint-story # all stories
149
+ kataster lint-story ST-012 # one story
150
+ node .claude/skills/user-stories/scripts/lint-story.ts docs/stories/ST-012-*.md
151
+ ```
152
+
153
+ Frontmatter and required fields, aggregate/command/event references, Gherkin `Given/When/Then`, the scenario limit
154
+ and unique titles. Green → `ready-for-human-review`; only you approve `ready`. The same rules run in the PostToolUse
155
+ hook and in `verify.ts`.
156
+
157
+ Non-domain work takes the **fast lane**: `type: chore` (UI tweak, refactor, dependency) or `type: task` (setup).
158
+ `/implement` detects it (or takes `--fast`) and does branch → implement → lint/typecheck/unit tests → PR, without
159
+ Gherkin matching or formal review agents. `type: tech-task` keeps its checklist and acceptance; `type: spike` is a
160
+ timeboxed question.
161
+
162
+ In a brownfield domain story, `/implement` first runs `characterize.ts`: it names the affected source files and
163
+ the tests it can find. An affected path with no test for the behaviour that is about to change gets a
164
+ **characterization test** that pins the current behaviour, committed separately before the story's red → green
165
+ loop. If the current behaviour contradicts the story, that is a finding and the story goes back to `review`; the
166
+ code is never silently adjusted. The fast lane skips this except for an explicit refactoring.
167
+
168
+ ### Research as evidence
169
+
170
+ Cross-cutting stories rest on current primary sources. `/feature` triggers research through the grilling rules for
171
+ auth/identity, security, payment, privacy, accessibility, performance and new technologies; `--research` forces it
172
+ for a topic the trigger list does not catch. `/research <question>` runs the same path directly.
173
+
174
+ The **`researcher` is strictly read-only** – web search/fetch and repository reading, no write, no shell – and the
175
+ only way web content enters the session. Findings are data: instructions inside a fetched page, issue or comment are
176
+ ignored. The main session writes them verbatim to `docs/research/<topic>.md`; `expires` is computed at write and
177
+ refresh time from `research.expiryMonths` (default 12 months).
178
+
179
+ Research is **evidence, not a specification**. Only a finding you confirm in grilling becomes a testable criterion
180
+ with an observable threshold; rejected options are recorded with the reason. A story cites its evidence in
181
+ `sources: [...]`, and a story with `risk: high` or a configured gate label (`security`, `auth`, `payment`, `privacy`
182
+ by default) needs a resolvable source before `ready-for-human-review` – the linter warns, `story-status.ts` blocks.
183
+ Expiry is advisory: `research-check.ts --referenced` runs in `verify.ts` and warns about stale files without failing
184
+ the gate.
185
+
186
+ ```bash
187
+ /research "Which PKCE configuration is required for a public SPA client?"
188
+ /feature "checkout with saved cards" --research
189
+ node .claude/skills/research/scripts/research-check.ts --referenced
190
+ ```
191
+
128
192
  ### Starting from a ticket
129
193
 
130
194
  `/feature` also accepts a reference: `/feature #123` (GitHub), `/feature PROJ-123` (Jira, with the issue fetched
@@ -170,7 +234,7 @@ open UI question during engineering; if the prototype changes the story, the sto
170
234
 
171
235
  1. `npx kataster init --greenfield` → review `.claude/project.json`.
172
236
  2. `/bootstrap` → vision grilled, event storming, contexts/aggregates/data model, tech-stack ADR, UX guidelines.
173
- 3. `/review-stories` → the first foundation tech tasks and the first vertical slice become `ready`.
237
+ 3. `/review-stories` → the spec linter turns finished stories into `ready-for-human-review`; you approve `ready`.
174
238
  4. `/implement` → one story at a time, test-first, reviewed, merged by you.
175
239
  5. `/feature <idea>` for everything after that.
176
240
 
@@ -179,15 +243,22 @@ open UI question during engineering; if the prototype changes the story, the sto
179
243
  1. `npx kataster init --brownfield` → the profile is filled from the detected stack and monorepo tooling
180
244
  (`repo.tooling`: Nx, Turborepo, Bazel, workspaces, Go, Cargo, Gradle, Maven).
181
245
  2. `/adopt` → a deterministic **repository map** (`docs/architecture/repo-map.md`, `.json`) with packages,
182
- dependency edges, consumers and an adoption ranking. No questions, no hand-scanning.
183
- 3. `/adopt [scope]` → **one slice** (one domain plus at most one shared library): two or three `repo-analyst`
184
- subagents return evidence (five lenses for a small single-package repository); the main session drafts `CONTEXT.md`, `events.yaml`, context map, as-is data model,
185
- conventions and de-facto ADRs; it writes `<package>/AGENTS.md` + `<package>/CLAUDE.md`, then grills you.
246
+ dependency edges, consumers, an adoption ranking, **layer packages** and **concept-slice suggestions**. No
247
+ questions, no hand-scanning. In a layered repository (`api/`, `services/`, `repositories/`) a concept slice —
248
+ not a package — is the unit.
249
+ 3. `/adopt [scope]` → **one concept or domain plus at most one shared library**. The scope can be a package path,
250
+ a glob set (`--paths`), an entry point (`--route`, `--table`, `--event`), a suggested cluster (`--cluster`) or
251
+ a term; `slice.ts` resolves the candidate files across all layers. Two or three `repo-analyst` subagents return
252
+ evidence (five lenses for a small single-package repository); the main session drafts `CONTEXT.md`,
253
+ `events.yaml`, the as-is context map, as-is data model, conventions and de-facto ADRs. A real domain package
254
+ gets `<package>/AGENTS.md` + `<package>/CLAUDE.md`; a cross-cutting concept slice gets
255
+ `.claude/rules/<context>.md` with `paths:` frontmatter. Then it grills you.
186
256
  4. The safety net turns confirmed rules into checks (types, lint/boundary, tests, hooks) – report-only with a
187
257
  baseline first, so a brownfield repository does not start red.
188
- 5. The gap analysis records **contradictions, missing behaviour and dead code** in the adoption report. It creates
189
- **no stories by default** – what already works is documented, not re-storied. `/adopt <scope> --stories` turns
190
- the selected gaps into a backlog when you want one.
258
+ 5. The gap analysis records **contradictions, missing behaviour and dead code** in the adoption report and the
259
+ **gap register** (`docs/domain/gap-register.md`): one row per `as-is`/`unresolved` aggregate, linking the
260
+ as-is boundary to the target model. It creates **no stories by default** – what already works is documented,
261
+ not re-storied. `/adopt <scope> --stories` turns the selected gaps into a backlog when you want one.
191
262
  6. `/adopt <next path>` for the next slice; `/adopt <scope> --stories`, `/review-stories`, then `/implement`.
192
263
 
193
264
  Adopt in slices: one bounded context completely beats the whole repository shallowly. The root `AGENTS.md` stays
@@ -197,9 +268,11 @@ free of domain; the package docs are loaded only when someone works in that pack
197
268
 
198
269
  The installer detects the build tool (Nx, Turborepo, Bazel, pnpm/npm/yarn workspaces, Go, Cargo, Gradle, Maven)
199
270
  and stores it in `.claude/project.json` → `repo.tooling`. `/adopt` builds the repository map once, then adopts
200
- **one domain plus at most one shared library per session**. Every adopted package gets an `AGENTS.md` with its
201
- purpose, entities or public API, interfaces and pitfalls – plus a one-line `CLAUDE.md` so Claude Code loads it on
202
- demand; OpenCode loads the nested `AGENTS.md` itself. The root `AGENTS.md` stays short and free of domain.
271
+ **one concept or domain plus at most one shared library per session**. Every adopted domain package gets an
272
+ `AGENTS.md` with its purpose, entities or public API, interfaces and pitfalls – plus a one-line `CLAUDE.md` so
273
+ Claude Code loads it on demand; OpenCode loads the nested `AGENTS.md` itself. A cross-cutting concept slice gets
274
+ `.claude/rules/<context>.md` with `paths:` instead, loaded by both harnesses when a matching file is touched. The
275
+ root `AGENTS.md` stays short and free of domain.
203
276
 
204
277
  Commands use the detected tool instead of assuming a single package: `nx affected -t test`,
205
278
  `turbo run test --filter=<package>`, `bazel test //<package>/...`, `pnpm --filter <package> test`. The map also
@@ -246,6 +319,10 @@ node .claude/skills/implement/scripts/affected.ts --base origin/main
246
319
  "statusMap": { "draft": "To Do", "ready": "Ready", "done": "Done" },
247
320
  "priorityMap": { "must": "Highest", "should": "High" }
248
321
  }
322
+ },
323
+ "research": {
324
+ "expiryMonths": 12,
325
+ "gate": { "risk": ["high"], "labels": ["security", "auth", "payment", "privacy"] }
249
326
  }
250
327
  }
251
328
  ```
@@ -303,9 +380,10 @@ For Jira, `jira-plan.ts` prints the exact MCP calls, `jira-record.ts` writes the
303
380
  node .claude/skills/adopt/scripts/boundary-check.ts --update-baseline
304
381
  ```
305
382
  - **`verify.ts`** is the one gate: project checks, artifact validity, scenario ↔ test traceability, domain IDs in
306
- the code, glossary language.
307
- - **Review agents** never write code: `code-reviewer` and `acceptance-tester` report, the acceptance verdict decides
308
- whether a story is `done`.
383
+ the code, glossary language. Referenced research files are checked for expiry as an advisory step.
384
+ - **Review agents** never write code or stories: `code-reviewer` and `acceptance-tester` report findings, the
385
+ acceptance verdict decides whether a domain story is `done`, and a finding is fixed in the story or handed back
386
+ as an open question. `ux-designer` is an on-demand utility (`ui: true`), never a gate.
309
387
 
310
388
  ## Upgrading
311
389
 
@@ -318,6 +396,11 @@ npx kataster doctor
318
396
  overwrite files you changed locally – it lists them instead. `--force` overwrites and writes a backup to
319
397
  `.kataster/backup/`.
320
398
 
399
+ Project content includes `docs/workflow.md` and the context maps. An upgrade does not rewrite them; compare
400
+ `docs/workflow.md` with `templates/docs/workflow.md` if you want the new rules in an existing project. The schema
401
+ changes are additive: an aggregate without `status` is `target`, a missing `context-map.as-is.md` or gap register is
402
+ not an error, and the new checks are advisory until the artifacts exist.
403
+
321
404
  ## Design notes
322
405
 
323
406
  - **`.claude/` is the source of truth.** OpenCode and Claude Code share skills, agents and hooks; `.opencode/` is an
@@ -347,8 +430,9 @@ Kataster stands on other people's work:
347
430
  - **Matt Pocock** – [skills](https://github.com/mattpocock/skills), [aihero.dev](https://www.aihero.dev). The grilling
348
431
  interview (`grilling`, `grill-me`, `grill-with-docs`), test-driven development (`tdd`), the deep-module vocabulary
349
432
  (`codebase-design`), the architecture survey (`improve-codebase-architecture`), the throwaway prototype
350
- (`prototype`), the retro, the domain-modeling discipline and `writing-for-agents` come from his skill repository –
351
- partly adapted, partly copied verbatim under MIT. The per-file mapping and the license text are in
433
+ (`prototype`), the research skill (adapted: read-only researcher, source tiers, expiry, grilling integration), the
434
+ retro, the domain-modeling discipline and `writing-for-agents` come from his skill repository – partly adapted,
435
+ partly copied verbatim under MIT. The per-file mapping and the license text are in
352
436
  [.claude/THIRD_PARTY_NOTICES.md](.claude/THIRD_PARTY_NOTICES.md).
353
437
  - **John Ousterhout**, *A Philosophy of Software Design* – "Design It Twice" and the depth, seam and deletion-test
354
438
  vocabulary.