xtrm-tools 2.4.0 → 2.4.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 (125) hide show
  1. package/README.md +23 -9
  2. package/cli/dist/index.cjs +774 -240
  3. package/cli/dist/index.cjs.map +1 -1
  4. package/cli/package.json +1 -1
  5. package/config/hooks.json +10 -0
  6. package/config/pi/extensions/core/adapter.ts +2 -14
  7. package/config/pi/extensions/core/guard-rules.ts +70 -0
  8. package/config/pi/extensions/core/session-state.ts +59 -0
  9. package/config/pi/extensions/main-guard.ts +10 -14
  10. package/config/pi/extensions/plan-mode/README.md +65 -0
  11. package/config/pi/extensions/plan-mode/index.ts +340 -0
  12. package/config/pi/extensions/plan-mode/utils.ts +168 -0
  13. package/config/pi/extensions/service-skills.ts +51 -7
  14. package/config/pi/extensions/session-flow.ts +117 -0
  15. package/hooks/beads-claim-sync.mjs +123 -2
  16. package/hooks/beads-compact-restore.mjs +41 -9
  17. package/hooks/beads-compact-save.mjs +36 -5
  18. package/hooks/beads-gate-messages.mjs +27 -1
  19. package/hooks/beads-stop-gate.mjs +58 -8
  20. package/hooks/guard-rules.mjs +86 -0
  21. package/hooks/hooks.json +28 -18
  22. package/hooks/main-guard.mjs +3 -21
  23. package/hooks/quality-check.cjs +1286 -0
  24. package/hooks/quality-check.py +345 -0
  25. package/hooks/session-state.mjs +138 -0
  26. package/package.json +2 -1
  27. package/project-skills/quality-gates/.claude/settings.json +1 -24
  28. package/skills/creating-service-skills/SKILL.md +433 -0
  29. package/skills/creating-service-skills/references/script_quality_standards.md +425 -0
  30. package/skills/creating-service-skills/references/service_skill_system_guide.md +278 -0
  31. package/skills/creating-service-skills/scripts/bootstrap.py +326 -0
  32. package/skills/creating-service-skills/scripts/deep_dive.py +304 -0
  33. package/skills/creating-service-skills/scripts/scaffolder.py +482 -0
  34. package/skills/scoping-service-skills/SKILL.md +231 -0
  35. package/skills/scoping-service-skills/scripts/scope.py +74 -0
  36. package/skills/sync-docs/SKILL.md +235 -0
  37. package/skills/sync-docs/evals/evals.json +89 -0
  38. package/skills/sync-docs/references/doc-structure.md +104 -0
  39. package/skills/sync-docs/references/schema.md +103 -0
  40. package/skills/sync-docs/scripts/context_gatherer.py +246 -0
  41. package/skills/sync-docs/scripts/doc_structure_analyzer.py +495 -0
  42. package/skills/sync-docs/scripts/validate_doc.py +365 -0
  43. package/skills/sync-docs-workspace/iteration-1/benchmark.json +293 -0
  44. package/skills/sync-docs-workspace/iteration-1/benchmark.md +13 -0
  45. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/eval_metadata.json +27 -0
  46. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/outputs/result.md +210 -0
  47. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/grading.json +28 -0
  48. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/timing.json +1 -0
  49. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/outputs/result.md +101 -0
  50. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/grading.json +28 -0
  51. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/timing.json +5 -0
  52. package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/timing.json +5 -0
  53. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/eval_metadata.json +27 -0
  54. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/outputs/result.md +198 -0
  55. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/grading.json +28 -0
  56. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/timing.json +1 -0
  57. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/outputs/result.md +94 -0
  58. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/grading.json +28 -0
  59. package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/timing.json +1 -0
  60. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/eval_metadata.json +27 -0
  61. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/outputs/result.md +237 -0
  62. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/grading.json +28 -0
  63. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
  64. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/outputs/result.md +134 -0
  65. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/grading.json +28 -0
  66. package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/timing.json +1 -0
  67. package/skills/sync-docs-workspace/iteration-2/benchmark.json +297 -0
  68. package/skills/sync-docs-workspace/iteration-2/benchmark.md +13 -0
  69. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/eval_metadata.json +27 -0
  70. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/outputs/result.md +137 -0
  71. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/grading.json +92 -0
  72. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/timing.json +1 -0
  73. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/outputs/result.md +134 -0
  74. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/grading.json +86 -0
  75. package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/timing.json +1 -0
  76. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/eval_metadata.json +27 -0
  77. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/outputs/result.md +193 -0
  78. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/grading.json +72 -0
  79. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/timing.json +1 -0
  80. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/outputs/result.md +211 -0
  81. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/grading.json +91 -0
  82. package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/timing.json +5 -0
  83. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/eval_metadata.json +27 -0
  84. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/outputs/result.md +182 -0
  85. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
  86. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
  87. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/outputs/result.md +222 -0
  88. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/grading.json +88 -0
  89. package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
  90. package/skills/sync-docs-workspace/iteration-3/benchmark.json +298 -0
  91. package/skills/sync-docs-workspace/iteration-3/benchmark.md +13 -0
  92. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/eval_metadata.json +27 -0
  93. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/outputs/result.md +125 -0
  94. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/grading.json +97 -0
  95. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/timing.json +5 -0
  96. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/outputs/result.md +144 -0
  97. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/grading.json +78 -0
  98. package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/timing.json +5 -0
  99. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/eval_metadata.json +27 -0
  100. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/outputs/result.md +104 -0
  101. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/grading.json +91 -0
  102. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/timing.json +5 -0
  103. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/outputs/result.md +79 -0
  104. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/grading.json +82 -0
  105. package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/timing.json +5 -0
  106. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/eval_metadata.json +27 -0
  107. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase1_context.json +302 -0
  108. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase2_drift.txt +33 -0
  109. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase3_analysis.json +114 -0
  110. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase4_fix.txt +118 -0
  111. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase5_validate.txt +38 -0
  112. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/result.md +158 -0
  113. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
  114. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/timing.json +5 -0
  115. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/outputs/result.md +71 -0
  116. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/grading.json +90 -0
  117. package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
  118. package/skills/updating-service-skills/SKILL.md +136 -0
  119. package/skills/updating-service-skills/scripts/drift_detector.py +222 -0
  120. package/skills/using-quality-gates/SKILL.md +254 -0
  121. package/skills/using-service-skills/SKILL.md +108 -0
  122. package/skills/using-service-skills/scripts/cataloger.py +74 -0
  123. package/skills/using-service-skills/scripts/skill_activator.py +152 -0
  124. package/skills/using-service-skills/scripts/test_skill_activator.py +58 -0
  125. package/skills/using-xtrm/SKILL.md +34 -38
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ scope.py — Read service-registry.json and output a formatted service catalog.
4
+
5
+ Used by the /scope skill to provide registry data for agent reasoning before
6
+ any files are touched. The agent uses this output to map a task description
7
+ to the relevant registered service(s).
8
+ """
9
+
10
+ import json
11
+ import os
12
+ import sys
13
+ from pathlib import Path
14
+
15
+
16
+ def find_registry() -> Path | None:
17
+ # 1. CLAUDE_PROJECT_DIR env var (set by Claude Code hooks)
18
+ project_dir = os.environ.get("CLAUDE_PROJECT_DIR")
19
+ if project_dir:
20
+ p = Path(project_dir) / ".claude" / "skills" / "service-registry.json"
21
+ if p.exists():
22
+ return p
23
+
24
+ # 2. Walk up from CWD until .git boundary
25
+ cwd = Path.cwd()
26
+ for parent in [cwd, *cwd.parents]:
27
+ p = parent / ".claude" / "skills" / "service-registry.json"
28
+ if p.exists():
29
+ return p
30
+ if (parent / ".git").exists():
31
+ break
32
+
33
+ return None
34
+
35
+
36
+ def main() -> None:
37
+ registry_path = find_registry()
38
+
39
+ if not registry_path:
40
+ print("ERROR: service-registry.json not found.")
41
+ print("Run /creating-service-skills to set up service skills first.")
42
+ sys.exit(1)
43
+
44
+ try:
45
+ with open(registry_path, encoding="utf-8") as f:
46
+ registry = json.load(f)
47
+ except json.JSONDecodeError as e:
48
+ print(f"ERROR: service-registry.json is malformed: {e}")
49
+ sys.exit(1)
50
+
51
+ services = registry.get("services", {})
52
+ if not services:
53
+ print("Registry is empty — no services registered.")
54
+ sys.exit(0)
55
+
56
+ print(f"Registry : {registry_path}")
57
+ print(f"Version : {registry.get('version', 'unknown')}")
58
+ print(f"Services : {len(services)} registered")
59
+ print("─" * 60)
60
+
61
+ for service_id, info in services.items():
62
+ territories = ", ".join(info.get("territory", [])) or "—"
63
+ print(f"\n[{service_id}]")
64
+ print(f" Container : {info.get('container', 'unknown')}")
65
+ print(f" Territory : {territories}")
66
+ print(f" Skill : {info.get('skill_path', 'unknown')}")
67
+ print(f" Description: {info.get('description', '—')}")
68
+
69
+ print("\n" + "─" * 60)
70
+ print("Map the task description to the service(s) above, then load their skills.")
71
+
72
+
73
+ if __name__ == "__main__":
74
+ main()
@@ -0,0 +1,235 @@
1
+ ---
2
+ name: sync-docs
3
+ description: >-
4
+ Doc audit and structural sync for xtrm projects. Use whenever the README
5
+ feels too long, docs are out of sync after a sprint, the CHANGELOG is behind,
6
+ or the user asks to "sync docs", "doc audit", "split readme", "check docs
7
+ health", or "detect drift". Also triggers after closing bd issues or merging
8
+ PRs when documentation cleanup is implied. Reads bd issues, PRs, and memories
9
+ to understand what changed, then runs drift detection on README.md,
10
+ CHANGELOG.md, and docs/ — creating missing focused files instead of a
11
+ monolithic README. Prefer over /documenting for any structural reorganization
12
+ or multi-file sync work.
13
+ gemini-command: sync-docs
14
+ version: 1.0.0
15
+ ---
16
+
17
+ # sync-docs
18
+
19
+ Keeps documentation in sync with reality. Reads what was done (bd issues, PRs, memories), finds what's stale or structurally wrong, and fixes it with Serena precision.
20
+
21
+ ## Overview
22
+
23
+ ```
24
+ Phase 1: Gather context — what was done recently?
25
+ Phase 2: Detect drift — what's stale in SSOT memories?
26
+ Phase 3: Analyze structure — what's in the wrong place?
27
+ Phase 4: Plan + execute — fix with Serena (SKIP if audit/read-only task)
28
+ Phase 5: Validate — schema-check all docs/
29
+ ```
30
+
31
+ **Audit vs Execute mode:** If the user asked for an audit, report, or "just check", stop after Phase 3 — do not run `--fix` or edit any files. Only proceed to Phase 4 when the user explicitly wants changes made.
32
+
33
+ ---
34
+
35
+ ## MANDATORY FIRST STEP
36
+
37
+ Activate the Serena project before any file edits:
38
+
39
+ ```javascript
40
+ mcp__serena__activate_project({ project: "<cwd>" })
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Phase 1: Gather Context
46
+
47
+ ```bash
48
+ # If skill is installed globally:
49
+ python3 "$HOME/.claude/skills/sync-docs/scripts/context_gatherer.py" [--since=30]
50
+
51
+ # If running from the repo directly:
52
+ python3 "skills/sync-docs/scripts/context_gatherer.py" [--since=30]
53
+ ```
54
+
55
+ Outputs a JSON report with:
56
+ - Recently closed bd issues (id, title, closed date)
57
+ - Merged PRs (subject, merge date) from git history
58
+ - bd memories persisted this cycle (`bd memory list` if available)
59
+ - Stale Serena memories (delegates to drift_detector.py)
60
+
61
+ If no `.beads/` directory exists, falls back to git-only context. All output is JSON — read it and keep the key findings in mind for Phase 3.
62
+
63
+ ---
64
+
65
+ ## Phase 2: Detect SSOT Drift
66
+
67
+ ```bash
68
+ python3 "$HOME/.claude/skills/documenting/scripts/drift_detector.py" scan
69
+ ```
70
+
71
+ This checks which Serena memories have `tracks:` globs matching recently modified files. If something is stale, note the memory name. You will handle it in Phase 4 using the same update steps as `/documenting` — but with Serena tools (not Edit/Write).
72
+
73
+ > **Note:** `drift_detector.py` requires `pyyaml`. If you see `ModuleNotFoundError: No module named 'yaml'`, skip Phase 2 and note it — the rest of the skill works without it. Do not `pip install` unless the user explicitly approves.
74
+
75
+ ---
76
+
77
+ ## Phase 3: Analyze Document Structure
78
+
79
+ ```bash
80
+ # Analysis only (no changes) — always safe to run:
81
+ python3 "$HOME/.claude/skills/sync-docs/scripts/doc_structure_analyzer.py"
82
+ # or from repo: python3 "skills/sync-docs/scripts/doc_structure_analyzer.py"
83
+ ```
84
+
85
+ Checks:
86
+ 1. **README.md bloat** — flags if > 200 lines or contains sections that belong in `docs/`
87
+ 2. **CHANGELOG.md coverage** — date gap AND version gap (package.json vs latest changelog entry)
88
+ 3. **docs/ gaps** — expected focused files that don't exist yet
89
+ 4. **Schema validity** — existing docs/ files missing YAML frontmatter
90
+
91
+ Reports are categorized as `BLOATED`, `EXTRACTABLE`, `MISSING`, `STALE`, `INVALID_SCHEMA`, or `OK`.
92
+
93
+ **If the task is audit/analysis only → stop here.** Summarize findings and present to the user. Do not run `--fix` without explicit intent to make changes.
94
+
95
+ Read `references/doc-structure.md` for the complete guide on what belongs in each docs/ file.
96
+
97
+ ---
98
+
99
+ ## Phase 4: Decide and Execute
100
+
101
+ | Situation | Action |
102
+ |---|---|
103
+ | README bloated + section belongs in docs/ | Extract → new `docs/X.md`, replace with summary + link |
104
+ | docs/ file missing for existing subsystem | Create `docs/X.md` with schema frontmatter |
105
+ | Serena memory stale | Update memory using Serena tools (see below) |
106
+ | bd issue closed, no doc reflects it | Update CHANGELOG + relevant doc |
107
+ | docs/ file schema invalid | Fix frontmatter, regenerate INDEX |
108
+ | Everything clean | Report "All docs in sync" and stop |
109
+
110
+ ### Editing with Serena (required for all doc edits)
111
+
112
+ Never use the raw `Edit` tool on documentation files. Always go through Serena:
113
+
114
+ ```javascript
115
+ // 1. Map structure first
116
+ mcp__serena__get_symbols_overview({ relative_path: "README.md", depth: 1 })
117
+
118
+ // 2. Read only the relevant section
119
+ mcp__serena__find_symbol({ name: "Section Name", include_body: true })
120
+
121
+ // 3. Replace section content
122
+ mcp__serena__replace_symbol_body({ symbol_name: "Section Name", new_body: "..." })
123
+
124
+ // 4. Insert a new section after an existing one
125
+ mcp__serena__insert_after_symbol({ symbol_name: "Existing Section", new_symbol: "..." })
126
+ ```
127
+
128
+ The reason this matters: Serena edits are atomic and reference-safe. Direct edits on large markdown files risk corrupting heading structure or inserting duplicates.
129
+
130
+ ### Auto-scaffolding missing docs/ files (--fix)
131
+
132
+ For known subsystem patterns (hooks/, policies/, skills/, etc.), run `--fix` to generate all missing scaffolds at once:
133
+
134
+ ```bash
135
+ python3 "$HOME/.claude/skills/sync-docs/scripts/doc_structure_analyzer.py" --fix
136
+ ```
137
+
138
+ Combine with `--bd-remember` to persist a summary insight for future sessions:
139
+
140
+ ```bash
141
+ python3 "$HOME/.claude/skills/sync-docs/scripts/doc_structure_analyzer.py" --fix --bd-remember
142
+ ```
143
+
144
+ `--fix` only handles known MISSING patterns. README extraction (BLOATED/EXTRACTABLE) still requires Serena — content judgment is needed to split correctly.
145
+
146
+ ### Creating a single docs/ file manually
147
+
148
+ Generate the scaffold with valid frontmatter:
149
+
150
+ ```bash
151
+ python3 "$HOME/.claude/skills/sync-docs/scripts/validate_doc.py" --generate docs/hooks.md \
152
+ --title "Hooks Reference" --scope "hooks" --category "reference" \
153
+ --source-for "hooks/**/*.mjs,policies/*.json"
154
+ ```
155
+
156
+ Then fill content using Serena. See `references/schema.md` for all frontmatter fields.
157
+
158
+ ### Updating Serena memories (when drift detected)
159
+
160
+ 1. Read the `<!-- INDEX -->` block only — identify stale sections
161
+ 2. Use `mcp__serena__search_for_pattern` to jump to stale content
162
+ 3. Use `mcp__serena__replace_symbol_body` to update
163
+ 4. Bump `version:` (patch = content fix, minor = new section) and `updated:` in frontmatter
164
+ 5. Regenerate INDEX:
165
+
166
+ ```bash
167
+ python3 "$HOME/.claude/skills/documenting/scripts/validate_metadata.py" <memory-file>
168
+ ```
169
+
170
+ ### Updating CHANGELOG
171
+
172
+ ```bash
173
+ python3 "$HOME/.claude/skills/documenting/scripts/changelog/add_entry.py" \
174
+ CHANGELOG.md <type> "<summary>"
175
+ ```
176
+
177
+ Types: `Added`, `Changed`, `Fixed`, `Removed`.
178
+
179
+ ### Persisting insights via bd remember
180
+
181
+ After significant doc work (new docs/ files created, README reorganized, major drift fixed), persist a summary for future sessions:
182
+
183
+ ```bash
184
+ bd remember "<what was done and why>" --key sync-docs-<scope>-<YYYY-MM-DD>
185
+ ```
186
+
187
+ Examples:
188
+ ```bash
189
+ bd remember "docs/hooks.md created — extracted from README section + 12 hook scripts cataloged" --key sync-docs-hooks-2026-03-18
190
+ bd remember "README trimmed from 340 to 180 lines — policies, hooks, MCP moved to docs/" --key sync-docs-readme-trim-2026-03-18
191
+ ```
192
+
193
+ This is done automatically when using `--fix --bd-remember`, but do it manually too when making structural changes via Serena.
194
+
195
+ ---
196
+
197
+ ## Phase 5: Validate
198
+
199
+ Run schema validation on all docs/ files before finishing:
200
+
201
+ ```bash
202
+ python3 "$HOME/.claude/skills/sync-docs/scripts/validate_doc.py" docs/
203
+ ```
204
+
205
+ Exits 0 if all pass. Fix any errors before reporting completion.
206
+
207
+ ---
208
+
209
+ ## Standard docs/ Structure
210
+
211
+ See `references/doc-structure.md` for the complete guide. At minimum, a mature xtrm project should have:
212
+
213
+ ```
214
+ docs/
215
+ ├── hooks.md # Hook events, scripts, and their behavior
216
+ ├── pi-extensions.md # Pi/Copilot extension catalog
217
+ ├── architecture.md # System design, key components
218
+ └── plans/ # In-progress and completed work plans
219
+ ```
220
+
221
+ If any of these are missing and the project has the relevant code, create them.
222
+
223
+ ---
224
+
225
+ ## Relationship to /documenting
226
+
227
+ | Use `/sync-docs` when | Use `/documenting` when |
228
+ |---|---|
229
+ | Finishing a feature cycle | Just adding a CHANGELOG entry |
230
+ | README feels too big | Creating a single Serena memory |
231
+ | After merging multiple PRs | Updating one stale memory |
232
+ | Need bd context to know what changed | The scope is already clear |
233
+ | Structural reorganization needed | No structural changes needed |
234
+
235
+ `/documenting` inherits the changelog scripts from this skill. Both can run in the same repo — they don't conflict.
@@ -0,0 +1,89 @@
1
+ {
2
+ "skill_name": "sync-docs",
3
+ "evals": [
4
+ {
5
+ "id": 1,
6
+ "prompt": "I just closed a bunch of bd issues this sprint and merged 3 PRs. The README.md is getting long — can you sync the docs and make sure everything's in order? Use sync-docs.",
7
+ "expected_output": "Runs context_gatherer.py and doc_structure_analyzer.py, reports what was found (closed issues, PRs, any drift), identifies README extraction candidates or MISSING docs/ files, and either fixes them or gives a clear plan with next steps.",
8
+ "files": [],
9
+ "assertions": [
10
+ {
11
+ "id": "ran-context-gatherer",
12
+ "description": "Ran context_gatherer.py and reported bd closed issues or merged PRs from the output",
13
+ "check": "result.md mentions context_gatherer or bd closed issues or merged PRs with specific data"
14
+ },
15
+ {
16
+ "id": "ran-structure-analyzer",
17
+ "description": "Ran doc_structure_analyzer.py and used its output to identify doc issues",
18
+ "check": "result.md references MISSING, STALE, EXTRACTABLE, or BLOATED status from the analyzer"
19
+ },
20
+ {
21
+ "id": "concrete-action",
22
+ "description": "Produced at least one concrete recommendation or action (not just a vague summary)",
23
+ "check": "result.md names a specific file (e.g. docs/hooks.md) or section with a specific next step"
24
+ },
25
+ {
26
+ "id": "used-skill-scripts",
27
+ "description": "Used the skill scripts rather than just reading files manually",
28
+ "check": "result.md shows script execution output, not just manual file reading"
29
+ }
30
+ ]
31
+ },
32
+ {
33
+ "id": 2,
34
+ "prompt": "Run sync-docs --fix on this project and remember what you did with bd.",
35
+ "expected_output": "Runs doc_structure_analyzer.py --fix --bd-remember, creates scaffold files for any missing docs/ subsystems, persists a bd memory with the summary, then validates the created files with validate_doc.py.",
36
+ "files": [],
37
+ "assertions": [
38
+ {
39
+ "id": "ran-fix-flag",
40
+ "description": "Ran doc_structure_analyzer.py with --fix flag",
41
+ "check": "result.md shows the --fix command was executed"
42
+ },
43
+ {
44
+ "id": "ran-bd-remember",
45
+ "description": "Ran with --bd-remember or manually ran bd remember with a summary",
46
+ "check": "result.md shows bd remember was called and reports the memory key"
47
+ },
48
+ {
49
+ "id": "scaffold-created",
50
+ "description": "At least one scaffold file was created in docs/",
51
+ "check": "result.md lists a docs/*.md file created, OR reports no gaps found (valid outcome)"
52
+ },
53
+ {
54
+ "id": "validated-schema",
55
+ "description": "Ran validate_doc.py on created files to confirm schema",
56
+ "check": "result.md shows validate_doc.py was run and reports pass/fail for created files"
57
+ }
58
+ ]
59
+ },
60
+ {
61
+ "id": 3,
62
+ "prompt": "Do a doc audit. I think the README has sections that should be in docs/ but I'm not sure which ones.",
63
+ "expected_output": "Runs the full 5-phase sync-docs workflow: gathers context, runs drift detection, runs doc_structure_analyzer.py, identifies EXTRACTABLE/BLOATED sections with specific suggestions for what goes in which docs/ file, and uses Serena to map README structure before recommending or making changes.",
64
+ "files": [],
65
+ "assertions": [
66
+ {
67
+ "id": "ran-analyzer",
68
+ "description": "Ran doc_structure_analyzer.py and referenced its structured output",
69
+ "check": "result.md cites the analyzer output (EXTRACTABLE, BLOATED, line count, or specific section names from the report)"
70
+ },
71
+ {
72
+ "id": "named-specific-sections",
73
+ "description": "Named specific README sections with their suggested docs/ destination",
74
+ "check": "result.md lists at least 2 specific sections (e.g. '## Policy System → docs/policies.md') not just generic advice"
75
+ },
76
+ {
77
+ "id": "actionable-report",
78
+ "description": "Report is actionable — tells user exactly what to do next, not just observations",
79
+ "check": "result.md includes a prioritized list or clear next steps, not just 'the README could be shorter'"
80
+ },
81
+ {
82
+ "id": "no-edits-made",
83
+ "description": "Did not edit or create any files (audit only)",
84
+ "check": "result.md does not claim to have modified README.md or created docs/ files"
85
+ }
86
+ ]
87
+ }
88
+ ]
89
+ }
@@ -0,0 +1,104 @@
1
+ # docs/ Structure Guide
2
+
3
+ This reference defines what belongs in each focused docs/ file vs README.md and `.serena/memories/`.
4
+
5
+ ## The Rule
6
+
7
+ **README.md** is an entry point — a quick-start and orientation map. It should be < 200 lines. Anything that requires more than a few bullet points belongs in a focused docs/ file.
8
+
9
+ **docs/** holds focused, public-facing SSOT files for each subsystem. Each file:
10
+ - Has YAML frontmatter (see `schema.md`)
11
+ - Covers exactly one subsystem or concern
12
+ - Is linked from README.md with a single line
13
+
14
+ **.serena/memories/** holds internal AI memory — architecture decisions, patterns, workflows — for the AI agents themselves. These are not user docs.
15
+
16
+ ---
17
+
18
+ ## What Goes Where
19
+
20
+ | Content Type | Location | When to Create |
21
+ |---|---|---|
22
+ | Quick start, one-liner install | `README.md` | Always |
23
+ | Feature overview table | `README.md` | Always, < 20 lines |
24
+ | Hook events, scripts, behavior | `docs/hooks.md` | When hooks/ dir exists |
25
+ | Pi/Copilot extension catalog | `docs/pi-extensions.md` | When config/pi/extensions/ exists |
26
+ | System architecture, components | `docs/architecture.md` | When > 2 major subsystems |
27
+ | Policy rules and enforcement | `docs/policies.md` | When policies/ dir exists |
28
+ | MCP server config and usage | `docs/mcp-servers.md` | When .mcp.json or mcp servers exist |
29
+ | Skills catalog | `docs/skills.md` | When skills/ dir has > 5 skills |
30
+ | CLI commands reference | `docs/cli-reference.md` | When CLI has > 10 commands |
31
+ | Troubleshooting and FAQs | `docs/troubleshooting.md` | When recurring issues exist |
32
+ | In-progress work plans | `docs/plans/` | Always for planning docs |
33
+ | Architecture decisions (AI) | `.serena/memories/*_ssot.md` | For AI context only |
34
+ | Implementation patterns (AI) | `.serena/memories/*_pattern.md` | For AI context only |
35
+
36
+ ---
37
+
38
+ ## Standard File Shapes
39
+
40
+ ### docs/hooks.md
41
+ Covers: hook events, what triggers each hook, which scripts run, output format.
42
+ Section outline:
43
+ ```
44
+ ## Overview
45
+ ## Hook Events
46
+ ## Scripts Reference
47
+ ## Adding a New Hook
48
+ ```
49
+
50
+ ### docs/pi-extensions.md
51
+ Covers: what Pi extensions are installed, their events, behavior, and configuration.
52
+ Section outline:
53
+ ```
54
+ ## Overview
55
+ ## Installed Extensions
56
+ ## Extension Events
57
+ ## Configuration
58
+ ```
59
+
60
+ ### docs/architecture.md
61
+ Covers: system overview, key components, data flow, dependency diagram.
62
+ Section outline:
63
+ ```
64
+ ## System Overview
65
+ ## Key Components
66
+ ## Data Flow
67
+ ## Directory Structure
68
+ ```
69
+
70
+ ### docs/policies.md
71
+ Covers: what policies exist, what each enforces, runtime targets.
72
+ Section outline:
73
+ ```
74
+ ## Overview
75
+ ## Policy Files
76
+ ## Policy Compiler
77
+ ## Adding a Policy
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Detecting When README is Too Big
83
+
84
+ The `doc_structure_analyzer.py` script flags README as `BLOATED` when:
85
+ 1. Line count > 200, AND
86
+ 2. At least one section has a matching `docs/` file that doesn't exist yet
87
+
88
+ The `EXTRACTABLE` status means sections are present but README isn't over threshold yet — worth noting but not urgent.
89
+
90
+ ---
91
+
92
+ ## Extraction Process
93
+
94
+ When extracting a section from README to docs/:
95
+
96
+ 1. Run `mcp__serena__get_symbols_overview` on README.md to map all sections
97
+ 2. Use `mcp__serena__find_symbol` to read the target section body
98
+ 3. Create `docs/X.md` with `validate_doc.py --generate`
99
+ 4. Paste the section content into the new file
100
+ 5. Use `mcp__serena__replace_symbol_body` to replace README section with:
101
+ ```markdown
102
+ See [docs/X.md](docs/X.md) for the full reference.
103
+ ```
104
+ 6. Run `validate_doc.py docs/X.md` to confirm schema
@@ -0,0 +1,103 @@
1
+ # docs/ File Schema
2
+
3
+ Every file in `docs/` must have YAML frontmatter. This is enforced by `validate_doc.py`.
4
+
5
+ ## Frontmatter Fields
6
+
7
+ ```yaml
8
+ ---
9
+ title: Human Readable Title # required — clear, descriptive
10
+ scope: kebab-case-identifier # required — unique slug for this doc
11
+ category: reference # required — see valid values below
12
+ version: 1.0.0 # required — semver (x.y.z)
13
+ updated: 2026-03-18 # required — ISO date of last update
14
+ description: "One-line summary" # optional
15
+ source_of_truth_for: # optional — glob patterns this doc describes
16
+ - "hooks/**/*.mjs"
17
+ - "policies/*.json"
18
+ domain: [hooks, claude, policy] # optional — cross-cutting tags
19
+ ---
20
+ ```
21
+
22
+ ## Required Fields
23
+
24
+ | Field | Type | Description | Example |
25
+ |-------|------|-------------|---------|
26
+ | `title` | string | Clear, descriptive title | "Hooks Reference" |
27
+ | `scope` | string | Unique kebab-case slug | "hooks" |
28
+ | `category` | enum | Document type | "reference" |
29
+ | `version` | semver | x.y.z — bump on every update | "1.2.0" |
30
+ | `updated` | date | YYYY-MM-DD of last change | "2026-03-18" |
31
+
32
+ ## Category Values
33
+
34
+ | Value | Purpose |
35
+ |---|---|
36
+ | `reference` | Look-up table, cheat sheet, technical spec |
37
+ | `guide` | Step-by-step how-to documentation |
38
+ | `architecture` | System design and component overview |
39
+ | `api` | API contracts, interfaces, schemas |
40
+ | `plan` | Implementation plan or roadmap |
41
+ | `overview` | Summary introduction to a subsystem |
42
+
43
+ ## Optional Fields
44
+
45
+ ### source_of_truth_for
46
+ A list of glob patterns (fnmatch syntax) pointing to the source files this doc describes. Used by `drift_detector.py` and `doc_structure_analyzer.py` to detect when the source changed but the doc wasn't updated.
47
+
48
+ ```yaml
49
+ source_of_truth_for:
50
+ - "hooks/**/*.mjs"
51
+ - "policies/*.json"
52
+ - "config/pi/extensions/**/*.ts"
53
+ ```
54
+
55
+ ### domain
56
+ Tags for cross-cutting concerns. Useful for searching related docs.
57
+
58
+ ```yaml
59
+ domain: [hooks, claude, pi, enforcement]
60
+ ```
61
+
62
+ ## Version Bumping Rules
63
+
64
+ | Change | Bump |
65
+ |---|---|
66
+ | Fix a typo or outdated detail | `patch` (1.0.0 → 1.0.1) |
67
+ | Add a new section | `minor` (1.0.0 → 1.1.0) |
68
+ | Full rewrite or restructure | `major` (1.0.0 → 2.0.0) |
69
+
70
+ Always update `updated:` to today's date alongside the version bump.
71
+
72
+ ## INDEX Block
73
+
74
+ `validate_doc.py` auto-generates a navigation table from `##` headings:
75
+
76
+ ```markdown
77
+ <!-- INDEX: auto-generated by validate_doc.py — do not edit manually -->
78
+ | Section | Summary |
79
+ |---|---|
80
+ | [Overview](#overview) | ... |
81
+ | [Hook Events](#hook-events) | ... |
82
+ <!-- END INDEX -->
83
+ ```
84
+
85
+ This block is regenerated every time `validate_doc.py` runs on the file. Do not edit it manually.
86
+
87
+ ## Complete Example
88
+
89
+ ```yaml
90
+ ---
91
+ title: Hooks Reference
92
+ scope: hooks
93
+ category: reference
94
+ version: 1.1.0
95
+ updated: 2026-03-18
96
+ description: "All hook events, scripts, and behavior for the xtrm plugin"
97
+ source_of_truth_for:
98
+ - "hooks/**/*.mjs"
99
+ - "policies/beads.json"
100
+ - "policies/main-guard.json"
101
+ domain: [hooks, claude, enforcement]
102
+ ---
103
+ ```