@nurix/etna 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +34 -27
  2. package/bin/etna.js +82 -52
  3. package/data/harness-index.json +2 -8
  4. package/data/harnesses/code/CLAUDE.md +18 -9
  5. package/data/harnesses/code/agents/change-review.md +80 -0
  6. package/data/harnesses/code/agents/contract-monitor.md +65 -0
  7. package/data/harnesses/code/agents/dep-health.md +148 -0
  8. package/data/harnesses/code/agents/git-history.md +201 -0
  9. package/data/harnesses/code/agents/maintenance.md +112 -0
  10. package/data/harnesses/code/agents/review.md +109 -0
  11. package/data/harnesses/code/agents/spec-mode.md +56 -0
  12. package/data/harnesses/code/rules/general.md +96 -0
  13. package/data/harnesses/code/rules/nomenclature.md +34 -0
  14. package/data/harnesses/code/scripts/build-ownership-index.sh +138 -0
  15. package/data/harnesses/code/scripts/check-doc-drift.sh +125 -0
  16. package/data/harnesses/code/skills/documentation/SKILL.md +238 -0
  17. package/data/harnesses/code/skills/documentation/references/examples.md +193 -0
  18. package/data/harnesses/code/skills/documentation/references/style-guide.md +288 -0
  19. package/data/harnesses/code/skills/documentation/references/templates.md +901 -0
  20. package/data/harnesses/code/skills/introspect/SKILL.md +135 -0
  21. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +430 -0
  22. package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +214 -0
  23. package/data/harnesses/kb-agi/CLAUDE.md +57 -0
  24. package/data/harnesses/kb-agi/agents/kb-agi-init.md +276 -0
  25. package/data/harnesses/kb-agi/agents/kb-catch-stale.md +22 -0
  26. package/data/harnesses/kb-agi/agents/kb-find-gaps.md +27 -0
  27. package/data/harnesses/kb-agi/agents/kb-fix-links.md +22 -0
  28. package/data/harnesses/kb-agi/agents/kb-refresh-frontdoor.md +22 -0
  29. package/data/harnesses/kb-agi/agents/kb-refresh-summaries.md +22 -0
  30. package/data/harnesses/kb-agi/agents/kb-sync-metadata.md +25 -0
  31. package/data/harnesses/kb-agi/rules/kb.md +13 -0
  32. package/package.json +1 -1
