moflo 4.8.22 → 4.8.23

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 (93) hide show
  1. package/.claude/workflow-state.json +1 -1
  2. package/README.md +13 -0
  3. package/package.json +2 -2
  4. package/src/@claude-flow/cli/dist/src/commands/doctor.js +13 -1
  5. package/src/@claude-flow/cli/dist/src/commands/init.js +3 -8
  6. package/src/@claude-flow/cli/package.json +1 -1
  7. package/src/@claude-flow/guidance/dist/adversarial.d.ts +284 -0
  8. package/src/@claude-flow/guidance/dist/adversarial.js +572 -0
  9. package/src/@claude-flow/guidance/dist/analyzer.d.ts +530 -0
  10. package/src/@claude-flow/guidance/dist/analyzer.js +2518 -0
  11. package/src/@claude-flow/guidance/dist/artifacts.d.ts +283 -0
  12. package/src/@claude-flow/guidance/dist/artifacts.js +356 -0
  13. package/src/@claude-flow/guidance/dist/authority.d.ts +290 -0
  14. package/src/@claude-flow/guidance/dist/authority.js +558 -0
  15. package/src/@claude-flow/guidance/dist/capabilities.d.ts +209 -0
  16. package/src/@claude-flow/guidance/dist/capabilities.js +485 -0
  17. package/src/@claude-flow/guidance/dist/coherence.d.ts +233 -0
  18. package/src/@claude-flow/guidance/dist/coherence.js +372 -0
  19. package/src/@claude-flow/guidance/dist/compiler.d.ts +87 -0
  20. package/src/@claude-flow/guidance/dist/compiler.js +419 -0
  21. package/src/@claude-flow/guidance/dist/conformance-kit.d.ts +225 -0
  22. package/src/@claude-flow/guidance/dist/conformance-kit.js +629 -0
  23. package/src/@claude-flow/guidance/dist/continue-gate.d.ts +214 -0
  24. package/src/@claude-flow/guidance/dist/continue-gate.js +353 -0
  25. package/src/@claude-flow/guidance/dist/crypto-utils.d.ts +17 -0
  26. package/src/@claude-flow/guidance/dist/crypto-utils.js +24 -0
  27. package/src/@claude-flow/guidance/dist/evolution.d.ts +282 -0
  28. package/src/@claude-flow/guidance/dist/evolution.js +500 -0
  29. package/src/@claude-flow/guidance/dist/gates.d.ts +79 -0
  30. package/src/@claude-flow/guidance/dist/gates.js +302 -0
  31. package/src/@claude-flow/guidance/dist/gateway.d.ts +206 -0
  32. package/src/@claude-flow/guidance/dist/gateway.js +452 -0
  33. package/src/@claude-flow/guidance/dist/generators.d.ts +153 -0
  34. package/src/@claude-flow/guidance/dist/generators.js +682 -0
  35. package/src/@claude-flow/guidance/dist/headless.d.ts +177 -0
  36. package/src/@claude-flow/guidance/dist/headless.js +342 -0
  37. package/src/@claude-flow/guidance/dist/hooks.d.ts +109 -0
  38. package/src/@claude-flow/guidance/dist/hooks.js +347 -0
  39. package/src/@claude-flow/guidance/dist/index.d.ts +205 -0
  40. package/src/@claude-flow/guidance/dist/index.js +321 -0
  41. package/src/@claude-flow/guidance/dist/ledger.d.ts +162 -0
  42. package/src/@claude-flow/guidance/dist/ledger.js +375 -0
  43. package/src/@claude-flow/guidance/dist/manifest-validator.d.ts +289 -0
  44. package/src/@claude-flow/guidance/dist/manifest-validator.js +838 -0
  45. package/src/@claude-flow/guidance/dist/memory-gate.d.ts +222 -0
  46. package/src/@claude-flow/guidance/dist/memory-gate.js +382 -0
  47. package/src/@claude-flow/guidance/dist/meta-governance.d.ts +265 -0
  48. package/src/@claude-flow/guidance/dist/meta-governance.js +348 -0
  49. package/src/@claude-flow/guidance/dist/optimizer.d.ts +104 -0
  50. package/src/@claude-flow/guidance/dist/optimizer.js +329 -0
  51. package/src/@claude-flow/guidance/dist/persistence.d.ts +189 -0
  52. package/src/@claude-flow/guidance/dist/persistence.js +464 -0
  53. package/src/@claude-flow/guidance/dist/proof.d.ts +185 -0
  54. package/src/@claude-flow/guidance/dist/proof.js +238 -0
  55. package/src/@claude-flow/guidance/dist/retriever.d.ts +116 -0
  56. package/src/@claude-flow/guidance/dist/retriever.js +394 -0
  57. package/src/@claude-flow/guidance/dist/ruvbot-integration.d.ts +370 -0
  58. package/src/@claude-flow/guidance/dist/ruvbot-integration.js +738 -0
  59. package/src/@claude-flow/guidance/dist/temporal.d.ts +426 -0
  60. package/src/@claude-flow/guidance/dist/temporal.js +658 -0
  61. package/src/@claude-flow/guidance/dist/trust.d.ts +283 -0
  62. package/src/@claude-flow/guidance/dist/trust.js +473 -0
  63. package/src/@claude-flow/guidance/dist/truth-anchors.d.ts +276 -0
  64. package/src/@claude-flow/guidance/dist/truth-anchors.js +488 -0
  65. package/src/@claude-flow/guidance/dist/types.d.ts +378 -0
  66. package/src/@claude-flow/guidance/dist/types.js +10 -0
  67. package/src/@claude-flow/guidance/dist/uncertainty.d.ts +372 -0
  68. package/src/@claude-flow/guidance/dist/uncertainty.js +619 -0
  69. package/src/@claude-flow/guidance/dist/wasm-kernel.d.ts +48 -0
  70. package/src/@claude-flow/guidance/dist/wasm-kernel.js +158 -0
  71. package/src/@claude-flow/memory/dist/agent-memory-scope.test.js +7 -4
  72. package/src/@claude-flow/memory/dist/agentdb-backend.d.ts +0 -2
  73. package/src/@claude-flow/memory/dist/agentdb-backend.js +0 -2
  74. package/src/@claude-flow/memory/dist/auto-memory-bridge.test.js +12 -9
  75. package/src/@claude-flow/memory/dist/benchmark.test.js +1 -1
  76. package/src/@claude-flow/memory/dist/controller-registry.test.js +0 -43
  77. package/src/@claude-flow/memory/dist/database-provider.d.ts +2 -2
  78. package/src/@claude-flow/memory/dist/database-provider.js +3 -6
  79. package/src/@claude-flow/memory/dist/database-provider.test.js +3 -1
  80. package/src/@claude-flow/memory/dist/index.d.ts +0 -3
  81. package/src/@claude-flow/memory/dist/index.js +0 -3
  82. package/src/@claude-flow/memory/dist/sqljs-backend.d.ts +3 -4
  83. package/src/@claude-flow/memory/dist/sqljs-backend.js +4 -5
  84. package/src/@claude-flow/shared/dist/core/config/defaults.js +1 -1
  85. package/src/@claude-flow/shared/dist/core/config/loader.js +1 -1
  86. package/src/@claude-flow/shared/dist/core/config/schema.js +1 -1
  87. package/src/@claude-flow/shared/dist/events/event-store.js +19 -3
  88. package/src/@claude-flow/shared/dist/events/event-store.test.js +8 -4
  89. package/src/@claude-flow/shared/dist/hooks/executor.js +7 -4
  90. package/src/@claude-flow/shared/dist/hooks/safety/file-organization.js +1 -1
  91. package/src/@claude-flow/shared/dist/hooks/safety/git-commit.js +3 -3
  92. package/src/@claude-flow/shared/dist/hooks/verify-exports.test.js +6 -6
  93. package/src/@claude-flow/shared/dist/utils/secure-logger.js +1 -1
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Task Intent Classifier + Shard Retriever
3
+ *
4
+ * Stores rule shards in vector storage with embeddings and metadata.
5
+ * At task start, retrieves the top N shards by semantic similarity
6
+ * with hard filters by risk class and repo scope.
7
+ *
8
+ * Retrieval contract:
9
+ * 1. Always include the constitution
10
+ * 2. Retrieve up to 5 shards by semantic similarity
11
+ * 3. Add hard filters by risk class and repo scope
12
+ * 4. Contradiction check: prefer higher-priority rule ID
13
+ *
14
+ * @module @claude-flow/guidance/retriever
15
+ */
16
+ // ============================================================================
17
+ // Intent Classification
18
+ // ============================================================================
19
+ /** Intent detection patterns with confidence weights */
20
+ const INTENT_PATTERNS = {
21
+ 'bug-fix': [
22
+ { pattern: /\b(fix|bug|broken|error|crash|issue|wrong|incorrect|fail)\b/i, weight: 0.8 },
23
+ { pattern: /\b(not working|doesn't work|unexpected|regression)\b/i, weight: 0.9 },
24
+ ],
25
+ 'feature': [
26
+ { pattern: /\b(add|create|implement|build|new|introduce|develop)\b/i, weight: 0.5 },
27
+ { pattern: /\b(feature|capability|functionality|support for)\b/i, weight: 0.9 },
28
+ { pattern: /\b(user|page|profile|dashboard|form|widget|component|module)\b/i, weight: 0.3 },
29
+ ],
30
+ 'refactor': [
31
+ { pattern: /\b(refactor|restructure|reorganize|simplify|clean|extract|inline)\b/i, weight: 0.9 },
32
+ { pattern: /\b(improve readability|reduce complexity|code quality)\b/i, weight: 0.8 },
33
+ ],
34
+ 'security': [
35
+ { pattern: /\b(security|auth|permission|access control|encrypt|secret|token)\b/i, weight: 0.9 },
36
+ { pattern: /\b(cve|vulnerability|injection|xss|csrf|sanitize)\b/i, weight: 1.0 },
37
+ ],
38
+ 'performance': [
39
+ { pattern: /\b(performance|optimize|speed|slow|fast|cache|memory usage|latency)\b/i, weight: 0.9 },
40
+ { pattern: /\b(bottleneck|profile|benchmark|throughput|efficient)\b/i, weight: 0.8 },
41
+ ],
42
+ 'testing': [
43
+ { pattern: /\b(tests?|specs?|coverage|mocks?|asserts?|tdd|unit tests?|integration tests?)\b/i, weight: 1.0 },
44
+ { pattern: /\b(test suite|test case|test plan|quality assurance)\b/i, weight: 0.9 },
45
+ ],
46
+ 'docs': [
47
+ { pattern: /\b(document|readme|jsdoc|comment|explain|describe|tutorial)\b/i, weight: 0.8 },
48
+ { pattern: /\b(api docs|documentation|usage guide|changelog)\b/i, weight: 0.9 },
49
+ ],
50
+ 'deployment': [
51
+ { pattern: /\b(deploy|release|publish|ci|cd|pipeline|docker|kubernetes)\b/i, weight: 0.9 },
52
+ { pattern: /\b(staging|production|rollback|migration|version)\b/i, weight: 0.7 },
53
+ ],
54
+ 'architecture': [
55
+ { pattern: /\b(architect|design pattern|system design|structure|boundary)\b/i, weight: 0.8 },
56
+ { pattern: /\b(module boundary|component architecture|layer|service mesh|domain model|aggregate root)\b/i, weight: 0.7 },
57
+ { pattern: /\b(interface|api design|separation of concerns)\b/i, weight: 0.6 },
58
+ ],
59
+ 'debug': [
60
+ { pattern: /\b(debug|trace|log|diagnose|investigate|root cause)\b/i, weight: 0.9 },
61
+ { pattern: /\b(stack trace|breakpoint|inspect|reproduction)\b/i, weight: 0.8 },
62
+ ],
63
+ 'general': [
64
+ { pattern: /./, weight: 0.1 },
65
+ ],
66
+ };
67
+ /**
68
+ * Deterministic hash-based embedding provider — **test-only**.
69
+ *
70
+ * Produces fixed-dimension vectors from a simple character-hash → sin()
71
+ * transform. The resulting embeddings have no real semantic meaning;
72
+ * they are stable and fast, which makes them useful for unit/integration
73
+ * tests that need a concrete {@link IEmbeddingProvider} without loading
74
+ * an ONNX model.
75
+ *
76
+ * **Do NOT use in production** — replace with a real model-backed
77
+ * provider (e.g. the agentic-flow ONNX integration).
78
+ */
79
+ export class HashEmbeddingProvider {
80
+ dimensions;
81
+ cache = new Map();
82
+ constructor(dimensions = 384) {
83
+ this.dimensions = dimensions;
84
+ }
85
+ async embed(text) {
86
+ const key = text.slice(0, 200);
87
+ if (this.cache.has(key))
88
+ return this.cache.get(key);
89
+ const embedding = this.hashEmbed(text);
90
+ this.cache.set(key, embedding);
91
+ return embedding;
92
+ }
93
+ async batchEmbed(texts) {
94
+ return Promise.all(texts.map(t => this.embed(t)));
95
+ }
96
+ hashEmbed(text) {
97
+ const embedding = new Float32Array(this.dimensions);
98
+ const normalized = text.toLowerCase().trim();
99
+ for (let i = 0; i < this.dimensions; i++) {
100
+ let hash = 0;
101
+ for (let j = 0; j < normalized.length; j++) {
102
+ hash = ((hash << 5) - hash + normalized.charCodeAt(j) * (i + 1)) | 0;
103
+ }
104
+ embedding[i] = (Math.sin(hash) + 1) / 2;
105
+ }
106
+ // L2 normalize
107
+ let norm = 0;
108
+ for (let i = 0; i < this.dimensions; i++) {
109
+ norm += embedding[i] * embedding[i];
110
+ }
111
+ norm = Math.sqrt(norm);
112
+ if (norm > 0) {
113
+ for (let i = 0; i < this.dimensions; i++) {
114
+ embedding[i] /= norm;
115
+ }
116
+ }
117
+ return embedding;
118
+ }
119
+ }
120
+ // ============================================================================
121
+ // Shard Retriever
122
+ // ============================================================================
123
+ export class ShardRetriever {
124
+ shards = [];
125
+ constitution = null;
126
+ embeddingProvider;
127
+ indexed = false;
128
+ globCache = new Map();
129
+ constructor(embeddingProvider) {
130
+ this.embeddingProvider = embeddingProvider ?? new HashEmbeddingProvider();
131
+ }
132
+ /**
133
+ * Load a compiled policy bundle
134
+ */
135
+ async loadBundle(bundle) {
136
+ this.constitution = bundle.constitution;
137
+ this.shards = bundle.shards;
138
+ this.indexed = false;
139
+ await this.indexShards();
140
+ }
141
+ /**
142
+ * Index all shards by generating embeddings
143
+ */
144
+ async indexShards() {
145
+ if (this.indexed)
146
+ return;
147
+ const texts = this.shards.map(s => s.compactText);
148
+ const embeddings = await this.embeddingProvider.batchEmbed(texts);
149
+ for (let i = 0; i < this.shards.length; i++) {
150
+ this.shards[i].embedding = embeddings[i];
151
+ }
152
+ this.indexed = true;
153
+ }
154
+ /**
155
+ * Classify task intent
156
+ */
157
+ classifyIntent(taskDescription) {
158
+ let bestIntent = 'general';
159
+ let bestScore = 0;
160
+ for (const [intent, patterns] of Object.entries(INTENT_PATTERNS)) {
161
+ if (intent === 'general')
162
+ continue; // Skip general fallback during scoring
163
+ let score = 0;
164
+ for (const { pattern, weight } of patterns) {
165
+ if (pattern.test(taskDescription)) {
166
+ score += weight;
167
+ }
168
+ }
169
+ if (score > bestScore) {
170
+ bestScore = score;
171
+ bestIntent = intent;
172
+ }
173
+ }
174
+ // Normalize confidence to 0-1
175
+ const confidence = Math.min(bestScore / 3, 1);
176
+ return { intent: bestIntent, confidence };
177
+ }
178
+ /**
179
+ * Retrieve relevant shards for a task
180
+ *
181
+ * Contract:
182
+ * 1. Always include the constitution
183
+ * 2. Up to maxShards by semantic similarity
184
+ * 3. Hard filters by risk class and repo scope
185
+ * 4. Contradiction check: prefer higher priority
186
+ */
187
+ async retrieve(request) {
188
+ const startTime = performance.now();
189
+ if (!this.constitution) {
190
+ throw new Error('No policy bundle loaded. Call loadBundle() first.');
191
+ }
192
+ // Step 1: Classify intent
193
+ const { intent: detectedIntent } = this.classifyIntent(request.taskDescription);
194
+ const intent = request.intent ?? detectedIntent;
195
+ // Step 2: Generate query embedding
196
+ const queryEmbedding = await this.embeddingProvider.embed(request.taskDescription);
197
+ // Step 3: Score all shards
198
+ const maxShards = request.maxShards ?? 5;
199
+ const scored = this.scoreShards(queryEmbedding, intent, request.riskFilter, request.repoScope);
200
+ // Step 4: Select top N with contradiction resolution
201
+ const selected = this.selectWithContradictionCheck(scored, maxShards);
202
+ // Step 5: Build combined policy text
203
+ const policyText = this.buildPolicyText(this.constitution, selected);
204
+ const latencyMs = performance.now() - startTime;
205
+ return {
206
+ constitution: this.constitution,
207
+ shards: selected,
208
+ detectedIntent: intent,
209
+ contradictionsResolved: this.countContradictions(selected),
210
+ policyText,
211
+ latencyMs,
212
+ };
213
+ }
214
+ /**
215
+ * Score all shards against the query
216
+ */
217
+ scoreShards(queryEmbedding, intent, riskFilter, repoScope) {
218
+ const results = [];
219
+ for (const shard of this.shards) {
220
+ // Hard filter: risk class
221
+ if (riskFilter && riskFilter.length > 0) {
222
+ if (!riskFilter.includes(shard.rule.riskClass))
223
+ continue;
224
+ }
225
+ // Hard filter: repo scope
226
+ if (repoScope) {
227
+ const matchesScope = shard.rule.repoScopes.some(scope => scope === '**/*' || this.matchGlob(repoScope, scope));
228
+ if (!matchesScope)
229
+ continue;
230
+ }
231
+ // Semantic similarity
232
+ let similarity = 0;
233
+ if (shard.embedding) {
234
+ similarity = this.cosineSimilarity(queryEmbedding, shard.embedding);
235
+ }
236
+ // Intent boost: if shard matches detected intent, boost score
237
+ const intentBoost = shard.rule.intents.includes(intent) ? 0.15 : 0;
238
+ // Risk boost: critical/high rules get a boost
239
+ const riskBoost = shard.rule.riskClass === 'critical' ? 0.1
240
+ : shard.rule.riskClass === 'high' ? 0.05
241
+ : 0;
242
+ const finalScore = similarity + intentBoost + riskBoost;
243
+ const reasons = [];
244
+ if (similarity > 0.3)
245
+ reasons.push(`semantic match (${(similarity * 100).toFixed(0)}%)`);
246
+ if (intentBoost > 0)
247
+ reasons.push(`intent match (${intent})`);
248
+ if (riskBoost > 0)
249
+ reasons.push(`risk priority (${shard.rule.riskClass})`);
250
+ results.push({
251
+ shard,
252
+ similarity: finalScore,
253
+ reason: reasons.join(', ') || 'general relevance',
254
+ });
255
+ }
256
+ // Sort by combined score descending
257
+ return results.sort((a, b) => b.similarity - a.similarity);
258
+ }
259
+ /**
260
+ * Select top N shards with contradiction checking
261
+ * When two rules contradict, keep the one with higher priority
262
+ */
263
+ selectWithContradictionCheck(scored, maxShards) {
264
+ const selected = [];
265
+ const selectedDomains = new Map(); // domain -> highest priority
266
+ for (const item of scored) {
267
+ if (selected.length >= maxShards)
268
+ break;
269
+ // Check for potential contradictions with already selected shards
270
+ let dominated = false;
271
+ for (const domain of item.shard.rule.domains) {
272
+ const existingPriority = selectedDomains.get(domain);
273
+ if (existingPriority !== undefined && existingPriority > item.shard.rule.priority) {
274
+ // Higher priority rule already selected for this domain
275
+ // Check if they're likely contradictory (similar domain, different intent)
276
+ const existing = selected.find(s => s.shard.rule.domains.includes(domain) &&
277
+ s.shard.rule.priority > item.shard.rule.priority);
278
+ if (existing && this.areContradictory(existing.shard.rule, item.shard.rule)) {
279
+ dominated = true;
280
+ break;
281
+ }
282
+ }
283
+ }
284
+ if (!dominated) {
285
+ selected.push(item);
286
+ for (const domain of item.shard.rule.domains) {
287
+ const current = selectedDomains.get(domain) ?? 0;
288
+ selectedDomains.set(domain, Math.max(current, item.shard.rule.priority));
289
+ }
290
+ }
291
+ }
292
+ return selected;
293
+ }
294
+ /**
295
+ * Check if two rules are contradictory
296
+ */
297
+ areContradictory(a, b) {
298
+ const negationPatterns = [
299
+ { positive: /\bmust\b/i, negative: /\bnever\b|\bdo not\b|\bavoid\b/i },
300
+ { positive: /\balways\b/i, negative: /\bnever\b|\bdon't\b/i },
301
+ { positive: /\brequire\b/i, negative: /\bforbid\b|\bprohibit\b/i },
302
+ ];
303
+ for (const { positive, negative } of negationPatterns) {
304
+ if ((positive.test(a.text) && negative.test(b.text)) ||
305
+ (negative.test(a.text) && positive.test(b.text))) {
306
+ return true;
307
+ }
308
+ }
309
+ return false;
310
+ }
311
+ /**
312
+ * Count contradictions in selected set
313
+ */
314
+ countContradictions(selected) {
315
+ let count = 0;
316
+ for (let i = 0; i < selected.length; i++) {
317
+ for (let j = i + 1; j < selected.length; j++) {
318
+ if (this.areContradictory(selected[i].shard.rule, selected[j].shard.rule)) {
319
+ count++;
320
+ }
321
+ }
322
+ }
323
+ return count;
324
+ }
325
+ /**
326
+ * Build combined policy text for injection
327
+ */
328
+ buildPolicyText(constitution, shards) {
329
+ const parts = [];
330
+ // Always include constitution
331
+ parts.push(constitution.text);
332
+ // Add retrieved shards
333
+ if (shards.length > 0) {
334
+ parts.push('');
335
+ parts.push('## Task-Specific Rules');
336
+ parts.push('');
337
+ for (const { shard, reason } of shards) {
338
+ parts.push(`- ${shard.compactText}`);
339
+ }
340
+ }
341
+ return parts.join('\n');
342
+ }
343
+ /**
344
+ * Simple glob matching (supports * and **).
345
+ * Compiled regexes are cached per glob to avoid re-compiling on every call.
346
+ */
347
+ matchGlob(path, glob) {
348
+ let re = this.globCache.get(glob);
349
+ if (!re) {
350
+ const pattern = glob
351
+ .replace(/\*\*/g, '{{GLOBSTAR}}')
352
+ .replace(/\*/g, '[^/]*')
353
+ .replace(/{{GLOBSTAR}}/g, '.*')
354
+ .replace(/\//g, '\\/');
355
+ re = new RegExp(`^${pattern}$`);
356
+ this.globCache.set(glob, re);
357
+ }
358
+ return re.test(path);
359
+ }
360
+ /**
361
+ * Cosine similarity between two vectors
362
+ */
363
+ cosineSimilarity(a, b) {
364
+ if (a.length !== b.length)
365
+ return 0;
366
+ let dot = 0, normA = 0, normB = 0;
367
+ for (let i = 0; i < a.length; i++) {
368
+ dot += a[i] * b[i];
369
+ normA += a[i] * a[i];
370
+ normB += b[i] * b[i];
371
+ }
372
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
373
+ return denom > 0 ? Math.max(0, Math.min(1, dot / denom)) : 0;
374
+ }
375
+ /**
376
+ * Get current shard count
377
+ */
378
+ get shardCount() {
379
+ return this.shards.length;
380
+ }
381
+ /**
382
+ * Get constitution
383
+ */
384
+ getConstitution() {
385
+ return this.constitution;
386
+ }
387
+ }
388
+ /**
389
+ * Create a retriever instance
390
+ */
391
+ export function createRetriever(embeddingProvider) {
392
+ return new ShardRetriever(embeddingProvider);
393
+ }
394
+ //# sourceMappingURL=retriever.js.map