mcp-cognition-engine 1.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +281 -0
  3. package/dist/cli.d.ts +18 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +66 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/cognition-engine/ast-constraint-solver.d.ts +67 -0
  8. package/dist/cognition-engine/ast-constraint-solver.d.ts.map +1 -0
  9. package/dist/cognition-engine/ast-constraint-solver.js +294 -0
  10. package/dist/cognition-engine/ast-constraint-solver.js.map +1 -0
  11. package/dist/cognition-engine/constraint-validator.d.ts +35 -0
  12. package/dist/cognition-engine/constraint-validator.d.ts.map +1 -0
  13. package/dist/cognition-engine/constraint-validator.js +55 -0
  14. package/dist/cognition-engine/constraint-validator.js.map +1 -0
  15. package/dist/cognition-engine/graph-traverser.d.ts +43 -0
  16. package/dist/cognition-engine/graph-traverser.d.ts.map +1 -0
  17. package/dist/cognition-engine/graph-traverser.js +205 -0
  18. package/dist/cognition-engine/graph-traverser.js.map +1 -0
  19. package/dist/cognition-engine/index.d.ts +51 -0
  20. package/dist/cognition-engine/index.d.ts.map +1 -0
  21. package/dist/cognition-engine/index.js +60 -0
  22. package/dist/cognition-engine/index.js.map +1 -0
  23. package/dist/cognition-engine/intent-recognizer.d.ts +25 -0
  24. package/dist/cognition-engine/intent-recognizer.d.ts.map +1 -0
  25. package/dist/cognition-engine/intent-recognizer.js +226 -0
  26. package/dist/cognition-engine/intent-recognizer.js.map +1 -0
  27. package/dist/cognition-engine/types.d.ts +96 -0
  28. package/dist/cognition-engine/types.d.ts.map +1 -0
  29. package/dist/cognition-engine/types.js +17 -0
  30. package/dist/cognition-engine/types.js.map +1 -0
  31. package/dist/conflict/arbitrator.d.ts +24 -0
  32. package/dist/conflict/arbitrator.d.ts.map +1 -0
  33. package/dist/conflict/arbitrator.js +43 -0
  34. package/dist/conflict/arbitrator.js.map +1 -0
  35. package/dist/index.d.ts +17 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +90 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/legacy-engine/ast-diff.d.ts +23 -0
  40. package/dist/legacy-engine/ast-diff.d.ts.map +1 -0
  41. package/dist/legacy-engine/ast-diff.js +146 -0
  42. package/dist/legacy-engine/ast-diff.js.map +1 -0
  43. package/dist/legacy-engine/ast-node.d.ts +24 -0
  44. package/dist/legacy-engine/ast-node.d.ts.map +1 -0
  45. package/dist/legacy-engine/ast-node.js +52 -0
  46. package/dist/legacy-engine/ast-node.js.map +1 -0
  47. package/dist/legacy-engine/parsers.d.ts +34 -0
  48. package/dist/legacy-engine/parsers.d.ts.map +1 -0
  49. package/dist/legacy-engine/parsers.js +134 -0
  50. package/dist/legacy-engine/parsers.js.map +1 -0
  51. package/dist/legacy-engine/regex-fallback.d.ts +23 -0
  52. package/dist/legacy-engine/regex-fallback.d.ts.map +1 -0
  53. package/dist/legacy-engine/regex-fallback.js +40 -0
  54. package/dist/legacy-engine/regex-fallback.js.map +1 -0
  55. package/dist/legacy-engine/rule-generator.d.ts +31 -0
  56. package/dist/legacy-engine/rule-generator.d.ts.map +1 -0
  57. package/dist/legacy-engine/rule-generator.js +54 -0
  58. package/dist/legacy-engine/rule-generator.js.map +1 -0
  59. package/dist/legacy-engine/rule-matcher.d.ts +28 -0
  60. package/dist/legacy-engine/rule-matcher.d.ts.map +1 -0
  61. package/dist/legacy-engine/rule-matcher.js +79 -0
  62. package/dist/legacy-engine/rule-matcher.js.map +1 -0
  63. package/dist/legacy-engine/token-controller.d.ts +31 -0
  64. package/dist/legacy-engine/token-controller.d.ts.map +1 -0
  65. package/dist/legacy-engine/token-controller.js +66 -0
  66. package/dist/legacy-engine/token-controller.js.map +1 -0
  67. package/dist/middleware/response-validation.d.ts +27 -0
  68. package/dist/middleware/response-validation.d.ts.map +1 -0
  69. package/dist/middleware/response-validation.js +50 -0
  70. package/dist/middleware/response-validation.js.map +1 -0
  71. package/dist/modes/confirm.d.ts +29 -0
  72. package/dist/modes/confirm.d.ts.map +1 -0
  73. package/dist/modes/confirm.js +27 -0
  74. package/dist/modes/confirm.js.map +1 -0
  75. package/dist/modes/silent.d.ts +24 -0
  76. package/dist/modes/silent.d.ts.map +1 -0
  77. package/dist/modes/silent.js +24 -0
  78. package/dist/modes/silent.js.map +1 -0
  79. package/dist/resources/cognition-resources.d.ts +28 -0
  80. package/dist/resources/cognition-resources.d.ts.map +1 -0
  81. package/dist/resources/cognition-resources.js +124 -0
  82. package/dist/resources/cognition-resources.js.map +1 -0
  83. package/dist/storage/client.d.ts +26 -0
  84. package/dist/storage/client.d.ts.map +1 -0
  85. package/dist/storage/client.js +45 -0
  86. package/dist/storage/client.js.map +1 -0
  87. package/dist/storage/cognition-repository.d.ts +55 -0
  88. package/dist/storage/cognition-repository.d.ts.map +1 -0
  89. package/dist/storage/cognition-repository.js +287 -0
  90. package/dist/storage/cognition-repository.js.map +1 -0
  91. package/dist/storage/cognition-types.d.ts +96 -0
  92. package/dist/storage/cognition-types.d.ts.map +1 -0
  93. package/dist/storage/cognition-types.js +41 -0
  94. package/dist/storage/cognition-types.js.map +1 -0
  95. package/dist/storage/conflict-repo.d.ts +41 -0
  96. package/dist/storage/conflict-repo.d.ts.map +1 -0
  97. package/dist/storage/conflict-repo.js +67 -0
  98. package/dist/storage/conflict-repo.js.map +1 -0
  99. package/dist/storage/diff-log-repo.d.ts +48 -0
  100. package/dist/storage/diff-log-repo.d.ts.map +1 -0
  101. package/dist/storage/diff-log-repo.js +51 -0
  102. package/dist/storage/diff-log-repo.js.map +1 -0
  103. package/dist/storage/metric-repo.d.ts +20 -0
  104. package/dist/storage/metric-repo.d.ts.map +1 -0
  105. package/dist/storage/metric-repo.js +36 -0
  106. package/dist/storage/metric-repo.js.map +1 -0
  107. package/dist/storage/rule-repo.d.ts +66 -0
  108. package/dist/storage/rule-repo.d.ts.map +1 -0
  109. package/dist/storage/rule-repo.js +188 -0
  110. package/dist/storage/rule-repo.js.map +1 -0
  111. package/dist/tools/analyze-workspace.d.ts +26 -0
  112. package/dist/tools/analyze-workspace.d.ts.map +1 -0
  113. package/dist/tools/analyze-workspace.js +147 -0
  114. package/dist/tools/analyze-workspace.js.map +1 -0
  115. package/dist/tools/capture-diff.d.ts +26 -0
  116. package/dist/tools/capture-diff.d.ts.map +1 -0
  117. package/dist/tools/capture-diff.js +58 -0
  118. package/dist/tools/capture-diff.js.map +1 -0
  119. package/dist/tools/cognition-tools.d.ts +60 -0
  120. package/dist/tools/cognition-tools.d.ts.map +1 -0
  121. package/dist/tools/cognition-tools.js +170 -0
  122. package/dist/tools/cognition-tools.js.map +1 -0
  123. package/dist/tools/config-tools.d.ts +29 -0
  124. package/dist/tools/config-tools.d.ts.map +1 -0
  125. package/dist/tools/config-tools.js +58 -0
  126. package/dist/tools/config-tools.js.map +1 -0
  127. package/dist/tools/confirm-rule.d.ts +32 -0
  128. package/dist/tools/confirm-rule.d.ts.map +1 -0
  129. package/dist/tools/confirm-rule.js +64 -0
  130. package/dist/tools/confirm-rule.js.map +1 -0
  131. package/dist/tools/injection-approval.d.ts +43 -0
  132. package/dist/tools/injection-approval.d.ts.map +1 -0
  133. package/dist/tools/injection-approval.js +102 -0
  134. package/dist/tools/injection-approval.js.map +1 -0
  135. package/dist/tools/list-rules.d.ts +24 -0
  136. package/dist/tools/list-rules.d.ts.map +1 -0
  137. package/dist/tools/list-rules.js +20 -0
  138. package/dist/tools/list-rules.js.map +1 -0
  139. package/dist/tools/query-rules.d.ts +25 -0
  140. package/dist/tools/query-rules.d.ts.map +1 -0
  141. package/dist/tools/query-rules.js +65 -0
  142. package/dist/tools/query-rules.js.map +1 -0
  143. package/dist/tools/resolve-conflict.d.ts +33 -0
  144. package/dist/tools/resolve-conflict.d.ts.map +1 -0
  145. package/dist/tools/resolve-conflict.js +35 -0
  146. package/dist/tools/resolve-conflict.js.map +1 -0
  147. package/dist/types.d.ts +190 -0
  148. package/dist/types.d.ts.map +1 -0
  149. package/dist/types.js +50 -0
  150. package/dist/types.js.map +1 -0
  151. package/docs/api-reference.md +1229 -0
  152. package/docs/community/feedback-playbook.md +94 -0
  153. package/docs/integration-snippets.md +100 -0
  154. package/docs/mcp-integration-guide.md +151 -0
  155. package/docs/phase4-mcp-feedback.md +155 -0
  156. package/docs/trust-governance-protocol.md +72 -0
  157. package/package.json +74 -0
  158. package/prisma/schema.prisma +145 -0
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Copyright 2026 熊高锐
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { parseToAST } from "../legacy-engine/parsers.js";
17
+ // ── DSL Parser ────────────────────────────────────────────
18
+ /**
19
+ * Parse templateDsl JSON string into AstConstraint array.
20
+ */
21
+ export function parseConstraintDsl(dsl) {
22
+ try {
23
+ const parsed = JSON.parse(dsl);
24
+ if (Array.isArray(parsed))
25
+ return parsed;
26
+ if (parsed && typeof parsed === "object" && parsed.nodeType) {
27
+ return [parsed];
28
+ }
29
+ return [];
30
+ }
31
+ catch {
32
+ // If plain text, try line-based DSL format:
33
+ // NODE:FunctionDeclaration
34
+ // FIELD:name MATCH:{{placeholder}}
35
+ // FIELD:returnType EXISTS:true
36
+ return parseLineBasedDsl(dsl);
37
+ }
38
+ }
39
+ function parseLineBasedDsl(dsl) {
40
+ const constraints = [];
41
+ let current = null;
42
+ for (const line of dsl.split("\n")) {
43
+ const trimmed = line.trim();
44
+ if (!trimmed)
45
+ continue;
46
+ if (trimmed.startsWith("NODE:")) {
47
+ if (current)
48
+ constraints.push(current);
49
+ current = { nodeType: trimmed.slice(5).trim(), fields: {} };
50
+ }
51
+ else if (trimmed.startsWith("FIELD:") && current) {
52
+ const rest = trimmed.slice(6);
53
+ const matchMatcher = rest.match(/^(\S+)\s+MATCH:(.+)$/);
54
+ const existsMatcher = rest.match(/^(\S+)\s+EXISTS:(true|false)$/);
55
+ const childTypeMatcher = rest.match(/^(\S+)\s+CHILD_TYPE:(.+)$/);
56
+ if (matchMatcher) {
57
+ current.fields[matchMatcher[1]] = { match: matchMatcher[2] };
58
+ }
59
+ else if (existsMatcher) {
60
+ current.fields[existsMatcher[1]] = { exists: existsMatcher[2] === "true" };
61
+ }
62
+ else if (childTypeMatcher) {
63
+ current.fields[childTypeMatcher[1]] = { childType: childTypeMatcher[2] };
64
+ }
65
+ }
66
+ }
67
+ if (current)
68
+ constraints.push(current);
69
+ return constraints;
70
+ }
71
+ /**
72
+ * Bind {{placeholder}} values in a constraint to actual AST node text.
73
+ * Walks the AST to find nodes matching each constraint's nodeType,
74
+ * then extracts text values for placeholders.
75
+ */
76
+ export function bindConstraints(constraints, ast) {
77
+ const bindings = {};
78
+ const bound = constraints.map((c) => ({
79
+ ...c,
80
+ fields: Object.fromEntries(Object.entries(c.fields).map(([key, fc]) => {
81
+ const boundFc = { ...fc };
82
+ if (fc.match && fc.match.includes("{{")) {
83
+ const placeholder = fc.match.match(/\{\{(.+?)\}\}/)?.[1];
84
+ if (placeholder) {
85
+ const actualValue = extractFieldValue(ast, c.nodeType, key);
86
+ if (actualValue) {
87
+ bindings[placeholder] = actualValue;
88
+ boundFc.match = fc.match.replace(/\{\{(.+?)\}\}/, actualValue);
89
+ }
90
+ }
91
+ }
92
+ return [key, boundFc];
93
+ })),
94
+ }));
95
+ return { bound, bindings };
96
+ }
97
+ /**
98
+ * Extract a field value from an AST node.
99
+ * Simplified: checks node type match, then children for field values.
100
+ */
101
+ function extractFieldValue(ast, nodeType, field) {
102
+ const matchingNodes = findNodesByType(ast, nodeType);
103
+ if (matchingNodes.length === 0)
104
+ return null;
105
+ const node = matchingNodes[0];
106
+ // Check if any child's type matches the field name
107
+ for (const child of node.children) {
108
+ if (child.type === field) {
109
+ return child.text;
110
+ }
111
+ }
112
+ // Fallback: return node text itself
113
+ return field === "name" ? node.text : null;
114
+ }
115
+ function findNodesByType(node, type) {
116
+ const results = [];
117
+ if (node.type === type)
118
+ results.push(node);
119
+ for (const child of node.children) {
120
+ results.push(...findNodesByType(child, type));
121
+ }
122
+ return results;
123
+ }
124
+ // ── Constraint Validation ─────────────────────────────────
125
+ /**
126
+ * Validate an AST against a set of bound constraints.
127
+ *
128
+ * @param constraints Parsed + bound AstConstraint array
129
+ * @param nodeId Source cognition node ID (for traceability)
130
+ * @param templateDsl Original template DSL string
131
+ * @param ast Target AST to validate
132
+ * @returns Structured validation result
133
+ */
134
+ export function validateConstraints(constraints, nodeId, templateDsl, ast) {
135
+ const failures = [];
136
+ for (const constraint of constraints) {
137
+ const matchingNodes = findNodesByType(ast, constraint.nodeType);
138
+ if (matchingNodes.length === 0) {
139
+ failures.push({
140
+ nodeId,
141
+ templateDsl,
142
+ constraintPath: '$.type',
143
+ expected: constraint.nodeType,
144
+ actual: `(no matching node)`,
145
+ });
146
+ continue;
147
+ }
148
+ for (const matchingNode of matchingNodes) {
149
+ for (const [fieldName, fieldConstraint] of Object.entries(constraint.fields)) {
150
+ const result = checkFieldConstraint(fieldName, fieldConstraint, matchingNode);
151
+ if (result) {
152
+ failures.push({ nodeId, templateDsl, ...result });
153
+ }
154
+ }
155
+ }
156
+ }
157
+ return {
158
+ isValid: failures.length === 0,
159
+ failures,
160
+ };
161
+ }
162
+ function checkFieldConstraint(fieldName, fc, node) {
163
+ // Check existence
164
+ if (fc.exists !== undefined) {
165
+ const exists = node.children.some((c) => c.type === fieldName);
166
+ if (fc.exists && !exists) {
167
+ return {
168
+ constraintPath: '$.children.',
169
+ expected: 'exists: true',
170
+ actual: `(child "${fieldName}" not found)`,
171
+ };
172
+ }
173
+ }
174
+ // Check match (literal or bound placeholder)
175
+ if (fc.match) {
176
+ const actual = node.text;
177
+ if (actual !== fc.match) {
178
+ return {
179
+ constraintPath: '$.text',
180
+ expected: fc.match,
181
+ actual,
182
+ };
183
+ }
184
+ }
185
+ // Check child type
186
+ if (fc.childType) {
187
+ const hasChild = node.children.some((c) => c.type === fc.childType);
188
+ if (!hasChild) {
189
+ return {
190
+ constraintPath: '$.children.' + fieldName,
191
+ expected: fc.childType,
192
+ actual: `(child "${fc.childType}" not found)`,
193
+ };
194
+ }
195
+ }
196
+ // Check child count
197
+ if (fc.childCount) {
198
+ const count = node.children.length;
199
+ if (fc.childCount.min !== undefined && count < fc.childCount.min) {
200
+ return {
201
+ constraintPath: '$.children.length',
202
+ expected: '>= ' + fc.childCount.min,
203
+ actual: String(count),
204
+ };
205
+ }
206
+ if (fc.childCount.max !== undefined && count > fc.childCount.max) {
207
+ return {
208
+ constraintPath: '$.children.length',
209
+ expected: '<= ' + fc.childCount.max,
210
+ actual: String(count),
211
+ };
212
+ }
213
+ }
214
+ return null;
215
+ }
216
+ // ── Transform Patch Generation ────────────────────────────
217
+ /**
218
+ * Generate a transform patch from validation failures.
219
+ * Creates operations that would fix the validation failures.
220
+ */
221
+ export function generatePatchFromFailures(failures, ast) {
222
+ const patches = new Map();
223
+ for (const failure of failures) {
224
+ const nodeId = failure.nodeId;
225
+ if (!patches.has(nodeId)) {
226
+ patches.set(nodeId, { nodeId, operations: [], description: "" });
227
+ }
228
+ const patch = patches.get(nodeId);
229
+ const ops = [];
230
+ if (failure.actual.includes("(no matching node)")) {
231
+ ops.push({
232
+ type: "INSERT",
233
+ path: "$",
234
+ value: failure.expected,
235
+ originalText: undefined,
236
+ });
237
+ }
238
+ else if (failure.constraintPath === "$.text") {
239
+ ops.push({
240
+ type: "REPLACE",
241
+ path: "$.text",
242
+ value: failure.expected,
243
+ originalText: failure.actual,
244
+ });
245
+ }
246
+ patch.operations.push(...ops);
247
+ const briefDesc = `${failure.constraintPath}: "${failure.actual}" → "${failure.expected}"`;
248
+ patch.description = patch.description
249
+ ? `${patch.description}; `
250
+ : briefDesc;
251
+ }
252
+ return [...patches.values()];
253
+ }
254
+ // ── High-level API ────────────────────────────────────────
255
+ /**
256
+ * Run the full constraint-solving pipeline:
257
+ * 1. Parse templateDSL from cognition nodes
258
+ * 2. Parse file content to AST
259
+ * 3. Bind {{placeholder}} values
260
+ * 4. Validate constraints
261
+ * 5. Generate transform patches
262
+ *
263
+ * @param cognitionNodes Nodes with astTemplate to check
264
+ * @param fileContent Source code to validate against
265
+ * @param language Language for AST parsing
266
+ * @returns Validation + patch results
267
+ */
268
+ export async function solveConstraints(cognitionNodes, fileContent, language) {
269
+ const allValidations = [];
270
+ const allPatches = [];
271
+ const allBindings = {};
272
+ const { ast } = await parseToAST(fileContent, language);
273
+ for (const node of cognitionNodes) {
274
+ if (!node.astTemplate)
275
+ continue;
276
+ const constraints = parseConstraintDsl(node.astTemplate.templateDsl);
277
+ if (constraints.length === 0)
278
+ continue;
279
+ const { bound, bindings } = bindConstraints(constraints, ast);
280
+ Object.assign(allBindings, bindings);
281
+ const validation = validateConstraints(bound, node.id, node.astTemplate.templateDsl, ast);
282
+ allValidations.push(validation);
283
+ if (!validation.isValid) {
284
+ const patches = generatePatchFromFailures(validation.failures, ast);
285
+ allPatches.push(...patches);
286
+ }
287
+ }
288
+ return {
289
+ validations: allValidations,
290
+ patches: allPatches,
291
+ boundValues: allBindings,
292
+ };
293
+ }
294
+ //# sourceMappingURL=ast-constraint-solver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-constraint-solver.js","sourceRoot":"","sources":["../../src/cognition-engine/ast-constraint-solver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAYH,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAYzD,6DAA6D;AAE7D;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,MAAyB,CAAC;QAC5D,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC5D,OAAO,CAAC,MAAuB,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,4CAA4C;QAC5C,6BAA6B;QAC7B,qCAAqC;QACrC,iCAAiC;QACjC,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,WAAW,GAAoB,EAAE,CAAC;IACxC,IAAI,OAAO,GAAyB,IAAI,CAAC;IAEzC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,SAAS;QAEvB,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,IAAI,OAAO;gBAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,OAAO,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC9D,CAAC;aAAM,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,OAAO,EAAE,CAAC;YACnD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YACxD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YAClE,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAEjE,IAAI,YAAY,EAAE,CAAC;gBACjB,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,CAAC;iBAAM,IAAI,aAAa,EAAE,CAAC;gBACzB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;YAC7E,CAAC;iBAAM,IAAI,gBAAgB,EAAE,CAAC;gBAC5B,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3E,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,OAAO;QAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,WAAW,CAAC;AACrB,CAAC;AAUD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,WAA4B,EAC5B,GAAY;IAEZ,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAE5C,MAAM,KAAK,GAAoB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrD,GAAG,CAAC;QACJ,MAAM,EAAE,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;YACzC,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;YAC1B,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxC,MAAM,WAAW,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACzD,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,WAAW,GAAG,iBAAiB,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;oBAC5D,IAAI,WAAW,EAAE,CAAC;wBAChB,QAAQ,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;wBACpC,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;oBACjE,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACxB,CAAC,CAAC,CACH;KACF,CAAC,CAAC,CAAC;IAEJ,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,GAAY,EAAE,QAAgB,EAAE,KAAa;IACtE,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACrD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5C,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC9B,mDAAmD;IACnD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IACD,oCAAoC;IACpC,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,SAAS,eAAe,CAAC,IAAa,EAAE,IAAY;IAClD,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6DAA6D;AAE7D;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,WAA4B,EAC5B,MAAc,EACd,WAAmB,EACnB,GAAY;IAEZ,MAAM,QAAQ,GAAwB,EAAE,CAAC;IAEzC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;QAEhE,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC;gBACZ,MAAM;gBACN,WAAW;gBACX,cAAc,EAAE,QAAQ;gBACxB,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,MAAM,EAAE,oBAAoB;aAC7B,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;YACzC,KAAK,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7E,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;gBAC9E,IAAI,MAAM,EAAE,CAAC;oBACX,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;QAC9B,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,SAAiB,EACjB,EAAmB,EACnB,IAAa;IAEb,kBAAkB;IAClB,IAAI,EAAE,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAC/D,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;YACzB,OAAO;gBACL,cAAc,EAAE,aAAa;gBAC7B,QAAQ,EAAE,cAAc;gBACxB,MAAM,EAAE,WAAW,SAAS,cAAc;aAC3C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC;QACzB,IAAI,MAAM,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC;YACxB,OAAO;gBACL,cAAc,EAAE,QAAQ;gBACxB,QAAQ,EAAE,EAAE,CAAC,KAAK;gBAClB,MAAM;aACP,CAAC;QACJ,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,IAAI,EAAE,CAAC,SAAS,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,SAAS,CAAC,CAAC;QACpE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;gBACL,cAAc,EAAE,aAAa,GAAG,SAAS;gBACzC,QAAQ,EAAE,EAAE,CAAC,SAAS;gBACtB,MAAM,EAAE,WAAW,EAAE,CAAC,SAAS,cAAc;aAC9C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QACnC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;YACjE,OAAO;gBACH,cAAc,EAAE,mBAAmB;gBACnC,QAAQ,EAAE,KAAK,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG;gBACrC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC;aACtB,CAAC;QACJ,CAAC;QACD,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;YACjE,OAAO;gBACL,cAAc,EAAE,mBAAmB;gBACnC,QAAQ,EAAE,KAAK,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG;gBACnC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC;aACtB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6DAA6D;AAE7D;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAA6B,EAC7B,GAAY;IAEZ,MAAM,OAAO,GAAgC,IAAI,GAAG,EAAE,CAAC;IAEvD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;QACnC,MAAM,GAAG,GAAkB,EAAE,CAAC;QAE9B,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAClD,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,GAAG;gBACT,KAAK,EAAE,OAAO,CAAC,QAAQ;gBACvB,YAAY,EAAE,SAAS;aACxB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,OAAO,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;YAC/C,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,OAAO,CAAC,QAAQ;gBACvB,YAAY,EAAE,OAAO,CAAC,MAAM;aAC7B,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,cAAc,MAAM,OAAO,CAAC,MAAM,QAAQ,OAAO,CAAC,QAAQ,GAAG,CAAC;QAC3F,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW;YACnC,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,IAAI;YAC1B,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IAED,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,6DAA6D;AAE7D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,cAAmC,EACnC,WAAmB,EACnB,QAAgB;IAMhB,MAAM,cAAc,GAAuB,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,MAAM,WAAW,GAA2B,EAAE,CAAC;IAE/C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,UAAU,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAExD,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,SAAS;QAEhC,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QACrE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEvC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAErC,MAAM,UAAU,GAAG,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC1F,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEhC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,yBAAyB,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YACpE,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO;QACL,WAAW,EAAE,cAAc;QAC3B,OAAO,EAAE,UAAU;QACnB,WAAW,EAAE,WAAW;KACzB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Copyright 2026 熊高锐
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ export type ValidationMode = "REJECT" | "WARN";
17
+ export type RuleLevel = "GLOBAL" | "PROJECT";
18
+ export interface ConstraintViolation {
19
+ ruleId: string;
20
+ ruleLevel: RuleLevel;
21
+ mode: ValidationMode;
22
+ constraintPath: string;
23
+ expected: string;
24
+ actual: string;
25
+ message: string;
26
+ }
27
+ export interface ValidationReport {
28
+ passed: boolean;
29
+ violations: ConstraintViolation[];
30
+ hardBlocks: number;
31
+ softWarnings: number;
32
+ }
33
+ /** Validate code content against constraints. */
34
+ export declare function validateCode(codeContent: string, language: string, projectId?: string): Promise<ValidationReport>;
35
+ //# sourceMappingURL=constraint-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraint-validator.d.ts","sourceRoot":"","sources":["../../src/cognition-engine/constraint-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC/C,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,iDAAiD;AACjD,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqBvH"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Copyright 2026 熊高锐
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * @file Constraint Validator — Trust & Governance Layer
18
+ * Reuses Phase 3 AstTemplate DSL parser for dual-mode validation.
19
+ */
20
+ import { parseConstraintDsl, validateConstraints } from "../cognition-engine/ast-constraint-solver.js";
21
+ import { CognitionRepository } from "../storage/cognition-repository.js";
22
+ /** Validate code content against constraints. */
23
+ export async function validateCode(codeContent, language, projectId) {
24
+ const repo = new CognitionRepository();
25
+ const violations = [];
26
+ const hash = simpleHash("NEGATIVE_CONSTRAINT:" + language);
27
+ const negativeNodes = await repo.findNodesBySemanticHash(hash);
28
+ let hardBlocks = 0;
29
+ let softWarnings = 0;
30
+ for (const node of negativeNodes) {
31
+ if (!node.astTemplate)
32
+ continue;
33
+ const constraints = parseConstraintDsl(node.astTemplate.templateDsl);
34
+ if (constraints.length === 0)
35
+ continue;
36
+ const { ast } = await import("../legacy-engine/parsers.js").then(m => m.parseToAST(codeContent, language));
37
+ const result = validateConstraints(constraints, node.id, node.astTemplate.templateDsl, ast);
38
+ if (!result.isValid) {
39
+ for (const f of result.failures) {
40
+ violations.push({ ruleId: node.id, ruleLevel: "GLOBAL", mode: "REJECT", constraintPath: f.constraintPath, expected: f.expected, actual: f.actual, message: "Hard block: " + f.constraintPath });
41
+ hardBlocks++;
42
+ }
43
+ }
44
+ }
45
+ return { passed: hardBlocks === 0, violations, hardBlocks, softWarnings };
46
+ }
47
+ function simpleHash(s) {
48
+ let hash = 0;
49
+ for (let i = 0; i < s.length; i++) {
50
+ hash = ((hash << 5) - hash) + s.charCodeAt(i);
51
+ hash |= 0;
52
+ }
53
+ return Math.abs(hash).toString(16);
54
+ }
55
+ //# sourceMappingURL=constraint-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraint-validator.js","sourceRoot":"","sources":["../../src/cognition-engine/constraint-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AACvG,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAsBzE,iDAAiD;AACjD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAmB,EAAE,QAAgB,EAAE,SAAkB;IAC1F,MAAM,IAAI,GAAG,IAAI,mBAAmB,EAAE,CAAC;IACvC,MAAM,UAAU,GAA0B,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,UAAU,CAAC,sBAAsB,GAAG,QAAQ,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAC/D,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,SAAS;QAChC,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QACrE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACvC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC3G,MAAM,MAAM,GAAG,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC5F,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAChC,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;gBAChM,UAAU,EAAE,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,UAAU,KAAK,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AAC5E,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAAC,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,IAAI,CAAC,CAAC;IAAC,CAAC;IAChG,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Copyright 2026 熊高锐
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * @file Graph Traverser
18
+ * Replaces the legacy rule-matcher by performing weighted BFS/DFS traversal
19
+ * over the cognition graph, starting from nodes matching the current code context.
20
+ *
21
+ * Reuses: ast-node.ts (computeSemanticHash-like logic via cognition-repository)
22
+ */
23
+ import { CognitionRepository } from "../storage/cognition-repository.js";
24
+ import type { TraversalOptions, TraversalResult } from "./types.js";
25
+ export declare class GraphTraverser {
26
+ private repo;
27
+ constructor(repo?: CognitionRepository);
28
+ /**
29
+ * Traverse the cognition graph starting from nodes relevant to the given code context.
30
+ *
31
+ * @param language Programming language (e.g., "typescript", "python")
32
+ * @param filePath File path for context extraction
33
+ * @param content Code snippet or AST signature for semantic matching
34
+ * @param options Traversal options
35
+ * @returns Scored cognition nodes sorted by relevance
36
+ */
37
+ traverse(language: string, filePath: string, content: string, options?: TraversalOptions, contextHash?: string): Promise<TraversalResult>;
38
+ /** Check if moving from sourceLevel to targetLevel is compatible. */
39
+ private isLevelCompatible;
40
+ /** Compute a relevance score [0, 1] for a frontier entry. */
41
+ private computeNodeScore;
42
+ }
43
+ //# sourceMappingURL=graph-traverser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-traverser.d.ts","sourceRoot":"","sources":["../../src/cognition-engine/graph-traverser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAuB,MAAM,oCAAoC,CAAC;AAI9F,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAuB,MAAM,YAAY,CAAC;AAoCzF,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAsB;gBAEtB,IAAI,CAAC,EAAE,mBAAmB;IAItC;;;;;;;;OAQG;IACG,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,gBAAqB,EAC9B,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC;IA2H3B,qEAAqE;IACrE,OAAO,CAAC,iBAAiB;IAyBzB,6DAA6D;IAC7D,OAAO,CAAC,gBAAgB;CAezB"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Copyright 2026 熊高锐
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * @file Graph Traverser
18
+ * Replaces the legacy rule-matcher by performing weighted BFS/DFS traversal
19
+ * over the cognition graph, starting from nodes matching the current code context.
20
+ *
21
+ * Reuses: ast-node.ts (computeSemanticHash-like logic via cognition-repository)
22
+ */
23
+ import { CognitionRepository, computeSemanticHash } from "../storage/cognition-repository.js";
24
+ // ── Constants ─────────────────────────────────────────────
25
+ /** Edge relation multipliers for weighted traversal. */
26
+ const RELATION_MULTIPLIERS = {
27
+ CAUSES: 1.5,
28
+ PRECEDES: 1.3,
29
+ REFINES: 1.2,
30
+ GENERALIZES: 0.5,
31
+ MUTEX: 0.3,
32
+ };
33
+ /** Intent bias: adjusts abstraction level preference based on intent. */
34
+ const INTENT_BIAS = {
35
+ REFACTOR: [2, 3, 1, 0], // prefer architecture/module level
36
+ BUGFIX: [0, 1, 2, 3], // prefer concrete/function level
37
+ BOILERPLATE: [1, 2, 0, 3], // prefer module/function level
38
+ };
39
+ const DEFAULT_MAX_DEPTH = 5;
40
+ const DEFAULT_MIN_RELEVANCE = 0.1;
41
+ const DEFAULT_MAX_DURATION_MS = 500;
42
+ // ── Graph Traverser ───────────────────────────────────────
43
+ export class GraphTraverser {
44
+ repo;
45
+ constructor(repo) {
46
+ this.repo = repo ?? new CognitionRepository();
47
+ }
48
+ /**
49
+ * Traverse the cognition graph starting from nodes relevant to the given code context.
50
+ *
51
+ * @param language Programming language (e.g., "typescript", "python")
52
+ * @param filePath File path for context extraction
53
+ * @param content Code snippet or AST signature for semantic matching
54
+ * @param options Traversal options
55
+ * @returns Scored cognition nodes sorted by relevance
56
+ */
57
+ async traverse(language, filePath, content, options = {}, contextHash) {
58
+ const startTime = performance.now();
59
+ const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
60
+ const minRelevance = options.minRelevance ?? DEFAULT_MIN_RELEVANCE;
61
+ const maxDuration = options.maxDurationMs ?? DEFAULT_MAX_DURATION_MS;
62
+ const intentHint = options.intentHint;
63
+ // 1. Compute semantic hash from code content
64
+ const semanticHash = contextHash ?? computeSemanticHash(language + ":" + filePath.split(".").pop(), { contentHash: simpleHash(content) });
65
+ // 2. Find matching nodes in the graph
66
+ const matchedNodes = await this.repo.findNodesBySemanticHash(semanticHash);
67
+ // If no exact match, try a broader search using file extension
68
+ let startNodes = matchedNodes;
69
+ if (startNodes.length === 0) {
70
+ const extHash = computeSemanticHash(language, { ext: filePath.split(".").pop() });
71
+ startNodes = await this.repo.findNodesBySemanticHash(extHash);
72
+ }
73
+ // 3. If still no matches, return empty result
74
+ if (startNodes.length === 0) {
75
+ return {
76
+ nodes: [],
77
+ edges: [],
78
+ durationMs: performance.now() - startTime,
79
+ truncated: false,
80
+ };
81
+ }
82
+ // 4. Weighted BFS traversal from matched nodes
83
+ const visitedNodeIds = new Set();
84
+ const visitedEdgeIds = new Set();
85
+ const scoredNodes = new Map();
86
+ const allEdges = new Map();
87
+ const frontier = [];
88
+ // Initialize frontier with start nodes
89
+ for (const node of startNodes) {
90
+ visitedNodeIds.add(node.id);
91
+ frontier.push({
92
+ nodeId: node.id,
93
+ node,
94
+ depth: 0,
95
+ pathWeight: 1.0,
96
+ trace: [],
97
+ });
98
+ }
99
+ let elapsed = performance.now() - startTime;
100
+ let truncated = false;
101
+ while (frontier.length > 0 && elapsed < maxDuration) {
102
+ // Sort frontier: highest pathWeight first, then lowest depth
103
+ frontier.sort((a, b) => b.pathWeight - a.pathWeight || a.depth - b.depth);
104
+ const current = frontier.shift();
105
+ // Score and store
106
+ const score = this.computeNodeScore(current, intentHint);
107
+ if (score >= minRelevance) {
108
+ scoredNodes.set(current.node.id, {
109
+ node: current.node,
110
+ relevanceScore: score,
111
+ trace: current.trace,
112
+ });
113
+ }
114
+ // Stop at max depth
115
+ if (current.depth >= maxDepth)
116
+ continue;
117
+ // Fetch outgoing edges for this node
118
+ const subgraph = await this.repo.getSubgraph(current.nodeId, 1);
119
+ const outgoingEdges = subgraph.edges.filter(e => e.sourceId === current.nodeId && !visitedEdgeIds.has(e.id));
120
+ for (const edge of outgoingEdges) {
121
+ visitedEdgeIds.add(edge.id);
122
+ allEdges.set(edge.id, edge);
123
+ // Apply abstraction level filter
124
+ const targetNode = subgraph.nodes.find(n => n.id === edge.targetId);
125
+ if (!targetNode)
126
+ continue;
127
+ if (!this.isLevelCompatible(current.node.abstractionLevel, targetNode.abstractionLevel, edge.relation, intentHint)) {
128
+ continue;
129
+ }
130
+ // Apply GENERALIZES pruning
131
+ const multiplier = RELATION_MULTIPLIERS[edge.relation] ?? 0.5;
132
+ if (edge.relation === "GENERALIZES" && current.depth > 1)
133
+ continue;
134
+ if (!visitedNodeIds.has(edge.targetId)) {
135
+ visitedNodeIds.add(edge.targetId);
136
+ frontier.push({
137
+ nodeId: edge.targetId,
138
+ node: targetNode,
139
+ depth: current.depth + 1,
140
+ pathWeight: current.pathWeight * multiplier * Math.max(0.5, edge.weight / 1.0),
141
+ trace: [...current.trace, edge.relation + ' → ' + targetNode.type + ':' + targetNode.abstractionLevel],
142
+ });
143
+ }
144
+ }
145
+ elapsed = performance.now() - startTime;
146
+ }
147
+ if (frontier.length > 0)
148
+ truncated = true;
149
+ // 5. Sort by score descending
150
+ const sorted = [...scoredNodes.values()]
151
+ .sort((a, b) => b.relevanceScore - a.relevanceScore);
152
+ return {
153
+ nodes: sorted,
154
+ edges: [...allEdges.values()],
155
+ durationMs: performance.now() - startTime,
156
+ truncated,
157
+ };
158
+ }
159
+ // ── Private Helpers ────────────────────────────────────
160
+ /** Check if moving from sourceLevel to targetLevel is compatible. */
161
+ isLevelCompatible(sourceLevel, targetLevel, relation, intentHint) {
162
+ const absDiff = Math.abs(sourceLevel - targetLevel);
163
+ // Always allow same or adjacent levels
164
+ if (absDiff <= 1)
165
+ return true;
166
+ // Jumping from 0→2 or 1→3 (or reverse) needs REFINES connection
167
+ if (absDiff === 2 && relation === "REFINES")
168
+ return true;
169
+ // Intent-based filtering
170
+ if (intentHint) {
171
+ const bias = INTENT_BIAS[intentHint] ?? [0, 1, 2, 3];
172
+ // If target level is prioritized by intent, allow
173
+ if (bias.indexOf(targetLevel) <= bias.indexOf(sourceLevel) + 1)
174
+ return true;
175
+ }
176
+ // Skip large level jumps unless explicitly connected
177
+ return absDiff <= 2 && (relation === "CAUSES" || relation === "REFINES");
178
+ }
179
+ /** Compute a relevance score [0, 1] for a frontier entry. */
180
+ computeNodeScore(entry, intentHint) {
181
+ const depthPenalty = 1 - 0.15 * entry.depth;
182
+ const weightScore = Math.min(1, entry.pathWeight / 1.5);
183
+ const levelScore = intentHint
184
+ ? 1 - Math.abs(INTENT_BIAS[intentHint].indexOf(entry.node.abstractionLevel) - INTENT_BIAS[intentHint].indexOf(0)) * 0.2
185
+ : 1 - Math.abs(entry.node.abstractionLevel - 1) * 0.15;
186
+ // Base score
187
+ let score = Math.max(0, weightScore * depthPenalty * levelScore);
188
+ // Bonus for nodes with AST templates (more actionable)
189
+ if (entry.node.astTemplate)
190
+ score = Math.min(1, score * 1.2);
191
+ return Math.round(score * 100) / 100;
192
+ }
193
+ }
194
+ // ── Utility ───────────────────────────────────────────────
195
+ function simpleHash(s) {
196
+ if (!s)
197
+ return "0";
198
+ let hash = 0;
199
+ for (let i = 0; i < s.length; i++) {
200
+ hash = ((hash << 5) - hash) + s.charCodeAt(i);
201
+ hash |= 0;
202
+ }
203
+ return Math.abs(hash).toString(16);
204
+ }
205
+ //# sourceMappingURL=graph-traverser.js.map