@zeix/cause-effect 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/.github/copilot-instructions.md +5 -1
  2. package/.zed/settings.json +24 -1
  3. package/ARCHITECTURE.md +27 -1
  4. package/CHANGELOG.md +21 -0
  5. package/CLAUDE.md +1 -1
  6. package/GUIDE.md +2 -5
  7. package/README.md +45 -3
  8. package/REQUIREMENTS.md +3 -3
  9. package/eslint.config.js +2 -1
  10. package/index.dev.js +14 -0
  11. package/index.js +1 -1
  12. package/index.ts +1 -1
  13. package/package.json +5 -4
  14. package/skills/cause-effect/SKILL.md +69 -0
  15. package/skills/cause-effect/agents/openai.yaml +4 -0
  16. package/skills/cause-effect/references/api-facts.md +179 -0
  17. package/skills/cause-effect/references/error-classes.md +153 -0
  18. package/skills/cause-effect/references/non-obvious-behaviors.md +195 -0
  19. package/skills/cause-effect/references/signal-types.md +292 -0
  20. package/skills/cause-effect/workflows/answer-question.md +54 -0
  21. package/skills/cause-effect/workflows/debug.md +71 -0
  22. package/skills/cause-effect/workflows/use-api.md +63 -0
  23. package/skills/cause-effect-dev/SKILL.md +61 -100
  24. package/skills/cause-effect-dev/references/api-facts.md +96 -0
  25. package/skills/cause-effect-dev/references/error-classes.md +97 -0
  26. package/skills/cause-effect-dev/references/internal-types.md +54 -0
  27. package/skills/cause-effect-dev/references/non-obvious-behaviors.md +162 -0
  28. package/skills/cause-effect-dev/references/source-map.md +45 -0
  29. package/skills/cause-effect-dev/workflows/answer-question.md +55 -0
  30. package/skills/cause-effect-dev/workflows/fix-bug.md +63 -0
  31. package/skills/cause-effect-dev/workflows/implement-feature.md +46 -0
  32. package/skills/cause-effect-dev/workflows/write-tests.md +64 -0
  33. package/skills/changelog-keeper/SKILL.md +47 -37
  34. package/skills/tech-writer/SKILL.md +94 -0
  35. package/skills/tech-writer/references/document-map.md +199 -0
  36. package/skills/tech-writer/references/tone-guide.md +189 -0
  37. package/skills/tech-writer/workflows/consistency-review.md +98 -0
  38. package/skills/tech-writer/workflows/update-after-change.md +65 -0
  39. package/skills/tech-writer/workflows/update-agent-docs.md +77 -0
  40. package/skills/tech-writer/workflows/update-architecture.md +61 -0
  41. package/skills/tech-writer/workflows/update-jsdoc.md +72 -0
  42. package/skills/tech-writer/workflows/update-public-api.md +59 -0
  43. package/skills/tech-writer/workflows/update-requirements.md +80 -0
  44. package/src/graph.ts +2 -0
  45. package/src/nodes/collection.ts +38 -0
  46. package/src/nodes/effect.ts +13 -1
  47. package/src/nodes/list.ts +41 -2
  48. package/src/nodes/memo.ts +0 -1
  49. package/src/nodes/sensor.ts +10 -4
  50. package/src/nodes/store.ts +11 -0
  51. package/src/signal.ts +6 -0
  52. package/test/list.test.ts +121 -0
  53. package/tsconfig.json +9 -0
  54. package/types/index.d.ts +1 -1
  55. package/types/src/graph.d.ts +2 -0
  56. package/types/src/nodes/collection.d.ts +38 -0
  57. package/types/src/nodes/effect.d.ts +13 -1
  58. package/types/src/nodes/list.d.ts +30 -2
  59. package/types/src/nodes/memo.d.ts +0 -1
  60. package/types/src/nodes/sensor.d.ts +10 -4
  61. package/types/src/nodes/store.d.ts +11 -0
  62. package/types/src/signal.d.ts +6 -0
