@praneeth_54/agentdoctor 1.0.0 → 1.1.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 (208) hide show
  1. package/CHANGELOG.md +60 -5
  2. package/README.md +462 -251
  3. package/dist/cli/commands/brain-mcp.d.ts +9 -0
  4. package/dist/cli/commands/brain-mcp.js +38 -0
  5. package/dist/cli/program.js +13 -0
  6. package/dist/constants.d.ts +1 -1
  7. package/dist/constants.js +1 -1
  8. package/dist/core/understanding/architecture/index.d.ts +4 -0
  9. package/dist/core/understanding/architecture/index.js +3 -0
  10. package/dist/core/understanding/architecture/infer.d.ts +6 -0
  11. package/dist/core/understanding/architecture/infer.js +39 -0
  12. package/dist/core/understanding/architecture/models.d.ts +23 -0
  13. package/dist/core/understanding/architecture/models.js +127 -0
  14. package/dist/core/understanding/architecture/patterns/distribution.d.ts +2 -0
  15. package/dist/core/understanding/architecture/patterns/distribution.js +115 -0
  16. package/dist/core/understanding/architecture/patterns/index.d.ts +2 -0
  17. package/dist/core/understanding/architecture/patterns/index.js +8 -0
  18. package/dist/core/understanding/architecture/patterns/layered.d.ts +2 -0
  19. package/dist/core/understanding/architecture/patterns/layered.js +279 -0
  20. package/dist/core/understanding/architecture/patterns/structural.d.ts +2 -0
  21. package/dist/core/understanding/architecture/patterns/structural.js +197 -0
  22. package/dist/core/understanding/architecture/rules.d.ts +4 -0
  23. package/dist/core/understanding/architecture/rules.js +6 -0
  24. package/dist/core/understanding/architecture/types.d.ts +52 -0
  25. package/dist/core/understanding/architecture/types.js +1 -0
  26. package/dist/core/understanding/brain/build.d.ts +13 -0
  27. package/dist/core/understanding/brain/build.js +158 -0
  28. package/dist/core/understanding/brain/claims/index.d.ts +3 -0
  29. package/dist/core/understanding/brain/claims/index.js +2 -0
  30. package/dist/core/understanding/brain/claims/lifecycle.d.ts +16 -0
  31. package/dist/core/understanding/brain/claims/lifecycle.js +78 -0
  32. package/dist/core/understanding/brain/claims/types.d.ts +32 -0
  33. package/dist/core/understanding/brain/claims/types.js +25 -0
  34. package/dist/core/understanding/brain/components/index.d.ts +17 -0
  35. package/dist/core/understanding/brain/components/index.js +97 -0
  36. package/dist/core/understanding/brain/components/types.d.ts +16 -0
  37. package/dist/core/understanding/brain/components/types.js +8 -0
  38. package/dist/core/understanding/brain/confidence.d.ts +19 -0
  39. package/dist/core/understanding/brain/confidence.js +39 -0
  40. package/dist/core/understanding/brain/contract.d.ts +17 -0
  41. package/dist/core/understanding/brain/contract.js +100 -0
  42. package/dist/core/understanding/brain/contradictions/index.d.ts +12 -0
  43. package/dist/core/understanding/brain/contradictions/index.js +57 -0
  44. package/dist/core/understanding/brain/contradictions/types.d.ts +12 -0
  45. package/dist/core/understanding/brain/contradictions/types.js +8 -0
  46. package/dist/core/understanding/brain/delta.d.ts +25 -0
  47. package/dist/core/understanding/brain/delta.js +116 -0
  48. package/dist/core/understanding/brain/evidence/index.d.ts +3 -0
  49. package/dist/core/understanding/brain/evidence/index.js +2 -0
  50. package/dist/core/understanding/brain/evidence/redact.d.ts +4 -0
  51. package/dist/core/understanding/brain/evidence/redact.js +36 -0
  52. package/dist/core/understanding/brain/evidence/types.d.ts +34 -0
  53. package/dist/core/understanding/brain/evidence/types.js +35 -0
  54. package/dist/core/understanding/brain/explain.d.ts +17 -0
  55. package/dist/core/understanding/brain/explain.js +33 -0
  56. package/dist/core/understanding/brain/index.d.ts +28 -0
  57. package/dist/core/understanding/brain/index.js +16 -0
  58. package/dist/core/understanding/brain/migrate.d.ts +21 -0
  59. package/dist/core/understanding/brain/migrate.js +47 -0
  60. package/dist/core/understanding/brain/query.d.ts +60 -0
  61. package/dist/core/understanding/brain/query.js +92 -0
  62. package/dist/core/understanding/brain/security.d.ts +3 -0
  63. package/dist/core/understanding/brain/security.js +43 -0
  64. package/dist/core/understanding/brain/storage/index.d.ts +2 -0
  65. package/dist/core/understanding/brain/storage/index.js +1 -0
  66. package/dist/core/understanding/brain/storage/store.d.ts +53 -0
  67. package/dist/core/understanding/brain/storage/store.js +305 -0
  68. package/dist/core/understanding/brain/trace.d.ts +24 -0
  69. package/dist/core/understanding/brain/trace.js +207 -0
  70. package/dist/core/understanding/brain/types.d.ts +32 -0
  71. package/dist/core/understanding/brain/types.js +8 -0
  72. package/dist/core/understanding/brain/version.d.ts +13 -0
  73. package/dist/core/understanding/brain/version.js +7 -0
  74. package/dist/core/understanding/delta/compare.d.ts +26 -0
  75. package/dist/core/understanding/delta/compare.js +74 -0
  76. package/dist/core/understanding/delta/index.d.ts +2 -0
  77. package/dist/core/understanding/delta/index.js +1 -0
  78. package/dist/core/understanding/dependencies/discover.d.ts +7 -0
  79. package/dist/core/understanding/dependencies/discover.js +550 -0
  80. package/dist/core/understanding/dependencies/extract.d.ts +10 -0
  81. package/dist/core/understanding/dependencies/extract.js +189 -0
  82. package/dist/core/understanding/dependencies/index.d.ts +4 -0
  83. package/dist/core/understanding/dependencies/index.js +3 -0
  84. package/dist/core/understanding/dependencies/models.d.ts +12 -0
  85. package/dist/core/understanding/dependencies/models.js +125 -0
  86. package/dist/core/understanding/dependencies/types.d.ts +27 -0
  87. package/dist/core/understanding/dependencies/types.js +1 -0
  88. package/dist/core/understanding/domain/discover.d.ts +14 -0
  89. package/dist/core/understanding/domain/discover.js +90 -0
  90. package/dist/core/understanding/domain/index.d.ts +2 -0
  91. package/dist/core/understanding/domain/index.js +1 -0
  92. package/dist/core/understanding/entrypoints/discover.d.ts +6 -0
  93. package/dist/core/understanding/entrypoints/discover.js +62 -0
  94. package/dist/core/understanding/entrypoints/extract.d.ts +19 -0
  95. package/dist/core/understanding/entrypoints/extract.js +43 -0
  96. package/dist/core/understanding/entrypoints/index.d.ts +4 -0
  97. package/dist/core/understanding/entrypoints/index.js +3 -0
  98. package/dist/core/understanding/entrypoints/models.d.ts +26 -0
  99. package/dist/core/understanding/entrypoints/models.js +216 -0
  100. package/dist/core/understanding/entrypoints/types.d.ts +20 -0
  101. package/dist/core/understanding/entrypoints/types.js +1 -0
  102. package/dist/core/understanding/index.d.ts +32 -0
  103. package/dist/core/understanding/index.js +18 -0
  104. package/dist/core/understanding/mind/build.d.ts +16 -0
  105. package/dist/core/understanding/mind/build.js +134 -0
  106. package/dist/core/understanding/mind/index.d.ts +6 -0
  107. package/dist/core/understanding/mind/index.js +3 -0
  108. package/dist/core/understanding/mind/query.d.ts +33 -0
  109. package/dist/core/understanding/mind/query.js +39 -0
  110. package/dist/core/understanding/mind/types.d.ts +24 -0
  111. package/dist/core/understanding/mind/types.js +7 -0
  112. package/dist/core/understanding/model/builder.d.ts +9 -0
  113. package/dist/core/understanding/model/builder.js +209 -0
  114. package/dist/core/understanding/model/ids.d.ts +7 -0
  115. package/dist/core/understanding/model/ids.js +48 -0
  116. package/dist/core/understanding/model/index.d.ts +7 -0
  117. package/dist/core/understanding/model/index.js +6 -0
  118. package/dist/core/understanding/model/schema.d.ts +12 -0
  119. package/dist/core/understanding/model/schema.js +33 -0
  120. package/dist/core/understanding/model/serializer.d.ts +9 -0
  121. package/dist/core/understanding/model/serializer.js +46 -0
  122. package/dist/core/understanding/model/types.d.ts +110 -0
  123. package/dist/core/understanding/model/types.js +1 -0
  124. package/dist/core/understanding/model/validator.d.ts +5 -0
  125. package/dist/core/understanding/model/validator.js +126 -0
  126. package/dist/core/understanding/model/version.d.ts +9 -0
  127. package/dist/core/understanding/model/version.js +7 -0
  128. package/dist/core/understanding/ownership/discover.d.ts +12 -0
  129. package/dist/core/understanding/ownership/discover.js +242 -0
  130. package/dist/core/understanding/ownership/index.d.ts +2 -0
  131. package/dist/core/understanding/ownership/index.js +1 -0
  132. package/dist/core/understanding/ownership/types.d.ts +23 -0
  133. package/dist/core/understanding/ownership/types.js +1 -0
  134. package/dist/core/understanding/query/engine.d.ts +24 -0
  135. package/dist/core/understanding/query/engine.js +35 -0
  136. package/dist/core/understanding/query/errors.d.ts +13 -0
  137. package/dist/core/understanding/query/errors.js +26 -0
  138. package/dist/core/understanding/query/executor.d.ts +8 -0
  139. package/dist/core/understanding/query/executor.js +34 -0
  140. package/dist/core/understanding/query/index.d.ts +7 -0
  141. package/dist/core/understanding/query/index.js +5 -0
  142. package/dist/core/understanding/query/models.d.ts +102 -0
  143. package/dist/core/understanding/query/models.js +1 -0
  144. package/dist/core/understanding/query/query.d.ts +68 -0
  145. package/dist/core/understanding/query/query.js +145 -0
  146. package/dist/core/understanding/query/registry.d.ts +8 -0
  147. package/dist/core/understanding/query/registry.js +340 -0
  148. package/dist/core/understanding/query/types.d.ts +63 -0
  149. package/dist/core/understanding/query/types.js +1 -0
  150. package/dist/core/understanding/relationships/discover.d.ts +11 -0
  151. package/dist/core/understanding/relationships/discover.js +517 -0
  152. package/dist/core/understanding/relationships/extract.d.ts +14 -0
  153. package/dist/core/understanding/relationships/extract.js +165 -0
  154. package/dist/core/understanding/relationships/index.d.ts +4 -0
  155. package/dist/core/understanding/relationships/index.js +3 -0
  156. package/dist/core/understanding/relationships/models.d.ts +21 -0
  157. package/dist/core/understanding/relationships/models.js +185 -0
  158. package/dist/core/understanding/relationships/types.d.ts +42 -0
  159. package/dist/core/understanding/relationships/types.js +1 -0
  160. package/dist/core/understanding/risks/discover.d.ts +8 -0
  161. package/dist/core/understanding/risks/discover.js +155 -0
  162. package/dist/core/understanding/risks/index.d.ts +2 -0
  163. package/dist/core/understanding/risks/index.js +1 -0
  164. package/dist/core/understanding/risks/types.d.ts +26 -0
  165. package/dist/core/understanding/risks/types.js +1 -0
  166. package/dist/core/understanding/shared/domain-lexicon.d.ts +9 -0
  167. package/dist/core/understanding/shared/domain-lexicon.js +107 -0
  168. package/dist/core/understanding/shared/index.d.ts +2 -0
  169. package/dist/core/understanding/shared/index.js +2 -0
  170. package/dist/core/understanding/shared/tokens.d.ts +7 -0
  171. package/dist/core/understanding/shared/tokens.js +141 -0
  172. package/dist/core/understanding/snapshot/identity.d.ts +24 -0
  173. package/dist/core/understanding/snapshot/identity.js +79 -0
  174. package/dist/core/understanding/snapshot/index.d.ts +2 -0
  175. package/dist/core/understanding/snapshot/index.js +1 -0
  176. package/dist/core/understanding/types/index.d.ts +22 -0
  177. package/dist/core/understanding/types/index.js +1 -0
  178. package/dist/core/understanding/understand/formatter.d.ts +10 -0
  179. package/dist/core/understanding/understand/formatter.js +115 -0
  180. package/dist/core/understanding/understand/index.d.ts +4 -0
  181. package/dist/core/understanding/understand/index.js +3 -0
  182. package/dist/core/understanding/understand/service.d.ts +17 -0
  183. package/dist/core/understanding/understand/service.js +76 -0
  184. package/dist/core/understanding/understand/summary.d.ts +14 -0
  185. package/dist/core/understanding/understand/summary.js +39 -0
  186. package/dist/core/understanding/understand/types.d.ts +31 -0
  187. package/dist/core/understanding/understand/types.js +1 -0
  188. package/dist/mcp/brain/compile.d.ts +9 -0
  189. package/dist/mcp/brain/compile.js +42 -0
  190. package/dist/mcp/brain/errors.d.ts +12 -0
  191. package/dist/mcp/brain/errors.js +23 -0
  192. package/dist/mcp/brain/index.d.ts +11 -0
  193. package/dist/mcp/brain/index.js +8 -0
  194. package/dist/mcp/brain/provenance.d.ts +29 -0
  195. package/dist/mcp/brain/provenance.js +59 -0
  196. package/dist/mcp/brain/schemas.d.ts +13 -0
  197. package/dist/mcp/brain/schemas.js +105 -0
  198. package/dist/mcp/brain/security/root.d.ts +6 -0
  199. package/dist/mcp/brain/security/root.js +66 -0
  200. package/dist/mcp/brain/server.d.ts +12 -0
  201. package/dist/mcp/brain/server.js +46 -0
  202. package/dist/mcp/brain/session.d.ts +33 -0
  203. package/dist/mcp/brain/session.js +117 -0
  204. package/dist/mcp/brain/tools/handlers.d.ts +13 -0
  205. package/dist/mcp/brain/tools/handlers.js +483 -0
  206. package/dist/mcp/brain/tools/registry.d.ts +9 -0
  207. package/dist/mcp/brain/tools/registry.js +191 -0
  208. package/package.json +11 -4
