@organon-methodology/tools 0.3.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 (287) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +152 -0
  3. package/dist/cli/commands/coverage.d.ts +12 -0
  4. package/dist/cli/commands/coverage.d.ts.map +1 -0
  5. package/dist/cli/commands/coverage.js +80 -0
  6. package/dist/cli/commands/coverage.js.map +1 -0
  7. package/dist/cli/commands/find.d.ts +15 -0
  8. package/dist/cli/commands/find.d.ts.map +1 -0
  9. package/dist/cli/commands/find.js +81 -0
  10. package/dist/cli/commands/find.js.map +1 -0
  11. package/dist/cli/commands/generate-tests.d.ts +14 -0
  12. package/dist/cli/commands/generate-tests.d.ts.map +1 -0
  13. package/dist/cli/commands/generate-tests.js +87 -0
  14. package/dist/cli/commands/generate-tests.js.map +1 -0
  15. package/dist/cli/commands/generate.d.ts +15 -0
  16. package/dist/cli/commands/generate.d.ts.map +1 -0
  17. package/dist/cli/commands/generate.js +77 -0
  18. package/dist/cli/commands/generate.js.map +1 -0
  19. package/dist/cli/commands/health.d.ts +13 -0
  20. package/dist/cli/commands/health.d.ts.map +1 -0
  21. package/dist/cli/commands/health.js +79 -0
  22. package/dist/cli/commands/health.js.map +1 -0
  23. package/dist/cli/commands/init.d.ts +14 -0
  24. package/dist/cli/commands/init.d.ts.map +1 -0
  25. package/dist/cli/commands/init.js +132 -0
  26. package/dist/cli/commands/init.js.map +1 -0
  27. package/dist/cli/commands/mcp.d.ts +11 -0
  28. package/dist/cli/commands/mcp.d.ts.map +1 -0
  29. package/dist/cli/commands/mcp.js +26 -0
  30. package/dist/cli/commands/mcp.js.map +1 -0
  31. package/dist/cli/commands/query.d.ts +19 -0
  32. package/dist/cli/commands/query.d.ts.map +1 -0
  33. package/dist/cli/commands/query.js +103 -0
  34. package/dist/cli/commands/query.js.map +1 -0
  35. package/dist/cli/commands/upgrade.d.ts +13 -0
  36. package/dist/cli/commands/upgrade.d.ts.map +1 -0
  37. package/dist/cli/commands/upgrade.js +162 -0
  38. package/dist/cli/commands/upgrade.js.map +1 -0
  39. package/dist/cli/commands/validate.d.ts +13 -0
  40. package/dist/cli/commands/validate.d.ts.map +1 -0
  41. package/dist/cli/commands/validate.js +89 -0
  42. package/dist/cli/commands/validate.js.map +1 -0
  43. package/dist/cli/commands/verify.d.ts +12 -0
  44. package/dist/cli/commands/verify.d.ts.map +1 -0
  45. package/dist/cli/commands/verify.js +67 -0
  46. package/dist/cli/commands/verify.js.map +1 -0
  47. package/dist/cli/index.d.ts +19 -0
  48. package/dist/cli/index.d.ts.map +1 -0
  49. package/dist/cli/index.js +59 -0
  50. package/dist/cli/index.js.map +1 -0
  51. package/dist/core/add-protocols-array.d.ts +17 -0
  52. package/dist/core/add-protocols-array.d.ts.map +1 -0
  53. package/dist/core/add-protocols-array.js +95 -0
  54. package/dist/core/add-protocols-array.js.map +1 -0
  55. package/dist/core/add-protocols-array.test.d.ts +2 -0
  56. package/dist/core/add-protocols-array.test.d.ts.map +1 -0
  57. package/dist/core/add-protocols-array.test.js +86 -0
  58. package/dist/core/add-protocols-array.test.js.map +1 -0
  59. package/dist/core/config.d.ts +44 -0
  60. package/dist/core/config.d.ts.map +1 -0
  61. package/dist/core/config.js +130 -0
  62. package/dist/core/config.js.map +1 -0
  63. package/dist/core/config.test.d.ts +2 -0
  64. package/dist/core/config.test.d.ts.map +1 -0
  65. package/dist/core/config.test.js +88 -0
  66. package/dist/core/config.test.js.map +1 -0
  67. package/dist/core/find.d.ts +29 -0
  68. package/dist/core/find.d.ts.map +1 -0
  69. package/dist/core/find.js +191 -0
  70. package/dist/core/find.js.map +1 -0
  71. package/dist/core/find.test.d.ts +2 -0
  72. package/dist/core/find.test.d.ts.map +1 -0
  73. package/dist/core/find.test.js +91 -0
  74. package/dist/core/find.test.js.map +1 -0
  75. package/dist/core/frontmatter-parser.d.ts +45 -0
  76. package/dist/core/frontmatter-parser.d.ts.map +1 -0
  77. package/dist/core/frontmatter-parser.js +122 -0
  78. package/dist/core/frontmatter-parser.js.map +1 -0
  79. package/dist/core/frontmatter-parser.test.d.ts +2 -0
  80. package/dist/core/frontmatter-parser.test.d.ts.map +1 -0
  81. package/dist/core/frontmatter-parser.test.js +200 -0
  82. package/dist/core/frontmatter-parser.test.js.map +1 -0
  83. package/dist/core/generate-frontmatter.d.ts +27 -0
  84. package/dist/core/generate-frontmatter.d.ts.map +1 -0
  85. package/dist/core/generate-frontmatter.js +219 -0
  86. package/dist/core/generate-frontmatter.js.map +1 -0
  87. package/dist/core/generate-frontmatter.test.d.ts +2 -0
  88. package/dist/core/generate-frontmatter.test.d.ts.map +1 -0
  89. package/dist/core/generate-frontmatter.test.js +161 -0
  90. package/dist/core/generate-frontmatter.test.js.map +1 -0
  91. package/dist/core/generate-tests.d.ts +41 -0
  92. package/dist/core/generate-tests.d.ts.map +1 -0
  93. package/dist/core/generate-tests.js +191 -0
  94. package/dist/core/generate-tests.js.map +1 -0
  95. package/dist/core/generate-tests.test.d.ts +2 -0
  96. package/dist/core/generate-tests.test.d.ts.map +1 -0
  97. package/dist/core/generate-tests.test.js +205 -0
  98. package/dist/core/generate-tests.test.js.map +1 -0
  99. package/dist/core/health.d.ts +16 -0
  100. package/dist/core/health.d.ts.map +1 -0
  101. package/dist/core/health.js +156 -0
  102. package/dist/core/health.js.map +1 -0
  103. package/dist/core/health.test.d.ts +2 -0
  104. package/dist/core/health.test.d.ts.map +1 -0
  105. package/dist/core/health.test.js +97 -0
  106. package/dist/core/health.test.js.map +1 -0
  107. package/dist/core/init.d.ts +25 -0
  108. package/dist/core/init.d.ts.map +1 -0
  109. package/dist/core/init.js +100 -0
  110. package/dist/core/init.js.map +1 -0
  111. package/dist/core/init.test.d.ts +8 -0
  112. package/dist/core/init.test.d.ts.map +1 -0
  113. package/dist/core/init.test.js +203 -0
  114. package/dist/core/init.test.js.map +1 -0
  115. package/dist/core/invariant-coverage.d.ts +41 -0
  116. package/dist/core/invariant-coverage.d.ts.map +1 -0
  117. package/dist/core/invariant-coverage.js +181 -0
  118. package/dist/core/invariant-coverage.js.map +1 -0
  119. package/dist/core/invariant-coverage.test.d.ts +2 -0
  120. package/dist/core/invariant-coverage.test.d.ts.map +1 -0
  121. package/dist/core/invariant-coverage.test.js +188 -0
  122. package/dist/core/invariant-coverage.test.js.map +1 -0
  123. package/dist/core/meta-invariants.test.d.ts +17 -0
  124. package/dist/core/meta-invariants.test.d.ts.map +1 -0
  125. package/dist/core/meta-invariants.test.js +191 -0
  126. package/dist/core/meta-invariants.test.js.map +1 -0
  127. package/dist/core/node-fs.d.ts +22 -0
  128. package/dist/core/node-fs.d.ts.map +1 -0
  129. package/dist/core/node-fs.js +47 -0
  130. package/dist/core/node-fs.js.map +1 -0
  131. package/dist/core/organon-invariants.test.d.ts +15 -0
  132. package/dist/core/organon-invariants.test.d.ts.map +1 -0
  133. package/dist/core/organon-invariants.test.js +149 -0
  134. package/dist/core/organon-invariants.test.js.map +1 -0
  135. package/dist/core/query.d.ts +35 -0
  136. package/dist/core/query.d.ts.map +1 -0
  137. package/dist/core/query.js +139 -0
  138. package/dist/core/query.js.map +1 -0
  139. package/dist/core/query.test.d.ts +2 -0
  140. package/dist/core/query.test.d.ts.map +1 -0
  141. package/dist/core/query.test.js +97 -0
  142. package/dist/core/query.test.js.map +1 -0
  143. package/dist/core/suggest-tools.d.ts +15 -0
  144. package/dist/core/suggest-tools.d.ts.map +1 -0
  145. package/dist/core/suggest-tools.js +139 -0
  146. package/dist/core/suggest-tools.js.map +1 -0
  147. package/dist/core/suggest-tools.test.d.ts +2 -0
  148. package/dist/core/suggest-tools.test.d.ts.map +1 -0
  149. package/dist/core/suggest-tools.test.js +122 -0
  150. package/dist/core/suggest-tools.test.js.map +1 -0
  151. package/dist/core/test-helpers.d.ts +63 -0
  152. package/dist/core/test-helpers.d.ts.map +1 -0
  153. package/dist/core/test-helpers.js +265 -0
  154. package/dist/core/test-helpers.js.map +1 -0
  155. package/dist/core/types.d.ts +277 -0
  156. package/dist/core/types.d.ts.map +1 -0
  157. package/dist/core/types.js +9 -0
  158. package/dist/core/types.js.map +1 -0
  159. package/dist/core/upgrade.d.ts +46 -0
  160. package/dist/core/upgrade.d.ts.map +1 -0
  161. package/dist/core/upgrade.js +227 -0
  162. package/dist/core/upgrade.js.map +1 -0
  163. package/dist/core/upgrade.test.d.ts +8 -0
  164. package/dist/core/upgrade.test.d.ts.map +1 -0
  165. package/dist/core/upgrade.test.js +370 -0
  166. package/dist/core/upgrade.test.js.map +1 -0
  167. package/dist/core/validate-frontmatter.d.ts +20 -0
  168. package/dist/core/validate-frontmatter.d.ts.map +1 -0
  169. package/dist/core/validate-frontmatter.js +529 -0
  170. package/dist/core/validate-frontmatter.js.map +1 -0
  171. package/dist/core/validate-frontmatter.test.d.ts +2 -0
  172. package/dist/core/validate-frontmatter.test.d.ts.map +1 -0
  173. package/dist/core/validate-frontmatter.test.js +366 -0
  174. package/dist/core/validate-frontmatter.test.js.map +1 -0
  175. package/dist/core/validate-workflow.d.ts +17 -0
  176. package/dist/core/validate-workflow.d.ts.map +1 -0
  177. package/dist/core/validate-workflow.js +233 -0
  178. package/dist/core/validate-workflow.js.map +1 -0
  179. package/dist/core/validate-workflow.test.d.ts +2 -0
  180. package/dist/core/validate-workflow.test.d.ts.map +1 -0
  181. package/dist/core/validate-workflow.test.js +205 -0
  182. package/dist/core/validate-workflow.test.js.map +1 -0
  183. package/dist/core/verify-tier4-tests.d.ts +34 -0
  184. package/dist/core/verify-tier4-tests.d.ts.map +1 -0
  185. package/dist/core/verify-tier4-tests.js +106 -0
  186. package/dist/core/verify-tier4-tests.js.map +1 -0
  187. package/dist/core/verify-tier4-tests.test.d.ts +2 -0
  188. package/dist/core/verify-tier4-tests.test.d.ts.map +1 -0
  189. package/dist/core/verify-tier4-tests.test.js +140 -0
  190. package/dist/core/verify-tier4-tests.test.js.map +1 -0
  191. package/dist/core/verify-triplets.d.ts +17 -0
  192. package/dist/core/verify-triplets.d.ts.map +1 -0
  193. package/dist/core/verify-triplets.js +217 -0
  194. package/dist/core/verify-triplets.js.map +1 -0
  195. package/dist/core/verify-triplets.test.d.ts +2 -0
  196. package/dist/core/verify-triplets.test.d.ts.map +1 -0
  197. package/dist/core/verify-triplets.test.js +147 -0
  198. package/dist/core/verify-triplets.test.js.map +1 -0
  199. package/dist/core/verify.d.ts +19 -0
  200. package/dist/core/verify.d.ts.map +1 -0
  201. package/dist/core/verify.js +162 -0
  202. package/dist/core/verify.js.map +1 -0
  203. package/dist/core/verify.test.d.ts +2 -0
  204. package/dist/core/verify.test.d.ts.map +1 -0
  205. package/dist/core/verify.test.js +147 -0
  206. package/dist/core/verify.test.js.map +1 -0
  207. package/dist/index.d.ts +31 -0
  208. package/dist/index.d.ts.map +1 -0
  209. package/dist/index.js +27 -0
  210. package/dist/index.js.map +1 -0
  211. package/dist/mcp/prompts.d.ts +9 -0
  212. package/dist/mcp/prompts.d.ts.map +1 -0
  213. package/dist/mcp/prompts.js +265 -0
  214. package/dist/mcp/prompts.js.map +1 -0
  215. package/dist/mcp/resources.d.ts +7 -0
  216. package/dist/mcp/resources.d.ts.map +1 -0
  217. package/dist/mcp/resources.js +111 -0
  218. package/dist/mcp/resources.js.map +1 -0
  219. package/dist/mcp/server.d.ts +7 -0
  220. package/dist/mcp/server.d.ts.map +1 -0
  221. package/dist/mcp/server.js +31 -0
  222. package/dist/mcp/server.js.map +1 -0
  223. package/dist/mcp/tools.d.ts +7 -0
  224. package/dist/mcp/tools.d.ts.map +1 -0
  225. package/dist/mcp/tools.js +130 -0
  226. package/dist/mcp/tools.js.map +1 -0
  227. package/dist/templates/config.d.ts +6 -0
  228. package/dist/templates/config.d.ts.map +1 -0
  229. package/dist/templates/config.js +30 -0
  230. package/dist/templates/config.js.map +1 -0
  231. package/dist/templates/index.d.ts +7 -0
  232. package/dist/templates/index.d.ts.map +1 -0
  233. package/dist/templates/index.js +7 -0
  234. package/dist/templates/index.js.map +1 -0
  235. package/dist/templates/organon/claude-md.d.ts +7 -0
  236. package/dist/templates/organon/claude-md.d.ts.map +1 -0
  237. package/dist/templates/organon/claude-md.js +32 -0
  238. package/dist/templates/organon/claude-md.js.map +1 -0
  239. package/dist/templates/organon/ethos.d.ts +5 -0
  240. package/dist/templates/organon/ethos.d.ts.map +1 -0
  241. package/dist/templates/organon/ethos.js +69 -0
  242. package/dist/templates/organon/ethos.js.map +1 -0
  243. package/dist/templates/organon/index.d.ts +10 -0
  244. package/dist/templates/organon/index.d.ts.map +1 -0
  245. package/dist/templates/organon/index.js +10 -0
  246. package/dist/templates/organon/index.js.map +1 -0
  247. package/dist/templates/organon/observations-readme.d.ts +5 -0
  248. package/dist/templates/organon/observations-readme.d.ts.map +1 -0
  249. package/dist/templates/organon/observations-readme.js +25 -0
  250. package/dist/templates/organon/observations-readme.js.map +1 -0
  251. package/dist/templates/organon/philosophy.d.ts +5 -0
  252. package/dist/templates/organon/philosophy.d.ts.map +1 -0
  253. package/dist/templates/organon/philosophy.js +75 -0
  254. package/dist/templates/organon/philosophy.js.map +1 -0
  255. package/dist/templates/organon/protocols.d.ts +7 -0
  256. package/dist/templates/organon/protocols.d.ts.map +1 -0
  257. package/dist/templates/organon/protocols.js +197 -0
  258. package/dist/templates/organon/protocols.js.map +1 -0
  259. package/dist/templates/organon/readme.d.ts +5 -0
  260. package/dist/templates/organon/readme.d.ts.map +1 -0
  261. package/dist/templates/organon/readme.js +40 -0
  262. package/dist/templates/organon/readme.js.map +1 -0
  263. package/dist/templates/skills/domain-feature-design.d.ts +9 -0
  264. package/dist/templates/skills/domain-feature-design.d.ts.map +1 -0
  265. package/dist/templates/skills/domain-feature-design.js +123 -0
  266. package/dist/templates/skills/domain-feature-design.js.map +1 -0
  267. package/dist/templates/skills/index.d.ts +15 -0
  268. package/dist/templates/skills/index.d.ts.map +1 -0
  269. package/dist/templates/skills/index.js +35 -0
  270. package/dist/templates/skills/index.js.map +1 -0
  271. package/dist/templates/skills/organon-file-creation.d.ts +9 -0
  272. package/dist/templates/skills/organon-file-creation.d.ts.map +1 -0
  273. package/dist/templates/skills/organon-file-creation.js +138 -0
  274. package/dist/templates/skills/organon-file-creation.js.map +1 -0
  275. package/dist/templates/skills/quality-review.d.ts +9 -0
  276. package/dist/templates/skills/quality-review.d.ts.map +1 -0
  277. package/dist/templates/skills/quality-review.js +127 -0
  278. package/dist/templates/skills/quality-review.js.map +1 -0
  279. package/dist/templates/skills/session-compounding.d.ts +9 -0
  280. package/dist/templates/skills/session-compounding.d.ts.map +1 -0
  281. package/dist/templates/skills/session-compounding.js +118 -0
  282. package/dist/templates/skills/session-compounding.js.map +1 -0
  283. package/dist/templates/skills/verify-and-health.d.ts +9 -0
  284. package/dist/templates/skills/verify-and-health.d.ts.map +1 -0
  285. package/dist/templates/skills/verify-and-health.js +99 -0
  286. package/dist/templates/skills/verify-and-health.js.map +1 -0
  287. package/package.json +72 -0