@@ -0,0 +1,64 @@
1
+ <required_reading>
2
+ 1. references/source-map.md — locate the signal type or module being tested
3
+ 2. references/api-facts.md — correct API usage for test cases
4
+ 3. references/non-obvious-behaviors.md — ensure gotchas are covered
5
+ 4. references/error-classes.md — cover expected error conditions
6
+ </required_reading>
7
+
8
+ <process>
9
+ ## Step 1: Identify what to test
10
+
11
+ Clarify the scope before writing anything:
12
+ - Which signal type or behavior is under test?
13
+ - Is this a new test, an extension of existing coverage, or a regression test for a known bug?
14
+
15
+ ## Step 2: Read the source
16
+
17
+ Use references/source-map.md to locate the relevant source file in `src/nodes/`. Read it in full. Tests must match what the implementation actually does, not what you expect it to do.
18
+
19
+ ## Step 3: Read existing tests
20
+
21
+ Find the existing test file for the signal type (look adjacent to or named after the source file). Read it to understand:
22
+ - Test structure and helper patterns in use
23
+ - Which behaviors are already covered
24
+ - Naming conventions
25
+
26
+ ## Step 4: Identify gaps
27
+
28
+ Cross-reference the source, existing tests, and these reference files:
29
+ - references/non-obvious-behaviors.md — are gotchas covered?
30
+ - references/error-classes.md — are thrown errors tested?
31
+ - references/api-facts.md — are all option variants exercised (e.g. `equals`, `guard`)?
32
+
33
+ ## Step 5: Write tests
34
+
35
+ Follow the conventions of the existing test suite. Each test should:
36
+ - Have a descriptive name that states the expected behavior
37
+ - Be self-contained (no shared mutable state between tests)
38
+ - Cover one specific behavior per test
39
+
40
+ Priority order for coverage:
41
+ 1. Happy path (normal usage)
42
+ 2. Edge cases and boundary conditions
43
+ 3. Expected error throws (use `expect(() => ...).toThrow(ErrorClass)`)
44
+ 4. Non-obvious behaviors from references/non-obvious-behaviors.md
45
+ 5. Interaction with `batch`, `untrack`, `unown` if the signal participates in those
46
+
47
+ ## Step 6: Verify
48
+
49
+ Run the full test suite:
50
+
51
+ ```bash
52
+ bun test
53
+ ```
54
+
55
+ All tests — new and existing — must pass.
56
+ </process>
57
+
58
+ <success_criteria>
59
+ - Tests cover the specified signal type or behavior
60
+ - Each test is self-contained and has a descriptive name
61
+ - Expected error conditions are tested with the correct error class
62
+ - At least one relevant non-obvious behavior is covered if applicable
63
+ - `bun test` passes with no regressions
64
+ </success_criteria>
@@ -1,59 +1,69 @@
1
1
  ---
2
- name: changelog
3
- description: Update CHANGELOG.md with user-facing changes. Use after meaningful code changes, when asked to add release notes, or to prepare a release.
2
+ name: changelog-keeper
3
+ description: >
4
+ Maintain CHANGELOG.md for the @zeix/cause-effect library. Use after meaningful code
5
+ changes, when asked to add release notes, or to prepare a release.
4
6
  user_invocable: true
5
7
  ---
6
8
 