@@ -0,0 +1,57 @@
1
+ import { withClaimStatus } from "../claims/lifecycle.js";
2
+ import { createContradictionId } from "./types.js";
3
+ /**
4
+ * Detect contradictory ACTIVE claims sharing subject+predicate with different objects.
5
+ * Marks those claims CONTRADICTED and returns contradiction records.
6
+ */
7
+ export function detectContradictions(claims, snapshotId) {
8
+ const groups = new Map();
9
+ for (const claim of claims) {
10
+ if (claim.status !== "ACTIVE" && claim.status !== "CONTRADICTED") {
11
+ continue;
12
+ }
13
+ const key = `${claim.subject}\0${claim.predicate}`;
14
+ const list = groups.get(key) ?? [];
15
+ list.push(claim);
16
+ groups.set(key, list);
17
+ }
18
+ const contradictions = [];
19
+ const contradictedIds = new Map();
20
+ for (const [, group] of groups) {
21
+ const uniqueObjects = [...new Set(group.map((c) => c.object))];
22
+ if (uniqueObjects.length < 2) {
23
+ continue;
24
+ }
25
+ const subject = group[0]?.subject ?? "";
26
+ const predicate = group[0]?.predicate ?? "";
27
+ const id = createContradictionId(subject, predicate, uniqueObjects);
28
+ const claimIds = group.map((c) => c.id);
29
+ const evidenceIds = [...new Set(group.flatMap((c) => c.evidenceIds))];
30
+ contradictions.push({
31
+ id,
32
+ snapshotId,
33
+ claimIds,
34
+ subject,
35
+ predicate,
36
+ values: uniqueObjects.sort((a, b) => a.localeCompare(b)),
37
+ evidenceIds,
38
+ confidence: Math.min(...group.map((c) => c.confidence)),
39
+ rationale: `Multiple ACTIVE values for ${predicate} on ${subject}`,
40
+ });
41
+ for (const claim of group) {
42
+ const list = contradictedIds.get(claim.id) ?? [];
43
+ list.push(id);
44
+ contradictedIds.set(claim.id, list);
45
+ }
46
+ }
47
+ const nextClaims = claims.map((claim) => {
48
+ const contra = contradictedIds.get(claim.id);
49
+ if (!contra) {
50
+ return claim;
51
+ }
52
+ return withClaimStatus(claim, "CONTRADICTED", { contradictionIds: contra });
53
+ });
54
+ contradictions.sort((a, b) => a.id.localeCompare(b.id));
55
+ return { claims: nextClaims, contradictions };
56
+ }
57
+ export { createContradictionId } from "./types.js";
@@ -0,0 +1,12 @@
1
+ export interface BrainContradiction {
2
+ id: string;
3
+ snapshotId: string;
4
+ claimIds: readonly string[];
5
+ subject: string;
6
+ predicate: string;
7
+ values: readonly string[];
8
+ evidenceIds: readonly string[];
9
+ confidence: number;
10
+ rationale: string;
11
+ }
12
+ export declare function createContradictionId(subject: string, predicate: string, values: readonly string[]): string;
@@ -0,0 +1,8 @@
1
+ export function createContradictionId(subject, predicate, values) {
2
+ const key = `${subject}\0${predicate}\0${[...values].sort().join("|")}`;
3
+ let hash = 0;
4
+ for (let i = 0; i < key.length; i++) {
5
+ hash = (hash * 31 + key.charCodeAt(i)) >>> 0;
6
+ }
7
+ return `contra_${hash.toString(16).padStart(8, "0")}`;
8
+ }
@@ -0,0 +1,25 @@
1
+ import type { ProjectBrain } from "./types.js";
2
+ import { type DeltaSchemaVersion } from "./version.js";
3
+ export interface BrainDelta {
4
+ schemaVersion: DeltaSchemaVersion;
5
+ beforeSnapshotId: string;
6
+ afterSnapshotId: string;
7
+ addedClaimIds: readonly string[];
8
+ removedClaimIds: readonly string[];
9
+ changedClaimIds: readonly string[];
10
+ invalidatedClaimIds: readonly string[];
11
+ supersededClaimIds: readonly string[];
12
+ contradictedClaimIds: readonly string[];
13
+ newContradictionIds: readonly string[];
14
+ resolvedContradictionIds: readonly string[];
15
+ addedComponentIds: readonly string[];
16
+ removedComponentIds: readonly string[];
17
+ dependencyChanges: readonly string[];
18
+ ownershipChanges: readonly string[];
19
+ riskChanges: readonly string[];
20
+ summary: readonly string[];
21
+ createdAt: string;
22
+ }
23
+ export declare function buildBrainDelta(before: ProjectBrain, after: ProjectBrain): BrainDelta;
24
+ export declare function serializeBrainDelta(delta: BrainDelta): string;
25
+ export declare function parseBrainDelta(json: string): BrainDelta;
@@ -0,0 +1,116 @@
1
+ import { DELTA_SCHEMA_VERSION } from "./version.js";
2
+ function claimFinger(c) {
3
+ return `${c.subject}|${c.predicate}|${c.object}|${c.status}|${c.confidence}`;
4
+ }
5
+ export function buildBrainDelta(before, after) {
6
+ const beforeClaims = new Map(before.claims.map((c) => [c.id, c]));
7
+ const afterClaims = new Map(after.claims.map((c) => [c.id, c]));
8
+ const addedClaimIds = [];
9
+ const removedClaimIds = [];
10
+ const changedClaimIds = [];
11
+ const invalidatedClaimIds = [];
12
+ const supersededClaimIds = [];
13
+ const contradictedClaimIds = [];
14
+ for (const [id, claim] of afterClaims) {
15
+ const prev = beforeClaims.get(id);
16
+ if (!prev) {
17
+ addedClaimIds.push(id);
18
+ continue;
19
+ }
20
+ if (claimFinger(prev) !== claimFinger(claim)) {
21
+ changedClaimIds.push(id);
22
+ }
23
+ if (claim.status === "INVALIDATED" && prev.status !== "INVALIDATED") {
24
+ invalidatedClaimIds.push(id);
25
+ }
26
+ if (claim.status === "SUPERSEDED" && prev.status !== "SUPERSEDED") {
27
+ supersededClaimIds.push(id);
28
+ }
29
+ if (claim.status === "CONTRADICTED" && prev.status !== "CONTRADICTED") {
30
+ contradictedClaimIds.push(id);
31
+ }
32
+ }
33
+ for (const id of beforeClaims.keys()) {
34
+ if (!afterClaims.has(id)) {
35
+ removedClaimIds.push(id);
36
+ }
37
+ }
38
+ const beforeContra = new Set(before.contradictions.map((c) => c.id));
39
+ const afterContra = new Set(after.contradictions.map((c) => c.id));
40
+ const newContradictionIds = [...afterContra].filter((id) => !beforeContra.has(id)).sort();
41
+ const resolvedContradictionIds = [...beforeContra].filter((id) => !afterContra.has(id)).sort();
42
+ const beforeComps = new Set(before.components.map((c) => c.id));
43
+ const afterComps = new Set(after.components.map((c) => c.id));
44
+ const addedComponentIds = [...afterComps].filter((id) => !beforeComps.has(id)).sort();
45
+ const removedComponentIds = [...beforeComps].filter((id) => !afterComps.has(id)).sort();
46
+ const depKey = (b) => b.model.dependencies.map((d) => `${d.from}->${d.to}:${d.type}`).sort();
47
+ const beforeDeps = new Set(depKey(before));
48
+ const afterDeps = new Set(depKey(after));
49
+ const dependencyChanges = [
50
+ ...[...afterDeps].filter((k) => !beforeDeps.has(k)).map((k) => `+${k}`),
51
+ ...[...beforeDeps].filter((k) => !afterDeps.has(k)).map((k) => `-${k}`),
52
+ ].sort();
53
+ const ownKey = (b) => b.ownership.ownerships.map((o) => `${o.path}:${o.owners.join(",")}`).sort();
54
+ const beforeOwn = new Set(ownKey(before));
55
+ const afterOwn = new Set(ownKey(after));
56
+ const ownershipChanges = [
57
+ ...[...afterOwn].filter((k) => !beforeOwn.has(k)).map((k) => `+${k}`),
58
+ ...[...beforeOwn].filter((k) => !afterOwn.has(k)).map((k) => `-${k}`),
59
+ ].sort();
60
+ const riskKey = (b) => b.risks.risks.map((r) => `${r.kind}:${r.target}`).sort();
61
+ const beforeRisk = new Set(riskKey(before));
62
+ const afterRisk = new Set(riskKey(after));
63
+ const riskChanges = [
64
+ ...[...afterRisk].filter((k) => !beforeRisk.has(k)).map((k) => `+${k}`),
65
+ ...[...beforeRisk].filter((k) => !afterRisk.has(k)).map((k) => `-${k}`),
66
+ ].sort();
67
+ const summary = [];
68
+ if (addedClaimIds.length || invalidatedClaimIds.length) {
69
+ summary.push(`Claims +${addedClaimIds.length} / invalidated ${invalidatedClaimIds.length}`);
70
+ }
71
+ if (dependencyChanges.length) {
72
+ summary.push(`Dependency changes: ${dependencyChanges.length}`);
73
+ }
74
+ if (ownershipChanges.length) {
75
+ summary.push(`Ownership changes: ${ownershipChanges.length}`);
76
+ }
77
+ if (riskChanges.length) {
78
+ summary.push(`Risk changes: ${riskChanges.length}`);
79
+ }
80
+ if (newContradictionIds.length || resolvedContradictionIds.length) {
81
+ summary.push(`Contradictions +${newContradictionIds.length}/-${resolvedContradictionIds.length}`);
82
+ }
83
+ if (summary.length === 0) {
84
+ summary.push("No structural brain changes");
85
+ }
86
+ return {
87
+ schemaVersion: DELTA_SCHEMA_VERSION,
88
+ beforeSnapshotId: before.snapshot.id,
89
+ afterSnapshotId: after.snapshot.id,
90
+ addedClaimIds: addedClaimIds.sort(),
91
+ removedClaimIds: removedClaimIds.sort(),
92
+ changedClaimIds: changedClaimIds.sort(),
93
+ invalidatedClaimIds: invalidatedClaimIds.sort(),
94
+ supersededClaimIds: supersededClaimIds.sort(),
95
+ contradictedClaimIds: contradictedClaimIds.sort(),
96
+ newContradictionIds,
97
+ resolvedContradictionIds,
98
+ addedComponentIds,
99
+ removedComponentIds,
100
+ dependencyChanges,
101
+ ownershipChanges,
102
+ riskChanges,
103
+ summary,
104
+ createdAt: after.metadata.updatedAt,
105
+ };
106
+ }
107
+ export function serializeBrainDelta(delta) {
108
+ return `${JSON.stringify(delta, null, 2)}\n`;
109
+ }
110
+ export function parseBrainDelta(json) {
111
+ const parsed = JSON.parse(json);
112
+ if (parsed.schemaVersion !== DELTA_SCHEMA_VERSION) {
113
+ throw new Error(`incompatible delta schema ${String(parsed.schemaVersion)}`);
114
+ }
115
+ return parsed;
116
+ }
@@ -0,0 +1,3 @@
1
+ export type { BrainEvidence, EvidenceEpistemics, EvidenceKind, EvidenceRedactionStatus, } from "./types.js";
2
+ export { buildEvidence, createEvidenceId } from "./types.js";
3
+ export { redactEvidence, redactEvidenceList } from "./redact.js";
@@ -0,0 +1,2 @@
1
+ export { buildEvidence, createEvidenceId } from "./types.js";
2
+ export { redactEvidence, redactEvidenceList } from "./redact.js";
@@ -0,0 +1,4 @@
1
+ import type { BrainEvidence } from "./types.js";
2
+ /** Ensure evidence never carries secret plaintext; paths for sensitive files become path-only. */
3
+ export declare function redactEvidence(evidence: BrainEvidence): BrainEvidence;
4
+ export declare function redactEvidenceList(list: readonly BrainEvidence[]): BrainEvidence[];
@@ -0,0 +1,36 @@
1
+ import { looksLikeSensitiveFilename, redactSecretValue } from "../../../../security/redaction.js";
2
+ const SECRETISH = /(password|secret|token|api[_-]?key|private[_-]?key|credential)/i;
3
+ /** Ensure evidence never carries secret plaintext; paths for sensitive files become path-only. */
4
+ export function redactEvidence(evidence) {
5
+ const locator = evidence.locator;
6
+ let redaction = evidence.redaction;
7
+ let safeLocator = locator;
8
+ let symbol = evidence.symbol;
9
+ if (looksLikeSensitiveFilename(locator) || SECRETISH.test(locator)) {
10
+ redaction = "path-only";
11
+ // Keep path reference only; never attach contents.
12
+ safeLocator = locator.split(/[/\\]/).slice(0, -1).concat("[REDACTED_NAME]").join("/");
13
+ if (safeLocator === "[REDACTED_NAME]") {
14
+ safeLocator = "[REDACTED_PATH]";
15
+ }
16
+ }
17
+ if (symbol && SECRETISH.test(symbol)) {
18
+ symbol = redactSecretValue(symbol);
19
+ redaction = "redacted";
20
+ }
21
+ const next = {
22
+ ...evidence,
23
+ locator: safeLocator,
24
+ redaction,
25
+ };
26
+ if (symbol !== undefined) {
27
+ next.symbol = symbol;
28
+ }
29
+ else {
30
+ delete next.symbol;
31
+ }
32
+ return next;
33
+ }
34
+ export function redactEvidenceList(list) {
35
+ return list.map(redactEvidence);
36
+ }
@@ -0,0 +1,34 @@
1
+ import type { EvidenceSchemaVersion } from "../version.js";
2
+ export type EvidenceKind = "path" | "file-presence" | "config-key" | "import-edge" | "role-signal" | "pattern-match" | "ownership-rule" | "model-statistic" | "derived";
3
+ export type EvidenceEpistemics = "observed" | "inferred";
4
+ export type EvidenceRedactionStatus = "none" | "path-only" | "redacted";
5
+ export interface BrainEvidence {
6
+ schemaVersion: EvidenceSchemaVersion;
7
+ id: string;
8
+ kind: EvidenceKind;
9
+ /** Repository-relative locator (path, pattern, or symbolic key). Never secret contents. */
10
+ locator: string;
11
+ source: string;
12
+ snapshotId: string;
13
+ epistemics: EvidenceEpistemics;
14
+ symbol?: string;
15
+ range?: {
16
+ startLine: number;
17
+ endLine: number;
18
+ };
19
+ redaction: EvidenceRedactionStatus;
20
+ }
21
+ export declare function createEvidenceId(parts: readonly string[]): string;
22
+ export declare function buildEvidence(input: {
23
+ kind: EvidenceKind;
24
+ locator: string;
25
+ source: string;
26
+ snapshotId: string;
27
+ epistemics: EvidenceEpistemics;
28
+ symbol?: string;
29
+ range?: {
30
+ startLine: number;
31
+ endLine: number;
32
+ };
33
+ redaction?: EvidenceRedactionStatus;
34
+ }): BrainEvidence;
@@ -0,0 +1,35 @@
1
+ import { EVIDENCE_SCHEMA_VERSION } from "../version.js";
2
+ export function createEvidenceId(parts) {
3
+ const key = parts.join("\0");
4
+ let hash = 0;
5
+ for (let i = 0; i < key.length; i++) {
6
+ hash = (hash * 31 + key.charCodeAt(i)) >>> 0;
7
+ }
8
+ return `ev_${hash.toString(16).padStart(8, "0")}`;
9
+ }
10
+ export function buildEvidence(input) {
11
+ const evidence = {
12
+ schemaVersion: EVIDENCE_SCHEMA_VERSION,
13
+ id: createEvidenceId([
14
+ input.kind,
15
+ input.locator,
16
+ input.source,
17
+ input.snapshotId,
18
+ input.epistemics,
19
+ input.symbol ?? "",
20
+ ]),
21
+ kind: input.kind,
22
+ locator: input.locator,
23
+ source: input.source,
24
+ snapshotId: input.snapshotId,
25
+ epistemics: input.epistemics,
26
+ redaction: input.redaction ?? "path-only",
27
+ };
28
+ if (input.symbol !== undefined) {
29
+ evidence.symbol = input.symbol;
30
+ }
31
+ if (input.range !== undefined) {
32
+ evidence.range = input.range;
33
+ }
34
+ return evidence;
35
+ }
@@ -0,0 +1,17 @@
1
+ import type { BrainClaim } from "./claims/types.js";
2
+ import type { BrainEvidence } from "./evidence/types.js";
3
+ import type { ProjectBrain } from "./types.js";
4
+ export interface ClaimExplanation {
5
+ claim: BrainClaim;
6
+ status: BrainClaim["status"];
7
+ confidence: number;
8
+ supportingEvidence: readonly BrainEvidence[];
9
+ contradictions: readonly ProjectBrain["contradictions"][number][];
10
+ invalidationState: {
11
+ invalidated: boolean;
12
+ invalidatedAt?: string;
13
+ supersededBy?: string;
14
+ };
15
+ unknowns: readonly string[];
16
+ }
17
+ export declare function explainClaim(brain: ProjectBrain, claimId: string): ClaimExplanation | null;
@@ -0,0 +1,33 @@
1
+ export function explainClaim(brain, claimId) {
2
+ const claim = brain.claims.find((c) => c.id === claimId);
3
+ if (!claim) {
4
+ return null;
5
+ }
6
+ const supportingEvidence = brain.evidence.filter((e) => claim.evidenceIds.includes(e.id));
7
+ const contradictions = brain.contradictions.filter((c) => c.claimIds.includes(claim.id));
8
+ const unknowns = [];
9
+ if (supportingEvidence.length === 0) {
10
+ unknowns.push("No typed evidence records resolved for claim evidenceIds");
11
+ }
12
+ if (claim.status === "CONTRADICTED") {
13
+ unknowns.push("Claim is contradicted by one or more sibling values");
14
+ }
15
+ const invalidationState = {
16
+ invalidated: claim.status === "INVALIDATED",
17
+ };
18
+ if (claim.invalidatedAt !== undefined) {
19
+ invalidationState.invalidatedAt = claim.invalidatedAt;
20
+ }
21
+ if (claim.supersededBy !== undefined) {
22
+ invalidationState.supersededBy = claim.supersededBy;
23
+ }
24
+ return {
25
+ claim,
26
+ status: claim.status,
27
+ confidence: claim.confidence,
28
+ supportingEvidence,
29
+ contradictions,
30
+ invalidationState,
31
+ unknowns,
32
+ };
33
+ }
@@ -0,0 +1,28 @@
1
+ export { PROJECT_BRAIN_LIMITATIONS } from "./types.js";
2
+ export type { ProjectBrain, ProjectBrainMetadata } from "./types.js";
3
+ export { buildProjectBrain } from "./build.js";
4
+ export type { BuildProjectBrainOptions } from "./build.js";
5
+ export { PROJECT_BRAIN_SCHEMA_VERSION, CLAIM_SCHEMA_VERSION, EVIDENCE_SCHEMA_VERSION, DELTA_SCHEMA_VERSION, SNAPSHOT_META_SCHEMA_VERSION, BRAIN_STORAGE_FORMAT_VERSION, } from "./version.js";
6
+ export { CONFIDENCE_CONTRACT, clampBrainConfidence, assertBrainConfidence, averageBrainConfidence, } from "./confidence.js";
7
+ export type { ConfidenceMetadata } from "./confidence.js";
8
+ export { buildEvidence, redactEvidence, redactEvidenceList } from "./evidence/index.js";
9
+ export type { BrainEvidence, EvidenceKind, EvidenceEpistemics, EvidenceRedactionStatus, } from "./evidence/index.js";
10
+ export { buildClaim, createClaimId, applyClaimLifecycle, withClaimStatus } from "./claims/index.js";
11
+ export type { BrainClaim, ClaimStatus, ClaimSource } from "./claims/index.js";
12
+ export { detectContradictions } from "./contradictions/index.js";
13
+ export type { BrainContradiction } from "./contradictions/index.js";
14
+ export { buildComponents } from "./components/index.js";
15
+ export type { BrainComponent, BrainComponentType } from "./components/index.js";
16
+ export { LocalBrainStore, BrainStorageError, serializeBrain, checksumPayload, } from "./storage/index.js";
17
+ export type { BrainStoreMeta, SnapshotMeta, SnapshotComparison } from "./storage/index.js";
18
+ export { buildBrainDelta, serializeBrainDelta, parseBrainDelta } from "./delta.js";
19
+ export type { BrainDelta } from "./delta.js";
20
+ export { createBrainQueryEngine, BrainQueryEngine } from "./query.js";
21
+ export type { BrainQuery, BrainQueryType, BrainQueryResponse } from "./query.js";
22
+ export { explainClaim } from "./explain.js";
23
+ export type { ClaimExplanation } from "./explain.js";
24
+ export { traceBrain } from "./trace.js";
25
+ export type { TraceResult, TraceMode, TraceNode, TraceEdge } from "./trace.js";
26
+ export { redactBrainForStorage } from "./security.js";
27
+ export { checkBrainCompatibility, migrateBrain, currentVersions } from "./migrate.js";
28
+ export { PROJECT_BRAIN_CONTRACT, assertBrainContract, BrainContractError } from "./contract.js";
@@ -0,0 +1,16 @@
1
+ export { PROJECT_BRAIN_LIMITATIONS } from "./types.js";
2
+ export { buildProjectBrain } from "./build.js";
3
+ export { PROJECT_BRAIN_SCHEMA_VERSION, CLAIM_SCHEMA_VERSION, EVIDENCE_SCHEMA_VERSION, DELTA_SCHEMA_VERSION, SNAPSHOT_META_SCHEMA_VERSION, BRAIN_STORAGE_FORMAT_VERSION, } from "./version.js";
4
+ export { CONFIDENCE_CONTRACT, clampBrainConfidence, assertBrainConfidence, averageBrainConfidence, } from "./confidence.js";
5
+ export { buildEvidence, redactEvidence, redactEvidenceList } from "./evidence/index.js";
6
+ export { buildClaim, createClaimId, applyClaimLifecycle, withClaimStatus } from "./claims/index.js";
7
+ export { detectContradictions } from "./contradictions/index.js";
8
+ export { buildComponents } from "./components/index.js";
9
+ export { LocalBrainStore, BrainStorageError, serializeBrain, checksumPayload, } from "./storage/index.js";
10
+ export { buildBrainDelta, serializeBrainDelta, parseBrainDelta } from "./delta.js";
11
+ export { createBrainQueryEngine, BrainQueryEngine } from "./query.js";
12
+ export { explainClaim } from "./explain.js";
13
+ export { traceBrain } from "./trace.js";
14
+ export { redactBrainForStorage } from "./security.js";
15
+ export { checkBrainCompatibility, migrateBrain, currentVersions } from "./migrate.js";
16
+ export { PROJECT_BRAIN_CONTRACT, assertBrainContract, BrainContractError } from "./contract.js";
@@ -0,0 +1,21 @@
1
+ import { type BrainStorageFormatVersion, type ProjectBrainSchemaVersion } from "./version.js";
2
+ import type { ProjectBrain } from "./types.js";
3
+ export interface CompatibilityResult {
4
+ compatible: boolean;
5
+ reason?: string;
6
+ }
7
+ /** Reject incompatible brain / storage versions safely. */
8
+ export declare function checkBrainCompatibility(options: {
9
+ schemaVersion: string;
10
+ storageFormatVersion?: string;
11
+ }): CompatibilityResult;
12
+ export type MigrationFn = (brain: ProjectBrain) => ProjectBrain;
13
+ /**
14
+ * Migrate a loaded brain payload to the current schema when possible.
15
+ * Unknown versions are rejected (no silent best-effort parse).
16
+ */
17
+ export declare function migrateBrain(brain: ProjectBrain, fromVersion?: string): ProjectBrain;
18
+ export declare function currentVersions(): {
19
+ projectBrain: ProjectBrainSchemaVersion;
20
+ storage: BrainStorageFormatVersion;
21
+ };
@@ -0,0 +1,47 @@
1
+ import { BRAIN_STORAGE_FORMAT_VERSION, PROJECT_BRAIN_SCHEMA_VERSION, } from "./version.js";
2
+ import { BrainStorageError } from "./storage/store.js";
3
+ /** Reject incompatible brain / storage versions safely. */
4
+ export function checkBrainCompatibility(options) {
5
+ if (options.schemaVersion !== PROJECT_BRAIN_SCHEMA_VERSION) {
6
+ return {
7
+ compatible: false,
8
+ reason: `incompatible ProjectBrain schema ${options.schemaVersion}; expected ${PROJECT_BRAIN_SCHEMA_VERSION}`,
9
+ };
10
+ }
11
+ if (options.storageFormatVersion !== undefined &&
12
+ options.storageFormatVersion !== BRAIN_STORAGE_FORMAT_VERSION) {
13
+ return {
14
+ compatible: false,
15
+ reason: `incompatible storage format ${options.storageFormatVersion}; expected ${BRAIN_STORAGE_FORMAT_VERSION}`,
16
+ };
17
+ }
18
+ return { compatible: true };
19
+ }
20
+ const MIGRATIONS = {
21
+ // V1: identity. Future versions register here keyed by from→to.
22
+ "1.0.0": (brain) => brain,
23
+ };
24
+ /**
25
+ * Migrate a loaded brain payload to the current schema when possible.
26
+ * Unknown versions are rejected (no silent best-effort parse).
27
+ */
28
+ export function migrateBrain(brain, fromVersion = brain.metadata.schemaVersion) {
29
+ if (fromVersion === PROJECT_BRAIN_SCHEMA_VERSION) {
30
+ return brain;
31
+ }
32
+ const migrate = MIGRATIONS[fromVersion];
33
+ if (!migrate) {
34
+ throw new BrainStorageError(`no migration path from schema ${fromVersion} to ${PROJECT_BRAIN_SCHEMA_VERSION}`);
35
+ }
36
+ const next = migrate(brain);
37
+ if (next.metadata.schemaVersion !== PROJECT_BRAIN_SCHEMA_VERSION) {
38
+ throw new BrainStorageError(`migration from ${fromVersion} did not reach ${PROJECT_BRAIN_SCHEMA_VERSION}`);
39
+ }
40
+ return next;
41
+ }
42
+ export function currentVersions() {
43
+ return {
44
+ projectBrain: PROJECT_BRAIN_SCHEMA_VERSION,
45
+ storage: BRAIN_STORAGE_FORMAT_VERSION,
46
+ };
47
+ }
@@ -0,0 +1,60 @@
1
+ import type { ProjectBrain } from "./types.js";
2
+ export type BrainQueryType = "ProjectSummary" | "ListDomains" | "ListComponents" | "ListEntrypoints" | "ListDependencies" | "ListRelationships" | "ListArchitectures" | "ListOwnership" | "ListRisks" | "ListClaims" | "ListEvidence" | "ListContradictions" | "ListUnknowns" | "ListChanges" | "ListInvalidations" | "Impact" | "BlastRadius";
3
+ export type BrainQuery = {
4
+ type: "ProjectSummary";
5
+ } | {
6
+ type: "ListDomains";
7
+ } | {
8
+ type: "ListComponents";
9
+ } | {
10
+ type: "ListEntrypoints";
11
+ } | {
12
+ type: "ListDependencies";
13
+ } | {
14
+ type: "ListRelationships";
15
+ } | {
16
+ type: "ListArchitectures";
17
+ } | {
18
+ type: "ListOwnership";
19
+ } | {
20
+ type: "ListRisks";
21
+ } | {
22
+ type: "ListClaims";
23
+ status?: string;
24
+ } | {
25
+ type: "ListEvidence";
26
+ } | {
27
+ type: "ListContradictions";
28
+ } | {
29
+ type: "ListUnknowns";
30
+ } | {
31
+ type: "ListChanges";
32
+ previous?: ProjectBrain;
33
+ } | {
34
+ type: "ListInvalidations";
35
+ } | {
36
+ type: "Impact";
37
+ target: string;
38
+ } | {
39
+ type: "BlastRadius";
40
+ target: string;
41
+ };
42
+ export interface BrainQueryResponse<T> {
43
+ result: T;
44
+ evidenceIds: readonly string[];
45
+ confidence: number;
46
+ snapshotId: string;
47
+ metadata: {
48
+ queryType: BrainQueryType;
49
+ brainId: string;
50
+ schemaVersion: string;
51
+ projectName: string;
52
+ };
53
+ executionTimeMs: number;
54
+ }
55
+ export declare class BrainQueryEngine {
56
+ private readonly brain;
57
+ constructor(brain: ProjectBrain);
58
+ execute(query: BrainQuery): BrainQueryResponse<unknown>;
59
+ }
60
+ export declare function createBrainQueryEngine(brain: ProjectBrain): BrainQueryEngine;