mindforge-cc 1.0.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 (324) hide show
  1. package/.agent/CLAUDE.md +462 -0
  2. package/.agent/forge/help.md +7 -0
  3. package/.agent/forge/init-project.md +32 -0
  4. package/.agent/forge/plan-phase.md +30 -0
  5. package/.agent/mindforge/approve.md +18 -0
  6. package/.agent/mindforge/audit.md +30 -0
  7. package/.agent/mindforge/benchmark.md +33 -0
  8. package/.agent/mindforge/complete-milestone.md +18 -0
  9. package/.agent/mindforge/debug.md +126 -0
  10. package/.agent/mindforge/discuss-phase.md +138 -0
  11. package/.agent/mindforge/execute-phase.md +165 -0
  12. package/.agent/mindforge/health.md +21 -0
  13. package/.agent/mindforge/help.md +23 -0
  14. package/.agent/mindforge/init-org.md +131 -0
  15. package/.agent/mindforge/init-project.md +155 -0
  16. package/.agent/mindforge/install-skill.md +15 -0
  17. package/.agent/mindforge/map-codebase.md +298 -0
  18. package/.agent/mindforge/metrics.md +22 -0
  19. package/.agent/mindforge/migrate.md +40 -0
  20. package/.agent/mindforge/milestone.md +12 -0
  21. package/.agent/mindforge/next.md +105 -0
  22. package/.agent/mindforge/plan-phase.md +125 -0
  23. package/.agent/mindforge/plugins.md +40 -0
  24. package/.agent/mindforge/pr-review.md +41 -0
  25. package/.agent/mindforge/profile-team.md +23 -0
  26. package/.agent/mindforge/publish-skill.md +19 -0
  27. package/.agent/mindforge/quick.md +135 -0
  28. package/.agent/mindforge/release.md +10 -0
  29. package/.agent/mindforge/retrospective.md +26 -0
  30. package/.agent/mindforge/review.md +157 -0
  31. package/.agent/mindforge/security-scan.md +233 -0
  32. package/.agent/mindforge/ship.md +100 -0
  33. package/.agent/mindforge/skills.md +141 -0
  34. package/.agent/mindforge/status.md +104 -0
  35. package/.agent/mindforge/sync-confluence.md +11 -0
  36. package/.agent/mindforge/sync-jira.md +12 -0
  37. package/.agent/mindforge/tokens.md +8 -0
  38. package/.agent/mindforge/update.md +42 -0
  39. package/.agent/mindforge/verify-phase.md +62 -0
  40. package/.agent/mindforge/workspace.md +29 -0
  41. package/.claude/CLAUDE.md +462 -0
  42. package/.claude/commands/forge/help.md +7 -0
  43. package/.claude/commands/forge/init-project.md +32 -0
  44. package/.claude/commands/forge/plan-phase.md +30 -0
  45. package/.claude/commands/mindforge/approve.md +18 -0
  46. package/.claude/commands/mindforge/audit.md +30 -0
  47. package/.claude/commands/mindforge/benchmark.md +33 -0
  48. package/.claude/commands/mindforge/complete-milestone.md +18 -0
  49. package/.claude/commands/mindforge/debug.md +126 -0
  50. package/.claude/commands/mindforge/discuss-phase.md +138 -0
  51. package/.claude/commands/mindforge/execute-phase.md +165 -0
  52. package/.claude/commands/mindforge/health.md +21 -0
  53. package/.claude/commands/mindforge/help.md +23 -0
  54. package/.claude/commands/mindforge/init-org.md +131 -0
  55. package/.claude/commands/mindforge/init-project.md +155 -0
  56. package/.claude/commands/mindforge/install-skill.md +15 -0
  57. package/.claude/commands/mindforge/map-codebase.md +298 -0
  58. package/.claude/commands/mindforge/metrics.md +22 -0
  59. package/.claude/commands/mindforge/migrate.md +40 -0
  60. package/.claude/commands/mindforge/milestone.md +12 -0
  61. package/.claude/commands/mindforge/next.md +105 -0
  62. package/.claude/commands/mindforge/plan-phase.md +125 -0
  63. package/.claude/commands/mindforge/plugins.md +40 -0
  64. package/.claude/commands/mindforge/pr-review.md +41 -0
  65. package/.claude/commands/mindforge/profile-team.md +23 -0
  66. package/.claude/commands/mindforge/publish-skill.md +19 -0
  67. package/.claude/commands/mindforge/quick.md +135 -0
  68. package/.claude/commands/mindforge/release.md +10 -0
  69. package/.claude/commands/mindforge/retrospective.md +26 -0
  70. package/.claude/commands/mindforge/review.md +157 -0
  71. package/.claude/commands/mindforge/security-scan.md +233 -0
  72. package/.claude/commands/mindforge/ship.md +100 -0
  73. package/.claude/commands/mindforge/skills.md +141 -0
  74. package/.claude/commands/mindforge/status.md +104 -0
  75. package/.claude/commands/mindforge/sync-confluence.md +11 -0
  76. package/.claude/commands/mindforge/sync-jira.md +12 -0
  77. package/.claude/commands/mindforge/tokens.md +8 -0
  78. package/.claude/commands/mindforge/update.md +42 -0
  79. package/.claude/commands/mindforge/verify-phase.md +62 -0
  80. package/.claude/commands/mindforge/workspace.md +29 -0
  81. package/.forge/org/CONVENTIONS.md +0 -0
  82. package/.forge/org/ORG.md +0 -0
  83. package/.forge/org/SECURITY.md +0 -0
  84. package/.forge/org/TOOLS.md +0 -0
  85. package/.forge/personas/analyst.md +0 -0
  86. package/.forge/personas/architect.md +0 -0
  87. package/.forge/personas/debug-specialist.md +0 -0
  88. package/.forge/personas/developer.md +26 -0
  89. package/.forge/personas/qa-engineer.md +0 -0
  90. package/.forge/personas/release-manager.md +0 -0
  91. package/.forge/personas/security-reviewer.md +33 -0
  92. package/.forge/personas/tech-writer.md +0 -0
  93. package/.forge/skills/api-design/SKILL.md +0 -0
  94. package/.forge/skills/code-quality/SKILL.md +0 -0
  95. package/.forge/skills/documentation/SKILL.md +0 -0
  96. package/.forge/skills/security-review/SKILL.md +23 -0
  97. package/.forge/skills/testing-standards/SKILL.md +27 -0
  98. package/.github/workflows/mindforge-ci.yml +224 -0
  99. package/.gitlab-ci-mindforge.yml +18 -0
  100. package/.mindforge/MINDFORGE-SCHEMA.json +165 -0
  101. package/.mindforge/audit/AUDIT-SCHEMA.md +451 -0
  102. package/.mindforge/ci/ci-config-schema.md +21 -0
  103. package/.mindforge/ci/ci-mode.md +179 -0
  104. package/.mindforge/ci/github-actions-adapter.md +224 -0
  105. package/.mindforge/ci/gitlab-ci-adapter.md +31 -0
  106. package/.mindforge/ci/jenkins-adapter.md +44 -0
  107. package/.mindforge/distribution/registry-client.md +166 -0
  108. package/.mindforge/distribution/registry-schema.md +96 -0
  109. package/.mindforge/distribution/skill-publisher.md +44 -0
  110. package/.mindforge/distribution/skill-validator.md +74 -0
  111. package/.mindforge/engine/compaction-protocol.md +182 -0
  112. package/.mindforge/engine/context-injector.md +128 -0
  113. package/.mindforge/engine/dependency-parser.md +113 -0
  114. package/.mindforge/engine/skills/conflict-resolver.md +69 -0
  115. package/.mindforge/engine/skills/loader.md +184 -0
  116. package/.mindforge/engine/skills/registry.md +98 -0
  117. package/.mindforge/engine/skills/versioning.md +75 -0
  118. package/.mindforge/engine/verification-pipeline.md +111 -0
  119. package/.mindforge/engine/wave-executor.md +235 -0
  120. package/.mindforge/governance/GOVERNANCE-CONFIG.md +17 -0
  121. package/.mindforge/governance/approval-workflow.md +37 -0
  122. package/.mindforge/governance/change-classifier.md +63 -0
  123. package/.mindforge/governance/compliance-gates.md +31 -0
  124. package/.mindforge/integrations/confluence.md +27 -0
  125. package/.mindforge/integrations/connection-manager.md +163 -0
  126. package/.mindforge/integrations/github.md +25 -0
  127. package/.mindforge/integrations/gitlab.md +13 -0
  128. package/.mindforge/integrations/jira.md +102 -0
  129. package/.mindforge/integrations/slack.md +41 -0
  130. package/.mindforge/intelligence/antipattern-detector.md +75 -0
  131. package/.mindforge/intelligence/difficulty-scorer.md +55 -0
  132. package/.mindforge/intelligence/health-engine.md +208 -0
  133. package/.mindforge/intelligence/skill-gap-analyser.md +40 -0
  134. package/.mindforge/intelligence/smart-compaction.md +71 -0
  135. package/.mindforge/metrics/METRICS-SCHEMA.md +42 -0
  136. package/.mindforge/metrics/quality-tracker.md +32 -0
  137. package/.mindforge/monorepo/cross-package-planner.md +114 -0
  138. package/.mindforge/monorepo/dependency-graph-builder.md +32 -0
  139. package/.mindforge/monorepo/workspace-detector.md +129 -0
  140. package/.mindforge/org/CONVENTIONS.md +62 -0
  141. package/.mindforge/org/ORG.md +51 -0
  142. package/.mindforge/org/SECURITY.md +50 -0
  143. package/.mindforge/org/TOOLS.md +53 -0
  144. package/.mindforge/org/integrations/INTEGRATIONS-CONFIG.md +58 -0
  145. package/.mindforge/org/skills/MANIFEST.md +38 -0
  146. package/.mindforge/personas/analyst.md +52 -0
  147. package/.mindforge/personas/architect.md +75 -0
  148. package/.mindforge/personas/debug-specialist.md +52 -0
  149. package/.mindforge/personas/developer.md +85 -0
  150. package/.mindforge/personas/overrides/README.md +85 -0
  151. package/.mindforge/personas/qa-engineer.md +61 -0
  152. package/.mindforge/personas/release-manager.md +76 -0
  153. package/.mindforge/personas/security-reviewer.md +91 -0
  154. package/.mindforge/personas/tech-writer.md +51 -0
  155. package/.mindforge/plugins/PLUGINS-MANIFEST.md +23 -0
  156. package/.mindforge/plugins/plugin-loader.md +93 -0
  157. package/.mindforge/plugins/plugin-registry.md +44 -0
  158. package/.mindforge/plugins/plugin-schema.md +68 -0
  159. package/.mindforge/pr-review/ai-reviewer.md +266 -0
  160. package/.mindforge/pr-review/finding-formatter.md +46 -0
  161. package/.mindforge/pr-review/review-prompt-templates.md +44 -0
  162. package/.mindforge/production/compatibility-layer.md +39 -0
  163. package/.mindforge/production/migration-engine.md +52 -0
  164. package/.mindforge/production/production-checklist.md +165 -0
  165. package/.mindforge/production/token-optimiser.md +68 -0
  166. package/.mindforge/skills/accessibility/SKILL.md +106 -0
  167. package/.mindforge/skills/api-design/SKILL.md +98 -0
  168. package/.mindforge/skills/code-quality/SKILL.md +88 -0
  169. package/.mindforge/skills/data-privacy/SKILL.md +126 -0
  170. package/.mindforge/skills/database-patterns/SKILL.md +192 -0
  171. package/.mindforge/skills/documentation/SKILL.md +91 -0
  172. package/.mindforge/skills/incident-response/SKILL.md +180 -0
  173. package/.mindforge/skills/performance/SKILL.md +120 -0
  174. package/.mindforge/skills/security-review/SKILL.md +83 -0
  175. package/.mindforge/skills/testing-standards/SKILL.md +97 -0
  176. package/.mindforge/team/TEAM-PROFILE.md +42 -0
  177. package/.mindforge/team/multi-handoff.md +23 -0
  178. package/.mindforge/team/profiles/README.md +13 -0
  179. package/.mindforge/team/session-merger.md +18 -0
  180. package/.planning/ARCHITECTURE.md +0 -0
  181. package/.planning/AUDIT.jsonl +0 -0
  182. package/.planning/HANDOFF.json +28 -0
  183. package/.planning/PROJECT.md +33 -0
  184. package/.planning/RELEASE-CHECKLIST.md +68 -0
  185. package/.planning/REQUIREMENTS.md +0 -0
  186. package/.planning/ROADMAP.md +0 -0
  187. package/.planning/STATE.md +31 -0
  188. package/.planning/approvals/.gitkeep +1 -0
  189. package/.planning/archive/.gitkeep +1 -0
  190. package/.planning/audit-archive/.gitkeep +1 -0
  191. package/.planning/decisions/.gitkeep +0 -0
  192. package/.planning/decisions/ADR-001-handoff-tracking.md +41 -0
  193. package/.planning/decisions/ADR-002-markdown-commands.md +46 -0
  194. package/.planning/decisions/ADR-003-skills-trigger-model.md +37 -0
  195. package/.planning/decisions/ADR-004-wave-parallelism-model.md +45 -0
  196. package/.planning/decisions/ADR-005-append-only-audit-log.md +51 -0
  197. package/.planning/decisions/ADR-006-tiered-skills-system.md +22 -0
  198. package/.planning/decisions/ADR-007-trigger-keyword-model.md +22 -0
  199. package/.planning/decisions/ADR-008-just-in-time-skill-loading.md +29 -0
  200. package/.planning/decisions/ADR-009-enterprise-integration-retry-policy.md +8 -0
  201. package/.planning/decisions/ADR-010-governance-tier-escalation.md +8 -0
  202. package/.planning/decisions/ADR-011-multi-developer-handoff-contract.md +8 -0
  203. package/.planning/decisions/ADR-012-intelligence-feedback-loops.md +19 -0
  204. package/.planning/decisions/ADR-013-mindforge-md-constitution.md +16 -0
  205. package/.planning/decisions/ADR-014-metrics-as-signals-not-evaluation.md +15 -0
  206. package/.planning/decisions/ADR-015-npm-based-skill-registry.md +26 -0
  207. package/.planning/decisions/ADR-016-ci-exit-code-0-on-timeout.md +27 -0
  208. package/.planning/decisions/ADR-017-sdk-localhost-only.md +28 -0
  209. package/.planning/decisions/ADR-018-installer-self-install-detection.md +15 -0
  210. package/.planning/decisions/ADR-019-self-update-scope-preservation.md +14 -0
  211. package/.planning/decisions/ADR-020-v1.0.0-stable-interface-contract.md +23 -0
  212. package/.planning/jira-sync.json +9 -0
  213. package/.planning/milestones/.gitkeep +1 -0
  214. package/.planning/phases/day1/REVIEW-DAY1.md +50 -0
  215. package/.planning/phases/day1/SECURITY-REVIEW-DAY1.md +15 -0
  216. package/.planning/phases/day2/REVIEW-DAY2.md +521 -0
  217. package/.planning/phases/day3/REVIEW-DAY3.md +234 -0
  218. package/.planning/slack-threads.json +6 -0
  219. package/CHANGELOG.md +175 -0
  220. package/LICENSE +21 -0
  221. package/MINDFORGE.md +76 -0
  222. package/README.md +182 -0
  223. package/RELEASENOTES.md +41 -0
  224. package/SECURITY.md +4 -0
  225. package/bin/install.js +120 -0
  226. package/bin/installer-core.js +292 -0
  227. package/bin/migrations/0.1.0-to-0.5.0.js +37 -0
  228. package/bin/migrations/0.5.0-to-0.6.0.js +17 -0
  229. package/bin/migrations/0.6.0-to-1.0.0.js +100 -0
  230. package/bin/migrations/migrate.js +151 -0
  231. package/bin/migrations/schema-versions.js +64 -0
  232. package/bin/updater/changelog-fetcher.js +62 -0
  233. package/bin/updater/self-update.js +169 -0
  234. package/bin/updater/version-comparator.js +68 -0
  235. package/bin/validate-config.js +92 -0
  236. package/bin/wizard/config-generator.js +112 -0
  237. package/bin/wizard/environment-detector.js +76 -0
  238. package/bin/wizard/setup-wizard.js +237 -0
  239. package/docs/Context/Master-Context.md +701 -0
  240. package/docs/architecture/README.md +35 -0
  241. package/docs/architecture/decision-records-index.md +26 -0
  242. package/docs/ci-cd-integration.md +30 -0
  243. package/docs/ci-quickstart.md +78 -0
  244. package/docs/commands-reference.md +11 -0
  245. package/docs/contributing/CONTRIBUTING.md +38 -0
  246. package/docs/contributing/plugin-authoring.md +50 -0
  247. package/docs/contributing/skill-authoring.md +41 -0
  248. package/docs/enterprise-setup.md +25 -0
  249. package/docs/faq.md +38 -0
  250. package/docs/getting-started.md +36 -0
  251. package/docs/governance-guide.md +23 -0
  252. package/docs/mindforge-md-reference.md +53 -0
  253. package/docs/monorepo-guide.md +26 -0
  254. package/docs/persona-customisation.md +56 -0
  255. package/docs/quick-verify.md +33 -0
  256. package/docs/reference/audit-events.md +53 -0
  257. package/docs/reference/commands.md +82 -0
  258. package/docs/reference/config-reference.md +64 -0
  259. package/docs/reference/sdk-api.md +48 -0
  260. package/docs/reference/skills-api.md +57 -0
  261. package/docs/release-checklist-guide.md +37 -0
  262. package/docs/requirements.md +29 -0
  263. package/docs/sdk-reference.md +27 -0
  264. package/docs/security/SECURITY.md +42 -0
  265. package/docs/security/penetration-test-results.md +31 -0
  266. package/docs/security/threat-model.md +142 -0
  267. package/docs/skills-authoring-guide.md +119 -0
  268. package/docs/skills-publishing-guide.md +21 -0
  269. package/docs/team-setup-guide.md +21 -0
  270. package/docs/troubleshooting.md +119 -0
  271. package/docs/tutorial.md +195 -0
  272. package/docs/upgrade.md +44 -0
  273. package/docs/user-guide.md +131 -0
  274. package/docs/usp-features.md +214 -0
  275. package/eslint.config.mjs +31 -0
  276. package/examples/starter-project/.planning/AUDIT.jsonl +1 -0
  277. package/examples/starter-project/.planning/HANDOFF.json +23 -0
  278. package/examples/starter-project/.planning/PROJECT.md +27 -0
  279. package/examples/starter-project/.planning/STATE.md +10 -0
  280. package/examples/starter-project/MINDFORGE.md +40 -0
  281. package/examples/starter-project/README.md +14 -0
  282. package/implementation-roadmap/day-1-imp/DAY1-HARDEN.md +823 -0
  283. package/implementation-roadmap/day-1-imp/DAY1-IMPLEMENT.md +2459 -0
  284. package/implementation-roadmap/day-1-imp/DAY1-REVIEW.md +288 -0
  285. package/implementation-roadmap/day-2-imp/DAY2-HARDEN.md +954 -0
  286. package/implementation-roadmap/day-2-imp/DAY2-IMPLEMENT.md +2347 -0
  287. package/implementation-roadmap/day-2-imp/DAY2-REVIEW.md +422 -0
  288. package/implementation-roadmap/day-3-imp/DAY3-HARDEN.md +870 -0
  289. package/implementation-roadmap/day-3-imp/DAY3-IMPLEMENT.md +2798 -0
  290. package/implementation-roadmap/day-3-imp/DAY3-REVIEW.md +484 -0
  291. package/implementation-roadmap/day-4-imp/DAY4-HARDEN.md +1087 -0
  292. package/implementation-roadmap/day-4-imp/DAY4-IMPLEMENT.md +2874 -0
  293. package/implementation-roadmap/day-4-imp/DAY4-REVIEW.md +386 -0
  294. package/implementation-roadmap/day-5-imp/DAY5-HARDEN.md +1078 -0
  295. package/implementation-roadmap/day-5-imp/DAY5-IMPLEMENT.md +3151 -0
  296. package/implementation-roadmap/day-5-imp/DAY5-REVIEW.md +345 -0
  297. package/implementation-roadmap/day-6-imp/DAY6-COMPLETE.md +3919 -0
  298. package/implementation-roadmap/day-7-imp-prod/DAY7-PRODUCTION-FINAL.md +4513 -0
  299. package/package.json +31 -0
  300. package/sdk/README.md +69 -0
  301. package/sdk/eslint.config.mjs +34 -0
  302. package/sdk/package-lock.json +1507 -0
  303. package/sdk/package.json +30 -0
  304. package/sdk/src/client.ts +133 -0
  305. package/sdk/src/commands.ts +63 -0
  306. package/sdk/src/events.ts +166 -0
  307. package/sdk/src/index.ts +22 -0
  308. package/sdk/src/types.ts +87 -0
  309. package/sdk/tsconfig.json +13 -0
  310. package/tests/audit.test.js +206 -0
  311. package/tests/ci-mode.test.js +162 -0
  312. package/tests/compaction.test.js +161 -0
  313. package/tests/distribution.test.js +205 -0
  314. package/tests/e2e.test.js +618 -0
  315. package/tests/governance.test.js +130 -0
  316. package/tests/install.test.js +209 -0
  317. package/tests/integrations.test.js +128 -0
  318. package/tests/intelligence.test.js +117 -0
  319. package/tests/metrics.test.js +96 -0
  320. package/tests/migration.test.js +309 -0
  321. package/tests/production.test.js +416 -0
  322. package/tests/sdk.test.js +200 -0
  323. package/tests/skills-platform.test.js +403 -0
  324. package/tests/wave-engine.test.js +338 -0
