@harness-engineering/cli 1.26.1 → 1.27.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 (149) hide show
  1. package/dist/agents/skills/claude-code/cleanup-dead-code/SKILL.md +3 -1
  2. package/dist/agents/skills/claude-code/detect-doc-drift/SKILL.md +3 -1
  3. package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +4 -0
  4. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +55 -24
  5. package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +16 -5
  6. package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +21 -6
  7. package/dist/agents/skills/claude-code/harness-codebase-cleanup/SKILL.md +2 -0
  8. package/dist/agents/skills/claude-code/harness-debugging/SKILL.md +13 -1
  9. package/dist/agents/skills/claude-code/harness-dependency-health/SKILL.md +4 -0
  10. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +16 -6
  11. package/dist/agents/skills/claude-code/harness-impact-analysis/SKILL.md +2 -0
  12. package/dist/agents/skills/claude-code/harness-integration/SKILL.md +560 -0
  13. package/dist/agents/skills/claude-code/harness-integration/skill.yaml +65 -0
  14. package/dist/agents/skills/claude-code/harness-integrity/SKILL.md +2 -0
  15. package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +4 -0
  16. package/dist/agents/skills/claude-code/harness-perf/SKILL.md +9 -7
  17. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +77 -10
  18. package/dist/agents/skills/claude-code/harness-refactoring/SKILL.md +13 -4
  19. package/dist/agents/skills/claude-code/harness-security-scan/SKILL.md +3 -1
  20. package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +4 -0
  21. package/dist/agents/skills/claude-code/harness-tdd/SKILL.md +5 -2
  22. package/dist/agents/skills/claude-code/harness-verification/SKILL.md +4 -0
  23. package/dist/agents/skills/codex/cleanup-dead-code/SKILL.md +3 -1
  24. package/dist/agents/skills/codex/detect-doc-drift/SKILL.md +3 -1
  25. package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +4 -0
  26. package/dist/agents/skills/codex/harness-autopilot/SKILL.md +55 -24
  27. package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +16 -5
  28. package/dist/agents/skills/codex/harness-code-review/SKILL.md +21 -6
  29. package/dist/agents/skills/codex/harness-codebase-cleanup/SKILL.md +2 -0
  30. package/dist/agents/skills/codex/harness-debugging/SKILL.md +13 -1
  31. package/dist/agents/skills/codex/harness-dependency-health/SKILL.md +4 -0
  32. package/dist/agents/skills/codex/harness-execution/SKILL.md +16 -6
  33. package/dist/agents/skills/codex/harness-impact-analysis/SKILL.md +2 -0
  34. package/dist/agents/skills/codex/harness-integration/SKILL.md +560 -0
  35. package/dist/agents/skills/codex/harness-integration/skill.yaml +65 -0
  36. package/dist/agents/skills/codex/harness-integrity/SKILL.md +2 -0
  37. package/dist/agents/skills/codex/harness-onboarding/SKILL.md +4 -0
  38. package/dist/agents/skills/codex/harness-perf/SKILL.md +9 -7
  39. package/dist/agents/skills/codex/harness-planning/SKILL.md +77 -10
  40. package/dist/agents/skills/codex/harness-refactoring/SKILL.md +13 -4
  41. package/dist/agents/skills/codex/harness-security-scan/SKILL.md +3 -1
  42. package/dist/agents/skills/codex/harness-soundness-review/SKILL.md +4 -0
  43. package/dist/agents/skills/codex/harness-tdd/SKILL.md +5 -2
  44. package/dist/agents/skills/codex/harness-verification/SKILL.md +4 -0
  45. package/dist/agents/skills/cursor/cleanup-dead-code/SKILL.md +3 -1
  46. package/dist/agents/skills/cursor/detect-doc-drift/SKILL.md +3 -1
  47. package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +4 -0
  48. package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +55 -24
  49. package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +16 -5
  50. package/dist/agents/skills/cursor/harness-code-review/SKILL.md +21 -6
  51. package/dist/agents/skills/cursor/harness-codebase-cleanup/SKILL.md +2 -0
  52. package/dist/agents/skills/cursor/harness-debugging/SKILL.md +13 -1
  53. package/dist/agents/skills/cursor/harness-dependency-health/SKILL.md +4 -0
  54. package/dist/agents/skills/cursor/harness-execution/SKILL.md +16 -6
  55. package/dist/agents/skills/cursor/harness-impact-analysis/SKILL.md +2 -0
  56. package/dist/agents/skills/cursor/harness-integration/SKILL.md +560 -0
  57. package/dist/agents/skills/cursor/harness-integration/skill.yaml +65 -0
  58. package/dist/agents/skills/cursor/harness-integrity/SKILL.md +2 -0
  59. package/dist/agents/skills/cursor/harness-onboarding/SKILL.md +4 -0
  60. package/dist/agents/skills/cursor/harness-perf/SKILL.md +9 -7
  61. package/dist/agents/skills/cursor/harness-planning/SKILL.md +77 -10
  62. package/dist/agents/skills/cursor/harness-refactoring/SKILL.md +13 -4
  63. package/dist/agents/skills/cursor/harness-security-scan/SKILL.md +3 -1
  64. package/dist/agents/skills/cursor/harness-soundness-review/SKILL.md +4 -0
  65. package/dist/agents/skills/cursor/harness-tdd/SKILL.md +5 -2
  66. package/dist/agents/skills/cursor/harness-verification/SKILL.md +4 -0
  67. package/dist/agents/skills/gemini-cli/cleanup-dead-code/SKILL.md +3 -1
  68. package/dist/agents/skills/gemini-cli/detect-doc-drift/SKILL.md +3 -1
  69. package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +4 -0
  70. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +55 -24
  71. package/dist/agents/skills/gemini-cli/harness-brainstorming/SKILL.md +16 -5
  72. package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +21 -6
  73. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/SKILL.md +2 -0
  74. package/dist/agents/skills/gemini-cli/harness-debugging/SKILL.md +13 -1
  75. package/dist/agents/skills/gemini-cli/harness-dependency-health/SKILL.md +4 -0
  76. package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +16 -6
  77. package/dist/agents/skills/gemini-cli/harness-impact-analysis/SKILL.md +2 -0
  78. package/dist/agents/skills/gemini-cli/harness-integration/SKILL.md +560 -0
  79. package/dist/agents/skills/gemini-cli/harness-integration/skill.yaml +65 -0
  80. package/dist/agents/skills/gemini-cli/harness-integrity/SKILL.md +2 -0
  81. package/dist/agents/skills/gemini-cli/harness-onboarding/SKILL.md +4 -0
  82. package/dist/agents/skills/gemini-cli/harness-perf/SKILL.md +9 -7
  83. package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +77 -10
  84. package/dist/agents/skills/gemini-cli/harness-refactoring/SKILL.md +13 -4
  85. package/dist/agents/skills/gemini-cli/harness-security-scan/SKILL.md +3 -1
  86. package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +4 -0
  87. package/dist/agents/skills/gemini-cli/harness-tdd/SKILL.md +5 -2
  88. package/dist/agents/skills/gemini-cli/harness-verification/SKILL.md +4 -0
  89. package/dist/{agents-md-VI3HLR7E.js → agents-md-2RN666DE.js} +3 -3
  90. package/dist/{architecture-ZDDKEVID.js → architecture-ZR33YKJB.js} +4 -4
  91. package/dist/{assess-project-Y6W7YDUA.js → assess-project-LLWWEQEV.js} +1 -1
  92. package/dist/bin/harness-mcp.js +17 -16
  93. package/dist/bin/harness.js +27 -26
  94. package/dist/{business-knowledge-6RHYJOB3.js → business-knowledge-EISPR7FU.js} +1 -1
  95. package/dist/{check-phase-gate-CXR3VM22.js → check-phase-gate-ZVG56NT2.js} +4 -4
  96. package/dist/chunk-27AJKSQY.js +107 -0
  97. package/dist/{chunk-DBIX3X4H.js → chunk-2FOLD76X.js} +2 -2
  98. package/dist/{chunk-3AMQYWGT.js → chunk-3AJW7VQ3.js} +2 -2
  99. package/dist/{chunk-FUND5WJR.js → chunk-3XMOWLK3.js} +2 -2
  100. package/dist/{chunk-OLW7BJ5N.js → chunk-776JFSPK.js} +1 -1
  101. package/dist/{chunk-VKS3F46M.js → chunk-A4ETL34H.js} +7 -2
  102. package/dist/{chunk-JV4Y2U5F.js → chunk-BO4AJZRE.js} +1 -1
  103. package/dist/{chunk-WZ7UHPT3.js → chunk-BZZNYHRY.js} +9 -9
  104. package/dist/{chunk-ZN6ROTYP.js → chunk-C7RPQWBG.js} +1 -1
  105. package/dist/{chunk-RAVD7QLY.js → chunk-CJYNZMOP.js} +8 -8
  106. package/dist/{chunk-PNNFCVW4.js → chunk-EGRQHLDM.js} +5 -5
  107. package/dist/{chunk-2BPPS6YQ.js → chunk-EHTUWULH.js} +458 -363
  108. package/dist/{chunk-N6B6RKQQ.js → chunk-EICASBYP.js} +1 -1
  109. package/dist/{chunk-K56DTX7G.js → chunk-F3Y64VNF.js} +6 -6
  110. package/dist/{chunk-ORNEK65Y.js → chunk-FUS4OOGC.js} +1 -1
  111. package/dist/{chunk-2FPUPRCY.js → chunk-GAIOIINV.js} +594 -127
  112. package/dist/{chunk-YC4EYIER.js → chunk-IBTHD2UA.js} +132 -77
  113. package/dist/{chunk-RC5ZY3EV.js → chunk-IOW3MW2K.js} +2 -2
  114. package/dist/{chunk-B66LRB5M.js → chunk-L3Y7L4EG.js} +1 -1
  115. package/dist/{chunk-BK4DJIIY.js → chunk-MGPVA2EM.js} +27 -4
  116. package/dist/{chunk-NY7DTZ6K.js → chunk-Q5DKIL46.js} +3 -3
  117. package/dist/{chunk-TY2ESLVL.js → chunk-SDDQPMZK.js} +1 -1
  118. package/dist/{chunk-7GY6WNEI.js → chunk-SDPHFDQS.js} +1 -1
  119. package/dist/{chunk-56A6OXVA.js → chunk-T7UZOJF4.js} +9 -9
  120. package/dist/{chunk-AMRC4FU2.js → chunk-VCC47EXU.js} +109 -57
  121. package/dist/{chunk-Q3ZLVMQM.js → chunk-XKU37HGH.js} +10 -1
  122. package/dist/{chunk-TSVYBDDE.js → chunk-YZH4I4JO.js} +1 -1
  123. package/dist/{ci-workflow-EW37KVPS.js → ci-workflow-JFOL4YWW.js} +3 -3
  124. package/dist/{dist-NCNAXUFD.js → dist-BZS2XRLG.js} +5 -1
  125. package/dist/{dist-CJDGASPP.js → dist-CPKL5Y2R.js} +2 -2
  126. package/dist/{docs-4XI2FQW2.js → docs-FUTRJQHA.js} +4 -4
  127. package/dist/{engine-4L4CDTHU.js → engine-FB3HCNVT.js} +3 -3
  128. package/dist/{entropy-PBYSIQYS.js → entropy-FIEE4YDA.js} +3 -3
  129. package/dist/{feedback-OTIFW5MK.js → feedback-7EC4T6XG.js} +1 -1
  130. package/dist/{generate-agent-definitions-CZGUXIIN.js → generate-agent-definitions-FOSFADNR.js} +4 -4
  131. package/dist/{graph-loader-RDXSEBD7.js → graph-loader-QEI7SYOQ.js} +1 -1
  132. package/dist/hooks/adoption-tracker.js +36 -8
  133. package/dist/hooks/sentinel-pre.js +3 -2
  134. package/dist/hooks/telemetry-reporter.js +34 -15
  135. package/dist/index-builder-3AOQ3ZII.js +13 -0
  136. package/dist/index.d.ts +15 -0
  137. package/dist/index.js +29 -28
  138. package/dist/{loader-UZOXCWFC.js → loader-HXUOBTYA.js} +3 -3
  139. package/dist/{mcp-GWVVV6LH.js → mcp-NUG4BMKJ.js} +17 -16
  140. package/dist/{performance-5UQPP3XX.js → performance-TYXBCTR7.js} +4 -4
  141. package/dist/{review-pipeline-65V4EO6O.js → review-pipeline-B4WPU6BQ.js} +3 -3
  142. package/dist/{runtime-PXX7HNB3.js → runtime-HQQNOARD.js} +3 -3
  143. package/dist/{scan-WM7XDUF7.js → scan-M4EGDAQ2.js} +1 -1
  144. package/dist/{security-CAYDRZIZ.js → security-25VFLIAO.js} +1 -1
  145. package/dist/templates/orchestrator/harness.orchestrator.md +18 -8
  146. package/dist/{validate-CWGXR7QM.js → validate-EAVGKZQB.js} +4 -4
  147. package/dist/{validate-cross-check-BKCNLZYG.js → validate-cross-check-SPL3H4O5.js} +3 -3
  148. package/package.json +13 -5
  149. package/dist/hooks/profiles.ts +0 -48
