@solaqua/ghosts 0.2.2 → 0.3.1
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/README.md +22 -3
- package/engineering/skills/code-review/SKILL.md +2 -2
- package/engineering/skills/deep-module/SKILL.md +1 -1
- package/engineering/skills/explain-diff/SKILL.md +1 -1
- package/engineering/skills/github-pr/SKILL.md +1 -1
- package/engineering/skills/grill-me/SKILL.md +1 -1
- package/engineering/skills/loop-coding/SKILL.md +1 -1
- package/engineering/skills/loop-plan/SKILL.md +12 -11
- package/engineering/skills/task-handoff/SKILL.md +1 -1
- package/engineering/skills/test-review/SKILL.md +2 -2
- package/engineering/skills/test-review/references/backend.md +12 -147
- package/engineering/skills/test-review/references/common.md +64 -2
- package/engineering/skills/test-review/references/frontend.md +24 -53
- package/engineering/skills/work-breakdown/SKILL.md +1 -1
- package/engineering/skills/write-adr/README.md +17 -0
- package/engineering/skills/write-adr/SKILL.md +70 -0
- package/engineering/skills/write-adr/templates/adr.md +4 -0
- package/engineering/skills/write-glossary/README.md +14 -0
- package/engineering/skills/write-glossary/SKILL.md +60 -0
- package/engineering/skills/write-glossary/templates/glossary.md +9 -0
- package/package.json +1 -1
- package/research/skills/loop-research/SKILL.md +1 -1
- package/tools/skills/vibe-notion/SKILL.md +1 -1
- package/writing/skills/cold-reader/SKILL.md +1 -1
- package/writing/skills/eli5/SKILL.md +1 -1
- package/writing/skills/humanize-korean/SKILL.md +1 -1
- package/writing/skills/loop-skills/SKILL.md +1 -1
- package/writing/skills/rewrite/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ safe instruction that preserves the behavior.
|
|
|
10
10
|
### GitHub source
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
|
-
npx @solaqua/skul@latest add --global
|
|
13
|
+
npx @solaqua/skul@latest add --global sjquant/ghosts --all
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
### npm package
|
|
@@ -18,10 +18,29 @@ npx @solaqua/skul@latest add --global --agent codex sjquant/ghosts --all
|
|
|
18
18
|
This repository is also published as [`@solaqua/ghosts`](https://www.npmjs.com/package/@solaqua/ghosts). Install it through [`@solaqua/skul`](https://www.npmjs.com/package/@solaqua/skul):
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
|
-
npx @solaqua/skul@latest add --global
|
|
21
|
+
npx @solaqua/skul@latest add --global npm:@solaqua/ghosts --all
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Both examples use `--all` to install every bundle in the repository. Skul installs skills for every supported agent by default. Add `--agent <name>` to target one agent, or repeat the option to target several. The `--global` flag controls where Skul materializes the skills; it does not install `@solaqua/ghosts` as a Node.js dependency. Requires Node.js >=20 and git.
|
|
25
|
+
|
|
26
|
+
## Skill names
|
|
27
|
+
|
|
28
|
+
Skills maintained in this repository use the `ghosts:` namespace to distinguish
|
|
29
|
+
them from built-in skills and skills from other sources. Skul uses each
|
|
30
|
+
`SKILL.md`'s `name` to create the installed skill directory. Skills are
|
|
31
|
+
materialized in each supported agent's native location; invocation syntax
|
|
32
|
+
depends on the agent.
|
|
33
|
+
|
|
34
|
+
| Agent | Invocation example |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| Claude Code | `/ghosts:code-review` |
|
|
37
|
+
| Codex | `$ghosts:code-review` |
|
|
38
|
+
|
|
39
|
+
These are examples; installation is not limited to Claude Code and Codex.
|
|
40
|
+
|
|
41
|
+
Source directories keep their short names, so Skul item selectors still use
|
|
42
|
+
paths such as `--include skills/code-review`. External skills installed through
|
|
43
|
+
`registry/skul.refs.json` retain their upstream names.
|
|
25
44
|
|
|
26
45
|
## Bundles
|
|
27
46
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: code-review
|
|
2
|
+
name: ghosts:code-review
|
|
3
3
|
description: Broad, read-only code review using general agents and complete result synthesis.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
@@ -11,7 +11,7 @@ Consider every question below. Mark irrelevant questions `N/A — <reason>`. The
|
|
|
11
11
|
- `Any correctness or operational risks, including bugs, edge cases, race conditions, resource leaks, performance bottlenecks, scalability concerns, or security issues?`
|
|
12
12
|
- `Any design or API issues when viewed from the intended caller's perspective and from outside-in, deep-module, and dependency-direction perspectives, including whether the module hides state, lifecycle, and ordering details, or exposes internal collaboration methods as public API; also consider hidden obligations, awkward call sites, leaky abstractions, or circular dependencies?`
|
|
13
13
|
- `Any opportunities to simplify or clarify the code through better naming, standard libraries, utilities, or existing abstractions?`
|
|
14
|
-
- `Any test smells or test-suite bloat—such as brittle or implementation-coupled tests, over-mocking, unclear intent, missing negative-path coverage, surviving mutants, or redundant, overlapping, or low-signal tests whose maintenance, execution, and review costs outweigh the independent behavioral confidence they add?`
|
|
14
|
+
- `Any test smells or test-suite bloat—such as brittle or implementation-coupled tests, tautological tests that repeat the implementation or assert only mock setup, over-mocking, unclear intent, missing negative-path coverage, surviving mutants, or redundant, overlapping, or low-signal tests whose maintenance, execution, and review costs outweigh the independent behavioral confidence they add?`
|
|
15
15
|
|
|
16
16
|
After all agents respond and before synthesizing the final findings, triage every candidate point through this question: `Does this feedback identify a real, evidenced, material issue, or would addressing it add unnecessary complexity, flag a nonexistent or unsupported bug, or provide little value?` Judge the feedback itself, not only whether another agent made the same point. Do not omit any candidate point. Assign `P0`, `P1`, `P2`, or `P3` when it is actionable; assign `SKIP` only as a priority label when it is false, unsupported, duplicate, contradicted, out of scope, or not worth acting on. `SKIP` never means remove the item: every candidate must remain in `Findings` with its priority and the reason for that judgment. Do not leave skipped candidates only in `Reviewer Results`.
|
|
17
17
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: explain-diff
|
|
2
|
+
name: ghosts:explain-diff
|
|
3
3
|
description: Explain a complete code change, diff, branch, or PR as a visual, novice-first HTML lesson with large diagrams, few words, concrete examples, and an interactive quiz.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: loop-plan
|
|
2
|
+
name: ghosts:loop-plan
|
|
3
3
|
description: Planning-only loop for complex development and design problems, adaptable to other domains; uses evidence, alternatives, counterarguments, and premortems to resolve material uncertainty or costly tradeoffs. Skip routine implementation planning.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
@@ -57,9 +57,9 @@ fixed ceremony.
|
|
|
57
57
|
|
|
58
58
|
```text
|
|
59
59
|
[Understand] → [Route unknowns]
|
|
60
|
-
├─ evidence → [$loop-research]
|
|
61
|
-
├─ user decision → [$grill-me] ├→ [Frame + ledger] → [Draft]
|
|
62
|
-
└─ known
|
|
60
|
+
├─ evidence → [$ghosts:loop-research]┐
|
|
61
|
+
├─ user decision → [$ghosts:grill-me] ├→ [Frame + ledger] → [Draft]
|
|
62
|
+
└─ known →──────────────────────────┘ ↓
|
|
63
63
|
[Any high-impact uncertainty?]
|
|
64
64
|
├─ No → [Self challenge]
|
|
65
65
|
└─ Yes → [Targeted subagent questions]
|
|
@@ -132,14 +132,15 @@ questions that inspection can answer. Distinguish observed facts, inferences,
|
|
|
132
132
|
and assumptions; cite supporting files or sources. Identify the observable
|
|
133
133
|
outcome, non-goals, affected users or systems, and material constraints.
|
|
134
134
|
|
|
135
|
-
Route unresolved inputs before making design decisions. Use `$loop-research`
|
|
136
|
-
repository or document investigation, current or contested evidence,
|
|
135
|
+
Route unresolved inputs before making design decisions. Use `$ghosts:loop-research`
|
|
136
|
+
for repository or document investigation, current or contested evidence,
|
|
137
137
|
comparisons, feasibility checks, or source citations; it returns verified
|
|
138
138
|
claims, provenance, uncertainty, and leads that could change the plan. Use
|
|
139
|
-
`$grill-me` for choices only the user can make, such as outcome, scope,
|
|
140
|
-
risk tolerance, or external action. It asks the whole ready frontier
|
|
141
|
-
round and returns a short, grouped decision summary. Wait for the user
|
|
142
|
-
the shared understanding before carrying its decisions into the plan.
|
|
139
|
+
`$ghosts:grill-me` for choices only the user can make, such as outcome, scope,
|
|
140
|
+
priority, risk tolerance, or external action. It asks the whole ready frontier
|
|
141
|
+
in each round and returns a short, grouped decision summary. Wait for the user
|
|
142
|
+
to confirm the shared understanding before carrying its decisions into the plan.
|
|
143
|
+
Do not
|
|
143
144
|
ask the user for facts that inspection or research can establish, or infer a
|
|
144
145
|
material preference. Carry both outputs into the decision ledger.
|
|
145
146
|
|
|
@@ -214,6 +215,6 @@ Before delivery, verify references are accurate, critical assumptions are
|
|
|
214
215
|
validated or explicitly gated, acceptance checks cover intended behavior, and
|
|
215
216
|
another implementer can proceed without hidden design decisions.
|
|
216
217
|
Readiness describes the plan; it is not user approval or evidence that planned
|
|
217
|
-
checks passed. If handing the document to `loop-coding`, preserve explicit
|
|
218
|
+
checks passed. If handing the document to `ghosts:loop-coding`, preserve explicit
|
|
218
219
|
approval of that plan and let its implementation workflow own execution. End
|
|
219
220
|
with the plan path, chosen direction, and remaining decisions.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: test-review
|
|
2
|
+
name: ghosts:test-review
|
|
3
3
|
description: Read-only review of tests in a change, PR, or path against shared, frontend, and backend testing standards.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
@@ -8,7 +8,7 @@ disable-model-invocation: true
|
|
|
8
8
|
|
|
9
9
|
Review the tests read-only. If no target is given, review the tests in the current branch's diff against the base branch. Write in the user's language.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Read and apply [references/common.md](references/common.md) for every review. Read [references/frontend.md](references/frontend.md) for UI or browser tests and [references/backend.md](references/backend.md) for server, worker, or data tests as supplements; use both when the change spans them. For another stack, apply only the common standards.
|
|
12
12
|
|
|
13
13
|
1. Map each changed behavior to the existing and new tests that protect it. Flag behavior no test would catch if it broke, and removed tests whose protection is not covered elsewhere.
|
|
14
14
|
2. Review each added, changed, or removed test against the guides' review checklists.
|
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
# Backend Testing Guide
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This guide adds backend-specific rules and examples to the shared standards in `common.md`.
|
|
4
4
|
|
|
5
5
|
Repository structure, fixture names, and test commands may differ by repository. This guide focuses on shared judgment criteria for writing and reviewing backend tests, rather than repository-specific usage.
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
8
|
-
|
|
9
|
-
### 1.1 Meaningful Failure
|
|
10
|
-
|
|
11
|
-
- A test should fail when the behavior it protects is broken.
|
|
12
|
-
- A test that keeps passing after a requirement change or bug does not provide safety. It only adds maintenance cost.
|
|
13
|
-
- If a refactor breaks a test while observable behavior remains the same, the test is likely coupled too tightly to implementation details.
|
|
14
|
-
- Regression tests and snapshot tests are useful when they protect contracts that must not change accidentally.
|
|
15
|
-
- If a test failure does not reveal which requirement was broken, improve the test name, setup, or assertions.
|
|
16
|
-
|
|
17
|
-
### 1.2 Choose Test Targets By Value
|
|
18
|
-
|
|
19
|
-
Apply [Test Target Value](common.md#test-target-value), and:
|
|
20
|
-
|
|
21
|
-
- When an integration test already protects a behavior, do not automatically repeat it in unit tests for every participating layer. Add focused tests where they provide additional protection or clearer checks of important edge cases.
|
|
7
|
+
## 1. Test Targets
|
|
22
8
|
|
|
23
9
|
High-priority targets:
|
|
24
10
|
|
|
@@ -28,53 +14,17 @@ High-priority targets:
|
|
|
28
14
|
- Logic that interprets external system responses and mutates local state
|
|
29
15
|
- Edge-case-heavy logic such as dates, timezones, market holidays, exchange rates, decimals, and discounts
|
|
30
16
|
|
|
31
|
-
Lower-priority targets:
|
|
32
|
-
|
|
33
|
-
- Simple getters, setters, and DTO declarations
|
|
34
|
-
- Behavior already guaranteed by the library
|
|
35
|
-
- Shape errors that static analysis, type checkers, or linters catch better
|
|
36
|
-
- Tests that only repeat the implementation without improving behavioral safety
|
|
37
|
-
|
|
38
17
|
## 2. Test Scope Strategy
|
|
39
18
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Apply [Focused Scenarios](common.md#focused-scenarios).
|
|
43
|
-
|
|
44
|
-
Recommended approach:
|
|
45
|
-
|
|
46
|
-
1. First check whether the behavior can be tested through an existing public entrypoint from the perspective of a user or external system. Do not expand production interfaces solely for testing convenience.
|
|
47
|
-
2. Prefer integration tests when API, service, repository, DB, and cache behavior can be verified together clearly.
|
|
48
|
-
3. Narrow the scope one level when the integration test becomes too slow, too hard to set up, or too hard to debug.
|
|
49
|
-
4. Use unit tests directly for naturally small units such as pure calculations, parsers, and validators.
|
|
50
|
-
5. Replace external systems we do not control at the test boundary, such as third-party APIs, payment providers, email, and object storage.
|
|
51
|
-
|
|
52
|
-
Why we prefer larger tests:
|
|
53
|
-
|
|
54
|
-
- They catch real wiring, transaction, serialization, and dependency override issues.
|
|
55
|
-
- They remain stable when internal calls change but the feature behavior stays the same.
|
|
56
|
-
- They produce a signal closer to production behavior than tests with heavy mocking.
|
|
57
|
-
|
|
58
|
-
When to narrow the scope:
|
|
59
|
-
|
|
60
|
-
- The setup is so large that the important condition is hard to see.
|
|
61
|
-
- The failure cause is difficult to isolate.
|
|
62
|
-
- Replacing external dependencies takes up most of the test.
|
|
63
|
-
- Slow tests start hurting the feedback loop.
|
|
64
|
-
- One complex rule needs many focused edge-case checks.
|
|
19
|
+
API, service, repository, DB, and cache integration tests can catch wiring, transaction, serialization, and dependency override issues.
|
|
65
20
|
|
|
66
21
|
## 3. Test Naming And Grouping
|
|
67
22
|
|
|
68
|
-
Test names should reveal both the situation and the expected outcome.
|
|
69
|
-
|
|
70
23
|
Basic rules:
|
|
71
24
|
|
|
72
25
|
- Use `test_<situation>_<expected_outcome>` for test function names.
|
|
73
26
|
- Every test should have a docstring.
|
|
74
|
-
-
|
|
75
|
-
- Prefer capability- and outcome-oriented names over implementation-shaped names.
|
|
76
|
-
- Describe what the test actually exercises and observes. Do not claim to verify behavior that has been replaced by a test double.
|
|
77
|
-
- Use `pytest.mark.parametrize` with readable `ids` for cases of the same behavior that share an execution flow. Split cases when combining them introduces branches that obscure their different scenarios.
|
|
27
|
+
- Use `pytest.mark.parametrize` with readable `ids` for cases that share an execution flow.
|
|
78
28
|
|
|
79
29
|
Example:
|
|
80
30
|
|
|
@@ -96,7 +46,6 @@ Use classes when related tests are easier to read as one group. Standalone test
|
|
|
96
46
|
|
|
97
47
|
- Group tests by feature or public entrypoint.
|
|
98
48
|
- Do not use classes to hide important setup or build complex lifecycles.
|
|
99
|
-
- Each test inside the class should still be understandable on its own.
|
|
100
49
|
|
|
101
50
|
## 4. AAA Pattern
|
|
102
51
|
|
|
@@ -121,12 +70,6 @@ async def test_expired_subscription_removes_user_role(...) -> None:
|
|
|
121
70
|
assert not user_has_role(subscription.user_id, "premium")
|
|
122
71
|
```
|
|
123
72
|
|
|
124
|
-
Notes:
|
|
125
|
-
|
|
126
|
-
- If `when` contains several independent actions, it becomes unclear which action caused the failure.
|
|
127
|
-
- One test may verify multiple results, but they should all come from the same behavior.
|
|
128
|
-
- Use helpers when setup becomes long, but keep the important scenario conditions visible in the test body.
|
|
129
|
-
|
|
130
73
|
## 5. Layer-Specific Guidelines
|
|
131
74
|
|
|
132
75
|
Use the largest layer that still gives a clear signal.
|
|
@@ -139,30 +82,7 @@ Use the largest layer that still gives a clear signal.
|
|
|
139
82
|
|
|
140
83
|
## 6. Fixture And Test Data
|
|
141
84
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
Good fixtures:
|
|
145
|
-
|
|
146
|
-
- Hide repeated infrastructure setup.
|
|
147
|
-
- Provide common dependencies such as DB sessions, clients, caches, repositories, and services.
|
|
148
|
-
- Make their provided state clear from the name.
|
|
149
|
-
|
|
150
|
-
Fixtures to be careful with:
|
|
151
|
-
|
|
152
|
-
- Fixtures that automatically create too many rows and make test conditions hard to trace.
|
|
153
|
-
- Fixtures that hide the core condition of a scenario.
|
|
154
|
-
- Fixtures that accept many scenario-specific parameters and become a small DSL.
|
|
155
|
-
- Deep fixture dependency chains that make failures hard to diagnose.
|
|
156
|
-
|
|
157
|
-
Recommended approach:
|
|
158
|
-
|
|
159
|
-
- Promote helpers or fixtures to a shared place when multiple domains reuse them.
|
|
160
|
-
- Keep domain-specific helpers near that domain.
|
|
161
|
-
- Keep scenario-specific core conditions in the test body.
|
|
162
|
-
- Reuse established setup helpers when their behavior is outside the test's concern.
|
|
163
|
-
- Extract helpers to make scenarios easier to understand, not just to remove repeated lines. A little duplication is preferable to an abstraction that hides the important conditions or execution flow.
|
|
164
|
-
- Use helper and factory names that reveal intent. Examples: `create_expired_subscription`, `create_verified_user`
|
|
165
|
-
- Create only the minimum rows required by the test.
|
|
85
|
+
Backend fixtures commonly provide DB sessions, clients, caches, repositories, and services; scenario factories can use names such as `create_expired_subscription` or `create_verified_user`.
|
|
166
86
|
|
|
167
87
|
### 6.1 DB Setup
|
|
168
88
|
|
|
@@ -174,19 +94,15 @@ Recommended approach:
|
|
|
174
94
|
|
|
175
95
|
### 6.2 Cache And External State
|
|
176
96
|
|
|
177
|
-
-
|
|
178
|
-
- Do not repeat cleanup setup in individual tests when the repository already handles it globally.
|
|
97
|
+
- Isolate cache state and restore dependency overrides, monkeypatches, and environment overrides through the established fixture lifecycle.
|
|
179
98
|
- Verify cache keys, TTLs, and session values directly when they are part of the contract.
|
|
180
99
|
|
|
181
100
|
## 7. Test Double Policy
|
|
182
101
|
|
|
183
|
-
Use test doubles to move the external world and unstable inputs to the test boundary.
|
|
184
|
-
|
|
185
102
|
Good targets for test doubles:
|
|
186
103
|
|
|
187
104
|
- Payment providers, Google Play, Apple, Firebase, S3, Discord, email, and Kafka producers
|
|
188
105
|
- Other servers or external HTTP clients
|
|
189
|
-
- Current time, randomness, and UUIDs
|
|
190
106
|
- Very slow or nondeterministic library calls
|
|
191
107
|
|
|
192
108
|
Avoid replacing when possible:
|
|
@@ -199,8 +115,6 @@ Avoid replacing when possible:
|
|
|
199
115
|
|
|
200
116
|
Guidelines:
|
|
201
117
|
|
|
202
|
-
- Test doubles should make the test condition clearer.
|
|
203
|
-
- If replacing internal collaborators makes the test fragile during refactoring, switch to a larger-scope test.
|
|
204
118
|
- If a dependency is already mocked at an upper boundary, do not also mock the lower DAO unnecessarily.
|
|
205
119
|
- Use `spec` or real-object-based `patch.object` for `Mock` and `AsyncMock` whenever possible.
|
|
206
120
|
- Patch where the object is used, not where it is defined.
|
|
@@ -209,72 +123,23 @@ Partial replacement can be better than replacing the whole object. For example,
|
|
|
209
123
|
|
|
210
124
|
## 8. Time, Randomness, And Determinism
|
|
211
125
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
- Freeze or patch the current time.
|
|
215
|
-
- When timezone behavior matters, assert the base timezone, UTC conversion, and epoch values explicitly.
|
|
216
|
-
- Use fixed values when randomness, UUIDs, or current time appear in DB values or responses.
|
|
217
|
-
- For ordering-sensitive tests, make `created_at`, `id`, and cursor values explicit.
|
|
218
|
-
- External API response fixtures should contain only the fields needed, but enough fields to represent the edge case.
|
|
126
|
+
For ordering-sensitive queries and pagination, make `created_at`, IDs, and cursor values explicit. Verify timezone conversion or epoch values when they form the storage or response contract.
|
|
219
127
|
|
|
220
128
|
## 9. Assertions
|
|
221
129
|
|
|
222
|
-
Good assertions make it clear what broke when the test fails.
|
|
223
|
-
|
|
224
|
-
Recommended:
|
|
225
|
-
|
|
226
130
|
- In API tests, assert `status_code` first.
|
|
227
|
-
- Use snapshots or exact dictionaries when the whole response is the contract.
|
|
228
|
-
- Assert only the important fields explicitly when only some fields are contractual.
|
|
229
131
|
- Verify DB side effects by reading them back through a repository or query.
|
|
230
132
|
- Assert downstream contracts directly, such as event payloads, unique keys, and published flags.
|
|
231
|
-
-
|
|
232
|
-
|
|
233
|
-
Avoid:
|
|
234
|
-
|
|
235
|
-
- Assertions that provide little signal, such as `assert response.json() is not None`
|
|
236
|
-
- Overly broad snapshots that fail on unrelated field changes
|
|
237
|
-
- Tests that only assert mock call counts without verifying actual state changes
|
|
238
|
-
- Recomputing the expected value with the same logic as the implementation under test
|
|
133
|
+
- Verify authentication and authorization failures at the server boundary, including rejected requests and the absence of unauthorized side effects.
|
|
239
134
|
|
|
240
135
|
## 10. Snapshot Usage
|
|
241
136
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
Use snapshots when:
|
|
245
|
-
|
|
246
|
-
- The entire response structure is part of the API contract.
|
|
247
|
-
- Volatile values are stabilized with matchers, fixed time, or fixed IDs.
|
|
248
|
-
- Snapshot updates are intentional and reviewed in the same PR as the code change.
|
|
249
|
-
- The diff is small enough for reviewers to understand.
|
|
250
|
-
|
|
251
|
-
Avoid snapshots when:
|
|
252
|
-
|
|
253
|
-
- Only a few fields matter.
|
|
254
|
-
- The collection ordering is not stable.
|
|
255
|
-
- Timestamps, UUIDs, or ordering change on every run.
|
|
256
|
-
- The payload is so large that failures are hard to interpret.
|
|
257
|
-
|
|
258
|
-
## 11. Coverage
|
|
259
|
-
|
|
260
|
-
Coverage is a signal, not the quality goal itself.
|
|
261
|
-
|
|
262
|
-
- Whether changed code protects important branches and failure cases matters more than total coverage.
|
|
263
|
-
- If PR coverage is low, explain why the code does not need tests or which higher-level test covers it.
|
|
264
|
-
- Use missing lines in the coverage report to find candidate test targets.
|
|
265
|
-
- Do not add meaningless tests just to increase coverage.
|
|
137
|
+
Response JSON and event payloads can be snapshot targets when their full shape is a stable backend contract.
|
|
266
138
|
|
|
267
|
-
##
|
|
139
|
+
## 11. Review Checklist
|
|
268
140
|
|
|
269
|
-
|
|
141
|
+
Check these backend-specific concerns:
|
|
270
142
|
|
|
271
|
-
- If the scope was narrowed, is the reason clear?
|
|
272
|
-
- Do the name and docstring accurately describe what the test exercises and observes?
|
|
273
|
-
- Is the `given / when / then` flow clear?
|
|
274
143
|
- Can DB, cache, and dependency overrides leak between tests?
|
|
275
|
-
- Are
|
|
276
|
-
- Are necessary failure, permission, and authentication cases covered?
|
|
144
|
+
- Are server authentication and authorization enforced, including rejected requests and unauthorized side effects?
|
|
277
145
|
- Are backend-specific concerns such as pagination, cursors, idempotency, and transactions covered?
|
|
278
|
-
- If a snapshot is used, can reviewers understand the diff?
|
|
279
|
-
- If test doubles keep increasing, should the test move to a larger scope?
|
|
280
|
-
- If fixtures hide too many conditions, should those conditions move back into the test body?
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Common Testing Standards
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Apply these standards to every test review. Frontend and backend guides add stack-specific rules and examples.
|
|
4
|
+
|
|
5
|
+
## Meaningful Failure
|
|
6
|
+
|
|
7
|
+
Tests should fail when the behavior they protect is broken and make the broken requirement clear. Improve the name, setup, or assertions when a failure is hard to interpret. If a refactor breaks a test without changing observable behavior, reconsider its implementation coupling.
|
|
4
8
|
|
|
5
9
|
## Test Target Value
|
|
6
10
|
|
|
@@ -8,12 +12,62 @@ Do not try to test all code at the same density. Evaluate the protection each te
|
|
|
8
12
|
|
|
9
13
|
- Before adding or retaining a test, identify the important regression it catches that existing tests do not adequately cover.
|
|
10
14
|
- When a new feature reuses shared behavior, check what existing tests already protect. Add tests for how the feature uses that behavior and for any differences in its contract, rather than copying all tests for the shared behavior.
|
|
15
|
+
- When an integration test already protects a behavior, add narrower tests only when they provide independent protection or clearer checks of important edge cases.
|
|
11
16
|
- Before removing a test, confirm that important requirements and failure cases remain protected.
|
|
17
|
+
- Give lower priority to simple getters, setters, type declarations, and behavior already guaranteed by libraries or static analysis. Test application requirements those guarantees do not cover.
|
|
18
|
+
|
|
19
|
+
## Test Scope
|
|
20
|
+
|
|
21
|
+
Start from an existing public entrypoint and preserve the real collaboration needed to deliver the behavior. A test can involve several components while protecting one focused concern. Prefer integration tests when they give a clear signal; unit tests suit naturally small rules such as calculations, parsers, and validators.
|
|
22
|
+
|
|
23
|
+
- Narrow the scope when setup obscures the scenario, failures are difficult to isolate, dependency replacement dominates the test, execution cost hurts feedback, or one rule needs many focused edge cases. Keep the reason clear and check what integration protection remains.
|
|
24
|
+
- Replace external or unstable dependencies at the test boundary without replacing the behavior under test. If internal mocks keep increasing or make refactoring fragile, reconsider a larger scope.
|
|
25
|
+
- Before changing production code for testability, check existing public interfaces. Do not expose private members or add abstractions solely for testing convenience; require a clear behavioral testing benefit for design changes.
|
|
12
26
|
|
|
13
27
|
## Focused Scenarios
|
|
14
28
|
|
|
15
29
|
Keep each scenario focused on its intended behavior. Combine multiple actions when their sequence is itself the requirement, not merely because they can be placed in one workflow. Do not extend an existing test with unrelated assertions for a new feature when that behavior belongs in another test.
|
|
16
30
|
|
|
31
|
+
- Make each test understandable on its own, including when setup is shared. Names and descriptions should reveal the scenario and observable outcome; do not claim to verify behavior replaced by a test double.
|
|
32
|
+
- Keep setup, action, and observable results in the Given / When / Then flow. Multiple assertions should describe results of the same behavior.
|
|
33
|
+
- Parameterize cases of the same behavior with readable case names when they share an execution flow. Split cases when branches obscure their distinct scenarios.
|
|
34
|
+
|
|
35
|
+
## Fixtures And Isolation
|
|
36
|
+
|
|
37
|
+
- Reuse established setup for infrastructure outside the test's concern, while keeping scenario-specific conditions and actions visible.
|
|
38
|
+
- Create only the data required for the scenario, with enough fields and variation to represent its edge cases.
|
|
39
|
+
- Avoid helpers that create excessive data, accept many scenario-specific parameters, or hide conditions behind deep dependency chains.
|
|
40
|
+
- Extract helpers for clarity; a little duplication is preferable to hiding the scenario. Use names that reveal the provided state, share helpers when multiple features reuse them, and keep feature-specific helpers near the feature.
|
|
41
|
+
- Ensure mutable state and test overrides cannot leak between tests. Choose isolation or restoration appropriate to the resource; reuse established cleanup instead of repeating it when the environment already handles it.
|
|
42
|
+
|
|
43
|
+
## Deterministic Inputs
|
|
44
|
+
|
|
45
|
+
Control unstable inputs when they affect the behavior or assertions.
|
|
46
|
+
|
|
47
|
+
- Use fixed or controlled time, randomness, and UUIDs when their values matter to the scenario.
|
|
48
|
+
- For ordering-sensitive behavior, make sort inputs explicit and verify the required order.
|
|
49
|
+
- When timezone behavior is contractual, verify the relevant timezone, conversion, or epoch values.
|
|
50
|
+
|
|
51
|
+
## Assertions And Failure Cases
|
|
52
|
+
|
|
53
|
+
- Derive expected outcomes from requirements, independently of production logic. Avoid tautological tests that repeat production logic or assert only mock setup.
|
|
54
|
+
- Assert the observable results and outgoing interactions that form the contract. Check specific fields when only those fields matter, and exact objects when the whole payload is contractual.
|
|
55
|
+
- For lists, verify length, order, and item identities when those properties are requirements.
|
|
56
|
+
- Existence checks or mock call counts are sufficient only when existence or call count is itself the contract, such as preventing duplicate sends. Otherwise verify the intended result or payload.
|
|
57
|
+
- Cover failure, permission, and authentication cases relevant to the changed behavior through observable outcomes at the tested boundary.
|
|
58
|
+
|
|
59
|
+
## Snapshots
|
|
60
|
+
|
|
61
|
+
Use snapshots when the full shape of a focused output is a stable contract and reviewers can understand its diff.
|
|
62
|
+
|
|
63
|
+
- Stabilize volatile values and ordering using appropriate matchers or controlled inputs.
|
|
64
|
+
- Update snapshots intentionally and review their changes with the code change.
|
|
65
|
+
- Prefer explicit assertions when only a few fields matter. Avoid snapshots covering unrelated output or producing too much data to interpret.
|
|
66
|
+
|
|
67
|
+
## Coverage
|
|
68
|
+
|
|
69
|
+
Coverage is a signal for finding test gaps, not a quality goal. Protection of important branches and failure cases matters more than the percentage. Use uncovered code to identify candidate scenarios, explain protection elsewhere or low-value targets when relevant, and do not add meaningless tests to raise coverage.
|
|
70
|
+
|
|
17
71
|
## Review Checklist
|
|
18
72
|
|
|
19
73
|
Start with the test's purpose and contribution to the suite:
|
|
@@ -24,7 +78,15 @@ Start with the test's purpose and contribution to the suite:
|
|
|
24
78
|
|
|
25
79
|
Then check:
|
|
26
80
|
|
|
27
|
-
- Would this test actually fail if that behavior broke?
|
|
81
|
+
- Would this test actually fail if that behavior broke, or do its assertions merely repeat production logic or mock setup?
|
|
28
82
|
- Does it preserve useful collaboration between real components while keeping its concern focused?
|
|
83
|
+
- If the scope was narrowed, is the reason clear and is necessary integration protection retained?
|
|
84
|
+
- Do the name and description accurately reflect the scenario and observable outcome, with a clear Given / When / Then flow?
|
|
29
85
|
- Does the test verify externally observable behavior instead of internal implementation?
|
|
30
86
|
- Do test doubles replace external or unstable dependencies without replacing the behavior under test?
|
|
87
|
+
- Do fixtures expose the important conditions with only the necessary data, or should hidden setup move into the test body?
|
|
88
|
+
- Can mutable state or test overrides leak between tests?
|
|
89
|
+
- Are inputs that affect the result controlled, including time, UUIDs, randomness, and ordering?
|
|
90
|
+
- Do assertions verify the required results, payloads, or interactions rather than incidental properties?
|
|
91
|
+
- Are relevant failure, permission, and authentication cases covered?
|
|
92
|
+
- If a snapshot is used, does it protect a focused contract with a readable diff?
|
|
@@ -1,23 +1,8 @@
|
|
|
1
1
|
# Frontend Testing Guide
|
|
2
2
|
|
|
3
|
-
This guide
|
|
3
|
+
This guide adds frontend-specific rules and examples to the shared standards in `common.md`.
|
|
4
4
|
|
|
5
|
-
## 1.
|
|
6
|
-
|
|
7
|
-
### 1.1 Meaningful Failure
|
|
8
|
-
|
|
9
|
-
Tests are not written just to see `Pass`. They should fail when the behavior they protect is broken.
|
|
10
|
-
|
|
11
|
-
- A test that can keep passing after a meaningful regression does not improve safety. It only increases maintenance cost.
|
|
12
|
-
- When requirements change or a bug is introduced, the test must fail and provide a signal.
|
|
13
|
-
- Regression tests and snapshot tests are still valuable when they protect behavior that would fail after an unintended change.
|
|
14
|
-
- If a test does not meaningfully fail for any realistic change, reconsider whether it should exist at all. In many cases, deleting it is the better choice.
|
|
15
|
-
|
|
16
|
-
### 1.2 Value-Driven Target Selection
|
|
17
|
-
|
|
18
|
-
Apply [Test Target Value](common.md#test-target-value), and:
|
|
19
|
-
|
|
20
|
-
- When an integration test already protects a behavior, do not automatically repeat it in unit tests for every participating component or composable. Add focused tests where they provide additional protection or clearer checks of important edge cases.
|
|
5
|
+
## 1. Test Targets
|
|
21
6
|
|
|
22
7
|
Prioritize behaviors that matter most to users and the business:
|
|
23
8
|
|
|
@@ -30,14 +15,12 @@ Prioritize behaviors that matter most to users and the business:
|
|
|
30
15
|
|
|
31
16
|
We follow Kent C. Dodds' `Testing Trophy` model, with the strongest emphasis on integration tests.
|
|
32
17
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Apply [Focused Scenarios](common.md#focused-scenarios).
|
|
18
|
+
Component integration tests can exercise rendering, composables, and state management together.
|
|
36
19
|
|
|
37
20
|
1. `Static (Lint/Type)`
|
|
38
|
-
Use TypeScript and ESLint to catch typos, type mismatches, and other basic mistakes.
|
|
21
|
+
Use TypeScript and ESLint to catch typos, type mismatches, and other basic mistakes.
|
|
39
22
|
2. `Unit`
|
|
40
|
-
Verify
|
|
23
|
+
Verify calculations or naturally small units such as pure functions, parsers, and validators.
|
|
41
24
|
3. `Integration`
|
|
42
25
|
This is our primary tactic. Verify whether multiple components work together to deliver a feature. Prefer sociable tests with minimal mocking.
|
|
43
26
|
4. `E2E`
|
|
@@ -105,31 +88,14 @@ describe('applyDiscount', () => {
|
|
|
105
88
|
```
|
|
106
89
|
|
|
107
90
|
- Name each `describe` block after the test target. Example: component name, hook name, public function name
|
|
108
|
-
- Write each `it` or `test` block as a
|
|
91
|
+
- Write each `it` or `test` block as a scenario and observable outcome.
|
|
109
92
|
- Do not nest child `describe` blocks. If you need another context, split it into another top-level `describe` block instead.
|
|
110
|
-
-
|
|
111
|
-
- Prefer capability-oriented names over implementation-shaped names.
|
|
112
|
-
Example: `user can checkout with a valid cart` is better than `calls submitOrder with transformed payload`.
|
|
113
|
-
- Describe what the test actually exercises and observes. Do not claim to verify behavior that has been replaced by a test double.
|
|
114
|
-
- Use parameterized tests with readable case names for cases of the same behavior that share an execution flow. Split cases when combining them introduces branches that obscure their different scenarios.
|
|
115
|
-
|
|
116
|
-
## 4. Test Writing Principles
|
|
117
|
-
|
|
118
|
-
### 4.1 Black-box Tests
|
|
93
|
+
- Use `it.each` or `test.each` for cases that share an execution flow.
|
|
119
94
|
|
|
120
|
-
|
|
95
|
+
## 4. Black-box Component Tests
|
|
121
96
|
|
|
122
97
|
- Do not read private properties or component-internal state directly.
|
|
123
98
|
- Write tests from a black-box perspective. If input A is applied, does the user observe result B?
|
|
124
|
-
- If a refactor breaks the test without changing behavior, the test was too coupled to the implementation.
|
|
125
|
-
|
|
126
|
-
### 4.2 Avoid Designing Only For Tests
|
|
127
|
-
|
|
128
|
-
Be careful not to damage production code readability or introduce unnecessary abstractions just to make tests easier to write.
|
|
129
|
-
|
|
130
|
-
- First check whether the behavior can be verified through an existing public entrypoint before changing production code for testability.
|
|
131
|
-
- Change the design only when the testing value clearly outweighs the design cost.
|
|
132
|
-
- In most cases, improving a function interface is better than making the design more complex for testability.
|
|
133
99
|
|
|
134
100
|
## 5. Practical Guide
|
|
135
101
|
|
|
@@ -141,8 +107,6 @@ For consistency, every test follows the `AAA (Given-When-Then)` pattern, and eac
|
|
|
141
107
|
- `When`: The behavior under test
|
|
142
108
|
- `Then`: Observable results of `When`, such as rendered UI, user-visible state, and outgoing requests or events
|
|
143
109
|
|
|
144
|
-
One test may verify multiple results, but they should all come from the same behavior.
|
|
145
|
-
|
|
146
110
|
```tsx
|
|
147
111
|
it('상품 수량을 변경하면 장바구니 총액이 재계산된다', async () => {
|
|
148
112
|
// Given
|
|
@@ -178,8 +142,6 @@ it('쿠폰을 적용하면 최소 주문 금액 조건을 만족할 때만 할
|
|
|
178
142
|
|
|
179
143
|
### 5.2 Mocking Policy
|
|
180
144
|
|
|
181
|
-
Limit mocking to the external world that we do not control. Compared with unit tests that heavily mock internal collaborators, integration tests with real collaboration boundaries are more resilient to refactoring and more trustworthy from the user's perspective.
|
|
182
|
-
|
|
183
145
|
- Mock API calls at the network boundary with `MSW (Mock Service Worker)` instead of mocking server logic directly.
|
|
184
146
|
- Prefer testing the integrated state where parent and child components actually collaborate.
|
|
185
147
|
|
|
@@ -187,7 +149,6 @@ Limit mocking to the external world that we do not control. Compared with unit t
|
|
|
187
149
|
|
|
188
150
|
For MSW-based tests, do not repeat the same setup in every spec. Build tests on top of a shared test environment, then override only the conditions required for the scenario with `server.use(...)`.
|
|
189
151
|
|
|
190
|
-
- Control behavior at the network boundary.
|
|
191
152
|
- Do not default to fine-grained `vi.mock()` calls against internal composables or API modules.
|
|
192
153
|
- Write overrides so that they reveal only the condition the test is trying to validate.
|
|
193
154
|
- Prefer helpers with obvious intent over large and noisy fixture payloads.
|
|
@@ -196,13 +157,12 @@ For MSW-based tests, do not repeat the same setup in every spec. Build tests on
|
|
|
196
157
|
|
|
197
158
|
Reuse established setup helpers for dependencies outside the test's concern. For example, query client, store, injectables, and browser storage are usually better provided by the default test environment than recreated in each spec.
|
|
198
159
|
|
|
199
|
-
|
|
160
|
+
Isolate or reset query caches, stores, and browser storage, and restore MSW handlers, mocks, and environment overrides between tests.
|
|
200
161
|
|
|
201
162
|
#### 5.2.3 Test Double Usage Standard
|
|
202
163
|
|
|
203
164
|
In black-box component tests, keep real rendering whenever possible.
|
|
204
165
|
|
|
205
|
-
- Do not increase test double usage just to make the test easier to write.
|
|
206
166
|
- Consider stubs, spies, or mocks only when unrelated side effects make the test unstable or too noisy.
|
|
207
167
|
- If a test double is necessary, its reason should be easy to explain.
|
|
208
168
|
|
|
@@ -219,7 +179,7 @@ In component tests, the synchronization point should not be "has the request fin
|
|
|
219
179
|
|
|
220
180
|
### 5.4 Handling Non-Deterministic Inputs
|
|
221
181
|
|
|
222
|
-
|
|
182
|
+
For date-dependent UI, pass a fixed base date when the interface supports it:
|
|
223
183
|
|
|
224
184
|
```ts
|
|
225
185
|
// Before
|
|
@@ -239,6 +199,15 @@ it('마감일은 기준일로부터 7일 후다', () => {
|
|
|
239
199
|
});
|
|
240
200
|
```
|
|
241
201
|
|
|
202
|
+
### 5.5 Assertions And Failure Cases
|
|
203
|
+
|
|
204
|
+
- Verify rendered results, user-visible state, and outgoing request or event payloads that form the frontend contract.
|
|
205
|
+
- Verify failures through error feedback, restricted actions, and sign-in flows as appropriate to the changed behavior.
|
|
206
|
+
|
|
207
|
+
### 5.6 Snapshot Targets
|
|
208
|
+
|
|
209
|
+
Use rendered-structure or payload snapshots when their full shape is a stable frontend contract.
|
|
210
|
+
|
|
242
211
|
## 6. UI Verification And Accessibility
|
|
243
212
|
|
|
244
213
|
We avoid pixel-perfect visual regression tests by default. Screen structure and styles change often, and their maintenance cost is high. Instead, prioritize stable properties that users actually perceive and interact with.
|
|
@@ -292,10 +261,12 @@ expect(within(row).getByText('72,000')).toBeInTheDocument();
|
|
|
292
261
|
- Positional selectors such as `nth-child`
|
|
293
262
|
- Auto-generated or meaningless `id` values
|
|
294
263
|
- Text that is likely to change often
|
|
295
|
-
- Broad snapshot comparisons
|
|
296
264
|
|
|
297
265
|
## 7. Review Checklist
|
|
298
266
|
|
|
299
|
-
|
|
267
|
+
Check these frontend-specific concerns:
|
|
300
268
|
|
|
301
|
-
- Do
|
|
269
|
+
- Do queries identify UI through accessible roles, labels, or meaningful user-visible context?
|
|
270
|
+
- Does async synchronization wait for the intended DOM state?
|
|
271
|
+
- Can query caches, stores, browser storage, or MSW overrides leak between tests?
|
|
272
|
+
- Are relevant errors, restricted actions, and sign-in flows verified through observable frontend behavior?
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Write ADR
|
|
2
|
+
|
|
3
|
+
Write a compact decision record about architecture, technology, infrastructure,
|
|
4
|
+
security, engineering practices, or domain design. Starts with a title and a
|
|
5
|
+
short paragraph; adds status, alternatives, or consequences when useful.
|
|
6
|
+
Works independently of a glossary.
|
|
7
|
+
|
|
8
|
+
New records default to `/tmp/write-adr-<safe-decision-slug>.md`. A supplied
|
|
9
|
+
destination takes precedence, and requests to revise a specific record edit
|
|
10
|
+
that file.
|
|
11
|
+
|
|
12
|
+
## Credits
|
|
13
|
+
|
|
14
|
+
Shout-out to [Matt Pocock](https://github.com/mattpocock) for the ADR format in
|
|
15
|
+
[domain-modeling](https://github.com/mattpocock/skills/blob/main/skills/engineering/domain-modeling/ADR-FORMAT.md).
|
|
16
|
+
This skill adapts that format for standalone ADR writing across engineering
|
|
17
|
+
decisions.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ghosts:write-adr
|
|
3
|
+
description: Create or revise Architecture Decision Records (ADRs) that explain a decision, its context, and its rationale. Use when the user asks to document a decision about architecture, technology, infrastructure, security, engineering practices, or domain design.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Write ADR
|
|
8
|
+
|
|
9
|
+
Record a decision so a future reader can understand what was chosen and why.
|
|
10
|
+
ADRs can cover system structure, technology, deployment, security, engineering
|
|
11
|
+
practices, or domain boundaries. A glossary or domain-modeling session is not
|
|
12
|
+
a prerequisite.
|
|
13
|
+
|
|
14
|
+
## Gather context
|
|
15
|
+
|
|
16
|
+
Read the relevant discussion, existing ADRs, and supporting documentation or
|
|
17
|
+
code. Identify the decision, the constraints that shaped it, the reason for
|
|
18
|
+
the choice, and any material trade-off.
|
|
19
|
+
|
|
20
|
+
Separate a proposal from an agreed decision, and an agreed decision from its
|
|
21
|
+
implementation. Code can show what exists; it does not establish the original
|
|
22
|
+
rationale. Do not invent alternatives, evidence, or agreement. Ask only when
|
|
23
|
+
a missing choice or reason prevents an accurate record; otherwise state
|
|
24
|
+
material uncertainty explicitly.
|
|
25
|
+
|
|
26
|
+
## Write
|
|
27
|
+
|
|
28
|
+
Save a new record to the path the user supplies; otherwise use
|
|
29
|
+
`/tmp/write-adr-<safe-decision-slug>.md`, appending a timestamp when needed to
|
|
30
|
+
avoid a collision. This default applies even when the repository already has
|
|
31
|
+
an ADR directory. Create a repository directory only when the user specifies
|
|
32
|
+
it as the destination.
|
|
33
|
+
|
|
34
|
+
When the user asks to revise a specific record, edit that file. When saving a
|
|
35
|
+
new record to a user-specified ADR directory, follow its filename conventions;
|
|
36
|
+
if it uses sequential numbers, take the highest existing number plus one.
|
|
37
|
+
Do not renumber records or overwrite an unrelated file.
|
|
38
|
+
|
|
39
|
+
Follow an established document format when one exists. Otherwise use
|
|
40
|
+
[templates/adr.md](templates/adr.md). Write in the user's language. A title
|
|
41
|
+
and one short paragraph are sufficient when they explain:
|
|
42
|
+
|
|
43
|
+
- the situation or constraint that required a choice;
|
|
44
|
+
- the chosen approach and its scope;
|
|
45
|
+
- the reason for choosing it, including the key accepted trade-off.
|
|
46
|
+
|
|
47
|
+
Add only what helps a future reader assess the decision:
|
|
48
|
+
|
|
49
|
+
- **Status:** distinguish a proposal, an accepted decision, or a retired or
|
|
50
|
+
replaced record when that distinction matters. Use `proposed` for an
|
|
51
|
+
unsettled choice; do not mark it accepted without evidence of agreement.
|
|
52
|
+
- **Considered options:** explain alternatives actually considered when their
|
|
53
|
+
rejection is worth preserving.
|
|
54
|
+
- **Consequences:** state material costs, limits, or downstream effects that
|
|
55
|
+
the short paragraph cannot explain clearly.
|
|
56
|
+
|
|
57
|
+
Keep one decision per record. Edit an existing record for corrections or
|
|
58
|
+
clarifications when requested. When a new decision replaces an accepted one,
|
|
59
|
+
write a new ADR and link to the earlier record to make the replacement clear.
|
|
60
|
+
Update the earlier record only when requested. Documenting a decision does
|
|
61
|
+
not implement it or establish that implementation is complete.
|
|
62
|
+
|
|
63
|
+
## Verify and deliver
|
|
64
|
+
|
|
65
|
+
Reread the record without the preceding conversation. Check that the choice,
|
|
66
|
+
scope, rationale, and decision state are understandable, claims match the
|
|
67
|
+
available evidence, and referenced files or records exist.
|
|
68
|
+
|
|
69
|
+
Report the file path, the recorded decision, and any open questions or
|
|
70
|
+
proposal status.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Write Glossary
|
|
2
|
+
|
|
3
|
+
Create or update a project's vocabulary with short definitions, canonical
|
|
4
|
+
terms, and names to avoid. Respects existing document formats.
|
|
5
|
+
|
|
6
|
+
New glossaries default to `/tmp/write-glossary-<safe-project-slug>.md`. A
|
|
7
|
+
supplied destination takes precedence, and requests to revise a specific
|
|
8
|
+
glossary edit that file.
|
|
9
|
+
|
|
10
|
+
## Credits
|
|
11
|
+
|
|
12
|
+
Shout-out to [Matt Pocock](https://github.com/mattpocock) for the glossary format
|
|
13
|
+
in [domain-modeling](https://github.com/mattpocock/skills/blob/main/skills/engineering/domain-modeling/GLOSSARY-FORMAT.md).
|
|
14
|
+
This skill adapts that format for standalone glossary writing.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ghosts:write-glossary
|
|
3
|
+
description: Create or update a project's GLOSSARY.md with precise definitions and canonical terminology. Use when the user asks to write a glossary, document project vocabulary, or revise existing definitions.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Write Glossary
|
|
8
|
+
|
|
9
|
+
Write a glossary that gives the project a shared vocabulary. Capture the
|
|
10
|
+
meaning of terms; keep implementation choices and decision rationale in
|
|
11
|
+
their own documents.
|
|
12
|
+
|
|
13
|
+
## Gather context
|
|
14
|
+
|
|
15
|
+
Read the relevant discussion, documentation, and existing glossary. Inspect
|
|
16
|
+
code when it helps establish how a term is currently used. Distinguish current
|
|
17
|
+
usage from an intended definition; surface material contradictions instead of
|
|
18
|
+
silently treating either as authoritative.
|
|
19
|
+
|
|
20
|
+
Choose a canonical term for each concept. If a word names several concepts,
|
|
21
|
+
separate their definitions and make their scope clear. Ask only when the
|
|
22
|
+
available context cannot resolve a distinction that changes the meaning.
|
|
23
|
+
Do not invent agreement or turn unresolved terminology into a settled entry.
|
|
24
|
+
|
|
25
|
+
## Write
|
|
26
|
+
|
|
27
|
+
Save a new glossary to the path the user supplies; otherwise use
|
|
28
|
+
`/tmp/write-glossary-<safe-project-slug>.md`, appending a timestamp when needed
|
|
29
|
+
to avoid a collision. This default applies even when the repository already
|
|
30
|
+
has a glossary. When the user asks to revise a specific glossary, edit that
|
|
31
|
+
file. Create a repository directory only when the user specifies it as the
|
|
32
|
+
destination. Write once there is a resolved term to record. A single glossary
|
|
33
|
+
can group terms by area and qualify names whose meaning varies by area.
|
|
34
|
+
|
|
35
|
+
Follow an established document format when one exists. Otherwise use
|
|
36
|
+
[templates/glossary.md](templates/glossary.md). Write in the user's language
|
|
37
|
+
and preserve canonical names used by the project.
|
|
38
|
+
|
|
39
|
+
- Keep each definition to one or two sentences explaining the concept and
|
|
40
|
+
the boundary that distinguishes it from nearby concepts.
|
|
41
|
+
- Include vocabulary with a specific meaning in this project. Omit generic
|
|
42
|
+
programming definitions unless the project gives them a distinct meaning.
|
|
43
|
+
- List competing names under `_Avoid_` when they refer to the same concept or
|
|
44
|
+
would mislead readers. Omit the line when there are none.
|
|
45
|
+
- Group entries only when it helps readers find or distinguish terms.
|
|
46
|
+
- Keep schemas, algorithms, storage choices, and decision histories out of
|
|
47
|
+
glossary entries. Include conceptual relationships only when they clarify
|
|
48
|
+
the definition.
|
|
49
|
+
|
|
50
|
+
Update the relevant entries without rewriting unrelated content. This skill
|
|
51
|
+
produces the glossary; it does not rename code or create decision records.
|
|
52
|
+
|
|
53
|
+
## Verify and deliver
|
|
54
|
+
|
|
55
|
+
Reread the definitions without the preceding conversation. Check that each
|
|
56
|
+
term has a clear meaning within its stated scope, nearby concepts remain
|
|
57
|
+
distinct, and no entry presents an unresolved assumption as fact.
|
|
58
|
+
|
|
59
|
+
Report the file path, the vocabulary added or changed, and any unresolved
|
|
60
|
+
definitions left out.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# <Project or area name>
|
|
2
|
+
|
|
3
|
+
<One or two sentences describing the scope of this vocabulary.>
|
|
4
|
+
|
|
5
|
+
## Language
|
|
6
|
+
|
|
7
|
+
**<Canonical term>**:
|
|
8
|
+
<One or two sentences defining the concept and its distinguishing boundary.>
|
|
9
|
+
_Avoid_: <Competing or misleading names; omit this line when none apply.>
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: cold-reader
|
|
2
|
+
name: ghosts:cold-reader
|
|
3
3
|
description: Draft or revise PR descriptions, ADRs, design documents, implementation plans, review responses, and other engineering artifacts for readers who did not participate in the preceding conversation. Do not use for casual conversation, ordinary code comments, or documents explicitly intended to rely on linked prior context.
|
|
4
4
|
---
|
|
5
5
|
|