@@ -0,0 +1,96 @@
1
+ ---
2
+ applyTo: "**"
3
+ ---
4
+
5
+ # Technology Choices & Standards
6
+
7
+ Opinionated technology stack and implementation standards.
8
+
9
+ ## Environment & Versions
10
+
11
+ ### Runtime Versions
12
+
13
+ - **Node.js:** 22 LTS (latest)
14
+ - **Package manager:** project-determined — detect from lockfile (`pnpm-lock.yaml` → pnpm, `yarn.lock` → yarn, `package-lock.json` → npm). Use the matching command in scripts; don't hardcode a specific manager.
15
+ - **PostgreSQL:** 17
16
+ - **Redis:** 7.x (latest)
17
+
18
+ ### Recommended Packages
19
+
20
+ No alternatives. No explanations for obvious choices. Just use these.
21
+
22
+ | Package | Version | Use | Don't use |
23
+ | ------------------------ | --------- | ---------------------- | ----------------------- |
24
+ | react | ^19.2.3 | UI components | - |
25
+ | vite | ^8.0.0 | Build tool, dev server | webpack, CRA |
26
+ | tailwindcss | ^4.1.18 | Styling | styled-components |
27
+ | @vitejs/plugin-react-swc | ^4.2.2 | JSX compilation | @vitejs/plugin-react |
28
+ | react-router-dom | ^7.11.0 | Routing | - |
29
+ | @reduxjs/toolkit | ^2.11.2 | State management | zustand, jotai |
30
+ | react-redux | ^9.2.0 | Redux React bindings | - |
31
+ | axios | ^1.13.2 | HTTP requests | fetch |
32
+ | date-fns | ^4.1.0 | Date formatting | moment, dayjs |
33
+ | @dnd-kit/core | ^6.3.1 | Drag and drop | react-beautiful-dnd |
34
+ | motion | ^12.23.26 | Animations | react-spring |
35
+ | sonner | ^2.0.7 | Toast notifications | react-toastify |
36
+ | react-window | ^2.2.3 | List virtualization | react-virtualized |
37
+ | nanoid | ^5.1.6 | ID generation | uuid |
38
+ | express | ^5.2.1 | HTTP server | fastify, koa |
39
+ | prisma | ^7.2.0 | Database ORM | sequelize, typeorm |
40
+ | @prisma/client | ^7.2.0 | Database queries | - |
41
+ | zod | ^4.2.1 | Schema validation | yup, joi |
42
+ | jose | ^6.1.3 | JWT handling | jsonwebtoken |
43
+ | microdiff | ^1.5.0 | JSON object diffing | deep-diff, just-diff |
44
+ | react18-json-view | ^0.2.9 | JSON tree view | react-json-view |
45
+ | @tiptap/react | ^3.11.1 | Rich text editor | slate, quill, draft-js |
46
+ | shiki | ^3.22.0 | Syntax highlighting | prism, highlight.js |
47
+ | lucide-react | ^0.562.0 | Icons | react-icons, heroicons |
48
+ | @pdfme/generator | ^5.5.8 | PDF generation | jspdf, pdfkit |
49
+ | cmdk | ^1.1.1 | Command palette | kbar, ninja-keys |
50
+ | @monaco-editor/react | ^4.7.0 | Code editor | codemirror, ace |
51
+ | localforage | ^1.10.0 | Client-side storage | idb, dexie |
52
+ | socket.io-client | ^4.7.0 | WebSocket client | native WebSocket, ws |
53
+ | react-markdown | ^10.1.0 | Markdown rendering | marked, markdown-it |
54
+ | fast-deep-equal | ^3.1.3 | Deep equality checks | lodash.isEqual |
55
+ | @ngneat/falso | latest | Fake data generation | @faker-js/faker, chance |
56
+ | pino | ^10.1.0 | Logging | winston |
57
+
58
+ ---
59
+
60
+ ## Express 5.x Setup
61
+
62
+ ```javascript
63
+ app.use(cors({ origin: process.env.FRONTEND_URL }));
64
+ app.use(compression());
65
+ app.use(express.json({ limit: "10mb" }));
66
+ app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
67
+ ```
68
+
69
+ - Middleware order: body parsers, custom middleware, routes, error handlers
70
+ - Use Express Router for modular routes
71
+ - Centralized error handler as last middleware
72
+ - Use middleware for auth
73
+
74
+ ---
75
+
76
+ ## API Response Format
77
+
78
+ ```json
79
+ {
80
+ "status": 1,
81
+ "message": "Message sent successfully",
82
+ "data": { "delivered": [{ "user@example.com": 2 }] }
83
+ }
84
+ ```
85
+
86
+ **Error:**
87
+
88
+ ```json
89
+ {
90
+ "status": 0,
91
+ "message": "Error description",
92
+ "data": null
93
+ }
94
+ ```
95
+
96
+ HTTP codes: `200`, `201` (created), `400`, `401` (not authenticated), `403` (not authorized), `404`, `500`
@@ -0,0 +1,34 @@
1
+ ---
2
+ applyTo: "**"
3
+ ---
4
+
5
+ # Nomenclature Guidelines
6
+
7
+ ## Naming Guidelines
8
+
9
+ - Use descriptive names that reveal intent, purpose, and usage
10
+ - Names should explain why something exists and how it's used
11
+ - Favor clarity over brevity
12
+ - Maintain consistency within the codebase
13
+ - Avoid abbreviations unless they're universally understood
14
+
15
+ ## Naming Styles
16
+
17
+ - Variables : Use nouns or noun phrases. Examples: `userData`, `firstName`, `paymentStatus`, `configOptions`
18
+ - Functions & Methods : Use verbs or verb phrases that describe the action. Examples: `calculateTotal`, `getUserInfo`, `validateInput`, `sendNotification`
19
+ - Boolean Variables : Prefix with is**, has**, can**, or should**. Examples: `isValid`, `hasPermission`, `canEdit`, `shouldRefresh`
20
+ - Arrays : Use plural nouns. Examples: `users`, `productList`, `errorMessages`, `activeConnections`
21
+ - Classes & Components : Use singular nouns or noun phrases. Examples: `RequestHandler`, `UserProfile`, `PaymentProcessor`, `DataValidator`
22
+ - Constants : Use uppercase with meaningful names. Examples: `DEFAULT_TIMEOUT`, `API_BASE_URL`, `MAX_RETRY_COUNT`, `COLOR_PRIMARY`
23
+ - Event Handlers : Use Prefix with handle or on. Examples: `handleSubmit`, `onUserLogin`, `handleInputChange`, `onPageLoad`
24
+ - Interfaces & Types : Use Consider prefixing with I for interfaces (if preferred). Examples: `IUserData`, `IConfigOptions`, `AuthResponse`, `RequestParams`
25
+ - Promises & Async Functions : Use Consider using future tense or suffixes like Async. Examples: `fetchUserData`, `getUserProfileAsync`, `loadConfigAsync`, `processPayment`
26
+ - File & Folder Structure : Use lowercase with descriptive names. Group by feature or function type. Example: `auth/login_service.js`
27
+
28
+ ## Casing Styles
29
+
30
+ - camelCase : Used in Variables, function names, method names, property names. Examples: `userData`, `calculateTotal`, `firstName`, `isValidEmail`
31
+ - PascalCase : Used in Class names, component names, type definitions. Examples: `UserProfile`, `DataService`, `AuthProvider`, `RequestHandler`
32
+ - snake_case : Used in File names, folder names. Examples: `user_service`, `api_utils`, `auth_middleware`, `data_models`
33
+ - UPPER_SNAKE_CASE : Used in Constants, environment variables. Examples: `MAX_RETRY_COUNT`, `API_KEY`, `DEFAULT_TIMEOUT`, `COLOR_PRIMARY`
34
+ - kebab-case : Used in URLs, CSS class names, HTML IDs. Examples: `nav-container`, `user-profile`, `button-primary`, `form-wrapper`
@@ -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 |