@@ -22,26 +22,28 @@ Tier 1 violations are non-negotiable blockers. If a Tier 1 violation is detected
22
22
 
23
23
  ### Phase 1: ANALYZE — Structural and Coupling Checks
24
24
 
25
- 1. **Run structural checks.** Execute `harness check-perf --structural` to compute complexity metrics for all changed files:
25
+ 1. **Assess current performance posture.** Run `check_performance` to evaluate current performance metrics against defined budgets. Run `get_critical_paths` to identify performance-critical functions and hot paths.
26
+
27
+ 2. **Run structural checks.** Execute `harness check-perf --structural` to compute complexity metrics for all changed files:
26
28
  - Cyclomatic complexity per function
27
29
  - Nesting depth per function
28
30
  - File length (lines of code)
29
31
  - Parameter count per function
30
32
 
31
- 2. **Run coupling checks.** Execute `harness check-perf --coupling` to compute coupling metrics:
33
+ 3. **Run coupling checks.** Execute `harness check-perf --coupling` to compute coupling metrics:
32
34
  - Fan-in and fan-out per module
33
35
  - Afferent and efferent coupling
34
36
  - Transitive dependency depth
35
37
  - Circular dependency detection
36
38
 
37
- 3. **Classify violations by tier:**
39
+ 4. **Classify violations by tier:**
38
40
  - **Tier 1 (error, block commit):** Cyclomatic complexity > 15, circular dependencies, hotspot in top 5%
