audit-tools 0.32.17 → 0.32.19

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 (106) hide show
  1. package/dist/audit/cli/auditStep.d.ts +1 -0
  2. package/dist/audit/cli/auditStep.d.ts.map +1 -1
  3. package/dist/audit/cli/auditStep.js +5 -1
  4. package/dist/audit/cli/auditStep.js.map +1 -1
  5. package/dist/audit/cli/charterExtractionPrompt.d.ts +17 -0
  6. package/dist/audit/cli/charterExtractionPrompt.d.ts.map +1 -0
  7. package/dist/audit/cli/charterExtractionPrompt.js +94 -0
  8. package/dist/audit/cli/charterExtractionPrompt.js.map +1 -0
  9. package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
  10. package/dist/audit/cli/nextStepCommand.js +35 -0
  11. package/dist/audit/cli/nextStepCommand.js.map +1 -1
  12. package/dist/audit/cli/nextStepHelpers.d.ts +28 -0
  13. package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
  14. package/dist/audit/cli/nextStepHelpers.js +49 -0
  15. package/dist/audit/cli/nextStepHelpers.js.map +1 -1
  16. package/dist/audit/cli/steps.d.ts +4 -4
  17. package/dist/audit/cli/steps.d.ts.map +1 -1
  18. package/dist/audit/cli/steps.js +1 -0
  19. package/dist/audit/cli/steps.js.map +1 -1
  20. package/dist/audit/contracts/workerSchemas.d.ts +28 -28
  21. package/dist/audit/decompose/buildStructureDecomposition.d.ts +14 -0
  22. package/dist/audit/decompose/buildStructureDecomposition.d.ts.map +1 -0
  23. package/dist/audit/decompose/buildStructureDecomposition.js +107 -0
  24. package/dist/audit/decompose/buildStructureDecomposition.js.map +1 -0
  25. package/dist/audit/decompose/findings.d.ts +23 -0
  26. package/dist/audit/decompose/findings.d.ts.map +1 -0
  27. package/dist/audit/decompose/findings.js +121 -0
  28. package/dist/audit/decompose/findings.js.map +1 -0
  29. package/dist/audit/decompose/sources.d.ts +21 -0
  30. package/dist/audit/decompose/sources.d.ts.map +1 -0
  31. package/dist/audit/decompose/sources.js +168 -0
  32. package/dist/audit/decompose/sources.js.map +1 -0
  33. package/dist/audit/extractors/commentDecomposition.d.ts +52 -0
  34. package/dist/audit/extractors/commentDecomposition.d.ts.map +1 -0
  35. package/dist/audit/extractors/commentDecomposition.js +298 -0
  36. package/dist/audit/extractors/commentDecomposition.js.map +1 -0
  37. package/dist/audit/extractors/dataStateCoupling.d.ts +26 -0
  38. package/dist/audit/extractors/dataStateCoupling.d.ts.map +1 -0
  39. package/dist/audit/extractors/dataStateCoupling.js +71 -0
  40. package/dist/audit/extractors/dataStateCoupling.js.map +1 -0
  41. package/dist/audit/io/artifacts.d.ts +6 -0
  42. package/dist/audit/io/artifacts.d.ts.map +1 -1
  43. package/dist/audit/io/artifacts.js +2 -0
  44. package/dist/audit/io/artifacts.js.map +1 -1
  45. package/dist/audit/orchestrator/advanceTypes.d.ts +3 -1
  46. package/dist/audit/orchestrator/advanceTypes.d.ts.map +1 -1
  47. package/dist/audit/orchestrator/charterExtractionExecutor.d.ts +27 -0
  48. package/dist/audit/orchestrator/charterExtractionExecutor.d.ts.map +1 -0
  49. package/dist/audit/orchestrator/charterExtractionExecutor.js +95 -0
  50. package/dist/audit/orchestrator/charterExtractionExecutor.js.map +1 -0
  51. package/dist/audit/orchestrator/dependencyMap.d.ts +2 -0
  52. package/dist/audit/orchestrator/dependencyMap.d.ts.map +1 -1
  53. package/dist/audit/orchestrator/dependencyMap.js +23 -0
  54. package/dist/audit/orchestrator/dependencyMap.js.map +1 -1
  55. package/dist/audit/orchestrator/executorRunners.d.ts.map +1 -1
  56. package/dist/audit/orchestrator/executorRunners.js +4 -1
  57. package/dist/audit/orchestrator/executorRunners.js.map +1 -1
  58. package/dist/audit/orchestrator/executors.d.ts.map +1 -1
  59. package/dist/audit/orchestrator/executors.js +14 -0
  60. package/dist/audit/orchestrator/executors.js.map +1 -1
  61. package/dist/audit/orchestrator/nextStep.d.ts.map +1 -1
  62. package/dist/audit/orchestrator/nextStep.js +2 -0
  63. package/dist/audit/orchestrator/nextStep.js.map +1 -1
  64. package/dist/audit/orchestrator/state.d.ts.map +1 -1
  65. package/dist/audit/orchestrator/state.js +11 -0
  66. package/dist/audit/orchestrator/state.js.map +1 -1
  67. package/dist/audit/orchestrator/structureExecutors.d.ts +8 -0
  68. package/dist/audit/orchestrator/structureExecutors.d.ts.map +1 -1
  69. package/dist/audit/orchestrator/structureExecutors.js +30 -0
  70. package/dist/audit/orchestrator/structureExecutors.js.map +1 -1
  71. package/dist/audit/orchestrator/synthesisExecutors.d.ts.map +1 -1
  72. package/dist/audit/orchestrator/synthesisExecutors.js +2 -0
  73. package/dist/audit/orchestrator/synthesisExecutors.js.map +1 -1
  74. package/dist/audit/reporting/mergeFindings.d.ts +3 -1
  75. package/dist/audit/reporting/mergeFindings.d.ts.map +1 -1
  76. package/dist/audit/reporting/mergeFindings.js +5 -1
  77. package/dist/audit/reporting/mergeFindings.js.map +1 -1
  78. package/dist/audit/reporting/synthesis.d.ts +4 -0
  79. package/dist/audit/reporting/synthesis.d.ts.map +1 -1
  80. package/dist/audit/reporting/synthesis.js +1 -1
  81. package/dist/audit/reporting/synthesis.js.map +1 -1
  82. package/dist/audit/types/charterRegister.d.ts +42 -0
  83. package/dist/audit/types/charterRegister.d.ts.map +1 -0
  84. package/dist/audit/types/charterRegister.js +2 -0
  85. package/dist/audit/types/charterRegister.js.map +1 -0
  86. package/dist/audit/types/structureDecomposition.d.ts +27 -0
  87. package/dist/audit/types/structureDecomposition.d.ts.map +1 -0
  88. package/dist/audit/types/structureDecomposition.js +2 -0
  89. package/dist/audit/types/structureDecomposition.js.map +1 -0
  90. package/dist/shared/decompose/charterExtraction.d.ts +236 -0
  91. package/dist/shared/decompose/charterExtraction.d.ts.map +1 -0
  92. package/dist/shared/decompose/charterExtraction.js +209 -0
  93. package/dist/shared/decompose/charterExtraction.js.map +1 -0
  94. package/dist/shared/decompose/consensus.d.ts +66 -0
  95. package/dist/shared/decompose/consensus.d.ts.map +1 -0
  96. package/dist/shared/decompose/consensus.js +213 -0
  97. package/dist/shared/decompose/consensus.js.map +1 -0
  98. package/dist/shared/decompose/modularity.d.ts +44 -0
  99. package/dist/shared/decompose/modularity.d.ts.map +1 -0
  100. package/dist/shared/decompose/modularity.js +249 -0
  101. package/dist/shared/decompose/modularity.js.map +1 -0
  102. package/dist/shared/index.d.ts +6 -0
  103. package/dist/shared/index.d.ts.map +1 -1
  104. package/dist/shared/index.js +3 -0
  105. package/dist/shared/index.js.map +1 -1
  106. package/package.json +1 -1
