@nurix/etna 0.1.3 → 0.2.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.
Files changed (30) hide show
  1. package/README.md +35 -26
  2. package/bin/etna.js +82 -56
  3. package/data/harness-index.json +0 -7
  4. package/data/harnesses/code/agents/change-review.md +80 -0
  5. package/data/harnesses/code/agents/contract-monitor.md +65 -0
  6. package/data/harnesses/code/agents/dep-health.md +148 -0
  7. package/data/harnesses/code/agents/git-history.md +201 -0
  8. package/data/harnesses/code/agents/maintenance.md +112 -0
  9. package/data/harnesses/code/agents/review.md +109 -0
  10. package/data/harnesses/code/agents/spec-mode.md +56 -0
  11. package/data/harnesses/code/rules/general.md +96 -0
  12. package/data/harnesses/code/rules/nomenclature.md +34 -0
  13. package/data/harnesses/code/scripts/build-ownership-index.sh +138 -0
  14. package/data/harnesses/code/scripts/check-doc-drift.sh +125 -0
  15. package/data/harnesses/code/skills/documentation/SKILL.md +238 -0
  16. package/data/harnesses/code/skills/documentation/references/examples.md +193 -0
  17. package/data/harnesses/code/skills/documentation/references/style-guide.md +288 -0
  18. package/data/harnesses/code/skills/documentation/references/templates.md +901 -0
  19. package/data/harnesses/code/skills/introspect/SKILL.md +135 -0
  20. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +430 -0
  21. package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +214 -0
  22. package/data/harnesses/kb-agi/agents/kb-agi-init.md +276 -0
  23. package/data/harnesses/kb-agi/agents/kb-catch-stale.md +22 -0
  24. package/data/harnesses/kb-agi/agents/kb-find-gaps.md +27 -0
  25. package/data/harnesses/kb-agi/agents/kb-fix-links.md +22 -0
  26. package/data/harnesses/kb-agi/agents/kb-refresh-frontdoor.md +22 -0
  27. package/data/harnesses/kb-agi/agents/kb-refresh-summaries.md +22 -0
  28. package/data/harnesses/kb-agi/agents/kb-sync-metadata.md +25 -0
  29. package/data/harnesses/kb-agi/rules/kb.md +13 -0
  30. package/package.json +1 -1
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env bash
2
+ # scripts/build-ownership-index.sh - Generate docs/OWNERSHIP_INDEX.md from feature doc frontmatter
3
+
4
+ set -euo pipefail
5
+
6
+ REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
7
+ OUTPUT="$REPO_ROOT/docs/OWNERSHIP_INDEX.md"
8
+ FEATURES_DIR="$REPO_ROOT/docs/features"
9
+ TMP_OWNS=$(mktemp)
10
+ TMP_DEPS=$(mktemp)
11
+ TMP_DIRS=$(mktemp)
12
+ trap 'rm -f "$TMP_OWNS" "$TMP_DEPS" "$TMP_DIRS"' EXIT
13
+
14
+ # Extract YAML frontmatter list field values from a markdown file
15
+ extract_field() {
16
+ local file="$1" field="$2"
17
+ awk -v field="$field" '
18
+ /^---$/ { fm++; next }
19
+ fm == 1 && $0 ~ "^"field":" {
20
+ in_field = 1
21
+ sub("^"field":[ ]*", "")
22
+ if ($0 != "" && $0 !~ /^\[/) { print $0; in_field = 0 }
23
+ next
24
+ }
25
+ fm == 1 && in_field && /^ +- / {
26
+ sub("^ +- ", "")
27
+ gsub(/^[ \t]+|[ \t]+$/, "")
28
+ print
29
+ next
30
+ }
31
+ fm == 1 && in_field && /^[a-z]/ { in_field = 0 }
32
+ fm == 1 && in_field && /^---$/ { in_field = 0 }
33
+ fm >= 2 { exit }
34
+ ' "$file"
35
+ }
36
+
37
+ # Collect ownership and dependency data from all feature docs
38
+ find "$FEATURES_DIR" -name "*.md" ! -name "README.md" -print0 | sort -z | while IFS= read -r -d '' file; do
39
+ rel_path="${file#$REPO_ROOT/}"
40
+
41
+ extract_field "$file" "owns" | while IFS= read -r pattern; do
42
+ [ -z "$pattern" ] && continue
43
+ printf '%s\t%s\n' "$pattern" "$rel_path" >> "$TMP_OWNS"
44
+ done
45
+
46
+ deps=$(extract_field "$file" "depends_on" | tr '\n' ', ' | sed 's/,$//' | sed 's/, $//')
47
+ if [ -n "$deps" ]; then
48
+ printf '%s\t%s\n' "$rel_path" "$deps" >> "$TMP_DEPS"
49
+ fi
50
+ done
51
+
52
+ # Collect owned directory prefixes for unowned path detection
53
+ sed 's|/\*\*$||; s|/\*$||; s|/[^/]*$||' "$TMP_OWNS" | awk -F'\t' '{ print $1 }' | sort -u > "$TMP_DIRS"
54
+
55
+ # Find unowned src/ directories
56
+ unowned=""
57
+ if [ -d "$REPO_ROOT/src" ]; then
58
+ for dir in "$REPO_ROOT"/src/*/; do
59
+ [ -d "$dir" ] || continue
60
+ rel_dir="${dir#$REPO_ROOT/}"
61
+ rel_dir="${rel_dir%/}"
62
+ is_owned=0
63
+ while IFS= read -r owned; do
64
+ case "$rel_dir" in
65
+ "$owned"*) is_owned=1; break ;;
66
+ esac
67
+ case "$owned" in
68
+ "$rel_dir"*) is_owned=1; break ;;
69
+ esac
70
+ done < "$TMP_DIRS"
71
+ if [ "$is_owned" -eq 0 ]; then
72
+ unowned="${unowned}- \`${rel_dir}\`
73
+ "
74
+ fi
75
+ done
76
+ fi
77
+
78
+ # Generate output
79
+ cat > "$OUTPUT" << 'HEADER'
80
+ # Ownership Index
81
+
82
+ > **Generated file** — do not edit manually.
83
+ > Regenerate with: `bash scripts/build-ownership-index.sh`
84
+
85
+ Machine-readable lookup table generated from feature doc frontmatter.
86
+
87
+ ---
88
+
89
+ ## By Code Path
90
+
91
+ | Code Path | Owning Doc |
92
+ |---|---|
93
+ HEADER
94
+
95
+ sort "$TMP_OWNS" | while IFS=$'\t' read -r pattern doc; do
96
+ echo "| \`$pattern\` | \`$doc\` |" >> "$OUTPUT"
97
+ done
98
+
99
+ cat >> "$OUTPUT" << 'SECTION'
100
+
101
+ ---
102
+
103
+ ## Unowned Paths
104
+
105
+ Top-level `src/` directories with no owning feature doc:
106
+
107
+ SECTION
108
+
109
+ if [ -z "$unowned" ]; then
110
+ echo "_All top-level src/ directories have owners._" >> "$OUTPUT"
111
+ else
112
+ printf '%s' "$unowned" >> "$OUTPUT"
113
+ fi
114
+
115
+ cat >> "$OUTPUT" << 'SECTION'
116
+
117
+ ---
118
+
119
+ ## Dependency Graph
120
+
121
+ Feature docs and their declared `depends_on` relationships:
122
+
123
+ | Feature Doc | Depends On |
124
+ |---|---|
125
+ SECTION
126
+
127
+ if [ -s "$TMP_DEPS" ]; then
128
+ sort "$TMP_DEPS" | while IFS=$'\t' read -r doc deps; do
129
+ echo "| \`$doc\` | $deps |" >> "$OUTPUT"
130
+ done
131
+ fi
132
+
133
+ echo "" >> "$OUTPUT"
134
+ echo "---" >> "$OUTPUT"
135
+ echo "" >> "$OUTPUT"
136
+ echo "_Generated: $(date -u '+%Y-%m-%d %H:%M UTC')_" >> "$OUTPUT"
137
+
138
+ echo "Generated $OUTPUT"
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env bash
2
+ # scripts/check-doc-drift.sh - Detect potentially stale docs based on recent code changes
3
+
4
+ set -euo pipefail
5
+
6
+ DAYS="${1:-14}"
7
+ REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
8
+ FEATURES_DIR="$REPO_ROOT/docs/features"
9
+ TMP_OWNS=$(mktemp)
10
+ TMP_STALE=$(mktemp)
11
+ TMP_UNOWNED=$(mktemp)
12
+ trap 'rm -f "$TMP_OWNS" "$TMP_STALE" "$TMP_UNOWNED"' EXIT
13
+
14
+ echo "Checking for doc drift over the last $DAYS days..."
15
+ echo ""
16
+
17
+ # Extract owns patterns from a markdown file
18
+ extract_owns() {
19
+ local file="$1"
20
+ awk '
21
+ /^---$/ { fm++; next }
22
+ fm == 1 && /^owns:/ { in_owns = 1; next }
23
+ fm == 1 && in_owns && /^ +- / {
24
+ sub("^ +- ", "")
25
+ gsub(/^[ \t]+|[ \t]+$/, "")
26
+ print
27
+ next
28
+ }
29
+ fm == 1 && in_owns && /^[a-z]/ { exit }
30
+ fm >= 2 { exit }
31
+ ' "$file"
32
+ }
33
+
34
+ # Get recently changed files
35
+ changed_files=$(cd "$REPO_ROOT" && git log --since="$DAYS days ago" --name-only --pretty=format:"" | sort -u | grep -v '^$' || true)
36
+
37
+ if [ -z "$changed_files" ]; then
38
+ echo "No files changed in the last $DAYS days."
39
+ exit 0
40
+ fi
41
+
42
+ changed_count=$(echo "$changed_files" | wc -l | tr -d ' ')
43
+ echo "Found $changed_count changed files in the last $DAYS days."
44
+ echo ""
45
+
46
+ # Build ownership map: pattern\tdoc
47
+ find "$FEATURES_DIR" -name "*.md" ! -name "README.md" -print0 | sort -z | while IFS= read -r -d '' file; do
48
+ rel_path="${file#$REPO_ROOT/}"
49
+ extract_owns "$file" | while IFS= read -r pattern; do
50
+ [ -z "$pattern" ] && continue
51
+ printf '%s\t%s\n' "$pattern" "$rel_path" >> "$TMP_OWNS"
52
+ done
53
+ done
54
+
55
+ # Check each changed file against ownership
56
+ echo "$changed_files" | while IFS= read -r changed_file; do
57
+ [ -z "$changed_file" ] && continue
58
+ # Skip non-source files
59
+ case "$changed_file" in
60
+ docs/*|.claude/*|.github/*|node_modules/*|package*.json|*.lock*|*.config*) continue ;;
61
+ esac
62
+
63
+ found_owner=0
64
+ while IFS=$'\t' read -r pattern doc; do
65
+ prefix="${pattern%%\*\**}"
66
+ prefix="${prefix%%\**}"
67
+ case "$changed_file" in
68
+ ${prefix}*)
69
+ found_owner=1
70
+ # Check if the doc was also modified recently
71
+ if ! echo "$changed_files" | grep -q "^${doc}$"; then
72
+ printf '%s\t%s\n' "$doc" "$changed_file" >> "$TMP_STALE"
73
+ fi
74
+ break
75
+ ;;
76
+ esac
77
+ done < "$TMP_OWNS"
78
+
79
+ if [ "$found_owner" -eq 0 ]; then
80
+ case "$changed_file" in
81
+ src/*|app/*|packages/*) echo "$changed_file" >> "$TMP_UNOWNED" ;;
82
+ esac
83
+ fi
84
+ done
85
+
86
+ # Report stale docs
87
+ if [ -s "$TMP_STALE" ]; then
88
+ echo "## Potentially Stale Docs"
89
+ echo ""
90
+ echo "These docs own code that changed recently, but the docs themselves were not updated:"
91
+ echo ""
92
+ current_doc=""
93
+ sort "$TMP_STALE" | while IFS=$'\t' read -r doc file; do
94
+ if [ "$doc" != "$current_doc" ]; then
95
+ [ -n "$current_doc" ] && echo ""
96
+ echo "**$doc**"
97
+ current_doc="$doc"
98
+ fi
99
+ echo " - $file"
100
+ done
101
+ echo ""
102
+ else
103
+ echo "## No Stale Docs Detected"
104
+ echo ""
105
+ echo "All docs whose owned code changed were also updated."
106
+ fi
107
+
108
+ echo ""
109
+
110
+ # Report unowned files
111
+ if [ -s "$TMP_UNOWNED" ]; then
112
+ unowned_count=$(wc -l < "$TMP_UNOWNED" | tr -d ' ')
113
+ echo "## Unowned Changed Files ($unowned_count)"
114
+ echo ""
115
+ echo "These changed source files have no owning feature doc:"
116
+ echo ""
117
+ sort -u "$TMP_UNOWNED" | head -30 | while IFS= read -r file; do
118
+ echo "- $file"
119
+ done
120
+ if [ "$unowned_count" -gt 30 ]; then
121
+ echo "- ... and $((unowned_count - 30)) more"
122
+ fi
123
+ else
124
+ echo "## No Unowned Changed Files"
125
+ fi
@@ -0,0 +1,238 @@
1
+ ---
2
+ name: documentation
3
+ description: Create and maintain technical documentation. Use when the user asks to (1) baseline, audit, or reorganize docs — enforces an opinionated 6-folder structure (architecture, features, operations, history, memory, tests) with ownership frontmatter and scaffold files, (2) document a feature or module, (3) create or update a changelog entry, (4) document data flows or Redux state, (5) add to protected files, (6) create or update guardrails (cascading failure boundaries), (7) record an architecture decision (ADR), (8) create or update the project root README, (9) create or update a plan, or (10) co-author any technical doc. Triggers on "document this", "create docs", "update changelog", "baseline docs", "audit docs", "add to protected files", "guardrails", "ADR", "architecture decision", "root README", "plan".
4
+ ---
5
+
6
+ # Technical Documentation Skill
7
+
8
+ Document contracts and architecture, not implementation details. Show function signatures and API shapes — never paste full implementations (they rot fast). Use ASCII diagrams over prose for flows. Only document state at persistence boundaries (Redux persistence, DB schemas, API shapes), not component-level or transient state. Mark deprecated fields with `// UNUSED:` comments. Breaking changes belong in changelogs only, not module docs.
9
+
10
+ **No redirect docs.** When moving a doc to a new location, delete the old file entirely. Update all references (routing, ownership index, memory files, frontmatter `depends_on`, cross-doc links) to point to the new path. Never leave a stub file that says "Moved to X" — redirect docs rot, clutter the repo, and create false search hits.
11
+
12
+ ---
13
+
14
+ ## Decision Tree
15
+
16
+ ```
17
+ User request
18
+ │
19
+ ├─ "Baseline/audit docs" ──────────▶ Baseline Audit (below)
20
+ │
21
+ ├─ "Document feature/module" ──────▶ Module Template
22
+ │
23
+ ├─ "Create/update changelog" ──────▶ Changelog Template
24
+ │
25
+ ├─ "Document data flow" ───────────▶ Module Template (Architecture section)
26
+ │
27
+ ├─ "Document Redux/state" ─────────▶ Module Template (State section)
28
+ │
29
+ ├─ "Add to protected files" ───────▶ Protected Files Template
30
+ │
31
+ ├─ "Create/update guardrails" ─────▶ Guardrails Template
32
+ │
33
+ ├─ "Record architecture decision" ─▶ ADR Template
34
+ │
35
+ ├─ "Create/update root README" ────▶ Project Root README Template
36
+ │
37
+ ├─ "Create/update plan" ───────────▶ Plan Template
38
+ │
39
+ ├─ "Update existing doc" ──────────▶ Preserve existing structure
40
+ │
41
+ └─ No template matches ────────────▶ Co-Authoring Workflow (below)
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Baseline Audit
47
+
48
+ When asked to "baseline", "audit", or "review" docs, enforce the canonical 6-folder documentation structure. This is an opinionated reorganization — the target structure is non-negotiable.
49
+
50
+ ### Target Structure
51
+
52
+ ```
53
+ docs/
54
+ ├── README.md # Documentation root — quick links table, section index
55
+ ├── structure.md # Authority map, folder rules, health log
56
+ ├── CODEBASE_MAP.md # Auto-generated directory map (optional)
57
+ ├── faq.md # Common issues (optional)
58
+ ├── architecture/ # System-wide decisions, patterns, technical references
59
+ │ ├── adr/ # Architecture Decision Records (numbered, immutable)
60
+ │ └── core/ # Core module internals (auth, state, routing)
61
+ ├── features/ # Living feature specs with ownership frontmatter
62
+ │ └── {feature}/ # Subfolder for deep features (e.g., editor/)
63
+ ├── operations/ # Setup, development, deployment, CI/CD
64
+ │ └── guardrails.md # Cascading failure boundaries (cross-module contracts)
65
+ ├── history/ # Frozen/append-only records
66
+ │ ├── CHANGELOG.md # Master changelog index
67
+ │ ├── changelog/ # Individual changelog entries
68
+ │ ├── plans/ # Historical implementation plans (Status field required)
69
+ │ └── backlog.md # Tracked work items by priority (P0-P3)
70
+ ├── memory/ # Agent memory files
71
+ └── tests/ # Test plans and automation docs (optional)
72
+ ```
73
+
74
+ ### Workflow
75
+
76
+ **Step 1: Inventory existing docs**
77
+
78
+ Glob all markdown files in the repo. Categorize each file:
79
+
80
+ | Category | Matches | Target |
81
+ |----------|---------|--------|
82
+ | Architecture | System design, patterns, config, API specs, tech decisions | `docs/architecture/` |
83
+ | Features | How a feature works, user-facing behavior, data models | `docs/features/` |
84
+ | Operations | Setup, dev workflow, deployment, CI/CD, runbooks | `docs/operations/` |
85
+ | Plans | Implementation plans, proposals, RFCs | `docs/history/plans/` |
86
+ | Changelogs | Change records, release notes | `docs/history/changelog/` |
87
+ | Backlogs/Tasks | Work items, TODOs, tech debt | Merge into `docs/history/backlog.md` |
88
+ | Stale/Deprecated | Self-marked deprecated, fully superseded, empty docs | Delete |
89
+ | Root docs | `README.md`, `CLAUDE.md`, `AGENTS.md` | Stay in root |
90
+
91
+ **Step 2: Detect duplicates and overlaps**
92
+
93
+ For each topic, identify all files covering it. Keep the most complete version as canonical. Extract unique content from others before deleting.
94
+
95
+ **Step 3: Present reorganization plan**
96
+
97
+ Present a table to the user:
98
+
99
+ ```
100
+ | File | Action | From | To | Reason |
101
+ ```
102
+
103
+ Actions: `Move`, `Merge into {target}`, `Delete`, `Keep`, `Create`
104
+
105
+ Ask: "Approve this plan? I'll execute all moves, merges, and deletions."
106
+
107
+ **Step 4: Execute reorganization**
108
+
109
+ After approval:
110
+
111
+ 1. Create the full folder structure:
112
+ - `docs/architecture/`
113
+ - `docs/features/`
114
+ - `docs/operations/`
115
+ - `docs/history/plans/`
116
+ - `docs/history/changelog/`
117
+ - `docs/memory/`
118
+ - `docs/tests/` (if test docs exist)
119
+ 2. Move files per the plan
120
+ 3. Merge content where specified (extract unique content, append to target)
121
+ 4. Delete stale/superseded files
122
+ 5. Add `Status: Complete | In Progress | Draft | Abandoned` to all plan files
123
+ 6. Add YAML frontmatter to feature docs (see Frontmatter Derivation below)
124
+ 7. Merge scattered backlog/task files into `docs/history/backlog.md`
125
+ 8. Scaffold standard files if missing:
126
+ - `docs/README.md` — from template (see `references/templates.md`)
127
+ - `docs/structure.md` — from template (see `references/templates.md`)
128
+ - `docs/operations/guardrails.md` — cascading failure boundaries (see `references/templates.md` for what to include/exclude)
129
+ - `docs/history/CHANGELOG.md` — master changelog index (header + table linking to entries)
130
+ - `docs/history/backlog.md` — work items by priority (P0-P3 sections, empty if nothing to merge)
131
+ - `docs/memory/index.md` — agent memory index (empty scaffold with section headers)
132
+ - `docs/memory/main.md` — main agent project memory (empty header + date marker)
133
+ - `docs/OWNERSHIP_INDEX.md` — generated table of feature doc ownership. Build it now from the frontmatter you derived in Step 6 (same shape the maintenance agent regenerates each run — see `references/templates.md`)
134
+ - `README.md` (repo root) — from §11 in `references/templates.md`, filled with concrete details from the repo (real package manager from the lockfile, real scripts, real layout). **Never overwrite an existing root README** — if one is present, leave it untouched.
135
+ 9. Fix all internal links broken by moves
136
+ 10. Record baseline in `docs/memory/index.md` with today's date (see template)
137
+
138
+ **Step 5: Verify**
139
+
140
+ 1. Confirm all standard files exist: `docs/README.md`, `docs/structure.md`, `docs/operations/guardrails.md`, `docs/history/CHANGELOG.md`, `docs/history/backlog.md`, `docs/memory/index.md`, `docs/memory/main.md`, `docs/OWNERSHIP_INDEX.md`, `README.md` (repo root — must exist; either pre-existing untouched or freshly scaffolded)
141
+ 2. Confirm no dead links in `docs/README.md`
142
+ 3. Confirm every plan file has a `Status:` field
143
+ 4. Confirm feature docs have ownership frontmatter
144
+ 5. Confirm `docs/OWNERSHIP_INDEX.md` rows match the frontmatter on disk (no orphans, no missing entries)
145
+ 6. Confirm no docs remain outside the 6-folder structure (except `README.md`, `structure.md`, `CODEBASE_MAP.md`, `faq.md`)
146
+ 7. Confirm duplicates are eliminated — each topic has one canonical source
147
+
148
+ ### Rules
149
+
150
+ - The 6-folder structure is mandatory. No `docs/guides/`, `docs/core/`, `docs/editor/`, `docs/pt/`, or any other top-level folder
151
+ - Guides about how-to-run → `operations/`. Guides about a feature → `features/`
152
+ - Core module docs → `docs/architecture/core/`. Editor module docs → `docs/features/editor/`
153
+ - Only `CLAUDE.md`, `AGENTS.md`, and `README.md` are allowed in the repository root (not inside `docs/`)
154
+ - Root-level `README.md` is for humans. `docs/README.md` is the agent/doc entry point
155
+ - One canonical source per topic — link, don't copy
156
+ - **No redirect docs** — when moving a file, delete the original and fix all references. Never leave a "Moved to X" stub.
157
+ - For 10+ files, use parallel sub-agents (5-8 files each)
158
+
159
+ ### Naming & Lifecycle
160
+
161
+ - Features: `kebab-case.md` — living reference, status `Active`
162
+ - Plans: `YYYY-MM-DD-kebab-case.md` — frozen after `Complete` or `Abandoned`
163
+ - Changelogs: `YYYY-MM-DD-kebab-case.md` — append-only
164
+ - Memory: `{agent-name}.md` — agent-maintained
165
+
166
+ ---
167
+
168
+ ## Frontmatter Derivation
169
+
170
+ When creating or updating a feature doc in `docs/features/`, generate `owns`, `touches`, `depends_on` frontmatter from the source code the doc describes.
171
+
172
+ ### When to run
173
+
174
+ - **Baseline audit Step 6** — for every feature doc missing frontmatter
175
+ - **New feature doc** — when creating a doc via the Module Documentation template
176
+ - **Doc update** — when updating an existing feature doc and the frontmatter is missing or the documented scope changed
177
+
178
+ ### How to derive values
179
+
180
+ **1. Identify `owns` patterns**
181
+
182
+ Read the feature doc's content. Extract every source file path referenced in the doc (file listings, function locations, component paths). Group them into the narrowest glob patterns that cover all referenced files without overlapping other features.
183
+
184
+ | Doc references | `owns` pattern |
185
+ |---|---|
186
+ | Multiple files under one directory | `src/feature/**` |
187
+ | Specific files in a shared directory | List each file explicitly |
188
+ | A single entry-point file | The exact file path |
189
+
190
+ Verify patterns match real files — glob each pattern against the codebase. Remove any that match nothing.
191
+
192
+ **2. Identify `touches` patterns**
193
+
194
+ From the same source files the doc describes, find imports and calls to code outside the `owns` scope. These are files the feature uses but doesn't own.
195
+
196
+ Common `touches` candidates:
197
+ - Shared Redux slices the feature reads/writes
198
+ - Utility functions from other modules
199
+ - Shared hooks the feature calls
200
+ - API route files the feature's frontend calls
201
+
202
+ Keep `touches` to direct dependencies only — not transitive ones.
203
+
204
+ **3. Identify `depends_on` docs**
205
+
206
+ Check for explicit cross-references to other docs in `docs/features/` or `docs/architecture/`. Also check if the feature's `touches` paths are `owns`-ed by another feature doc — that doc is a dependency.
207
+
208
+ ### Rules
209
+
210
+ - Every feature doc must have all three fields, even if empty (`depends_on: []`)
211
+ - Use glob patterns for directories, explicit paths for individual files
212
+ - Don't list paths that don't exist in the codebase
213
+ - When a doc covers a deep feature with sub-specs (e.g., `editor/`), each sub-spec gets its own frontmatter — don't duplicate ownership across siblings
214
+ - For baseline audits with 10+ files needing frontmatter, use parallel sub-agents to read and analyze the source files
215
+
216
+ ---
217
+
218
+ ## Co-Authoring Workflow
219
+
220
+ For docs that don't match templates:
221
+
222
+ **Stage 1: Context Gathering**
223
+ - Ask: Audience? Purpose? Existing format?
224
+ - Have user dump all context, then ask 5-10 clarifying questions
225
+
226
+ **Stage 2: Structure & Draft**
227
+ - Propose section structure, draft section by section
228
+ - User indicates changes (don't edit directly — learn their style)
229
+
230
+ ---
231
+
232
+ ## Resources
233
+
234
+ | File | Use For |
235
+ |------|---------|
236
+ | `references/templates.md` | docs/README.md, structure.md, frontmatter, scaffolds (CHANGELOG, backlog, memory, OWNERSHIP_INDEX), guardrails, feature, changelog, plan, protected files, ADR, project root README templates |
237
+ | `references/style-guide.md` | Writing rules, formatting conventions |
238
+ | `references/examples.md` | Good vs bad documentation examples |
@@ -0,0 +1,193 @@
1
+ # Documentation Examples
2
+
3
+ Good vs bad examples showing the key differences.
4
+
5
+ ---
6
+
7
+ ## Example 1: Function Documentation
8
+
9
+ ### ❌ Bad: Full Implementation
10
+
11
+ ```markdown
12
+ ### mergeData
13
+
14
+ function mergeData(server, local, changes) {
15
+ const result = {};
16
+ const serverMap = new Map(server.map((i) => [i.id, i]));
17
+ // ... 30 more lines
18
+ return result;
19
+ }
20
+ ```
21
+
22
+ **Problems:** Will become obsolete, focuses on HOW not WHAT.
23
+
24
+ ### ✅ Good: Contract Only
25
+
26
+ ```markdown
27
+ ### `mergeData(serverData, localData, changes)`
28
+
29
+ **Goal:** Merge server data with local changes
30
+ **Input:**
31
+
32
+ - `serverData` (array) - Fresh from API
33
+ - `localData` (array) - Current state
34
+ - `changes` (object) - `{ added, updated, removed }`
35
+ **Output:** `{ merged: array, conflicts: array }`
36
+
37
+ **Merge Rules:**
38
+
39
+ - Server wins for conflicts
40
+ - Local additions preserved
41
+ - Local removals marked as intent
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Example 2: State Documentation
47
+
48
+ ### ❌ Bad: State Everywhere
49
+
50
+ ```markdown
51
+ ## Component State
52
+
53
+ const [items, setItems] = useState([]);
54
+
55
+ ## Hook State
56
+
57
+ { data: items, isLoading: loading, error: null }
58
+
59
+ ## Redux State
60
+
61
+ { items: [], loading: false, error: null }
62
+ ```
63
+
64
+ **Problems:** Documents transient state, repeats shapes.
65
+
66
+ ### ✅ Good: Persistence Points Only
67
+
68
+ ```markdown
69
+ ## State
70
+
71
+ **Frontend (at persistence):**
72
+ {
73
+ "data": [],
74
+ "changes": { "added": [], "updated": [], "removed": [] }
75
+ // "cache": {} // UNUSED: Deprecated
76
+ }
77
+
78
+ **Storage:** localStorage `app_state`
79
+
80
+ **Backend:**
81
+ model Item {
82
+ id String @id
83
+ data Json
84
+ }
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Example 3: Changelog
90
+
91
+ ### ❌ Bad: Vague
92
+
93
+ ```markdown
94
+ # 2025-01-05 - Updates
95
+
96
+ ## Changes
97
+
98
+ - Updated editor
99
+ - Fixed bugs
100
+ - Improved performance
101
+
102
+ ## Files
103
+
104
+ - Various files in src/
105
+ ```
106
+
107
+ ### ✅ Good: Function-Level Detail
108
+
109
+ ```markdown
110
+ # 2025-01-05 - Version-Based Merge
111
+
112
+ ## Summary
113
+
114
+ Replaced change-tracking merge with version-based conflict resolution.
115
+
116
+ ## Changes
117
+
118
+ ### Added
119
+
120
+ - `mergeAndDerive(server, local, versionsMatch, type)` in `src/utils/merge.js`
121
+ - Purpose: Single-pass merge with change detection
122
+ - Returns: `{ merged, changes }`
123
+
124
+ ### Modified
125
+
126
+ - `useDataSync()` in `src/hooks/useDataSync.js`
127
+ - Changed: Now compares versions before merge
128
+
129
+ ### Removed
130
+
131
+ - `deriveChanges()` from `src/utils/derive.js`
132
+ - Replaced by: Logic in `mergeAndDerive()`
133
+
134
+ ## Breaking Changes
135
+
136
+ ⚠️ **Merge behavior changed**
137
+
138
+ - Old: Local changes always preserved
139
+ - New: Local preserved only if versions match
140
+
141
+ ## Files Changed
142
+
143
+ - `src/hooks/useDataSync.js`
144
+ - `src/utils/merge.js`
145
+ - `src/utils/derive.js` (deleted)
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Example 4: Data Flow
151
+
152
+ ### ❌ Bad: Prose Description
153
+
154
+ ```markdown
155
+ When the page loads, the useAppInit hook calls the syncData function.
156
+ This function first fetches data from the server using the API. Then
157
+ it gets the local data from Redux. After that, it compares versions...
158
+ ```
159
+
160
+ ### ✅ Good: Diagram + Key Points
161
+
162
+ ```markdown
163
+ ## Data Flow
164
+
165
+ ┌─────────────────────────────────────────┐
166
+ │ DATA SYNC │
167
+ ├─────────────────────────────────────────┤
168
+ │ │
169
+ │ ┌──────┐ ┌──────┐ ┌──────┐ │
170
+ │ │Server│────▶│Merge │────▶│Redux │ │
171
+ │ │ API │ │ │ │Store │ │
172
+ │ └──────┘ └──────┘ └──────┘ │
173
+ │ │ │
174
+ │ ▼ │
175
+ │ Version Check │
176
+ │ │
177
+ └─────────────────────────────────────────┘
178
+
179
+ **Trigger:** `useAppInit()` on page load
180
+ **Version Rule:** Match → local wins, Mismatch → server wins
181
+ ```
182
+
183
+ ---
184
+
185
+ ## Quick Comparison
186
+
187
+ | Aspect | Bad | Good |
188
+ | ---------- | -------------------- | --------------------------- |
189
+ | Code | Full implementations | Signatures + contracts |
190
+ | State | Every occurrence | Persistence points only |
191
+ | Flows | Prose paragraphs | ASCII diagrams |
192
+ | Changelogs | "Updated X" | Function names + migrations |
193
+ | Length | 100+ lines | 20-40 lines |