39
41
  - **Tier 2 (warning, block merge):** Complexity > 10, nesting > 4, fan-out > 10, size budget exceeded
40
42
  - **Tier 3 (info, no gate):** File length > 300, fan-in > 20, transitive depth > 30
41
43
 
42
- 4. **If Tier 1 violations found,** report them immediately and STOP. Do not proceed to benchmarks. The violations must be fixed first.
44
+ 5. **If Tier 1 violations found,** report them immediately and STOP. Do not proceed to benchmarks. The violations must be fixed first.
43
45
 
44
- 5. **If no violations found,** proceed to Phase 2.
46
+ 6. **If no violations found,** proceed to Phase 2.
45
47
 
46
48
  ---
47
49
 
@@ -83,7 +85,7 @@ This phase runs only when `.bench.ts` files exist in the project. If none are fo
83
85
 
84
86
  4. **Run benchmarks.** Execute `harness perf bench` to run all benchmark suites.
85
87
 
86
- 5. **Load baselines.** Read `.harness/perf/baselines.json` for previous benchmark results. If no baselines exist, treat this as a baseline-capture run.
88
+ 5. **Load baselines.** Load existing baselines via `get_perf_baselines` before running new benchmarks. Read `.harness/perf/baselines.json` for previous benchmark results. If no baselines exist, treat this as a baseline-capture run.
87
89
 
88
90
  6. **Compare results against baselines** using the `RegressionDetector`:
89
91
  - Calculate percentage change for each benchmark
@@ -100,7 +102,7 @@ This phase runs only when `.bench.ts` files exist in the project. If none are fo
100
102
  - **Tier 2:** >10% regression on a non-critical-path benchmark
101
103
  - **Tier 3:** >5% regression on a non-critical-path benchmark (within noise margin consideration)
102
104
 
103
- 9. **If this is a baseline-capture run,** report results without regression comparison. Recommend running `harness perf baselines update` to persist.
105
+ 9. **If this is a baseline-capture run,** report results without regression comparison. Recommend running `harness perf baselines update` to persist. After benchmarks pass, update baselines via `update_perf_baselines` to record new performance targets.
104
106
 
105
107
  ---
106
108
 
@@ -29,6 +29,7 @@ The `rigorLevel` is passed by autopilot (or set via `--fast`/`--thorough` flags)
29
29
  | Phase | `fast` | `standard` (default) | `thorough` |
30
30
  | --------- | -------------------------------------------------- | ------------------------------------------ | --------------------------------------------------- |
31
31
  | SCOPE | No change. | No change. | No change. |
32
+ | KNOWLEDGE | Skip entirely. | Run detect; fix if gaps found. | Run detect; fix if gaps found. |
32
33
  | DECOMPOSE | Skip skeleton. Full tasks directly after file map. | Skeleton if tasks >= 8; full tasks if < 8. | Always skeleton. Require approval before expanding. |
33
34
  | SEQUENCE | No change. | No change. | No change. |
34
35
  | VALIDATE | No change. | No change. | No change. |
@@ -41,7 +42,7 @@ The skeleton pass is the primary rigor lever. Fast mode goes straight to full de
41
42
 
42
43
  When invoked by autopilot (or with explicit arguments), resolve paths before starting:
43
44
 
44
- 1. **Session slug:** If `session-slug` argument provided, set `{sessionDir} = .harness/sessions/<session-slug>/`. Pass to `gather_context({ session: "<session-slug>" })`. All handoff writes go to `{sessionDir}/handoff.json`.
45
+ 1. **Session slug:** If `session-slug` argument provided, set `{sessionDir} = .harness/sessions/<session-slug>/`. Pass to `gather_context({ session: "<session-slug>", include: ["state", "learnings", "handoff", "graph", "businessKnowledge", "sessions", "validation"] })`. All handoff writes go to `{sessionDir}/handoff.json`.
45
46
  2. **Spec path:** If `spec-path` argument provided, read spec from that path. Otherwise, discover from `{sessionDir}/handoff.json` (read upstream brainstorming output) or prompt the user.
46
47
  3. **Rigor level:** If `fast`/`thorough` argument provided, use it. Otherwise default to `standard`.
47
48
 
@@ -69,14 +70,16 @@ Work backward from the goal. Start with "what must be true when we are done?"
69
70
 
70
71
  Store the parsed skill list for use in Phase 2 task annotation.
71
72
 
72
- 2. **Derive observable truths.** What can be observed (running a command, opening a browser, reading a file) that proves the goal is met? Be specific:
73
+ 2. **Review prior decisions.** Check `decisions` from the prior brainstorming session (loaded via `sessions` in gather_context). Do not re-decide what was already decided build on those choices.
74
+
75
+ 3. **Derive observable truths.** What can be observed (running a command, opening a browser, reading a file) that proves the goal is met? Be specific:
73
76
  - BAD: "The API handles errors"