7
- # Changelog Keeper
8
-
9
- Maintain `CHANGELOG.md` following [Keep a Changelog](https://keepachangelog.com) conventions.
10
-
11
- ## Structure
9
+ <objective>
10
+ Maintain `CHANGELOG.md` following [Keep a Changelog](https://keepachangelog.com) conventions,
11
+ adapted to this project's style: technically precise, developer-focused entries that include
12
+ implementation detail when it explains *why* behavior changed or *how* to migrate.
13
+ </objective>
12
14
 
15
+ <structure>
13
16
  The changelog uses this heading hierarchy:
14
17
 
15
18
  ```markdown
16
19
  # Changelog
17
20
 
18
- ## [Unreleased]
21
+ ## [Unreleased] ← only present when unreleased changes exist
19
22
 
20
23
  ### Added
21
- ### Changed
22
- ### Deprecated
23
- ### Removed
24
24
  ### Fixed
25
- ### Security
26
25
 
27
- ## 0.18.1
26
+ ## 1.0.0 ← released versions use bare version numbers, no brackets
28
27
 
29
- ### Added
28
+ ### Changed
30
29
  ...
31
30
  ```
32
31
 
33
- - `## [Unreleased]` is always the first version section. New changes go here.
34
- - Only include categories that have entries.
35
- - Version 0.18.0 is the baseline. Do not document changes before it.
36
-
37
- ## Adding entries
32
+ - `## [Unreleased]` is only present when there are documented changes not yet released.
33
+ Create it at the top (below `# Changelog`) when documenting the first new change after a release.
34
+ It does not exist between releases.
35
+ - Released versions use bare version numbers: `## 1.0.0`, `## 0.18.5`, etc. No brackets.
36
+ - Only include category headings (`### Added`, `### Changed`, etc.) that have entries.
37
+ - `## 0.18.0` is the baseline. Do not document changes before it.
38
+ </structure>
38
39
 
40
+ <adding_entries>
39
41
  1. Read `CHANGELOG.md`.
40
- 2. Determine which changes are user-facing by inspecting the diff (`git diff main..HEAD -- src/ index.ts` or as directed).
41
- 3. Classify each change into exactly one category: Added, Changed, Deprecated, Removed, Fixed, or Security.
42
- 4. Write concise bullets describing user-visible behavior. Use backticks for public API names.
43
- 5. Do not duplicate existing entries.
44
- 6. Edit the file in place using the Edit tool.
45
-
46
- ## Preparing a release
47
-
42
+ 2. Inspect the diff to identify changes: `git diff main..HEAD -- src/ index.ts` or as directed.
43
+ 3. If there is no `## [Unreleased]` section, create one immediately below `# Changelog`.
44
+ 4. Classify each change into exactly one category: Added, Changed, Deprecated, Removed, Fixed, or Security.
45
+ 5. Write entries following the style guide below.
46
+ 6. Do not duplicate existing entries.
47
+ 7. Edit the file in place using the Edit tool.
48
+ </adding_entries>
49
+
50
+ <preparing_a_release>
48
51
  When asked to release a version:
49
52
 
50
- 1. Move all `[Unreleased]` entries under a new `## X.Y.Z` heading.
51
- 2. Leave an empty `## [Unreleased]` section above it.
52
- 3. Update `version` in `package.json` and the `@version` tag in `index.ts` to match.
53
-
54
- ## Entry style
55
-
56
- - One behavior change per bullet.
57
- - Factual and concise; skip implementation-only details.
58
- - Include migration notes under Changed or Removed when behavior breaks compatibility.
59
- - Bold the API name or short summary at the start: `- **\`createMemo\` \`watched\` option**: description...`
53
+ 1. Rename `## [Unreleased]` to `## X.Y.Z` — do not leave an empty `[Unreleased]` section behind.
54
+ 2. Update `version` in `package.json` to match.
55
+ 3. Update the `@version` tag in `index.ts` to match.
56
+ </preparing_a_release>
57
+
58
+ <entry_style>
59
+ - **One behavior change per bullet.**
60
+ - **Bold the API name or short summary** at the start, followed by a colon:
61
+ `- **\`createMemo\` \`watched\` option**: description…`
62
+ - **Include implementation details** when they explain *why* the behavior changed, *how* the
63
+ fix works, or *what internal invariant* is preserved. This changelog is read by developers
64
+ and AI agents integrating or contributing to the library — precision is expected.
65
+ - **Use before/after framing for Fixed entries**: "Previously, X. Now, Y."
66
+ - **Include migration notes** under Changed or Removed when behavior breaks compatibility.
67
+ State clearly what consumers must change and why.
68
+ - Use backticks for all public API names, internal types, flags, and file names.
69
+ </entry_style>
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: tech-writer
3
+ description: >
4
+ Keep developer-facing documents up to date with the @zeix/cause-effect source code:
5
+ README.md, GUIDE.md, ARCHITECTURE.md, REQUIREMENTS.md, CLAUDE.md,
6
+ .github/copilot-instructions.md, and JSDoc in src/. Use after code changes, to verify
7
+ consistency, or to update a specific document.
8
+ user_invocable: true
9
+ ---
10
+
11
+ <scope>
12
+ This skill is for the cause-effect library repository. It expects source files at `src/`
13
+ and `index.ts`, documentation at the project root, and agent instructions at `.github/`.
14
+
15
+ For consumer projects using `@zeix/cause-effect` as a dependency, use the `cause-effect`
16
+ skill instead.
17
+ </scope>
18
+
19
+ <essential_principles>
20
+ **Read source before writing.** Always read the current state of the relevant source file(s)
21
+ and the target document before making any changes. Never update from memory.
22
+
23
+ **Tone adapts to audience.** Each document has a distinct primary reader and register.
24
+ See references/tone-guide.md. Violating the tone is as wrong as a factual error.
25
+
26
+ **Concise over comprehensive.** Every sentence must justify its presence. Cut anything
27
+ that does not add information the reader needs. Technical accuracy is non-negotiable;
28
+ length is not.
29
+
30
+ **Surgical edits only.** Update what changed. Do not rewrite sections that are still
31
+ accurate, and do not add commentary about what was updated.
32
+ </essential_principles>
33
+
34
+ <intake>
35
+ What do you need to do?
36
+
37
+ 1. **Update after a code change** — `src/` or `index.ts` has changed and documents need
38
+ to reflect it
39
+ 2. **Review consistency** — check that all documents reflect the current source
40
+ 3. **Update a specific document** — you know exactly which one
41
+
42
+ **Wait for response before proceeding.**
43
+ </intake>
44
+
45
+ <routing>
46
+ | Response | Workflow |
47
+ |---|---|
48
+ | 1, "code changed", "after change", "just merged", "new feature", "bug fix" | workflows/update-after-change.md |
49
+ | 2, "review", "consistency", "check", "audit", "verify" | workflows/consistency-review.md |
50
+ | 3, "specific", or names a document | See document routing below |
51
+
52
+ **Document-specific routing (option 3):**
53
+
54
+ | Document named | Workflow |
55
+ |---|---|
56
+ | `README.md` or `GUIDE.md` | workflows/update-public-api.md |
57
+ | `ARCHITECTURE.md` | workflows/update-architecture.md |
58
+ | `CLAUDE.md` or `copilot-instructions.md` | workflows/update-agent-docs.md |
59
+ | `REQUIREMENTS.md` | workflows/update-requirements.md |
60
+ | JSDoc / `src/` | workflows/update-jsdoc.md |
61
+
62
+ **Intent-based routing (clear intent without selecting a number):**
63
+ - "document the new API" / "update README" → workflows/update-public-api.md
64
+ - "update the architecture doc" → workflows/update-architecture.md
65
+ - "update CLAUDE.md" / "add non-obvious behavior" → workflows/update-agent-docs.md
66
+ - "update JSDoc" / "inline docs" → workflows/update-jsdoc.md
67
+ - "update requirements" → workflows/update-requirements.md
68
+ - "review all docs" / "check consistency" → workflows/consistency-review.md
69
+
70
+ **After identifying the workflow, read it and follow it exactly.**
71
+ </routing>
72
+
73
+ <reference_index>
74
+ All in `references/`:
75
+
76
+ | File | Contents |
77
+ |---|---|
78
+ | document-map.md | Each document's audience, scope, update triggers, and consistency checks |
79
+ | tone-guide.md | Writing tone, register, and conciseness rules per document type |
80
+ </reference_index>
81
+
82
+ <workflows_index>
83
+ All in `workflows/`:
84
+
85
+ | Workflow | Purpose |
86
+ |---|---|
87
+ | update-after-change.md | Determine which documents to update after a code change, then update them in order |
88
+ | update-public-api.md | Update `README.md` and `GUIDE.md` |
89
+ | update-architecture.md | Update `ARCHITECTURE.md` |
90
+ | update-agent-docs.md | Update `CLAUDE.md` and `.github/copilot-instructions.md` |
91
+ | update-requirements.md | Update `REQUIREMENTS.md` |
92
+ | update-jsdoc.md | Update JSDoc comments in `src/` |
93
+ | consistency-review.md | Review all documents for consistency with current source |
94
+ </workflows_index>
@@ -0,0 +1,199 @@
1
+ <overview>
2
+ Every document the tech-writer skill maintains, with its audience, scope, what triggers an
3
+ update, and what to verify in a consistency review. Load this reference whenever you need
4
+ to determine which documents are affected by a change.
5
+ </overview>
6
+
7
+ <documents>
8
+
9
+ <REQUIREMENTS_md>
10
+ **Path:** `REQUIREMENTS.md`
11
+ **Audience:** Stakeholders, potential contributors, library authors evaluating adoption
12
+ **Register:** Formal, strategic, timeless — written to survive version bumps
13
+ **Scope:** Vision, primary and secondary audience, design principles, signal type set,
14
+ runtime environments, bundle size targets, non-goals, stability guarantees
15
+
16
+ **Update triggers:**
17
+ - A signal type is added to or removed from the library
18
+ - A runtime environment is added or dropped
19
+ - A bundle size target changes
20
+ - A design principle is added, changed, or removed
21
+ - The primary or secondary audience shifts
22
+ - A non-goal is resolved or a new one is established
23
+ - Stability guarantees change (version milestone, compatibility stance)
24
+
25
+ **Do NOT update for:** bug fixes, new options on existing types, internal refactors,
26
+ documentation or tooling changes.
27
+
28
+ **Consistency checks:**
29
+ - Signal type count in prose ("9 signal types") matches the table row count
30
+ - Signal type table rows match the exports in `index.ts`
31
+ - Non-goals do not contradict any feature currently in the library
32
+ - Runtime environments list reflects current CI targets
33
+ </REQUIREMENTS_md>
34
+
35
+ <README_md>
36
+ **Path:** `README.md`
37
+ **Audience:** Developers integrating the library — library authors and framework integrators
38
+ **Register:** Instructional, example-driven, precise — assumes TypeScript competence
39
+ **Scope:** Installation, quick start, full public API reference, signal type selection guide,
40
+ advanced usage patterns (batching, cleanup, scopes, watched callbacks)
41
+
42
+ **Update triggers:**
43
+ - Any factory function is added, removed, or has a changed signature
44
+ - Any option is added, renamed, removed, or changes semantics
45
+ - Any exported type is added, removed, or renamed
46
+ - A behavioral guarantee changes (e.g. sync vs async execution, equality semantics)
47
+ - A new advanced usage pattern is added to the library
48
+
49
+ **Consistency checks:**
50
+ - Every factory function in `index.ts` has a `### SignalType` section under `## API`
51
+ - All `@param`-level option names match current factory signatures
52
+ - Code examples in the API sections use current factory signatures and compile
53
+ - "Choosing the Right Signal" table covers all signal types with accurate descriptions
54
+ - "Advanced Usage" examples use current API
55
+ </README_md>
56
+
57
+ <GUIDE_md>
58
+ **Path:** `GUIDE.md`
59
+ **Audience:** Developers migrating from React, Vue, or Angular
60
+ **Register:** Comparative, educational, approachable — draws explicit parallels to other frameworks
61
+ **Scope:** Conceptual mapping from React/Vue/Angular primitives, key behavioral differences
62
+ (synchronous effects, auto-tracked dependencies, non-nullable types, scope-based ownership),
63
+ and signal types that go beyond what standard frameworks provide
64
+
65
+ **Update triggers:**
66
+ - A core factory name changes (breaks the "Familiar Core" comparison table)
67
+ - A fundamental behavioral contract changes — sync execution, dependency tracking model,
68
+ nullability rules, or ownership semantics
69
+ - A new signal type is added that goes "Beyond the Basics"
70
+ - An existing "Beyond the Basics" signal type changes significantly enough that a framework
71
+ developer's mental model derived from the guide would now be wrong
72
+
73
+ **Do NOT update for:** new options on existing signal types, minor signature tweaks, internal
74
+ changes, or anything that does not change how a React/Vue/Angular developer would think about
75
+ the library.
76
+
77
+ **Consistency checks:**
78
+ - "The Familiar Core" table references current factory function names (`createState`,
79
+ `createMemo`, `createEffect`)
80
+ - "What Works Differently" sections describe current behavior accurately
81
+ - "Beyond the Basics" signal type sections use current factory signatures and options
82
+ - Code examples compile against current `index.ts`
83
+ </GUIDE_md>
84
+
85
+ <ARCHITECTURE_md>
86
+ **Path:** `ARCHITECTURE.md`
87
+ **Audience:** Contributors to the library; AI agents reasoning about internals
88
+ **Register:** Technical, precise, internal-facing — implementation details are expected and correct
89
+ **Scope:** Graph engine data structures (edges, node field mixins, concrete node types),
90
+ automatic dependency tracking (`activeSink`, `link`, `trimSources`, `unlink`), change
91
+ propagation (flag semantics, `propagate`, `refresh`, `setState`), effect scheduling (`batch`,
92
+ `flush`), ownership and cleanup (`activeOwner`, cleanup storage, `createScope`), and a
93
+ per-signal-type subsection describing each type's internal composition and lifecycle
94
+
95
+ **Update triggers:**
96
+ - The `Edge` type fields change
97
+ - Node field mixins (`SourceFields`, `SinkFields`, `OwnerFields`, `AsyncFields`) change
98
+ - A concrete node type is added, removed, or its composition changes
99
+ - `activeSink` or `activeOwner` semantics change
100
+ - `link()`, `trimSources()`, or `unlink()` behavior changes
101
+ - Flag names or values change (`FLAG_CLEAN`, `FLAG_CHECK`, `FLAG_DIRTY`, `FLAG_RUNNING`)
102
+ - `propagate()`, `refresh()`, `setState()`, `batch()`, or `flush()` behavior changes
103
+ - A new signal type is added (add a subsection) or removed (remove its subsection)
104
+
105
+ **Consistency checks:**
106
+ - "Concrete Node Types" table matches node shapes defined in `src/graph.ts`
107
+ - "Node Field Mixins" table matches field groups in `src/graph.ts`
108
+ - Flag names match constants in `src/graph.ts`
109
+ - Each signal type subsection describes current internal composition and lifecycle
110
+ - No subsection references a removed type, flag, or function
111
+ </ARCHITECTURE_md>
112
+
113
+ <CLAUDE_md>
114
+ **Path:** `CLAUDE.md`
115
+ **Audience:** Claude (this model) at inference time
116
+ **Register:** Terse, direct, AI-optimized — every token has a cost; no explanatory padding
117
+ **Scope:** Spreadsheet-cell mental model for all 9 signal types; internal node shapes and the
118
+ `activeSink`/`activeOwner` dual-pointer model; non-obvious behaviors that a competent reactive
119
+ developer would not predict from the public API alone
120
+
121
+ **Update triggers:**
122
+ - A signal type is added (extend the mental model list and node shapes)
123
+ - Internal node shapes change (`src/graph.ts` field composition)
124
+ - `activeSink` or `activeOwner` semantics change
125
+ - A non-obvious behavior is introduced, changed, or resolved
126
+ - An existing non-obvious behavior entry becomes inaccurate
127
+
128
+ **Consistency checks:**
129
+ - Mental model list covers all 9 signal types
130
+ - Internal Node Shapes block matches `src/graph.ts`
131
+ - `activeOwner`/`activeSink` description is accurate
132
+ - Every non-obvious behavior entry is still correct for the current implementation
133
+ - No entry describes behavior that has since changed or been removed
134
+ </CLAUDE_md>
135
+
136
+ <copilot_instructions_md>
137
+ **Path:** `.github/copilot-instructions.md`
138
+ **Audience:** GitHub Copilot during code generation
139
+ **Register:** Structured, pattern-oriented — code examples are generation templates, not prose
140
+ **Scope:** Project overview, core architecture summary (node types, edge structure, graph
141
+ operations, flags), signal type descriptions with factory names, key file paths, coding
142
+ conventions (TypeScript style, naming, error handling, performance patterns), API design
143
+ principles, common code patterns (signal creation, reactivity, type safety, resource
144
+ management), build system
145
+
146
+ **Update triggers:**
147
+ - A new signal type is added (add to signal types list, key files, and code patterns)
148
+ - A factory function signature changes (update the corresponding code pattern)
149
+ - A node type or flag is added, renamed, or removed (update Core Architecture section)
150
+ - A new source file is added to `src/` (update Key Files Structure)
151
+ - A coding convention or API design principle changes
152
+ - A new common code pattern is established
153
+
154
+ **Consistency checks:**
155
+ - Signal Types list covers all 9 signal types with accurate factory name and one-line
156
+ description
157
+ - Key Files Structure lists all current `src/` and `src/nodes/` files
158
+ - Code patterns in "Common Code Patterns" use current factory signatures and option names —
159
+ verify each against `index.ts`
160
+ - API Design Principles accurately describe current conventions
161
+ - Core Architecture node types and flags match `src/graph.ts`
162
+ </copilot_instructions_md>
163
+
164
+ <jsdoc_in_src>
165
+ **Path:** `src/nodes/*.ts`, `src/graph.ts`, `src/errors.ts`, `src/util.ts`, `src/signal.ts`
166
+ **Audience:** IDE users (hover documentation), API consumers reading source
167
+ **Register:** Brief, typed, precise — one-line summaries; `@param`/`@returns` only
168
+ **Scope:** Public API functions and their parameters, return values, and non-obvious
169
+ constraints. Internal helpers do not require JSDoc.
170
+
171
+ **Update triggers:**
172
+ - A public function's parameter is added, removed, renamed, or retyped
173
+ - A public function's return value or semantics change
174
+ - A public function is removed (remove its JSDoc block with it)
175
+
176
+ **Consistency checks (spot-check):**
177
+ - `@param` names match current parameter names in the function signature
178
+ - `@returns` descriptions match current return type semantics
179
+ - No `@param` tags reference removed parameters
180
+ - No `@example` blocks use deprecated API
181
+ </jsdoc_in_src>
182
+
183
+ </documents>
184
+
185
+ <change_to_document_matrix>
186
+ Quick reference for update-after-change.md. Use this to identify affected documents.
187
+
188
+ | Change type | JSDoc | ARCH | CLAUDE + copilot | README | GUIDE | REQ |
189
+ |------------------------------------|-------|------|------------------|--------|-------|-----|
190
+ | New signal type | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ * |
191
+ | Changed public signature / option | ✓ | — | ✓ if behavior | ✓ | ✓ if mental model | — |
192
+ | Removed public API | ✓ | ✓ if structural | ✓ | ✓ | ✓ if documented | — |
193
+ | New / changed non-obvious behavior | — | ✓ if graph-level | ✓ | ✓ if affects usage | — | — |
194
+ | Internal implementation change | — | ✓ | ✓ | — | — | — |
195
+ | Vision / scope / constraint change | — | — | — | — | — | ✓ |
196
+
197
+ \* For REQUIREMENTS.md: only the signal type table row. Not the prose count — update
198
+ that to match automatically.
199
+ </change_to_document_matrix>
@@ -0,0 +1,189 @@
1
+ <overview>
2
+ Writing tone, register, and conciseness rules for each document maintained by the tech-writer
3
+ skill. Violating the tone is as wrong as a factual error — each document has a distinct
4
+ primary reader and serves a distinct purpose.
5
+ </overview>
6
+
7
+ <shared_rules>
8
+ These rules apply to every document without exception:
9
+
10
+ - **Concise over comprehensive.** Every sentence must add information the reader needs.
11
+ Cut throat-clearing, transitional padding, and restatements of what the code already
12
+ shows.
13
+ - **Technically accurate over reassuring.** Do not soften edge cases, paper over
14
+ constraints, or omit behavior that is surprising but correct.
15
+ - **No changelog language in documentation.** Documents state current truth. Never write
16
+ "previously", "as of version X", "we changed", or "now supports". Those belong in
17
+ CHANGELOG.md.
18
+ - **No meta-commentary.** Do not write "This section explains…" or "See below for…".
19
+ Say the thing directly.
20
+ - **Backtick all code.** Every API name, flag, file name, type name, option key, and
21
+ shell command is wrapped in backticks, even mid-sentence.
22
+ </shared_rules>
23
+
24
+ <README>
25
+ **Primary audience:** Developers integrating `@zeix/cause-effect` into a project.
26
+ They know TypeScript and have used reactive libraries before.
27
+
28
+ **Register:** Instructional. Direct address ("use `createTask` when…"). Present tense.
29
+ Active voice. Short sentences in prose; examples do the heavy lifting.
30
+
31
+ **Structure rules:**
32
+ - Each `### SignalType` section: one short paragraph describing what the signal is for,
33
+ then the signature, then options, then example(s). Description first — don't open with
34
+ the signature.
35
+ - Options tables: one row per option. "Description" column is one line; if it needs more,
36
+ the option is complex enough to warrant a prose sentence below the table instead.
37
+ - Examples: realistic, not trivial. Show actual usage patterns, not `const x = createState(0)`.
38
+ Prefer examples that demonstrate the signal's distinctive behavior.
39
+
40
+ **What to cut:**
41
+ - Explanations of TypeScript concepts the reader already knows
42
+ - Warnings about things the type system already prevents
43
+ - Motivational framing ("This is useful when you need to…")
44
+ </README>
45
+
46
+ <GUIDE>
47
+ **Primary audience:** Developers migrating from React, Vue, or Angular who want to
48
+ understand where this library's concepts map to — and diverge from — what they already know.
49
+
50
+ **Register:** Comparative and educational. Assumes framework fluency; never assumes
51
+ knowledge of this library. Uses "if you've used X, this is like Y, except…" framing.
52
+ Approachable but never condescending.
53
+
54
+ **Structure rules:**
55
+ - Comparisons must be specific. Name the exact React hook, Vue function, or Angular
56
+ decorator being compared. Vague comparisons ("like in other frameworks") add no value.
57
+ - Divergences get more space than similarities. The reader can infer the familiar parts;
58
+ the non-obvious differences are why this section exists.
59
+ - Code examples: show both the framework equivalent and the cause-effect version side by
60
+ side when it aids comparison. Otherwise, cause-effect only.
61
+
62
+ **What to cut:**
63
+ - Explanations of how React/Vue/Angular work internally — assume the reader knows
64
+ - Repetition of content already in README.md — GUIDE.md is conceptual, not a reference
65
+ - Sections that say "this is the same as in other frameworks" without adding nuance
66
+ </GUIDE>
67
+
68
+ <ARCHITECTURE>
69
+ **Primary audience:** Contributors to the library and AI agents that need to understand
70
+ internals to implement or review changes correctly.
71
+
72
+ **Register:** Technical and precise. Third person, present tense. Implementation details
73
+ are expected and welcome. Internal function names, type names, flag names, and field names
74
+ are used freely without definition — this document assumes the reader has the source open.
75
+
76
+ **Structure rules:**
77
+ - Describe mechanisms, not intentions. Not "this enables efficient updates" but "when
78
+ `propagate()` marks a node `FLAG_CHECK`, downstream nodes call `refresh()` before
79
+ deciding whether to recompute".
80
+ - Pseudocode and inline type definitions are appropriate when they make a structure clearer
81
+ than prose would. Match the actual source types exactly — do not simplify.
82
+ - Subsection depth: use the existing pattern (##, ###). Do not add new heading levels.
83
+
84
+ **What to cut:**
85
+ - Motivational framing ("The design optimizes for…") — state the mechanism, not the goal
86
+ - Public API description — that belongs in README.md
87
+ - Any sentence that could be replaced by reading the source directly
88
+ </ARCHITECTURE>
89
+
90
+ <CLAUDE_MD>
91
+ **Primary audience:** Claude (this model) at inference time. Every token has a cost.
92
+
93
+ **Register:** Terse, declarative, maximally dense. No hand-holding. No transitions.
94
+ Bold key terms. Bullet lists over prose. Code examples only when the correct pattern is
95
+ non-obvious from the statement.
96
+
97
+ **Structure rules:**
98
+ - Non-obvious behavior entries follow a strict three-part structure:
99
+ 1. **Bold statement** of the behavior — one sentence, declarative, specific.
100
+ 2. Implication or consequence — one or two sentences maximum.
101
+ 3. Code example — only if the correct pattern cannot be inferred from the statement.
102
+ Use before/after style (bad comment + good comment) only when the contrast is the point.
103
+ - The bar for "non-obvious": an experienced reactive developer would not predict this
104
+ behavior from the public API alone. If they would, it does not belong here.
105
+ - Internal names (`FLAG_CHECK`, `activeSink`, `trimSources`) are appropriate — Claude
106
+ can cross-reference ARCHITECTURE.md.
107
+
108
+ **What to cut:**
109
+ - Any sentence that restates what the bold statement already said
110
+ - Explanations of standard reactive concepts (memoization, lazy evaluation, dependency tracking)
111
+ - "Note that…", "Keep in mind…", "Be aware that…" — state it directly
112
+ - Examples that illustrate obvious correct usage; examples only for non-obvious patterns
113
+ </CLAUDE_MD>
114
+
115
+ <copilot_instructions>
116
+ **Primary audience:** GitHub Copilot during code generation. The document drives what
117
+ Copilot suggests as it completes function calls, option objects, and type annotations.
118
+
119
+ **Register:** Structured and pattern-oriented. Headers create anchors Copilot uses to
120
+ locate relevant context. Code blocks are generation templates — they must be complete,
121
+ compilable, and idiomatic.
122
+
123
+ **Structure rules:**
124
+ - Code patterns must compile against the current `index.ts`. Copilot generates from these
125
+ literally — a wrong parameter name or stale option key will be reproduced in generated code.
126
+ - Signal type descriptions: one line each in the format
127
+ `**Name** (\`createName\`): what it is and its key behavioral trait.`
128
+ - Do not use narrative prose in list items — use fragments that complete a pattern, not
129
+ sentences that explain one.
130
+
131
+ **What to cut:**
132
+ - Explanatory prose around code patterns — the pattern is self-documenting
133
+ - Options or parameters that are rarely used and not needed for the common case
134
+ - Duplication between sections (e.g. do not describe `createTask` in both "Signal Types"
135
+ and again identically in "Common Code Patterns")
136
+ </copilot_instructions>
137
+
138
+ <REQUIREMENTS>
139
+ **Primary audience:** Stakeholders, contributors, and future maintainers who need to
140
+ understand the library's purpose and boundaries. This document is read infrequently and
141
+ must remain accurate over many versions.
142
+
143
+ **Register:** Formal, strategic, timeless. Third person. Noun phrases over verb phrases
144
+ where possible ("The library is deliberately not a framework" rather than "We decided not
145
+ to make this a framework"). No version-specific language except in "Stability".
146
+
147
+ **Structure rules:**
148
+ - Tables state facts as rows — they do not tell a story. Each row is self-contained.
149
+ - "Non-Goals" entries are one bold heading + one sentence. The heading names the thing
150
+ that is out of scope; the sentence says why or what to do instead. No more.
151
+ - "Stability" is the only section that may reference specific version numbers. All other
152
+ sections describe the library as it is, not how it got there.
153
+
154
+ **What to cut:**
155
+ - Rationale for decisions that were obvious or uncontroversial — if it needs defending,
156
+ add one sentence; otherwise state the fact
157
+ - Historical context ("this was added because…")
158
+ - Implementation detail — REQUIREMENTS.md describes goals, not mechanisms
159
+ </REQUIREMENTS>
160
+
161
+ <jsdoc>
162
+ **Primary audience:** Developers reading function signatures in an IDE or in generated
163
+ API documentation. They see the JSDoc in a tooltip or a docs page alongside the TypeScript
164
+ signature.
165
+
166
+ **Register:** Brief, typed, precise. One-line summaries. No narrative. Fragments are
167
+ acceptable if they read naturally as a tooltip.
168
+
169
+ **Structure rules:**
170
+ - Summary line: one line. Describes what the function does, not what it is.
171
+ "Creates a mutable reactive signal." not "A factory function for State signals."
172
+ - `@param` tags: one line each. Describe semantics and constraints, not the TypeScript
173
+ type (the type is already visible in the signature). For options objects, document only
174
+ options whose behavior is non-obvious.
175
+ - `@returns`: one line. What is returned and any non-obvious guarantee
176
+ (e.g. "Always non-nullish per `T extends {}`").
177
+ - `@throws`: only for errors that can occur in correct, non-erroneous usage. Do not
178
+ document programmer-error throws (`RequiredOwnerError`, `InvalidCallbackError`,
179
+ `CircularDependencyError`) — they indicate a coding mistake, not a handled condition.
180
+ - `@example`: only if the usage pattern is so non-obvious that a developer would misuse
181
+ the function without it. Examples live primarily in README.md.
182
+
183
+ **What to cut:**
184
+ - `@param type` annotations — TypeScript already shows the type
185
+ - JSDoc that restates the TypeScript signature in prose
186
+ - Generic descriptions that would apply to any function ("Creates and returns a…")
187
+ - Multi-paragraph descriptions — if it needs that much explanation, the API design may
188
+ need review
189
+ </jsdoc>