@@ -0,0 +1,209 @@
1
+ // The charter layer of the conceptual design-review — assemble a gated charter
2
+ // register from a host LLM submission (Phase C; design of record
3
+ // spec/conceptual-design-review-design.md §"The four charters" + §"The True
4
+ // charter needs hard gates").
5
+ //
6
+ // Division of labour ([[contract-authoring-determinism-direction]]): the LLM emits
7
+ // JUDGMENT (per consensus subsystem, the four charter families in telos terms +
8
+ // the interpreted pairwise deltas it sees); this module is the deterministic
9
+ // ENFORCEMENT half — it assigns stable ids, derives each delta's kind + routing
10
+ // from its charter pair (the design's routing table, never host discretion), runs
11
+ // the Phase-A hard gates (applyTrueCharterGate drops un-falsifiable True;
12
+ // gateCharterDelta forces a low-confidence side to the human channel), grounds
13
+ // every subsystem against the Phase-B consensus scaffold, and surfaces the
14
+ // surviving deltas as Finding leads for synthesis. PURE + deterministic +
15
+ // language-neutral (operates on abstract node-id partitions + telos strings, no
16
+ // IO): provenance-on-disk grounding is the ingest's concern, not this module's.
17
+ import { z } from "zod";
18
+ import { CharterSchema, CharterKindSchema, GoalGraphSchema, } from "../types/charter.js";
19
+ import { applyTrueCharterGate, gateCharterDelta, } from "../validation/charterGate.js";
20
+ // ── Submission contract (what the host LLM writes to incoming/) ────────────────
21
+ /**
22
+ * A single charter as the host emits it — the persisted `Charter` minus its
23
+ * `charter_id`, which the tool assigns deterministically (`node_id:kind`) so
24
+ * charter identity can never drift from the host's free choice.
25
+ */
26
+ const CharterInputSchema = CharterSchema.omit({ charter_id: true });
27
+ /**
28
+ * A delta as the host emits it: the symmetric charter-kind `pair` it sees a gap
29
+ * across + the interpreted `summary` of that gap. The tool derives `kind`,
30
+ * `routed_to`, and `delta_id` — the host never picks the routing (that is the
31
+ * design's fixed table, enforced here).
32
+ */
33
+ const CharterDeltaInputSchema = z
34
+ .object({
35
+ pair: z.tuple([CharterKindSchema, CharterKindSchema]),
36
+ summary: z.string(),
37
+ })
38
+ .strict();
39
+ /** One reviewed subsystem: its consensus `node_id` + the charters/deltas for it. */
40
+ const CharterSubsystemInputSchema = z
41
+ .object({
42
+ node_id: z.string(),
43
+ charters: z.array(CharterInputSchema),
44
+ deltas: z.array(CharterDeltaInputSchema).default([]),
45
+ })
46
+ .strict();
47
+ /** The full host submission consumed at charter-extraction ingest. */
48
+ export const CharterSubmissionSchema = z
49
+ .object({
50
+ subsystems: z.array(CharterSubsystemInputSchema).default([]),
51
+ goal_graph: GoalGraphSchema.optional(),
52
+ })
53
+ .strict();
54
+ // ── Deterministic routing table (design §"The four charters") ──────────────────
55
+ /**
56
+ * Canonical charter-kind order — pairs are sorted by this so `[stated, revealed]`
57
+ * and `[revealed, stated]` map to one key (the deltas are symmetric).
58
+ */
59
+ const KIND_ORDER = ["stated", "inferred", "revealed", "true"];
60
+ function canonicalPair(pair) {
61
+ return [...pair].sort((a, b) => KIND_ORDER.indexOf(a) - KIND_ORDER.indexOf(b));
62
+ }
63
+ /**
64
+ * The design's routing table, keyed by canonical `pair` — who acts on each gap.
65
+ * A pair OUTSIDE this table has no defined owner and is a validation issue (the
66
+ * tool never invents a route). `severity` ranks the surfaced lead: a wrong-goal
67
+ * provocation is the highest-blast, an unstated assumption the lowest.
68
+ */
69
+ const DELTA_ROUTES = {
70
+ "stated|inferred": {
71
+ kind: "unstated_assumption",
72
+ routed_to: "clarification",
73
+ severity: "low",
74
+ },
75
+ "stated|revealed": {
76
+ kind: "spec_drift",
77
+ routed_to: "remediator",
78
+ severity: "medium",
79
+ },
80
+ "revealed|true": {
81
+ kind: "wrong_goal",
82
+ routed_to: "human",
83
+ severity: "high",
84
+ },
85
+ "stated|true": {
86
+ kind: "wrong_goal",
87
+ routed_to: "human",
88
+ severity: "high",
89
+ },
90
+ };
91
+ /** Lower of two charter confidences — a delta is only as strong as its weaker side. */
92
+ function weakerConfidence(a, b) {
93
+ const rank = { high: 2, medium: 1, low: 0 };
94
+ return rank[a.confidence] <= rank[b.confidence] ? a.confidence : b.confidence;
95
+ }
96
+ // ── Assembly ───────────────────────────────────────────────────────────────────
97
+ /**
98
+ * Assemble a gated charter register from a validated host submission.
99
+ *
100
+ * `membersByNode` grounds each submitted subsystem against the Phase-B consensus
101
+ * scaffold: a `node_id` the structure decomposition never surfaced is an invented
102
+ * subsystem → dropped with an issue (the host cannot conjure boundaries the
103
+ * deterministic layer didn't find). Deterministic throughout — same submission +
104
+ * same scaffold always yields the same register.
105
+ */
106
+ export function assembleCharterRegister(submission, membersByNode) {
107
+ const subsystems = [];
108
+ const deltas = [];
109
+ const findings = [];
110
+ const validation_issues = [];
111
+ // Stable output order: sort subsystems by node_id (content-derived, never input
112
+ // order — an incidentally-ordered array churns the artifact hash, cascading
113
+ // phantom staleness; see the extractor-ordering invariant in CLAUDE.md).
114
+ const sortedSubsystems = [...submission.subsystems].sort((a, b) => a.node_id.localeCompare(b.node_id));
115
+ for (const sub of sortedSubsystems) {
116
+ const members = membersByNode.get(sub.node_id);
117
+ if (!members) {
118
+ validation_issues.push(`subsystem "${sub.node_id}" is not a consensus node in the structure decomposition — dropped (charters may only review discovered subsystems)`);
119
+ continue;
120
+ }
121
+ // Assign ids + enforce one charter per kind (a dup kind is a submission error;
122
+ // keep the first, flag the rest).
123
+ const seenKinds = new Set();
124
+ const withIds = [];
125
+ for (const input of sub.charters) {
126
+ if (seenKinds.has(input.kind)) {
127
+ validation_issues.push(`subsystem "${sub.node_id}" has more than one "${input.kind}" charter — kept the first, dropped the rest`);
128
+ continue;
129
+ }
130
+ seenKinds.add(input.kind);
131
+ withIds.push({ ...input, charter_id: `${sub.node_id}:${input.kind}` });
132
+ }
133
+ // Phase-A True gate: drop un-falsifiable True nominations (no concrete
134
+ // alternative + cost). Surface each drop as an issue.
135
+ const { kept, dropped } = applyTrueCharterGate(withIds);
136
+ for (const drop of dropped) {
137
+ validation_issues.push(`${drop.charter_id}: ${drop.reason}`);
138
+ }
139
+ subsystems.push({
140
+ node_id: sub.node_id,
141
+ members,
142
+ charters: [...kept].sort((a, b) => a.charter_id.localeCompare(b.charter_id)),
143
+ });
144
+ const keptByKind = new Map(kept.map((c) => [c.kind, c]));
145
+ // Route + gate each submitted delta against the surviving charters.
146
+ for (const draft of sub.deltas) {
147
+ const [ka, kb] = canonicalPair(draft.pair);
148
+ if (ka === kb) {
149
+ validation_issues.push(`subsystem "${sub.node_id}" delta pairs "${ka}" with itself — dropped`);
150
+ continue;
151
+ }
152
+ const route = DELTA_ROUTES[`${ka}|${kb}`];
153
+ if (!route) {
154
+ validation_issues.push(`subsystem "${sub.node_id}" delta [${ka}, ${kb}] has no routing in the design's table — dropped`);
155
+ continue;
156
+ }
157
+ const charterA = keptByKind.get(ka);
158
+ const charterB = keptByKind.get(kb);
159
+ if (!charterA || !charterB) {
160
+ const missing = [!charterA ? ka : null, !charterB ? kb : null]
161
+ .filter((m) => m !== null)
162
+ .join(" + ");
163
+ validation_issues.push(`subsystem "${sub.node_id}" delta [${ka}, ${kb}] references a missing/dropped charter (${missing}) — dropped`);
164
+ continue;
165
+ }
166
+ const baseDelta = {
167
+ delta_id: `${sub.node_id}:${ka}-${kb}`,
168
+ pair: [ka, kb],
169
+ kind: route.kind,
170
+ routed_to: route.routed_to,
171
+ summary: draft.summary,
172
+ };
173
+ // Phase-A low-confidence gate: a shaky side forces the human channel.
174
+ const gated = gateCharterDelta(baseDelta, kept);
175
+ deltas.push(gated);
176
+ findings.push(deltaToFinding(gated, sub.node_id, members, route.severity, weakerConfidence(charterA, charterB)));
177
+ }
178
+ }
179
+ deltas.sort((a, b) => a.delta_id.localeCompare(b.delta_id));
180
+ findings.sort((a, b) => a.id.localeCompare(b.id));
181
+ return {
182
+ subsystems,
183
+ deltas,
184
+ findings,
185
+ goal_graph: submission.goal_graph ?? { nodes: [], edges: [] },
186
+ validation_issues,
187
+ };
188
+ }
189
+ /**
190
+ * Surface a routed charter delta as a Finding LEAD ([[leads-not-verdicts]] — the
191
+ * owner judges it; a charter delta is never a verdict). `lens` is `architecture`:
192
+ * a charter-boundary gap is a design defect. Members of the subsystem are the
193
+ * affected files (structure decomposition operates over file ids).
194
+ */
195
+ function deltaToFinding(delta, nodeId, members, severity, confidence) {
196
+ const kindLabel = delta.kind.replace(/_/g, " ");
197
+ return {
198
+ id: delta.delta_id,
199
+ title: `Charter delta (${kindLabel}) in subsystem ${nodeId}`,
200
+ category: `charter_delta:${delta.kind}`,
201
+ severity,
202
+ confidence,
203
+ lens: "architecture",
204
+ summary: delta.summary,
205
+ affected_files: members.map((path) => ({ path })),
206
+ systemic: true,
207
+ };
208
+ }
209
+ //# sourceMappingURL=charterExtraction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"charterExtraction.js","sourceRoot":"","sources":["../../../src/shared/decompose/charterExtraction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import type { Partition } from "./modularity.js";
2
+ /**
3
+ * One independently-sourced view of the target, contributing a family of
4
+ * partitions over the shared node universe. A multi-resolution behavior source
5
+ * (call/import, co-change, data/state) supplies several partitions (one per
6
+ * resolution); an intent-declared source (directory, docs, comments) typically
7
+ * supplies one.
8
+ */
9
+ export interface DecompositionSource {
10
+ /** Stable source id, e.g. `call_import` / `co_change` / `directory`. */
11
+ id: string;
12
+ /**
13
+ * Which decomposition family this source belongs to (design §"two families"):
14
+ * `behavior` = what the system does (coupling / co-change / data-state);
15
+ * `intent` = what humans assert the pieces are (dirs / docs / comments). Only
16
+ * `behavior` partitions feed the scale-stability score.
17
+ */
18
+ family: "behavior" | "intent";
19
+ partitions: Partition[];
20
+ }
21
+ /** A discovered subsystem candidate — an emergent node, never pre-defined. */
22
+ export interface DecomposedNode {
23
+ /** Stable id: the lexicographically smallest member. */
24
+ node_id: string;
25
+ /** Member node ids, lexically sorted. */
26
+ members: string[];
27
+ /** Fraction of sources co-locating the members, in [0,1]. */
28
+ agreed_across_source: number;
29
+ /** Fraction of behavior resolution levels co-locating the members, in [0,1]. */
30
+ stable_across_scale: number;
31
+ /** True when low on EITHER score (below the confident bar). */
32
+ contested: boolean;
33
+ }
34
+ export interface DecomposeResult {
35
+ target: string;
36
+ /** Nodes high on BOTH scores — confident subsystems. */
37
+ consensus: DecomposedNode[];
38
+ /** Nodes low on EITHER score — contested boundaries (each a hotspot/finding). */
39
+ contested: DecomposedNode[];
40
+ }
41
+ export interface DecomposeOptions {
42
+ /**
43
+ * Minimum agreed-across-source a pair needs for its members to be unioned into
44
+ * the same candidate node. The co-association edge threshold.
45
+ */
46
+ agreementThreshold?: number;
47
+ /**
48
+ * The "confident" bar: a node is consensus only when BOTH scores meet it.
49
+ */
50
+ confidentThreshold?: number;
51
+ }
52
+ /**
53
+ * Cluster nodes that co-locate in at least `minFraction` of the given partitions
54
+ * (a consensus over the partition family). Returns member groups of size ≥ 2,
55
+ * lexically sorted, in a deterministic order. Shared by {@link decompose} and by
56
+ * the non-co-localization finding detectors, which need behavior-only and
57
+ * intent-only cluster views separately.
58
+ */
59
+ export declare function clustersFromPartitions(partitions: Partition[], minFraction?: number): string[][];
60
+ /**
61
+ * The overlay-and-delta operator. Builds a co-association over all sources,
62
+ * unions strongly-agreed pairs into candidate nodes, scores each node on the two
63
+ * orthogonal robustness axes, and splits confident (consensus) from contested.
64
+ */
65
+ export declare function decompose(sources: DecompositionSource[], target: string, options?: DecomposeOptions): DecomposeResult;
66
+ //# sourceMappingURL=consensus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consensus.d.ts","sourceRoot":"","sources":["../../../src/shared/decompose/consensus.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAED,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6DAA6D;IAC7D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gFAAgF;IAChF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,iFAAiF;IACjF,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAE7B;AA4FD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,SAAS,EAAE,EACvB,WAAW,SAA8B,GACxC,MAAM,EAAE,EAAE,CAeZ;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,GAC7B,eAAe,CAiFjB"}
@@ -0,0 +1,213 @@
1
+ // The overlay-and-delta operator — consensus / ensemble decomposition (Phase B;
2
+ // design of record spec/conceptual-design-review-design.md §"The one operator").
3
+ //
4
+ // decompose(sources, target) → { consensus, contested }
5
+ //
6
+ // Feed several INDEPENDENTLY-SOURCED views of a target; where they AGREE you have
7
+ // a node (a real subsystem boundary), where they DISAGREE you have a finding and a
8
+ // hotspot. The views are NEVER reconciled into one truth — the disagreement is the
9
+ // product. A node carries TWO orthogonal robustness scores (design §"Granularity
10
+ // resolves across scale"):
11
+ // - agreed_across_source: how many independent sources co-locate its members.
12
+ // - stable_across_scale: how many resolution levels (within the behavior graphs'
13
+ // modularity sweep) keep its members together.
14
+ // High on BOTH = a confident subsystem (consensus). Low on EITHER = contested
15
+ // (routed to more adversarial review; the contested status is itself a finding).
16
+ //
17
+ // PURE + DETERMINISTIC + language-neutral: operates only on abstract partitions of
18
+ // string node ids, so the SAME primitive runs at the structure layer (this phase)
19
+ // and, in Phase C, at the charter layer (sources = the four charters). No IO.
20
+ const DEFAULT_AGREEMENT_THRESHOLD = 0.5;
21
+ const DEFAULT_CONFIDENT_THRESHOLD = 0.6;
22
+ /** Canonical unordered-pair key (`minmax`, a text-safe unit separator that
23
+ * cannot appear in a node id) so (u,v) and (v,u) collide. */
24
+ function pairKey(a, b) {
25
+ return a.localeCompare(b) <= 0 ? `${a}\u001f${b}` : `${b}\u001f${a}`;
26
+ }
27
+ function splitPairKey(key) {
28
+ const idx = key.indexOf("\u001f");
29
+ return [key.slice(0, idx), key.slice(idx + 1)];
30
+ }
31
+ /** Minimal deterministic union-find over string ids. */
32
+ class UnionFind {
33
+ parent = new Map();
34
+ find(x) {
35
+ let root = this.parent.get(x);
36
+ if (root === undefined) {
37
+ this.parent.set(x, x);
38
+ return x;
39
+ }
40
+ while (root !== this.parent.get(root)) {
41
+ const grand = this.parent.get(root);
42
+ this.parent.set(root, this.parent.get(grand));
43
+ root = this.parent.get(root);
44
+ }
45
+ return root;
46
+ }
47
+ add(x) {
48
+ if (!this.parent.has(x))
49
+ this.parent.set(x, x);
50
+ }
51
+ union(a, b) {
52
+ const ra = this.find(a);
53
+ const rb = this.find(b);
54
+ if (ra === rb)
55
+ return;
56
+ // Attach the lexically larger root under the smaller so the representative is
57
+ // stable and independent of union order.
58
+ if (ra.localeCompare(rb) < 0)
59
+ this.parent.set(rb, ra);
60
+ else
61
+ this.parent.set(ra, rb);
62
+ }
63
+ groups() {
64
+ const out = new Map();
65
+ for (const node of this.parent.keys()) {
66
+ const root = this.find(node);
67
+ const list = out.get(root);
68
+ if (list)
69
+ list.push(node);
70
+ else
71
+ out.set(root, [node]);
72
+ }
73
+ for (const list of out.values())
74
+ list.sort((a, b) => a.localeCompare(b));
75
+ return out;
76
+ }
77
+ }
78
+ /**
79
+ * Per-pair co-membership counts over a set of partitions. Only pairs that are
80
+ * co-located in at least one partition get an entry (so the result is bounded by
81
+ * Σ|community|² rather than |universe|²). Returns the counts + partition total.
82
+ */
83
+ function coMembershipCounts(partitions) {
84
+ const counts = new Map();
85
+ for (const partition of partitions) {
86
+ // Group nodes by community for this partition.
87
+ const communities = new Map();
88
+ for (const [node, comm] of partition) {
89
+ const list = communities.get(comm);
90
+ if (list)
91
+ list.push(node);
92
+ else
93
+ communities.set(comm, [node]);
94
+ }
95
+ for (const members of communities.values()) {
96
+ if (members.length < 2)
97
+ continue;
98
+ const sorted = [...members].sort((a, b) => a.localeCompare(b));
99
+ for (let i = 0; i < sorted.length; i++) {
100
+ for (let j = i + 1; j < sorted.length; j++) {
101
+ const key = pairKey(sorted[i], sorted[j]);
102
+ counts.set(key, (counts.get(key) ?? 0) + 1);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ return { counts, total: partitions.length };
108
+ }
109
+ /**
110
+ * Cluster nodes that co-locate in at least `minFraction` of the given partitions
111
+ * (a consensus over the partition family). Returns member groups of size ≥ 2,
112
+ * lexically sorted, in a deterministic order. Shared by {@link decompose} and by
113
+ * the non-co-localization finding detectors, which need behavior-only and
114
+ * intent-only cluster views separately.
115
+ */
116
+ export function clustersFromPartitions(partitions, minFraction = DEFAULT_AGREEMENT_THRESHOLD) {
117
+ const { counts, total } = coMembershipCounts(partitions);
118
+ if (total === 0)
119
+ return [];
120
+ const uf = new UnionFind();
121
+ for (const [key, count] of counts) {
122
+ if (count / total + 1e-12 >= minFraction) {
123
+ const [a, b] = splitPairKey(key);
124
+ uf.add(a);
125
+ uf.add(b);
126
+ uf.union(a, b);
127
+ }
128
+ }
129
+ const groups = [...uf.groups().values()].filter((g) => g.length >= 2);
130
+ groups.sort((a, b) => a[0].localeCompare(b[0]));
131
+ return groups;
132
+ }
133
+ /**
134
+ * The overlay-and-delta operator. Builds a co-association over all sources,
135
+ * unions strongly-agreed pairs into candidate nodes, scores each node on the two
136
+ * orthogonal robustness axes, and splits confident (consensus) from contested.
137
+ */
138
+ export function decompose(sources, target, options = {}) {
139
+ const agreementThreshold = options.agreementThreshold ?? DEFAULT_AGREEMENT_THRESHOLD;
140
+ const confidentThreshold = options.confidentThreshold ?? DEFAULT_CONFIDENT_THRESHOLD;
141
+ // agreed-across-source: mean over sources of each source's within-family
142
+ // co-location fraction. Accumulate one source at a time to bound memory.
143
+ const agreedSum = new Map();
144
+ const activeSources = sources.filter((s) => s.partitions.length > 0);
145
+ for (const source of activeSources) {
146
+ const { counts, total } = coMembershipCounts(source.partitions);
147
+ for (const [key, count] of counts) {
148
+ agreedSum.set(key, (agreedSum.get(key) ?? 0) + count / total);
149
+ }
150
+ }
151
+ const numSources = activeSources.length;
152
+ // stable-across-scale: co-location fraction pooled over ALL behavior partitions
153
+ // (every resolution level of every behavior source).
154
+ const behaviorPartitions = activeSources
155
+ .filter((s) => s.family === "behavior")
156
+ .flatMap((s) => s.partitions);
157
+ const { counts: stableCounts, total: behaviorTotal } = coMembershipCounts(behaviorPartitions);
158
+ const agreedOf = (key) => numSources === 0 ? 0 : (agreedSum.get(key) ?? 0) / numSources;
159
+ const stableOf = (key) => behaviorTotal === 0 ? 0 : (stableCounts.get(key) ?? 0) / behaviorTotal;
160
+ // Union strongly-agreed pairs into candidate nodes.
161
+ const uf = new UnionFind();
162
+ for (const key of agreedSum.keys()) {
163
+ if (agreedOf(key) + 1e-12 >= agreementThreshold) {
164
+ const [a, b] = splitPairKey(key);
165
+ uf.add(a);
166
+ uf.add(b);
167
+ uf.union(a, b);
168
+ }
169
+ }
170
+ const consensus = [];
171
+ const contested = [];
172
+ for (const members of uf.groups().values()) {
173
+ if (members.length < 2)
174
+ continue;
175
+ // Node scores = mean over all internal member-pairs (missing pair ⇒ 0), so a
176
+ // loosely-agreed component is penalized on both axes.
177
+ let agreedAcc = 0;
178
+ let stableAcc = 0;
179
+ let pairs = 0;
180
+ for (let i = 0; i < members.length; i++) {
181
+ for (let j = i + 1; j < members.length; j++) {
182
+ const key = pairKey(members[i], members[j]);
183
+ agreedAcc += agreedOf(key);
184
+ stableAcc += stableOf(key);
185
+ pairs += 1;
186
+ }
187
+ }
188
+ const agreed = pairs === 0 ? 0 : agreedAcc / pairs;
189
+ const stable = pairs === 0 ? 0 : stableAcc / pairs;
190
+ const isContested = !(agreed + 1e-12 >= confidentThreshold &&
191
+ stable + 1e-12 >= confidentThreshold);
192
+ const node = {
193
+ node_id: members[0],
194
+ members,
195
+ agreed_across_source: round(agreed),
196
+ stable_across_scale: round(stable),
197
+ contested: isContested,
198
+ };
199
+ if (isContested)
200
+ contested.push(node);
201
+ else
202
+ consensus.push(node);
203
+ }
204
+ const byId = (a, b) => a.node_id.localeCompare(b.node_id);
205
+ consensus.sort(byId);
206
+ contested.sort(byId);
207
+ return { target, consensus, contested };
208
+ }
209
+ /** Round a score to 4 decimals so persisted artifacts don't churn on float noise. */
210
+ function round(value) {
211
+ return Math.round(value * 1e4) / 1e4;
212
+ }
213
+ //# sourceMappingURL=consensus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consensus.js","sourceRoot":"","sources":["../../../src/shared/decompose/consensus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * A weighted undirected graph over string node ids. `edges` are undirected; a
3
+ * repeated {a,b} pair (either orientation) accumulates weight. Self-loops
4
+ * (a === b) are allowed and accounted for in the degree, which matters once
5
+ * communities are aggregated into super-nodes.
6
+ */
7
+ export interface WeightedGraph {
8
+ /** The full node universe (may include nodes with no edges). */
9
+ nodes: string[];
10
+ edges: Array<{
11
+ a: string;
12
+ b: string;
13
+ weight: number;
14
+ }>;
15
+ }
16
+ /**
17
+ * A partition of a node universe: a map from node id to the id of the community
18
+ * it belongs to. Community ids are themselves node ids (the lexicographically
19
+ * smallest member acts as the stable representative).
20
+ */
21
+ export type Partition = Map<string, string>;
22
+ /**
23
+ * Default resolution ladder, coarse→fine. Higher resolution γ penalizes large
24
+ * communities more, yielding more (smaller) communities — so the ladder walks
25
+ * from few coarse subsystems to many fine ones. A boundary present at coarse γ
26
+ * AND fine γ is scale-stable. Chosen as a geometric spread so each rung is a
27
+ * distinct scale rather than a small perturbation of its neighbor.
28
+ */
29
+ export declare const DEFAULT_RESOLUTIONS: readonly number[];
30
+ /**
31
+ * Detect communities in a weighted graph at a single resolution γ via the
32
+ * Louvain method: local-moving then aggregation, repeated until a level stops
33
+ * improving. Returns a flat node→community partition (community ids are the
34
+ * lexicographically smallest member). Deterministic for a given graph + γ.
35
+ */
36
+ export declare function louvain(graph: WeightedGraph, resolution: number): Partition;
37
+ /**
38
+ * Cluster the same graph at every resolution in the ladder, coarse→fine, and
39
+ * return the partitions in ladder order. The multi-resolution family is the
40
+ * input to scale-stability scoring (consensus.ts). Resolutions are applied in
41
+ * the given order; the default ladder is {@link DEFAULT_RESOLUTIONS}.
42
+ */
43
+ export declare function resolutionSweep(graph: WeightedGraph, resolutions?: readonly number[]): Partition[];
44
+ //# sourceMappingURL=modularity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modularity.d.ts","sourceRoot":"","sources":["../../../src/shared/decompose/modularity.ts"],"names":[],"mappings":"AAkBA;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE5C;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAyB,CAAC;AA0N3E;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,CAmC3E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,aAAa,EACpB,WAAW,GAAE,SAAS,MAAM,EAAwB,GACnD,SAAS,EAAE,CAEb"}