74
77
  - GOOD: "GET /api/users/nonexistent returns 404 with `{ error: 'User not found' }` body"
75
- 3. **Derive required artifacts.** For each truth, what files must exist? What functions? What tests pass? List exact file paths.
76
- 4. **Identify key links.** How do artifacts connect? What imports what? What calls what?
77
- 5. **Apply YAGNI.** For every artifact: "Is this required for an observable truth?" If not, cut it.
78
+ 4. **Derive required artifacts.** For each truth, what files must exist? What functions? What tests pass? List exact file paths.
79
+ 5. **Identify key links.** How do artifacts connect? What imports what? What calls what?
80
+ 6. **Apply YAGNI.** For every artifact: "Is this required for an observable truth?" If not, cut it.
78
81
 
79
- 6. **Surface uncertainties.** Before proceeding to Phase 2, explicitly list what you do NOT know. For each uncertainty, classify it:
82
+ 7. **Surface uncertainties.** Before proceeding to Phase 2, explicitly list what you do NOT know. For each uncertainty, classify it:
80
83
  - **Blocking:** Cannot decompose tasks without resolving this. Escalate to user.
81
84
  - **Assumption:** Can proceed with a stated assumption. Document it. If wrong, specific tasks will need revision.
82
85
  - **Deferrable:** Does not affect task decomposition. Note for execution phase.
@@ -90,7 +93,7 @@ Store the parsed skill list for use in Phase 2 task annotation.
90
93
  - [DEFERRABLE] Exact error message wording. (Can be finalized during implementation.)