@@ -0,0 +1,366 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { validateFrontmatter } from './validate-frontmatter.js';
3
+ import { MemoryFileSystem, makeEthos, makeReadme } from './test-helpers.js';
4
+ function makeConfig(projectRoot) {
5
+ return {
6
+ projectRoot,
7
+ organonPaths: ['.'],
8
+ organonGlobs: ['**/ETHOS.md', '**/PHILOSOPHY.md', '**/README.md'],
9
+ ignorePatterns: ['node_modules/**'],
10
+ workflowPaths: {},
11
+ freshnessThresholdHours: 24,
12
+ };
13
+ }
14
+ describe('validateFrontmatter', () => {
15
+ describe('Stage 1: Schema', () => {
16
+ it('passes valid ethos files', async () => {
17
+ const fs = new MemoryFileSystem({
18
+ '/project/ETHOS.md': makeEthos({ name: 'test', scope: 'product' }),
19
+ });
20
+ const config = makeConfig('/project');
21
+ const result = await validateFrontmatter({
22
+ projectRoot: '/project',
23
+ config,
24
+ fs,
25
+ files: ['ETHOS.md'],
26
+ stages: [1],
27
+ });
28
+ expect(result.success).toBe(true);
29
+ expect(result.filesChecked).toBe(1);
30
+ });
31
+ it('reports missing frontmatter', async () => {
32
+ const fs = new MemoryFileSystem({
33
+ '/project/ETHOS.md': '# No frontmatter\n\nJust content.',
34
+ });
35
+ const config = makeConfig('/project');
36
+ const result = await validateFrontmatter({
37
+ projectRoot: '/project',
38
+ config,
39
+ fs,
40
+ files: ['ETHOS.md'],
41
+ stages: [1],
42
+ });
43
+ expect(result.success).toBe(false);
44
+ expect(result.errors).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_MISSING' }));
45
+ });
46
+ it('reports invalid type enum', async () => {
47
+ const fs = new MemoryFileSystem({
48
+ '/project/ETHOS.md': `---
49
+ type: invalid_type
50
+ scope: domain
51
+ name: test
52
+ version: "1.0"
53
+ summary: Test
54
+ token_estimate: 100
55
+ ---
56
+
57
+ # Content`,
58
+ });
59
+ const config = makeConfig('/project');
60
+ const result = await validateFrontmatter({
61
+ projectRoot: '/project',
62
+ config,
63
+ fs,
64
+ files: ['ETHOS.md'],
65
+ stages: [1],
66
+ });
67
+ expect(result.success).toBe(false);
68
+ expect(result.errors).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_INVALID_TYPE' }));
69
+ });
70
+ it('reports non-kebab-case name', async () => {
71
+ const fs = new MemoryFileSystem({
72
+ '/project/ETHOS.md': `---
73
+ type: constraints
74
+ scope: domain
75
+ name: CamelCase
76
+ version: "1.0"
77
+ summary: Test
78
+ token_estimate: 100
79
+ ---
80
+
81
+ # Content`,
82
+ });
83
+ const config = makeConfig('/project');
84
+ const result = await validateFrontmatter({
85
+ projectRoot: '/project',
86
+ config,
87
+ fs,
88
+ files: ['ETHOS.md'],
89
+ stages: [1],
90
+ });
91
+ expect(result.success).toBe(false);
92
+ expect(result.errors).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_NAME_FORMAT' }));
93
+ });
94
+ it('reports invalid version format', async () => {
95
+ const fs = new MemoryFileSystem({
96
+ '/project/ETHOS.md': `---
97
+ type: constraints
98
+ scope: domain
99
+ name: test
100
+ version: "v1"
101
+ summary: Test
102
+ token_estimate: 100
103
+ ---
104
+
105
+ # Content`,
106
+ });
107
+ const config = makeConfig('/project');
108
+ const result = await validateFrontmatter({
109
+ projectRoot: '/project',
110
+ config,
111
+ fs,
112
+ files: ['ETHOS.md'],
113
+ stages: [1],
114
+ });
115
+ expect(result.success).toBe(false);
116
+ expect(result.errors).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_VERSION_FORMAT' }));
117
+ });
118
+ it('reports summary exceeding 200 characters', async () => {
119
+ const fs = new MemoryFileSystem({
120
+ '/project/ETHOS.md': `---
121
+ type: constraints
122
+ scope: domain
123
+ name: test
124
+ version: "1.0"
125
+ summary: ${'a'.repeat(201)}
126
+ token_estimate: 100
127
+ ---
128
+
129
+ # Content`,
130
+ });
131
+ const config = makeConfig('/project');
132
+ const result = await validateFrontmatter({
133
+ projectRoot: '/project',
134
+ config,
135
+ fs,
136
+ files: ['ETHOS.md'],
137
+ stages: [1],
138
+ });
139
+ expect(result.success).toBe(false);
140
+ expect(result.errors).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_SUMMARY_TOO_LONG' }));
141
+ });
142
+ it('warns about missing type-specific fields', async () => {
143
+ const fs = new MemoryFileSystem({
144
+ '/project/ETHOS.md': `---
145
+ type: constraints
146
+ scope: domain
147
+ name: test
148
+ version: "1.0"
149
+ summary: Test
150
+ token_estimate: 100
151
+ ---
152
+
153
+ # Content`,
154
+ });
155
+ const config = makeConfig('/project');
156
+ const result = await validateFrontmatter({
157
+ projectRoot: '/project',
158
+ config,
159
+ fs,
160
+ files: ['ETHOS.md'],
161
+ stages: [1],
162
+ });
163
+ expect(result.success).toBe(true);
164
+ expect(result.warnings).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_MISSING_TYPE_FIELD' }));
165
+ });
166
+ });
167
+ describe('Stage 3: Truthfulness', () => {
168
+ it('detects invariant count mismatch', async () => {
169
+ const content = makeEthos({ invariants: 3 }).replace('invariants_count: 3', 'invariants_count: 5');
170
+ const fs = new MemoryFileSystem({
171
+ '/project/ETHOS.md': content,
172
+ });
173
+ const config = makeConfig('/project');
174
+ const result = await validateFrontmatter({
175
+ projectRoot: '/project',
176
+ config,
177
+ fs,
178
+ files: ['ETHOS.md'],
179
+ stages: [3],
180
+ });
181
+ expect(result.errors).toContainEqual(expect.objectContaining({
182
+ code: 'FRONTMATTER_COUNT_MISMATCH',
183
+ message: expect.stringContaining('invariants_count'),
184
+ }));
185
+ });
186
+ it('detects principles count mismatch', async () => {
187
+ const content = makeEthos({ principles: 2 }).replace('principles_count: 2', 'principles_count: 5');
188
+ const fs = new MemoryFileSystem({
189
+ '/project/ETHOS.md': content,
190
+ });
191
+ const config = makeConfig('/project');
192
+ const result = await validateFrontmatter({
193
+ projectRoot: '/project',
194
+ config,
195
+ fs,
196
+ files: ['ETHOS.md'],
197
+ stages: [3],
198
+ });
199
+ expect(result.errors).toContainEqual(expect.objectContaining({
200
+ code: 'FRONTMATTER_COUNT_MISMATCH',
201
+ message: expect.stringContaining('principles_count'),
202
+ }));
203
+ });
204
+ it('warns on token estimate drift beyond 2x (load-or-skip misleading)', async () => {
205
+ const fs = new MemoryFileSystem({
206
+ '/project/ETHOS.md': `---
207
+ type: constraints
208
+ scope: domain
209
+ name: test
210
+ version: "1.0"
211
+ summary: Test
212
+ token_estimate: 10000
213
+ ---
214
+
215
+ # Short content`,
216
+ });
217
+ const config = makeConfig('/project');
218
+ const result = await validateFrontmatter({
219
+ projectRoot: '/project',
220
+ config,
221
+ fs,
222
+ files: ['ETHOS.md'],
223
+ stages: [3],
224
+ });
225
+ expect(result.warnings).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_TOKEN_DRIFT' }));
226
+ });
227
+ it('detects invariants array count mismatch', async () => {
228
+ const content = makeEthos({
229
+ invariants: 2,
230
+ extra: {
231
+ invariants: `\n - id: INV-TEST-1\n name: rule-one\n - id: INV-TEST-2\n name: rule-two\n - id: INV-TEST-3\n name: rule-three`,
232
+ },
233
+ });
234
+ const fs = new MemoryFileSystem({
235
+ '/project/ETHOS.md': content,
236
+ });
237
+ const config = makeConfig('/project');
238
+ const result = await validateFrontmatter({
239
+ projectRoot: '/project',
240
+ config,
241
+ fs,
242
+ files: ['ETHOS.md'],
243
+ stages: [3],
244
+ });
245
+ expect(result.errors).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_INVARIANT_COUNT_MISMATCH' }));
246
+ });
247
+ it('detects invalid invariant ID format', async () => {
248
+ const content = makeEthos({
249
+ extra: {
250
+ invariants: `\n - id: BAD-FORMAT\n name: bad`,
251
+ },
252
+ });
253
+ const fs = new MemoryFileSystem({
254
+ '/project/ETHOS.md': content,
255
+ });
256
+ const config = makeConfig('/project');
257
+ const result = await validateFrontmatter({
258
+ projectRoot: '/project',
259
+ config,
260
+ fs,
261
+ files: ['ETHOS.md'],
262
+ stages: [3],
263
+ });
264
+ expect(result.errors).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_INVARIANT_ID_FORMAT' }));
265
+ });
266
+ it('detects duplicate invariant IDs', async () => {
267
+ const content = makeEthos({
268
+ extra: {
269
+ invariants: `\n - id: INV-TEST-1\n name: first\n - id: INV-TEST-1\n name: duplicate`,
270
+ },
271
+ });
272
+ const fs = new MemoryFileSystem({
273
+ '/project/ETHOS.md': content,
274
+ });
275
+ const config = makeConfig('/project');
276
+ const result = await validateFrontmatter({
277
+ projectRoot: '/project',
278
+ config,
279
+ fs,
280
+ files: ['ETHOS.md'],
281
+ stages: [3],
282
+ });
283
+ expect(result.errors).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_INVARIANT_DUPLICATE_ID' }));
284
+ });
285
+ it('passes when counts match', async () => {
286
+ const fs = new MemoryFileSystem({
287
+ '/project/ETHOS.md': makeEthos({ invariants: 5, principles: 3, heuristics: 4 }),
288
+ });
289
+ const config = makeConfig('/project');
290
+ const result = await validateFrontmatter({
291
+ projectRoot: '/project',
292
+ config,
293
+ fs,
294
+ files: ['ETHOS.md'],
295
+ stages: [3],
296
+ });
297
+ const countErrors = result.errors.filter((e) => e.code === 'FRONTMATTER_COUNT_MISMATCH');
298
+ expect(countErrors).toHaveLength(0);
299
+ });
300
+ });
301
+ describe('Stage 4: Consistency', () => {
302
+ it('warns when name does not match parent directory', async () => {
303
+ const fs = new MemoryFileSystem({
304
+ '/project/organon/domains/genesis/ETHOS.md': makeEthos({ name: 'wrong-name', scope: 'domain' }),
305
+ });
306
+ const config = makeConfig('/project');
307
+ const result = await validateFrontmatter({
308
+ projectRoot: '/project',
309
+ config,
310
+ fs,
311
+ files: ['organon/domains/genesis/ETHOS.md'],
312
+ stages: [4],
313
+ });
314
+ expect(result.warnings).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_NAME_DIR_MISMATCH' }));
315
+ });
316
+ it('reports missing workflow for automated protocol', async () => {
317
+ const fs = new MemoryFileSystem({
318
+ '/project/PROTOCOL.md': `---
319
+ type: procedures
320
+ scope: domain
321
+ name: test
322
+ version: "1.0"
323
+ summary: Test
324
+ token_estimate: 200
325
+ protocols_count: 1
326
+ protocols:
327
+ - id: PROTO-TEST-1
328
+ name: Test
329
+ steps: 6
330
+ automation_tier: automated
331
+ complexity: high
332
+ ---
333
+
334
+ ## Steps
335
+ 1. Do thing.`,
336
+ });
337
+ const config = makeConfig('/project');
338
+ config.organonGlobs.push('**/PROTOCOL.md');
339
+ const result = await validateFrontmatter({
340
+ projectRoot: '/project',
341
+ config,
342
+ fs,
343
+ files: ['PROTOCOL.md'],
344
+ stages: [4],
345
+ });
346
+ expect(result.errors).toContainEqual(expect.objectContaining({ code: 'FRONTMATTER_MISSING_WORKFLOW' }));
347
+ });
348
+ });
349
+ describe('auto-discovery', () => {
350
+ it('discovers all organon files when no files specified', async () => {
351
+ const fs = new MemoryFileSystem({
352
+ '/project/ETHOS.md': makeEthos({ name: 'root', scope: 'product' }),
353
+ '/project/README.md': makeReadme({ name: 'root', scope: 'product' }),
354
+ });
355
+ const config = makeConfig('/project');
356
+ const result = await validateFrontmatter({
357
+ projectRoot: '/project',
358
+ config,
359
+ fs,
360
+ stages: [1],
361
+ });
362
+ expect(result.filesChecked).toBe(2);
363
+ });
364
+ });
365
+ });
366
+ //# sourceMappingURL=validate-frontmatter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-frontmatter.test.js","sourceRoot":"","sources":["../../src/core/validate-frontmatter.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Workflow quality validation.
3
+ *
4
+ * Checks workflow files against the quality attributes defined in
5
+ * workflow-authoring.md: completeness, context sufficiency, error
6
+ * recoverability, and tool references.
7
+ *
8
+ * Registered as the 'workflow-quality' verification gate.
9
+ */
10
+ import type { FileSystem, OrganonConfig, WorkflowValidationResult } from './types.js';
11
+ export interface ValidateWorkflowOptions {
12
+ projectRoot: string;
13
+ config: OrganonConfig;
14
+ fs: FileSystem;
15
+ }
16
+ export declare function validateWorkflow(options: ValidateWorkflowOptions): Promise<WorkflowValidationResult>;
17
+ //# sourceMappingURL=validate-workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-workflow.d.ts","sourceRoot":"","sources":["../../src/core/validate-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAEV,UAAU,EACV,aAAa,EAEb,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,EAAE,EAAE,UAAU,CAAC;CAChB;AAcD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,wBAAwB,CAAC,CAyLnC"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Workflow quality validation.
3
+ *
4
+ * Checks workflow files against the quality attributes defined in
5
+ * workflow-authoring.md: completeness, context sufficiency, error
6
+ * recoverability, and tool references.
7
+ *
8
+ * Registered as the 'workflow-quality' verification gate.
9
+ */
10
+ import { parseFrontmatter, extractSection } from './frontmatter-parser.js';
11
+ import { joinPath } from './config.js';
12
+ // ---------------------------------------------------------------------------
13
+ // Constants
14
+ // ---------------------------------------------------------------------------
15
+ const LOADS_SIZE_THRESHOLD = 10;
16
+ const TABLE_ROW_RE = /^\|[^|]+\|[^|]+\|/m;
17
+ const STEP_RE = /^\d+\.\s/gm;
18
+ // ---------------------------------------------------------------------------
19
+ // Main
20
+ // ---------------------------------------------------------------------------
21
+ export async function validateWorkflow(options) {
22
+ const { projectRoot, config, fs } = options;
23
+ const allErrors = [];
24
+ const allWarnings = [];
25
+ const results = [];
26
+ // Discover workflow files
27
+ const workflowFiles = await discoverWorkflowFiles(projectRoot, config, fs);
28
+ for (const file of workflowFiles) {
29
+ const fileErrors = [];
30
+ const fileWarnings = [];
31
+ const absPath = joinPath(projectRoot, file);
32
+ let content;
33
+ try {
34
+ content = await fs.readFile(absPath);
35
+ }
36
+ catch {
37
+ fileErrors.push({
38
+ severity: 'error',
39
+ code: 'FILE_READ_ERROR',
40
+ message: `Cannot read workflow file: ${file}`,
41
+ file,
42
+ });
43
+ results.push({ file, valid: false, errors: fileErrors, warnings: fileWarnings });
44
+ allErrors.push(...fileErrors);
45
+ continue;
46
+ }
47
+ const { frontmatter, body } = parseFrontmatter(content);
48
+ // --- Schema checks (errors) ---
49
+ const protocolId = frontmatter?.['protocol_id'];
50
+ const protocolFile = frontmatter?.['protocol_file'];
51
+ const tools = frontmatter?.['tools'];
52
+ const loads = frontmatter?.['loads'];
53
+ if (!protocolId) {
54
+ fileErrors.push({
55
+ severity: 'error',
56
+ code: 'WORKFLOW_MISSING_PROTOCOL_ID',
57
+ message: 'Workflow is missing required field: protocol_id',
58
+ file,
59
+ suggestion: 'Add protocol_id to frontmatter referencing the protocol this workflow implements',
60
+ });
61
+ }
62
+ if (!protocolFile) {
63
+ fileErrors.push({
64
+ severity: 'error',
65
+ code: 'WORKFLOW_MISSING_PROTOCOL_FILE',
66
+ message: 'Workflow is missing required field: protocol_file',
67
+ file,
68
+ suggestion: 'Add protocol_file to frontmatter with the path to the protocol source',
69
+ });
70
+ }
71
+ if (!tools || !Array.isArray(tools) || tools.length === 0) {
72
+ fileErrors.push({
73
+ severity: 'error',
74
+ code: 'WORKFLOW_MISSING_TOOLS',
75
+ message: 'Workflow is missing required field: tools (must be a non-empty array)',
76
+ file,
77
+ suggestion: 'Add tools array listing the tools this workflow orchestrates',
78
+ });
79
+ }
80
+ if (!loads || !Array.isArray(loads) || loads.length === 0) {
81
+ fileErrors.push({
82
+ severity: 'error',
83
+ code: 'WORKFLOW_MISSING_LOADS',
84
+ message: 'Workflow is missing required field: loads (must be a non-empty array)',
85
+ file,
86
+ suggestion: 'Add loads array listing organon files to load before execution',
87
+ });
88
+ }
89
+ // --- Loads sufficiency checks (errors) ---
90
+ if (loads && Array.isArray(loads)) {
91
+ for (const loadPath of loads) {
92
+ const absLoadPath = joinPath(projectRoot, loadPath);
93
+ const exists = await fs.exists(absLoadPath);
94
+ if (!exists) {
95
+ fileErrors.push({
96
+ severity: 'error',
97
+ code: 'WORKFLOW_BROKEN_LOADS_REF',
98
+ message: `Loads path '${loadPath}' does not resolve to an existing file`,
99
+ file,
100
+ suggestion: `Check the path or remove '${loadPath}' from loads array`,
101
+ });
102
+ }
103
+ }
104
+ // Loads overload warning
105
+ if (loads.length > LOADS_SIZE_THRESHOLD) {
106
+ fileWarnings.push({
107
+ severity: 'warning',
108
+ code: 'WORKFLOW_LOADS_OVERLOAD',
109
+ message: `Loads array has ${loads.length} entries (threshold: ${LOADS_SIZE_THRESHOLD}). Consider narrowing to only required files.`,
110
+ file,
111
+ });
112
+ }
113
+ }
114
+ // --- Error recovery check (warnings) ---
115
+ const recoverySection = extractSection(body, 'Error Recovery')
116
+ ?? extractSection(body, 'Recovery');
117
+ if (!recoverySection) {
118
+ fileWarnings.push({
119
+ severity: 'warning',
120
+ code: 'WORKFLOW_NO_ERROR_RECOVERY',
121
+ message: 'Workflow has no ## Error Recovery or ## Recovery section',
122
+ file,
123
+ suggestion: 'Add an error recovery section with a failure/recovery table',
124
+ });
125
+ }
126
+ else if (!TABLE_ROW_RE.test(recoverySection)) {
127
+ fileWarnings.push({
128
+ severity: 'warning',
129
+ code: 'WORKFLOW_RECOVERY_NO_TABLE',
130
+ message: 'Error recovery section exists but has no failure/recovery table',
131
+ file,
132
+ suggestion: 'Add a table with | Failure | Recovery Action | columns',
133
+ });
134
+ }
135
+ // --- Step coverage check (warnings) ---
136
+ if (protocolFile && protocolId) {
137
+ const stepCount = await getProtocolStepCount(projectRoot, protocolFile, protocolId, fs);
138
+ if (stepCount !== null) {
139
+ const stepsSection = extractSection(body, 'Steps');
140
+ if (stepsSection) {
141
+ const workflowSteps = countSteps(stepsSection);
142
+ if (workflowSteps < stepCount) {
143
+ fileWarnings.push({
144
+ severity: 'warning',
145
+ code: 'WORKFLOW_STEP_COUNT_LOW',
146
+ message: `Workflow has ${workflowSteps} steps but protocol ${protocolId} has ${stepCount}`,
147
+ file,
148
+ suggestion: 'Add missing steps or document why they are skipped',
149
+ });
150
+ }
151
+ }
152
+ }
153
+ }
154
+ // --- Tool reference check (warnings) ---
155
+ if (tools && Array.isArray(tools)) {
156
+ for (const tool of tools) {
157
+ // Check both the exact tool id (e.g. "organon-verify") and the
158
+ // CLI-command form (e.g. "organon verify") so kebab-case ids
159
+ // match natural command invocations in the workflow body.
160
+ const cliForm = tool.replace(/-/g, ' ');
161
+ if (!body.includes(tool) && !body.includes(cliForm)) {
162
+ fileWarnings.push({
163
+ severity: 'warning',
164
+ code: 'WORKFLOW_UNREFERENCED_TOOL',
165
+ message: `Tool '${tool}' is listed in tools array but not referenced in workflow body`,
166
+ file,
167
+ suggestion: `Reference '${tool}' in the Steps section or remove it from the tools array`,
168
+ });
169
+ }
170
+ }
171
+ }
172
+ const valid = fileErrors.length === 0;
173
+ results.push({ file, valid, errors: fileErrors, warnings: fileWarnings });
174
+ allErrors.push(...fileErrors);
175
+ allWarnings.push(...fileWarnings);
176
+ }
177
+ return {
178
+ success: allErrors.length === 0,
179
+ workflowsChecked: workflowFiles.length,
180
+ workflowsWithErrors: results.filter((r) => !r.valid).length,
181
+ workflowsWithWarnings: results.filter((r) => r.warnings.length > 0).length,
182
+ results,
183
+ errors: allErrors,
184
+ warnings: allWarnings,
185
+ };
186
+ }
187
+ // ---------------------------------------------------------------------------
188
+ // Helpers
189
+ // ---------------------------------------------------------------------------
190
+ function countSteps(stepsSection) {
191
+ const matches = stepsSection.match(STEP_RE);
192
+ return matches ? matches.length : 0;
193
+ }
194
+ async function getProtocolStepCount(projectRoot, protocolFile, protocolId, fs) {
195
+ const absPath = joinPath(projectRoot, protocolFile);
196
+ try {
197
+ const content = await fs.readFile(absPath);
198
+ const { frontmatter } = parseFrontmatter(content);
199
+ if (frontmatter?.protocols && Array.isArray(frontmatter.protocols)) {
200
+ const proto = frontmatter.protocols.find((p) => p.id === protocolId);
201
+ if (proto && typeof proto.steps === 'number') {
202
+ return proto.steps;
203
+ }
204
+ }
205
+ }
206
+ catch {
207
+ // Protocol file not found or unreadable — skip this check
208
+ }
209
+ return null;
210
+ }
211
+ async function discoverWorkflowFiles(projectRoot, config, fs) {
212
+ const files = new Set();
213
+ const paths = config.workflowPaths;
214
+ const searchPaths = [
215
+ paths.claudeCode,
216
+ paths.cursor,
217
+ paths.generic,
218
+ ].filter((p) => p !== undefined);
219
+ for (const dir of searchPaths) {
220
+ const fullDir = joinPath(projectRoot, dir);
221
+ if (await fs.exists(fullDir)) {
222
+ const matches = await fs.glob('**/*.md', {
223
+ cwd: fullDir,
224
+ ignore: [],
225
+ });
226
+ for (const m of matches) {
227
+ files.add(joinPath(dir, m));
228
+ }
229
+ }
230
+ }
231
+ return [...files].sort();
232
+ }
233
+ //# sourceMappingURL=validate-workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-workflow.js","sourceRoot":"","sources":["../../src/core/validate-workflow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=validate-workflow.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-workflow.test.d.ts","sourceRoot":"","sources":["../../src/core/validate-workflow.test.ts"],"names":[],"mappings":""}