@@ -0,0 +1,206 @@
1
+ /**
2
+ * MindForge Audit System Tests
3
+ * Run: node tests/audit.test.js
4
+ */
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const assert = require('assert');
9
+
10
+ let passed = 0;
11
+ let failed = 0;
12
+
13
+ function test(name, fn) {
14
+ try {
15
+ fn();
16
+ console.log(` ✅ ${name}`);
17
+ passed++;
18
+ } catch (err) {
19
+ console.error(` ❌ ${name}`);
20
+ console.error(` ${err.message}`);
21
+ failed++;
22
+ }
23
+ }
24
+
25
+ // ── Audit utility functions to test ──────────────────────────────────────────
26
+
27
+ function validateAuditEntry(entry) {
28
+ const required = ['id', 'timestamp', 'event', 'agent', 'session_id'];
29
+ const missing = required.filter(f => !entry[f]);
30
+ if (missing.length > 0) {
31
+ throw new Error(`Missing required fields: ${missing.join(', ')}`);
32
+ }
33
+ const ts = new Date(entry.timestamp);
34
+ if (isNaN(ts.getTime())) throw new Error(`Invalid timestamp: ${entry.timestamp}`);
35
+ if (!/^[0-9a-f-]{36}$/.test(entry.id)) throw new Error(`Invalid UUID format: ${entry.id}`);
36
+ }
37
+
38
+ function parseAuditLog(content) {
39
+ return content.trim().split('\n')
40
+ .filter(line => line.trim())
41
+ .map((line, index) => {
42
+ try {
43
+ return JSON.parse(line);
44
+ } catch (e) {
45
+ throw new Error(`Line ${index + 1} is not valid JSON: ${line.slice(0, 50)}...`);
46
+ }
47
+ });
48
+ }
49
+
50
+ // ── Tests ─────────────────────────────────────────────────────────────────────
51
+
52
+ console.log('\nMindForge Day 2 — Audit System Tests\n');
53
+
54
+ console.log('AUDIT.jsonl file:');
55
+
56
+ test('AUDIT.jsonl exists', () => {
57
+ assert.ok(fs.existsSync('.planning/AUDIT.jsonl'), 'AUDIT.jsonl not found');
58
+ });
59
+
60
+ test('AUDIT.jsonl is valid (empty or valid JSONL)', () => {
61
+ const content = fs.readFileSync('.planning/AUDIT.jsonl', 'utf8');
62
+ if (content.trim().length === 0) return;
63
+ parseAuditLog(content);
64
+ });
65
+
66
+ console.log('\nAudit entry validation:');
67
+
68
+ test('valid task_completed entry passes validation', () => {
69
+ const entry = {
70
+ id: '550e8400-e29b-41d4-a716-446655440000',
71
+ timestamp: new Date().toISOString(),
72
+ event: 'task_completed',
73
+ agent: 'mindforge-subagent-01',
74
+ phase: 1,
75
+ plan: '01',
76
+ session_id: 'sess_test',
77
+ task_name: 'Create user model',
78
+ commit_sha: 'abc1234',
79
+ verify_result: 'pass'
80
+ };
81
+ assert.doesNotThrow(() => validateAuditEntry(entry));
82
+ });
83
+
84
+ test('entry missing required field fails validation', () => {
85
+ const entry = {
86
+ timestamp: new Date().toISOString(),
87
+ event: 'task_completed',
88
+ agent: 'mindforge-subagent-01',
89
+ };
90
+ assert.throws(() => validateAuditEntry(entry), /Missing required fields/);
91
+ });
92
+
93
+ test('entry with invalid timestamp fails validation', () => {
94
+ const entry = {
95
+ id: '550e8400-e29b-41d4-a716-446655440000',
96
+ timestamp: 'not-a-date',
97
+ event: 'task_completed',
98
+ agent: 'mindforge-subagent-01',
99
+ session_id: 'sess_test',
100
+ };
101
+ assert.throws(() => validateAuditEntry(entry), /Invalid timestamp/);
102
+ });
103
+
104
+ test('JSONL parser handles multi-line audit log', () => {
105
+ const multiLine = [
106
+ '{"id":"550e8400-e29b-41d4-a716-446655440000","timestamp":"2026-03-20T10:00:00.000Z","event":"task_started","agent":"test","session_id":"s1"}',
107
+ '{"id":"550e8400-e29b-41d4-a716-446655440001","timestamp":"2026-03-20T10:05:00.000Z","event":"task_completed","agent":"test","session_id":"s1"}',
108
+ ].join('\n');
109
+ const entries = parseAuditLog(multiLine);
110
+ assert.strictEqual(entries.length, 2);
111
+ assert.strictEqual(entries[0].event, 'task_started');
112
+ assert.strictEqual(entries[1].event, 'task_completed');
113
+ });
114
+
115
+ test('JSONL parser rejects malformed JSON', () => {
116
+ const badLine = '{"id":"abc","timestamp": bad json}';
117
+ assert.throws(() => parseAuditLog(badLine), /not valid JSON/);
118
+ });
119
+
120
+ console.log('\nAudit schema files:');
121
+
122
+ test('AUDIT-SCHEMA.md exists and has content', () => {
123
+ const schemaPath = '.mindforge/audit/AUDIT-SCHEMA.md';
124
+ assert.ok(fs.existsSync(schemaPath), 'AUDIT-SCHEMA.md not found');
125
+ const content = fs.readFileSync(schemaPath, 'utf8');
126
+ assert.ok(content.length > 500, 'AUDIT-SCHEMA.md seems too short');
127
+ assert.ok(content.includes('task_completed'), 'Missing task_completed event type');
128
+ assert.ok(content.includes('security_finding'), 'Missing security_finding event type');
129
+ assert.ok(content.includes('context_compaction'), 'Missing context_compaction event type');
130
+ });
131
+
132
+ test('HANDOFF.json has _warning anti-secret field', () => {
133
+ const handoff = JSON.parse(fs.readFileSync('.planning/HANDOFF.json', 'utf8'));
134
+ assert.ok(handoff._warning, 'Missing _warning anti-secret field in HANDOFF.json');
135
+ assert.ok(handoff._warning.toLowerCase().includes('secret'), 'Warning should mention secrets');
136
+ });
137
+
138
+ console.log('\nAdditional audit tests:');
139
+
140
+ test('validates security_finding event type', () => {
141
+ const entry = {
142
+ id: '550e8400-e29b-41d4-a716-446655440002',
143
+ timestamp: new Date().toISOString(),
144
+ event: 'security_finding',
145
+ agent: 'mindforge-security-reviewer',
146
+ phase: 1,
147
+ session_id: 'sess_test',
148
+ severity: 'HIGH',
149
+ owasp_category: 'A03:Injection',
150
+ finding: 'SQL query built by string concatenation',
151
+ file: 'src/api/search.ts',
152
+ line: 42,
153
+ remediated: false
154
+ };
155
+ assert.doesNotThrow(() => validateAuditEntry(entry));
156
+ assert.strictEqual(entry.event, 'security_finding');
157
+ });
158
+
159
+ test('validates context_compaction event type', () => {
160
+ const entry = {
161
+ id: '550e8400-e29b-41d4-a716-446655440003',
162
+ timestamp: new Date().toISOString(),
163
+ event: 'context_compaction',
164
+ agent: 'mindforge-orchestrator',
165
+ phase: 2,
166
+ plan: '03',
167
+ session_id: 'sess_test',
168
+ context_usage_pct: 72,
169
+ handoff_written: true
170
+ };
171
+ assert.doesNotThrow(() => validateAuditEntry(entry));
172
+ });
173
+
174
+ test('rejects entry with malformed UUID', () => {
175
+ const entry = {
176
+ id: 'not-a-uuid',
177
+ timestamp: new Date().toISOString(),
178
+ event: 'task_completed',
179
+ agent: 'test',
180
+ session_id: 'sess_test'
181
+ };
182
+ assert.throws(() => validateAuditEntry(entry), /Invalid UUID/);
183
+ });
184
+
185
+ test('AUDIT.jsonl contains no secrets', () => {
186
+ const content = fs.readFileSync('.planning/AUDIT.jsonl', 'utf8');
187
+ const secretPatterns = [
188
+ /password\\s*["']?\\s*:\\s*["'][^"']{6,}/i,
189
+ /sk-[a-zA-Z0-9]{20,}/,
190
+ /-----BEGIN.*KEY-----/,
191
+ ];
192
+ secretPatterns.forEach(pattern => {
193
+ assert.ok(!pattern.test(content), `Potential secret found in AUDIT.jsonl`);
194
+ });
195
+ });
196
+
197
+ // ── Results ───────────────────────────────────────────────────────────────────
198
+ console.log(`\n${'─'.repeat(50)}`);
199
+ console.log(`Results: ${passed} passed, ${failed} failed`);
200
+
201
+ if (failed > 0) {
202
+ console.error(`\n❌ ${failed} test(s) failed.\n`);
203
+ process.exit(1);
204
+ } else {
205
+ console.log(`\n✅ All audit tests passed.\n`);
206
+ }
@@ -0,0 +1,162 @@
1
+ /**
2
+ * MindForge Day 6 — CI Mode Tests
3
+ * Run: node tests/ci-mode.test.js
4
+ */
5
+ 'use strict';
6
+ const fs = require('fs'), assert = require('assert');
7
+ let passed = 0, failed = 0;
8
+ function test(name, fn) {
9
+ try { fn(); console.log(` ✅ ${name}`); passed++; }
10
+ catch(e) { console.error(` ❌ ${name}\n ${e.message}`); failed++; }
11
+ }
12
+ const read = p => fs.existsSync(p) ? fs.readFileSync(p, 'utf8') : '';
13
+
14
+ // ── CI mode detection simulation ──────────────────────────────────────────────
15
+ function isCiMode() {
16
+ return process.env.CI === 'true' ||
17
+ process.env.MINDFORGE_CI === 'true' ||
18
+ process.stdin.isTTY === false;
19
+ }
20
+
21
+ // ── GitHub annotations format ─────────────────────────────────────────────────
22
+ function formatGitHubAnnotation(level, message, file, line) {
23
+ const loc = file ? ` file=${file}${line ? `,line=${line}` : ''}` : '';
24
+ return `::${level}${loc}::${message}`;
25
+ }
26
+
27
+ // ── Tier3 CI block simulation ─────────────────────────────────────────────────
28
+ function checkCiTierPolicy(tier, ciAutoApproveTier2 = false) {
29
+ if (tier === 1) return 'auto-approved';
30
+ if (tier === 2) return ciAutoApproveTier2 ? 'auto-approved' : 'blocked';
31
+ if (tier === 3) return 'blocked'; // Always blocked in CI
32
+ return 'unknown';
33
+ }
34
+
35
+ console.log('\nMindForge Day 6 — CI Mode Tests\n');
36
+
37
+ console.log('CI engine files:');
38
+ ['ci-mode.md','github-actions-adapter.md','gitlab-ci-adapter.md'].forEach(f => {
39
+ test(`${f} exists`, () => {
40
+ assert.ok(fs.existsSync(`.mindforge/ci/${f}`), `Missing: .mindforge/ci/${f}`);
41
+ });
42
+ });
43
+
44
+ console.log('\nCI mode detection:');
45
+ test('isCiMode returns false in normal test environment', () => {
46
+ const origCI = process.env.CI;
47
+ delete process.env.CI;
48
+ delete process.env.MINDFORGE_CI;
49
+ // In test environment, stdin.isTTY may be false — we test the env var logic only
50
+ const ciFromEnv = process.env.CI === 'true' || process.env.MINDFORGE_CI === 'true';
51
+ assert.strictEqual(ciFromEnv, false, 'Should not be CI mode from env vars');
52
+ if (origCI) process.env.CI = origCI;
53
+ });
54
+
55
+ test('CI=true activates CI mode', () => {
56
+ process.env.MINDFORGE_CI = 'true';
57
+ assert.strictEqual(process.env.MINDFORGE_CI, 'true');
58
+ delete process.env.MINDFORGE_CI;
59
+ });
60
+
61
+ console.log('\nCI tier policy:');
62
+ test('Tier 1 is always auto-approved in CI', () => {
63
+ assert.strictEqual(checkCiTierPolicy(1), 'auto-approved');
64
+ });
65
+
66
+ test('Tier 2 blocked by default in CI (safety-first)', () => {
67
+ assert.strictEqual(checkCiTierPolicy(2, false), 'blocked');
68
+ });
69
+
70
+ test('Tier 2 can be auto-approved in CI when configured', () => {
71
+ assert.strictEqual(checkCiTierPolicy(2, true), 'auto-approved');
72
+ });
73
+
74
+ test('Tier 3 is ALWAYS blocked in CI regardless of config', () => {
75
+ assert.strictEqual(checkCiTierPolicy(3, true), 'blocked'); // even with true
76
+ assert.strictEqual(checkCiTierPolicy(3, false), 'blocked');
77
+ });
78
+
79
+ console.log('\nGitHub annotations format:');
80
+ test('notice annotation format is correct', () => {
81
+ const ann = formatGitHubAnnotation('notice', 'Task 3-01 completed', null, null);
82
+ assert.strictEqual(ann, '::notice::Task 3-01 completed');
83
+ });
84
+
85
+ test('error annotation with file and line is correct', () => {
86
+ const ann = formatGitHubAnnotation('error', 'TypeScript error', 'src/auth.ts', 47);
87
+ assert.strictEqual(ann, '::error file=src/auth.ts,line=47::TypeScript error');
88
+ });
89
+
90
+ test('warning annotation with file only (no line)', () => {
91
+ const ann = formatGitHubAnnotation('warning', 'Security finding', 'src/utils.ts', null);
92
+ assert.strictEqual(ann, '::warning file=src/utils.ts::Security finding');
93
+ });
94
+
95
+ console.log('\nGitHub Actions workflow:');
96
+ test('github-actions-adapter.md defines mindforge-ci.yml structure', () => {
97
+ const c = read('.mindforge/ci/github-actions-adapter.md');
98
+ assert.ok(c.includes('mindforge-ci.yml') || c.includes('on:'), 'Should define GitHub Actions workflow');
99
+ assert.ok(c.includes('mindforge-health'), 'Should include health check job');
100
+ assert.ok(c.includes('mindforge-security'), 'Should include security scan job');
101
+ });
102
+
103
+ test('ci-mode.md defines Tier 3 block policy', () => {
104
+ const c = read('.mindforge/ci/ci-mode.md');
105
+ assert.ok(
106
+ (c.includes('Tier 3') && c.includes('block')) || c.includes('ALWAYS fails'),
107
+ 'CI mode should block Tier 3 changes'
108
+ );
109
+ });
110
+
111
+ test('ci-mode.md has timeout configuration', () => {
112
+ const c = read('.mindforge/ci/ci-mode.md');
113
+ assert.ok(c.includes('timeout') || c.includes('TIMEOUT'), 'CI mode should have timeout config');
114
+ });
115
+
116
+ console.log('\nMonorepo support:');
117
+ ['workspace-detector.md','cross-package-planner.md','dependency-graph-builder.md'].forEach(f => {
118
+ test(`${f} exists`, () => {
119
+ assert.ok(fs.existsSync(`.mindforge/monorepo/${f}`), `Missing: .mindforge/monorepo/${f}`);
120
+ });
121
+ });
122
+
123
+ test('workspace-detector supports major monorepo types', () => {
124
+ const c = read('.mindforge/monorepo/workspace-detector.md');
125
+ ['nx', 'turborepo', 'lerna', 'pnpm'].forEach(type => {
126
+ assert.ok(c.includes(type), `Should support ${type} monorepo type`);
127
+ });
128
+ });
129
+
130
+ test('cross-package-planner has topological sort', () => {
131
+ const c = read('.mindforge/monorepo/cross-package-planner.md');
132
+ assert.ok(
133
+ c.includes('topological') || c.includes('dependency order') || c.includes('Execution order'),
134
+ 'Should use topological sort for package order'
135
+ );
136
+ });
137
+
138
+ console.log('\nHardening-prompted CI tests:');
139
+
140
+ test('ci-mode uses exit code 0 for timeout (not 2)', () => {
141
+ const c = read('.mindforge/ci/ci-mode.md');
142
+ assert.ok(
143
+ c.includes('exit 0') && (c.includes('timeout') || c.includes('Timeout')),
144
+ 'Timeout should exit with code 0'
145
+ );
146
+ // Should NOT say exit 2 for timeout
147
+ const exit2ForTimeout = c.match(/timeout.*exit 2|exit 2.*timeout/is);
148
+ assert.ok(!exit2ForTimeout, 'Should not use exit 2 for timeout');
149
+ });
150
+
151
+ test('github-actions adapter has Tier 3 governance block with clear message', () => {
152
+ const c = read('.mindforge/ci/github-actions-adapter.md');
153
+ assert.ok(
154
+ c.includes('Tier 3') && c.includes('block'),
155
+ 'Should explain Tier 3 CI block clearly'
156
+ );
157
+ });
158
+
159
+ console.log(`\n${'─'.repeat(50)}`);
160
+ console.log(`Results: ${passed} passed, ${failed} failed`);
161
+ if (failed > 0) { console.error(`\n❌ ${failed} test(s) failed.\n`); process.exit(1); }
162
+ else { console.log(`\n✅ All CI mode tests passed.\n`); }
@@ -0,0 +1,161 @@
1
+ /**
2
+ * MindForge Context Compaction Tests
3
+ * Run: node tests/compaction.test.js
4
+ */
5
+
6
+ const fs = require('fs');
7
+ const assert = require('assert');
8
+
9
+ let passed = 0;
10
+ let failed = 0;
11
+
12
+ function test(name, fn) {
13
+ try {
14
+ fn();
15
+ console.log(` ✅ ${name}`);
16
+ passed++;
17
+ } catch (err) {
18
+ console.error(` ❌ ${name}`);
19
+ console.error(` ${err.message}`);
20
+ failed++;
21
+ }
22
+ }
23
+
24
+ // ── Compaction state validator ─────────────────────────────────────────────────
25
+
26
+ function validateHandoffJson(obj) {
27
+ const required = ['schema_version', 'next_task', '_warning', 'context_refs'];
28
+ const missing = required.filter(f => obj[f] === undefined);
29
+ if (missing.length > 0) throw new Error(`Missing: ${missing.join(', ')}`);
30
+ if (!Array.isArray(obj.context_refs)) throw new Error('context_refs must be an array');
31
+ if (!Array.isArray(obj.blockers)) throw new Error('blockers must be an array');
32
+ if (obj._warning.toLowerCase().includes('password') === false &&
33
+ obj._warning.toLowerCase().includes('secret') === false) {
34
+ throw new Error('_warning must mention secrets/passwords');
35
+ }
36
+ }
37
+
38
+ function validateStateHasCompactionCheckpoint(content) {
39
+ return content.includes('Compaction checkpoint') || content.includes('compaction');
40
+ }
41
+
42
+ // ── Tests ─────────────────────────────────────────────────────────────────────
43
+
44
+ console.log('\nMindForge Day 2 — Context Compaction Tests\n');
45
+
46
+ console.log('HANDOFF.json schema validation:');
47
+
48
+ test('HANDOFF.json exists', () => {
49
+ assert.ok(fs.existsSync('.planning/HANDOFF.json'));
50
+ });
51
+
52
+ test('HANDOFF.json is valid JSON', () => {
53
+ const content = fs.readFileSync('.planning/HANDOFF.json', 'utf8');
54
+ assert.doesNotThrow(() => JSON.parse(content));
55
+ });
56
+
57
+ test('HANDOFF.json has all required fields', () => {
58
+ const obj = JSON.parse(fs.readFileSync('.planning/HANDOFF.json', 'utf8'));
59
+ validateHandoffJson(obj);
60
+ });
61
+
62
+ test('HANDOFF.json schema_version is 1.0.0', () => {
63
+ const obj = JSON.parse(fs.readFileSync('.planning/HANDOFF.json', 'utf8'));
64
+ assert.strictEqual(obj.schema_version, '1.0.0');
65
+ });
66
+
67
+ test('HANDOFF.json context_refs is an array', () => {
68
+ const obj = JSON.parse(fs.readFileSync('.planning/HANDOFF.json', 'utf8'));
69
+ assert.ok(Array.isArray(obj.context_refs));
70
+ });
71
+
72
+ test('HANDOFF.json blockers is an array', () => {
73
+ const obj = JSON.parse(fs.readFileSync('.planning/HANDOFF.json', 'utf8'));
74
+ assert.ok(Array.isArray(obj.blockers));
75
+ });
76
+
77
+ test('HANDOFF.json decisions_needed is an array', () => {
78
+ const obj = JSON.parse(fs.readFileSync('.planning/HANDOFF.json', 'utf8'));
79
+ assert.ok(Array.isArray(obj.decisions_needed));
80
+ });
81
+
82
+ console.log('\nCompaction protocol file:');
83
+
84
+ test('compaction-protocol.md exists', () => {
85
+ assert.ok(
86
+ fs.existsSync('.mindforge/engine/compaction-protocol.md'),
87
+ 'compaction-protocol.md not found'
88
+ );
89
+ });
90
+
91
+ test('compaction-protocol.md mentions 70% threshold', () => {
92
+ const content = fs.readFileSync('.mindforge/engine/compaction-protocol.md', 'utf8');
93
+ assert.ok(content.includes('70%'), 'Should specify 70% compaction threshold');
94
+ });
95
+
96
+ test('compaction-protocol.md has all 6 steps', () => {
97
+ const content = fs.readFileSync('.mindforge/engine/compaction-protocol.md', 'utf8');
98
+ assert.ok(content.includes('Step 1'), 'Missing Step 1');
99
+ assert.ok(content.includes('Step 2'), 'Missing Step 2');
100
+ assert.ok(content.includes('Step 3'), 'Missing Step 3');
101
+ assert.ok(content.includes('Step 4'), 'Missing Step 4');
102
+ assert.ok(content.includes('Step 5'), 'Missing Step 5');
103
+ assert.ok(content.includes('Step 6'), 'Missing Step 6');
104
+ });
105
+
106
+ test('compaction-protocol.md covers session restart procedure', () => {
107
+ const content = fs.readFileSync('.mindforge/engine/compaction-protocol.md', 'utf8');
108
+ assert.ok(
109
+ content.includes('Session restart') || content.includes('restart from HANDOFF'),
110
+ 'Should cover session restart from HANDOFF.json'
111
+ );
112
+ });
113
+
114
+ console.log('\nAdditional compaction tests:');
115
+
116
+ test('HANDOFF.json has recent_commits field', () => {
117
+ const obj = JSON.parse(fs.readFileSync('.planning/HANDOFF.json', 'utf8'));
118
+ assert.ok('recent_commits' in obj, 'Missing recent_commits field');
119
+ assert.ok(Array.isArray(obj.recent_commits), 'recent_commits must be an array');
120
+ });
121
+
122
+ test('HANDOFF.json has recent_files field', () => {
123
+ const obj = JSON.parse(fs.readFileSync('.planning/HANDOFF.json', 'utf8'));
124
+ assert.ok('recent_files' in obj, 'Missing recent_files field');
125
+ assert.ok(Array.isArray(obj.recent_files), 'recent_files must be an array');
126
+ });
127
+
128
+ test('compaction-protocol.md covers WIP commit with --no-verify', () => {
129
+ const content = fs.readFileSync('.mindforge/engine/compaction-protocol.md', 'utf8');
130
+ assert.ok(
131
+ content.includes('--no-verify') || content.includes('no-verify'),
132
+ 'Should mention --no-verify for WIP commits that bypass hooks'
133
+ );
134
+ });
135
+
136
+ test('compaction-protocol.md covers staleness detection', () => {
137
+ const content = fs.readFileSync('.mindforge/engine/compaction-protocol.md', 'utf8');
138
+ assert.ok(
139
+ content.includes('48 hours') || content.includes('staleness') || content.includes('stale'),
140
+ 'Should cover HANDOFF.json staleness detection'
141
+ );
142
+ });
143
+
144
+ test('compaction-protocol.md mentions 85% emergency compaction', () => {
145
+ const content = fs.readFileSync('.mindforge/engine/compaction-protocol.md', 'utf8');
146
+ assert.ok(
147
+ content.includes('85%') || content.includes('emergency'),
148
+ 'Should cover emergency compaction when 85%+ context is reached'
149
+ );
150
+ });
151
+
152
+ // ── Results ───────────────────────────────────────────────────────────────────
153
+ console.log(`\n${'─'.repeat(50)}`);
154
+ console.log(`Results: ${passed} passed, ${failed} failed`);
155
+
156
+ if (failed > 0) {
157
+ console.error(`\n❌ ${failed} test(s) failed.\n`);
158
+ process.exit(1);
159
+ } else {
160
+ console.log(`\n✅ All compaction tests passed.\n`);
161
+ }