91
94
  ```
92
95
 
93
- **Read-only constraint:** Steps 1-5 above are research and analysis. Do not propose task structure, file organization, or implementation approaches during SCOPE. Record what must be true (observable truths) and what you do not know (uncertainties). Solutions belong in DECOMPOSE.
96
+ **Read-only constraint:** Steps 1-6 above are research and analysis. Do not propose task structure, file organization, or implementation approaches during SCOPE. Record what must be true (observable truths) and what you do not know (uncertainties). Solutions belong in DECOMPOSE.
94
97
 
95
98
  When scope is ambiguous, use `emit_interaction`:
96
99
 
@@ -160,9 +163,39 @@ When a knowledge graph exists at `.harness/graph/`, use graph queries for faster
160
163
 
161
164
  - `query_graph` — discover module dependencies for realistic task decomposition
162
165
  - `get_impact` — estimate which modules a feature touches
166
+ - `compute_blast_radius` — simulate failure propagation from target files to understand scope
167
+ - `predict_failures` — forecast which architectural constraints are at risk from planned changes, informing where extra test coverage or smaller tasks are needed
168
+ - `detect_anomalies` — identify structural irregularities in the affected area before planning tasks around them
163
169
 
164
170
  Fall back to file-based commands if no graph is available.
165
171
 
172
+ ### Intelligence Signals (when orchestrator is available)
173
+
174
+ If the orchestrator is running, request intelligence analysis via `POST /api/analyze` with the feature title/description before decomposing. The pipeline returns:
175
+
176
+ - **SEL** (Spec Enrichment) — affected systems and blast radius derived from the graph
177
+ - **CML** (Complexity Modeling) — structural, semantic, and historical complexity scores. Use `structuralComplexity > 0.7` to flag areas needing smaller, more cautious tasks.
178
+ - **PESL** (Pre-Execution Simulation) — simulated risk score. Use `riskScore > 0.6` to add extra checkpoints or split risky tasks further.
179
+
180
+ If no orchestrator, `predict_failures` and `compute_blast_radius` MCP tools provide equivalent directional signals.
181
+
182
+ ---
183
+
184
+ ### Phase 1.5: KNOWLEDGE BASELINE — Materialize Domain Knowledge
185
+
186
+ Before decomposing into tasks, ensure domain knowledge from PRDs and specs is documented. **Skip this phase** when no PRDs, specs, or business domain documents exist in the project, or when rigor level is `fast`.
187
+
188
+ 1. **Run knowledge pipeline in detect mode.** Execute `harness knowledge-pipeline --domain <feature-domain>` to produce a differential gap report comparing extracted business rules against documented knowledge in `docs/knowledge/`.
189
+
190
+ 2. **If gaps exist and `--fix` is appropriate,** run `harness knowledge-pipeline --fix --domain <feature-domain>` to materialize `docs/knowledge/{domain}/*.md` files from extracted findings. This creates the knowledge baseline from PRDs before any tasks are written.
191
+
192
+ 3. **Cross-check uncertainties against materialized knowledge** (from `businessKnowledge` loaded in gather_context and freshly materialized docs):
193
+ - Remove "assumptions" from the uncertainty list that are now documented facts in `docs/knowledge/`
194
+ - Escalate if contradictions exist between PRDs and existing knowledge docs
195
+ - Use `business_fact` nodes from the graph context to validate domain assumptions
196
+
197
+ 4. **Reference materialized knowledge in Phase 2 task decomposition.** Tasks should reference specific knowledge docs they implement. Observable truths should map back to documented business rules. Use the `businessKnowledge` context (domains, tags, documented facts) loaded in Phase 1 to ground task instructions in verified domain knowledge rather than assumptions.
198
+
166
199
  ---
167
200
 
168
201
  ### Phase 2: DECOMPOSE — Map File Structure and Create Tasks
@@ -219,11 +252,33 @@ Report progress: `**[Phase 2/4]** DECOMPOSE — mapping file structure and creat
219
252
  - `[checkpoint:decision]` — Pause, present options, wait for choice
220
253
  - `[checkpoint:human-action]` — Pause, instruct human on required action
221
254
 
255
+ 7. **Derive integration tasks from the spec's Integration Points section.** If the spec contains an Integration Points section, create tasks for each non-empty integration point. Skip subsections marked "None" — do not derive tasks from them. Integration tasks are normal plan tasks but tagged with `category: "integration"` in their description. They appear at the end of the task list, after all implementation tasks.
256
+
257
+ For each subsection of Integration Points, derive tasks:
258
+
259
+ | Integration Point | Example Derived Task |
260
+ | ----------------------------------------------- | -------------------------------------------------------------------------- |
261
+ | Entry Points: "New CLI command" | "Regenerate barrel exports. Verify new command appears in `_registry.ts`." |
262
+ | Registrations Required: "Skill at tier 2" | "Add skill to tier list in `AGENTS.md`. Generate slash commands." |
263
+ | Documentation Updates: "AGENTS.md capabilities" | "Update AGENTS.md to describe the feature." |
264
+ | Architectural Decisions: "ADR for approach X" | "Write ADR `docs/knowledge/decisions/NNNN-<slug>.md`." |
265
+ | Knowledge Impact: "Domain concept Y" | "Enrich knowledge graph with concept node." |
266
+
267
+ Integration tasks follow the same atomic task rules (2-5 minutes, exact file paths, exact code). Use the `**Category:** integration` tag in the task header, e.g.:
268
+
269
+ ```
270
+ ### Task N: Update AGENTS.md with new feature description
271
+
272
+ **Depends on:** Task N-1 | **Files:** `AGENTS.md` | **Category:** integration
273
+ ```
274
+
275
+ If the spec has no Integration Points section, skip this step.
276
+
222
277
  ---
223
278
 
224
279
  ### Phase 3: SEQUENCE — Order Tasks and Identify Dependencies
225
280
 
226
- 1. **Order by dependency.** Types before implementations. Implementations before integrations. Tests alongside implementations (same task, TDD style).
281
+ 1. **Order by dependency.** Types before implementations. Implementations before integrations. Integration tasks (tagged `category: "integration"`) after all implementation tasks. Tests alongside implementations (same task, TDD style).
227
282
  2. **Identify parallel opportunities.** Tasks touching different subsystems with no shared state can be marked parallelizable.
228
283
  3. **Number tasks sequentially.** Use `Task 1`, `Task 2`, etc. Dependencies reference task numbers.
229
284
  4. **Estimate total time.** Sum 2-5 minutes per task. If total exceeds available time, identify a milestone boundary for pausing.
@@ -260,7 +315,7 @@ Report progress: `**[Phase 2/4]** DECOMPOSE — mapping file structure and creat
260
315
  ```markdown
261
316
  # Plan: <Feature Name>
262
317
 
263
- **Date:** YYYY-MM-DD | **Spec:** (if applicable) | **Tasks:** N | **Time:** N min
318
+ **Date:** YYYY-MM-DD | **Spec:** (if applicable) | **Tasks:** N | **Time:** N min | **Integration Tier:** small | medium | large
264
319
 
265
320
  ## Goal
266
321
 
@@ -298,6 +353,18 @@ One sentence.
298
353
  [checkpoint:human-verify] ...
299
354
  ```
300
355
 
356
+ ### Integration Tier Heuristics
357
+
358
+ When a spec contains an **Integration Points** section, set the plan's `integrationTier` field based on scope:
359
+
360
+ | Tier | Signal | Integration Requirements |
361
+ | ---------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------ |
362
+ | **small** | Bug fix, config change, < 3 files, no new exports | Wiring checks only (defaults always run) |
363
+ | **medium** | New feature within existing package, new exports, 3-15 files | Wiring + project updates (roadmap, changelog, graph enrichment) |
364
+ | **large** | New package, new skill, new public API surface, architectural change | Wiring + project updates + knowledge materialization (ADRs, doc updates) |
365
+
366
+ If the spec has no Integration Points section, omit the `integrationTier` field from the plan header.
367
+
301
368
  ## Session State
302
369
 
303
370
  | Section | Read | Write | Purpose |
@@ -311,7 +378,7 @@ One sentence.
311
378
 
312
379
  **When to write:** Phase 1 — constraints and risks. Phase 2 — decisions about task structure. Phase 4 — resolve questions.
313
380
 
314
- **When to read:** Start of Phase 1 via `gather_context` with `include: ["sessions"]` to inherit brainstorming context.
381
+ **When to read:** Start of Phase 1 via `gather_context` with `include: ["state", "learnings", "handoff", "graph", "businessKnowledge", "sessions", "validation"]` to inherit brainstorming context and load documented business knowledge.
315
382
 
316
383
  ## Evidence Requirements
317
384
 
@@ -28,9 +28,11 @@ If tests are not green before you start, you are not refactoring — you are deb
28
28
 
29
29
  2. **Run `harness validate`** and **`harness check-deps`**. Both must pass. You are establishing a clean baseline. If either reports issues, fix those first (that is a separate task, not part of this refactoring).
30
30
 
31
- 3. **Identify the refactoring target.** Be specific: which file, function, class, or module? What is wrong with the current structure? What will be better after refactoring?
31
+ 3. **Run `compute_blast_radius` on target files** to understand downstream impact before refactoring. This reveals which modules, tests, and consumers will be affected by structural changes.
32
32
 
33
- 4. **Plan the steps.** Break the refactoring into the smallest possible individual changes. Each step should be independently committable and verifiable. If you cannot describe a step in one sentence, it is too large.
33
+ 4. **Identify the refactoring target.** Be specific: which file, function, class, or module? What is wrong with the current structure? What will be better after refactoring?
34
+
35
+ 5. **Plan the steps.** Break the refactoring into the smallest possible individual changes. Each step should be independently committable and verifiable. If you cannot describe a step in one sentence, it is too large.
34
36
 
35
37
  ### Graph-Enhanced Context (when available)
36
38
 
@@ -81,6 +83,10 @@ For EACH step in the plan:
81
83
 
82
84
  2. **Run `harness validate` and `harness check-deps` one final time.** Clean output.
83
85
 
86
+ 3. **Run `detect_stale_constraints`** to verify architectural constraints are still valid after structural changes. Refactoring can render existing constraints obsolete or misaligned.
87
+
88
+ 4. **Run `check_traceability`** to confirm refactoring didn't break requirement-to-implementation mappings. Moved or renamed code may orphan traceability links.
89
+
84
90
  ### Graph Refresh
85
91
 
86
92
  If a knowledge graph exists at `.harness/graph/`, refresh it after code changes to keep graph queries accurate:
@@ -91,9 +97,9 @@ harness scan [path]
91
97
 
92
98
  Skipping this step means subsequent graph queries (impact analysis, dependency health, test advisor) may return stale results.
93
99
 
94
- 3. **Review the cumulative diff.** Does the final state match the intended improvement? Is the code genuinely better, or just different?
100
+ 5. **Review the cumulative diff.** Does the final state match the intended improvement? Is the code genuinely better, or just different?
95
101
 
96
- 4. **If the refactoring introduced no improvement,** revert the entire sequence. Refactoring for its own sake is churn.
102
+ 6. **If the refactoring introduced no improvement,** revert the entire sequence. Refactoring for its own sake is churn.
97
103
 
98
104
  ## Common Refactoring Patterns
99
105
 
@@ -133,6 +139,9 @@ Skipping this step means subsequent graph queries (impact analysis, dependency h
133
139
  - **`harness check-deps`** — Run after each step, especially when moving code between files or layers. Catches dependency violations introduced by structural changes.
134
140
  - **`harness check-docs`** — Run after renaming or moving public APIs. Catches documentation that references old names or locations.
135
141
  - **`harness cleanup`** — Run after completing a refactoring sequence. Detects dead code that the refactoring may have created (unused exports, orphaned files).
142
+ - **`compute_blast_radius`** — Run in Phase 1 PREPARE before making changes. Reveals downstream impact of target files so you understand what the refactoring will affect.
143
+ - **`detect_stale_constraints`** — Run in Phase 3 VERIFY after refactoring. Checks whether architectural constraints are still valid after structural changes.
144
+ - **`check_traceability`** — Run in Phase 3 VERIFY after refactoring. Confirms requirement-to-implementation mappings were not broken by moved or renamed code.
136
145
 
137
146
  ## Success Criteria
138
147
 
@@ -34,7 +34,9 @@
34
34
  - `warning`: errors and warnings (default)
35
35
  - `info`: all findings
36
36
 
37
- 6. **Output report.** Present findings grouped by severity:
37
+ 6. **Check security trends.** Check `get_security_trends` to compare current scan results against the project's security posture history and identify trajectory changes.
38
+
39
+ 7. **Output report.** Present findings grouped by severity:
38
40
 
39
41
  ```
40
42
  Security Scan: [PASS/FAIL]
@@ -47,6 +47,10 @@ Every finding conforms to this structure:
47
47
 
48
48
  Execute all checks for the active mode. Classify each finding as `autoFixable: true` or `false`. Record total issue count.
49
49
 
50
+ #### Traceability and Cross-Check Tools
51
+
52
+ Run `check_traceability` to verify that all requirements in the spec/plan have corresponding implementation artifacts. Run `validate_cross_check` to verify plan-to-implementation alignment as part of the soundness assessment.
53
+
50
54
  #### Graph Detection and Fallback
51
55
 
52
56
  Before running checks, determine graph availability:
@@ -71,9 +71,11 @@ If you find yourself writing production code first, STOP. Delete it. Write the t
71
71
 
72
72
  2. **Run `harness validate`** to verify the full project health. This catches architectural drift, documentation gaps, and constraint violations.
73
73
 
74
- 3. **If either check fails,** fix the issue before committing. The fix may require another RED-GREEN-REFACTOR cycle if it involves behavioral changes.
74
+ 3. **Run `check_traceability`** to verify new tests map to specific requirements, ensuring test coverage aligns with spec expectations. This catches tests that exist in isolation without a traced requirement.
75
75
 
76
- 4. **Commit the cycle.** Each RED-GREEN-REFACTOR-VALIDATE cycle produces one atomic commit. The commit message references what behavior was added (not "add test" — describe the behavior).
76
+ 4. **If any check fails,** fix the issue before committing. The fix may require another RED-GREEN-REFACTOR cycle if it involves behavioral changes.
77
+
78
+ 5. **Commit the cycle.** Each RED-GREEN-REFACTOR-VALIDATE cycle produces one atomic commit. The commit message references what behavior was added (not "add test" — describe the behavior).
77
79
 
78
80
  ### Graph Refresh
79
81
 
@@ -111,6 +113,7 @@ Repeat the 4 phases for each new behavior. A typical feature requires 3-10 cycle
111
113
  - **`harness check-deps`** — Run in VALIDATE phase after each cycle. Catches forbidden imports and layer boundary violations introduced by new code.
112
114
  - **`harness validate`** — Run in VALIDATE phase after each cycle. Full project health check including architecture, documentation, and constraints.
113
115
  - **`harness cleanup`** — Run periodically (every 3-5 cycles) to detect entropy accumulation. Address any issues before they compound.
116
+ - **`check_traceability`** — Run in VALIDATE phase after tests are written. Verifies new tests map to specific requirements so test coverage aligns with spec expectations.
114
117
  - **Test runner** — Use the project's configured test runner. Harness does not prescribe a test framework but the test must actually execute and report results.
115
118
 
116
119
  ## Success Criteria
@@ -386,6 +386,10 @@ Task: "Create UserService with CRUD operations."
386
386
  - **`harness check-deps`** -- Run during Level 3 (WIRED) to verify dependency boundaries.
387
387
  - **`harness check-docs`** -- Verify documentation updated for new artifacts. Missing docs for public APIs is a gap.
388
388
  - **Test runner** -- Must be run fresh (not cached) during Level 3. Read actual output, check exit codes.
389
+ - **`check_traceability`** -- Run during Level 3 (WIRED) to verify every requirement in the spec maps to at least one implemented artifact and test.
390
+ - **`validate_cross_check`** -- Run after Level 3 against the plan to verify implementation matches planned file map and task descriptions.
391
+ - **`check_phase_gate`** -- Run before producing the verification report to validate the current phase meets all gate criteria before marking complete.
392
+ - **`detect_anomalies`** -- Run during the Anti-Pattern Scan to identify structural inconsistencies (orphaned files, missing tests, unusual coupling) introduced during execution.
389
393
  - **`emit_interaction`** -- Auto-transition to harness-code-review on PASS verdict only.
390
394
  - **Session directory** -- `.harness/sessions/<slug>/` contains `handoff.json`, `state.json`, `artifacts.json` (spec path, plan path, file lists from execution). Do not write to global `.harness/handoff.json` when session slug is known.
391
395
 
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  generateAgentsMd
3
- } from "./chunk-ZN6ROTYP.js";
4
- import "./chunk-YC4EYIER.js";
3
+ } from "./chunk-C7RPQWBG.js";
4
+ import "./chunk-IBTHD2UA.js";
5
5
  import "./chunk-RL4VMEXL.js";
6
- import "./chunk-2FPUPRCY.js";
6
+ import "./chunk-GAIOIINV.js";
7
7
  import "./chunk-KFQGP6VL.js";
8
8
  export {
9
9
  generateAgentsMd
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  checkDependenciesDefinition,
3
3
  handleCheckDependencies
4
- } from "./chunk-BK4DJIIY.js";
5
- import "./chunk-TSVYBDDE.js";
4
+ } from "./chunk-MGPVA2EM.js";
5
+ import "./chunk-YZH4I4JO.js";
6
6
  import "./chunk-EPUKTTJZ.js";
7
7
  import "./chunk-W6Y7ZW3Y.js";
8
- import "./chunk-YC4EYIER.js";
8
+ import "./chunk-IBTHD2UA.js";
9
9
  import "./chunk-RL4VMEXL.js";
10
- import "./chunk-2FPUPRCY.js";
10
+ import "./chunk-GAIOIINV.js";
11
11
  import "./chunk-KFQGP6VL.js";
12
12
  export {
13
13
  checkDependenciesDefinition,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  assessProjectDefinition,
3
3
  handleAssessProject
4
- } from "./chunk-K56DTX7G.js";
4
+ } from "./chunk-F3Y64VNF.js";
5
5
  import "./chunk-W6Y7ZW3Y.js";
6
6
  import "./chunk-KFQGP6VL.js";
7
7
  export {
@@ -1,27 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startServer
4
- } from "../chunk-2BPPS6YQ.js";
5
- import "../chunk-K56DTX7G.js";
6
- import "../chunk-RC5ZY3EV.js";
7
- import "../chunk-WZ7UHPT3.js";
8
- import "../chunk-3AMQYWGT.js";
9
- import "../chunk-DBIX3X4H.js";
10
- import "../chunk-NY7DTZ6K.js";
11
- import "../chunk-BK4DJIIY.js";
12
- import "../chunk-TSVYBDDE.js";
13
- import "../chunk-56A6OXVA.js";
14
- import "../chunk-PNNFCVW4.js";
15
- import "../chunk-RAVD7QLY.js";
4
+ } from "../chunk-EHTUWULH.js";
5
+ import "../chunk-2FOLD76X.js";
6
+ import "../chunk-F3Y64VNF.js";
7
+ import "../chunk-IOW3MW2K.js";
8
+ import "../chunk-BZZNYHRY.js";
9
+ import "../chunk-3AJW7VQ3.js";
10
+ import "../chunk-776JFSPK.js";
11
+ import "../chunk-Q5DKIL46.js";
12
+ import "../chunk-MGPVA2EM.js";
13
+ import "../chunk-YZH4I4JO.js";
14
+ import "../chunk-T7UZOJF4.js";
15
+ import "../chunk-EGRQHLDM.js";
16
+ import "../chunk-CJYNZMOP.js";
16
17
  import "../chunk-EPUKTTJZ.js";
17
18
  import "../chunk-W6Y7ZW3Y.js";
18
- import "../chunk-VKS3F46M.js";
19
+ import "../chunk-27AJKSQY.js";
20
+ import "../chunk-A4ETL34H.js";
19
21
  import "../chunk-3ISINLYT.js";
20
22
  import "../chunk-6B6UN6SG.js";
21
- import "../chunk-OLW7BJ5N.js";
22
- import "../chunk-YC4EYIER.js";
23
+ import "../chunk-IBTHD2UA.js";
23
24
  import "../chunk-RL4VMEXL.js";
24
- import "../chunk-2FPUPRCY.js";
25
+ import "../chunk-GAIOIINV.js";
25
26
  import "../chunk-HIK6OEUF.js";
26
27
  import "../chunk-EBJQ6N4M.js";
27
28
  import "../chunk-3WGJMBKH.js";
@@ -3,44 +3,45 @@ import {
3
3
  createProgram,
4
4
  installCommandTelemetry,
5
5
  printFirstRunWelcome
6
- } from "../chunk-AMRC4FU2.js";
7
- import "../chunk-ZN6ROTYP.js";
8
- import "../chunk-ORNEK65Y.js";
9
- import "../chunk-7GY6WNEI.js";
10
- import "../chunk-B66LRB5M.js";
6
+ } from "../chunk-VCC47EXU.js";
7
+ import "../chunk-EICASBYP.js";
8
+ import "../chunk-C7RPQWBG.js";
9
+ import "../chunk-FUS4OOGC.js";
10
+ import "../chunk-SDPHFDQS.js";
11
+ import "../chunk-L3Y7L4EG.js";
11
12
  import "../chunk-CQ553GZO.js";
12
- import "../chunk-N6B6RKQQ.js";
13
13
  import "../chunk-GISMXMVL.js";
14
14
  import "../chunk-WWACIIBA.js";
15
15
  import "../chunk-TEFCFC4H.js";
16
- import "../chunk-FUND5WJR.js";
17
- import "../chunk-TY2ESLVL.js";
16
+ import "../chunk-3XMOWLK3.js";
17
+ import "../chunk-SDDQPMZK.js";
18
18
  import "../chunk-KET4QQZB.js";
19
- import "../chunk-JV4Y2U5F.js";
20
- import "../chunk-Q3ZLVMQM.js";
19
+ import "../chunk-BO4AJZRE.js";
20
+ import "../chunk-XKU37HGH.js";
21
21
  import {
22
22
  dispatchSkillsFromGit
23
- } from "../chunk-2BPPS6YQ.js";
24
- import "../chunk-K56DTX7G.js";
25
- import "../chunk-RC5ZY3EV.js";
26
- import "../chunk-WZ7UHPT3.js";
27
- import "../chunk-3AMQYWGT.js";
28
- import "../chunk-DBIX3X4H.js";
29
- import "../chunk-NY7DTZ6K.js";
30
- import "../chunk-BK4DJIIY.js";
31
- import "../chunk-TSVYBDDE.js";
32
- import "../chunk-56A6OXVA.js";
33
- import "../chunk-PNNFCVW4.js";
34
- import "../chunk-RAVD7QLY.js";
23
+ } from "../chunk-EHTUWULH.js";
24
+ import "../chunk-2FOLD76X.js";
25
+ import "../chunk-F3Y64VNF.js";
26
+ import "../chunk-IOW3MW2K.js";
27
+ import "../chunk-BZZNYHRY.js";
28
+ import "../chunk-3AJW7VQ3.js";
29
+ import "../chunk-776JFSPK.js";
30
+ import "../chunk-Q5DKIL46.js";
31
+ import "../chunk-MGPVA2EM.js";
32
+ import "../chunk-YZH4I4JO.js";
33
+ import "../chunk-T7UZOJF4.js";
34
+ import "../chunk-EGRQHLDM.js";
35
+ import "../chunk-CJYNZMOP.js";
35
36
  import "../chunk-EPUKTTJZ.js";
36
37
  import "../chunk-W6Y7ZW3Y.js";
38
+ import "../chunk-27AJKSQY.js";
37
39
  import {
38
40
  findConfigFile,
39
41
  loadConfig
40
- } from "../chunk-VKS3F46M.js";
42
+ } from "../chunk-A4ETL34H.js";
41
43
  import "../chunk-3ISINLYT.js";
42
44
  import "../chunk-6B6UN6SG.js";
43
- import "../chunk-OLW7BJ5N.js";
44
45
  import {
45
46
  CLI_VERSION
46
47
  } from "../chunk-BM3PWGXQ.js";
@@ -51,9 +52,9 @@ import {
51
52
  readCheckState,
52
53
  shouldRunCheck,
53
54
  spawnBackgroundCheck
54
- } from "../chunk-YC4EYIER.js";
55
+ } from "../chunk-IBTHD2UA.js";
55
56
  import "../chunk-RL4VMEXL.js";
56
- import "../chunk-2FPUPRCY.js";
57
+ import "../chunk-GAIOIINV.js";
57
58
  import "../chunk-ZP5E7YET.js";
58
59
  import "../chunk-HIK6OEUF.js";
59
60
  import "../chunk-EBJQ6N4M.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getBusinessKnowledgeResource
3
- } from "./chunk-RC5ZY3EV.js";
3
+ } from "./chunk-IOW3MW2K.js";
4
4
  import "./chunk-KFQGP6VL.js";
5
5
  export {
6
6
  getBusinessKnowledgeResource
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createCheckPhaseGateCommand,
3
3
  runCheckPhaseGate
4
- } from "./chunk-FUND5WJR.js";
5
- import "./chunk-VKS3F46M.js";
6
- import "./chunk-YC4EYIER.js";
4
+ } from "./chunk-3XMOWLK3.js";
5
+ import "./chunk-A4ETL34H.js";
6
+ import "./chunk-IBTHD2UA.js";
7
7
  import "./chunk-RL4VMEXL.js";
8
- import "./chunk-2FPUPRCY.js";
8
+ import "./chunk-GAIOIINV.js";
9
9
  import "./chunk-EBJQ6N4M.js";
10
10
  import "./chunk-3WGJMBKH.js";
11
11
  import "./chunk-KFQGP6VL.js";
@@ -0,0 +1,107 @@
1
+ import {
2
+ resolveAllSkillsDirs
3
+ } from "./chunk-6B6UN6SG.js";
4
+ import {
5
+ SkillMetadataSchema
6
+ } from "./chunk-HIK6OEUF.js";
7
+
8
+ // src/skill/index-builder.ts
9
+ import fs from "fs";
10
+ import path from "path";
11
+ import crypto from "crypto";
12
+ import { parse } from "yaml";
13
+ function computeSkillsDirHash(skillsDirs) {
14
+ const hash = crypto.createHash("sha256");
15
+ for (const dir of skillsDirs) {
16
+ if (!fs.existsSync(dir)) continue;
17
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
18
+ if (!entry.isDirectory()) continue;
19
+ const yamlPath = path.join(dir, entry.name, "skill.yaml");
20
+ if (!fs.existsSync(yamlPath)) continue;
21
+ const stat = fs.statSync(yamlPath);
22
+ hash.update(`${yamlPath}:${stat.mtimeMs}`);
23
+ }
24
+ }
25
+ return hash.digest("hex");
26
+ }
27
+ function parseSkillEntry(yamlPath, source, tierOverrides) {
28
+ const raw = fs.readFileSync(yamlPath, "utf-8");
29
+ const parsed = parse(raw);
30
+ const result = SkillMetadataSchema.safeParse(parsed);
31
+ if (!result.success) return null;
32
+ const meta = result.data;
33
+ const effectiveTier = tierOverrides?.[meta.name] ?? meta.tier;
34
+ if (meta.internal) return null;
35
+ return {
36
+ tier: effectiveTier ?? 3,
37
+ type: meta.type,
38
+ description: meta.description,
39
+ keywords: meta.keywords ?? [],
40
+ stackSignals: meta.stack_signals ?? [],
41
+ cognitiveMode: meta.cognitive_mode,
42
+ phases: (meta.phases ?? []).map((p) => p.name),
43
+ paths: meta.paths ?? [],
44
+ relatedSkills: meta.related_skills ?? [],
45
+ source,
46
+ addresses: meta.addresses ?? [],
47
+ dependsOn: meta.depends_on ?? [],
48
+ triggers: meta.triggers ?? ["manual"],
49
+ ...meta.context_budget && {
50
+ contextBudget: {
51
+ maxTokens: meta.context_budget.max_tokens,
52
+ priority: meta.context_budget.priority
53
+ }
54
+ }
55
+ };
56
+ }
57
+ function scanDirectory(dir, source, index, tierOverrides) {
58
+ if (!fs.existsSync(dir)) return;
59
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
60
+ if (!entry.isDirectory()) continue;
61
+ if (index.skills[entry.name]) continue;
62
+ const yamlPath = path.join(dir, entry.name, "skill.yaml");
63
+ if (!fs.existsSync(yamlPath)) continue;
64
+ try {
65
+ const parsed = parseSkillEntry(yamlPath, source, tierOverrides);
66
+ if (parsed) index.skills[entry.name] = parsed;
67
+ } catch {
68
+ continue;
69
+ }
70
+ }
71
+ }
72
+ function buildIndex(platform, _projectRoot, tierOverrides) {
73
+ const skillsDirs = resolveAllSkillsDirs(platform);
74
+ const sourceMap = ["project", "community", "bundled"];
75
+ const index = {
76
+ version: 1,
77
+ hash: computeSkillsDirHash(skillsDirs),
78
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
79
+ skills: {}
80
+ };
81
+ for (let i = 0; i < skillsDirs.length; i++) {
82
+ scanDirectory(skillsDirs[i], sourceMap[i] ?? "bundled", index, tierOverrides);
83
+ }
84
+ return index;
85
+ }
86
+ function loadOrRebuildIndex(platform, projectRoot, tierOverrides) {
87
+ const indexPath = path.join(projectRoot, ".harness", "skills-index.json");
88
+ const skillsDirs = resolveAllSkillsDirs(platform);
89
+ const currentHash = computeSkillsDirHash(skillsDirs);
90
+ if (fs.existsSync(indexPath)) {
91
+ try {
92
+ const existing = JSON.parse(fs.readFileSync(indexPath, "utf-8"));
93
+ if (existing.hash === currentHash) return existing;
94
+ } catch {
95
+ }
96
+ }
97
+ const index = buildIndex(platform, projectRoot, tierOverrides);
98
+ fs.mkdirSync(path.dirname(indexPath), { recursive: true });
99
+ fs.writeFileSync(indexPath, JSON.stringify(index, null, 2));
100
+ return index;
101
+ }
102
+
103
+ export {
104
+ computeSkillsDirHash,
105
+ buildIndex,
106
+ loadOrRebuildIndex
107
+ };