tribunal-kit 9.2.6 → 9.2.7
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.
- package/.agent/ARCHITECTURE.md +2 -2
- package/.agent/history/architecture-intelligence.html +1487 -401
- package/.agent/history/architecture-model.json +9365 -5697
- package/.agent/history/architecture-verification.json +37 -9
- package/.agent/routing_index.json +2069 -3340
- package/.agent/rules/GEMINI.md +1 -1
- package/.agent/scripts/adaptive_execution.js +511 -0
- package/.agent/scripts/architecture_diff.js +303 -260
- package/.agent/scripts/architecture_extractor.js +792 -753
- package/.agent/scripts/architecture_health.js +293 -256
- package/.agent/scripts/architecture_intelligence.js +3100 -0
- package/.agent/scripts/architecture_verifier.js +303 -270
- package/.agent/scripts/architecture_visualizer.js +880 -873
- package/.agent/scripts/blast_radius_engine.js +274 -234
- package/.agent/scripts/capability_evolution.js +453 -0
- package/.agent/scripts/concept_extractor.js +240 -0
- package/.agent/scripts/consideration_engine.js +284 -0
- package/.agent/scripts/coverage_engine.js +102 -0
- package/.agent/scripts/cross_domain_engine.js +1883 -0
- package/.agent/scripts/engineering_memory.js +1313 -0
- package/.agent/scripts/integrity_manifest.js +1 -5
- package/.agent/scripts/judgment_engine.js +790 -0
- package/.agent/scripts/materiality_engine.js +251 -0
- package/.agent/scripts/outcome_engine.js +624 -0
- package/.agent/scripts/outcome_optimization_engine.js +1632 -0
- package/.agent/scripts/simulation_engine.js +1478 -0
- package/.agent/scripts/skill_intelligence.js +1371 -0
- package/.agent/scripts/validation_engine.js +236 -236
- package/.agent/scripts/verification_auditor.js +266 -0
- package/.agent/skill-intelligence/taxonomy/engineering-concepts.json +555 -0
- package/.agent/skill_topic_map.json +301 -341
- package/.agent/skills_inventory.json +4272 -6922
- package/.agent/workflows/arch.md +96 -80
- package/.agent/workflows/skill-intelligence.md +216 -0
- package/CONTRIBUTING.md +2 -2
- package/README.md +24 -24
- package/bin/adapter-install.js +1 -1
- package/package.json +8 -9
- package/plugins/core-plugin.json +1 -1
- package/plugins/gemini/extension.json +1 -1
- package/src/browser/index.js +2 -1
- package/src/browser/launcher.js +41 -1
- package/src/cli.js +3 -1
- package/src/commands/arch.js +261 -172
- package/src/commands/context.js +27 -8
- package/src/commands/learn.js +21 -6
- package/src/commands/memory.js +10 -1
- package/src/commands/native.js +12 -3
- package/src/commands/skill-intelligence.js +1165 -0
- package/src/commands/system1.js +105 -4
- package/src/context/ranker.js +337 -339
- package/src/evolution/engine.js +296 -295
- package/src/synthesis/claim_check_separator.js +294 -271
- package/src/system1/browser_intelligence.js +300 -0
- package/src/system1/constants.js +49 -0
- package/src/system1/decision_engine.js +498 -0
- package/src/system1/evidence_engine.js +602 -0
- package/src/system1/evolution_pipeline.js +581 -0
- package/src/system1/index.d.ts +114 -0
- package/src/system1/index.js +102 -0
- package/src/system1/reviewer_orchestrator.js +477 -0
- package/src/tui/banner.js +1 -1
- package/src/utils/fs.js +27 -0
|
@@ -1,256 +1,293 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* architecture_health.js — Tribunal Architectural Health & Risk Auditor
|
|
4
|
-
* ═════════════════════════════════════════════════════════════════════════════
|
|
5
|
-
* Produces explainable architectural signals backed by code evidence.
|
|
6
|
-
* No arbitrary "magic scores" — every signal links directly to source locations.
|
|
7
|
-
*
|
|
8
|
-
* Detects:
|
|
9
|
-
* - Circular Dependencies (Cycles with exact paths)
|
|
10
|
-
* - Single Points of Failure (SPOFs / High Fan-In bottlenecks)
|
|
11
|
-
* - Excessive Coupling (God Modules / High Fan-Out)
|
|
12
|
-
* - Security Trust Boundary Violations (Direct DB access from public routes)
|
|
13
|
-
* - Resilience Deficits (External HTTP calls lacking timeouts/retries)
|
|
14
|
-
* - Test Coverage Gaps on Critical Core Components
|
|
15
|
-
* - Orphaned / Dead Code Components
|
|
16
|
-
*
|
|
17
|
-
* Zero external dependencies.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
'use strict';
|
|
21
|
-
|
|
22
|
-
const fs = require('fs');
|
|
23
|
-
const path = require('path');
|
|
24
|
-
const {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
//
|
|
124
|
-
for (const rel of this.model.relationships || []) {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
//
|
|
145
|
-
for (const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* architecture_health.js — Tribunal Architectural Health & Risk Auditor
|
|
4
|
+
* ═════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
* Produces explainable architectural signals backed by code evidence.
|
|
6
|
+
* No arbitrary "magic scores" — every signal links directly to source locations.
|
|
7
|
+
*
|
|
8
|
+
* Detects:
|
|
9
|
+
* - Circular Dependencies (Cycles with exact paths)
|
|
10
|
+
* - Single Points of Failure (SPOFs / High Fan-In bottlenecks)
|
|
11
|
+
* - Excessive Coupling (God Modules / High Fan-Out)
|
|
12
|
+
* - Security Trust Boundary Violations (Direct DB access from public routes)
|
|
13
|
+
* - Resilience Deficits (External HTTP calls lacking timeouts/retries)
|
|
14
|
+
* - Test Coverage Gaps on Critical Core Components
|
|
15
|
+
* - Orphaned / Dead Code Components
|
|
16
|
+
*
|
|
17
|
+
* Zero external dependencies.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
'use strict';
|
|
21
|
+
|
|
22
|
+
const fs = require('fs');
|
|
23
|
+
const path = require('path');
|
|
24
|
+
const {
|
|
25
|
+
GREEN,
|
|
26
|
+
YELLOW,
|
|
27
|
+
CYAN,
|
|
28
|
+
RED,
|
|
29
|
+
BOLD,
|
|
30
|
+
DIM,
|
|
31
|
+
RESET,
|
|
32
|
+
BOX,
|
|
33
|
+
banner,
|
|
34
|
+
timer,
|
|
35
|
+
formatMs,
|
|
36
|
+
} = require('./_colors');
|
|
37
|
+
|
|
38
|
+
class ArchitectureHealthAuditor {
|
|
39
|
+
constructor(model) {
|
|
40
|
+
this.model = model;
|
|
41
|
+
this.entities = new Map((model.entities || []).map(e => [e.id, e]));
|
|
42
|
+
this.adjList = new Map(); // source -> array of target IDs
|
|
43
|
+
this.inDegree = new Map(); // target -> count
|
|
44
|
+
this.outDegree = new Map(); // source -> count
|
|
45
|
+
|
|
46
|
+
this.initAdjacency();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
initAdjacency() {
|
|
50
|
+
for (const e of this.entities.keys()) {
|
|
51
|
+
this.adjList.set(e, []);
|
|
52
|
+
this.inDegree.set(e, 0);
|
|
53
|
+
this.outDegree.set(e, 0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
for (const rel of this.model.relationships || []) {
|
|
57
|
+
if (this.adjList.has(rel.sourceId)) {
|
|
58
|
+
this.adjList.get(rel.sourceId).push({ targetId: rel.targetId, rel });
|
|
59
|
+
this.outDegree.set(rel.sourceId, (this.outDegree.get(rel.sourceId) || 0) + 1);
|
|
60
|
+
this.inDegree.set(rel.targetId, (this.inDegree.get(rel.targetId) || 0) + 1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
audit() {
|
|
66
|
+
const signals = [];
|
|
67
|
+
|
|
68
|
+
// 1. Detect Circular Dependencies (Tarjan's SCC)
|
|
69
|
+
const cycles = this.findCycles();
|
|
70
|
+
for (const cycle of cycles) {
|
|
71
|
+
const names = cycle.map(id => this.entities.get(id)?.name || id).join(' → ');
|
|
72
|
+
signals.push({
|
|
73
|
+
code: 'ARCH_CIRCULAR_DEPENDENCY',
|
|
74
|
+
severity: 'HIGH',
|
|
75
|
+
category: 'coupling',
|
|
76
|
+
title: 'Circular Dependency Detected',
|
|
77
|
+
message: `Circular dependency loop identified: ${names}`,
|
|
78
|
+
entities: cycle,
|
|
79
|
+
recommendation:
|
|
80
|
+
'Break cycle by inverting dependency, introducing an interface, or extracting common logic.',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 2. Detect Single Points of Failure (High Fan-In Bottlenecks)
|
|
85
|
+
for (const [id, count] of this.inDegree.entries()) {
|
|
86
|
+
const entity = this.entities.get(id);
|
|
87
|
+
if (entity && entity.kind === 'module' && !entity.tags?.includes('skill') && count >= 20) {
|
|
88
|
+
signals.push({
|
|
89
|
+
code: 'ARCH_SINGLE_POINT_OF_FAILURE',
|
|
90
|
+
severity: 'MEDIUM',
|
|
91
|
+
category: 'resilience',
|
|
92
|
+
title: 'High Centrality Bottleneck (SPOF)',
|
|
93
|
+
message: `Component "${entity.name}" has ${count} direct callers. Any breaking change will impact a large portion of the system.`,
|
|
94
|
+
entities: [id],
|
|
95
|
+
recommendation:
|
|
96
|
+
'Ensure 100% unit test coverage, freeze interface contracts, and consider modular partitioning.',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 3. Detect Excessive Coupling (High Fan-Out God Modules)
|
|
102
|
+
for (const [id, count] of this.outDegree.entries()) {
|
|
103
|
+
const entity = this.entities.get(id);
|
|
104
|
+
if (
|
|
105
|
+
entity &&
|
|
106
|
+
entity.kind === 'module' &&
|
|
107
|
+
!entity.tags?.includes('skill') &&
|
|
108
|
+
count >= 15 &&
|
|
109
|
+
!entity.scope.includes('test')
|
|
110
|
+
) {
|
|
111
|
+
signals.push({
|
|
112
|
+
code: 'ARCH_EXCESSIVE_COUPLING',
|
|
113
|
+
severity: 'MEDIUM',
|
|
114
|
+
category: 'architecture_smell',
|
|
115
|
+
title: 'Excessive Fan-Out (God Component)',
|
|
116
|
+
message: `Component "${entity.name}" depends directly on ${count} other modules.`,
|
|
117
|
+
entities: [id],
|
|
118
|
+
recommendation: 'Decompose module into single-responsibility sub-services or handlers.',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 4. Detect Security Boundary Violations (Public to Datastore Direct Call)
|
|
124
|
+
for (const rel of this.model.relationships || []) {
|
|
125
|
+
const src = this.entities.get(rel.sourceId);
|
|
126
|
+
const tgt = this.entities.get(rel.targetId);
|
|
127
|
+
if (src && tgt) {
|
|
128
|
+
if (src.trustZone === 'public_untrusted' && tgt.trustZone === 'isolated_datastore') {
|
|
129
|
+
signals.push({
|
|
130
|
+
code: 'ARCH_SECURITY_BOUNDARY_VIOLATION',
|
|
131
|
+
severity: 'CRITICAL',
|
|
132
|
+
category: 'security',
|
|
133
|
+
title: 'Unauthenticated Public Access to Datastore',
|
|
134
|
+
message: `Public component "${src.name}" directly communicates with isolated datastore "${tgt.name}" without passing through an authenticated service mesh or API gateway.`,
|
|
135
|
+
entities: [src.id, tgt.id],
|
|
136
|
+
evidence: rel.evidence || [],
|
|
137
|
+
recommendation:
|
|
138
|
+
'Route request through authenticated API middleware and isolate direct database connections.',
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 5. Detect Resilience Deficits (External Calls Lacking Timeouts/Circuit Breakers)
|
|
145
|
+
for (const rel of this.model.relationships || []) {
|
|
146
|
+
const tgt = this.entities.get(rel.targetId);
|
|
147
|
+
if (tgt && tgt.kind === 'external_api') {
|
|
148
|
+
const failureMode = rel.failureMode || {};
|
|
149
|
+
if (!failureMode.hasTimeout) {
|
|
150
|
+
const src = this.entities.get(rel.sourceId);
|
|
151
|
+
signals.push({
|
|
152
|
+
code: 'ARCH_MISSING_TIMEOUT',
|
|
153
|
+
severity: 'HIGH',
|
|
154
|
+
category: 'resilience',
|
|
155
|
+
title: 'External API Call Lacks Timeout Protection',
|
|
156
|
+
message: `Component "${src?.name || rel.sourceId}" calls external provider "${tgt.name}" without an explicit timeout or AbortController. Network hangs can exhaust server worker pools.`,
|
|
157
|
+
entities: [rel.sourceId, rel.targetId],
|
|
158
|
+
evidence: rel.evidence || [],
|
|
159
|
+
recommendation:
|
|
160
|
+
'Wrap external call with an AbortSignal.timeout(ms) or circuit breaker.',
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 6. Detect Critical Path Test Coverage Gaps
|
|
167
|
+
for (const [id, entity] of this.entities.entries()) {
|
|
168
|
+
if (
|
|
169
|
+
entity.kind === 'module' &&
|
|
170
|
+
!entity.tags?.includes('skill') &&
|
|
171
|
+
(entity.blastRadius?.riskScore >= 0.7 || this.inDegree.get(id) >= 10)
|
|
172
|
+
) {
|
|
173
|
+
// Check if any test suite imports this entity
|
|
174
|
+
const isTested = Array.from(this.adjList.entries()).some(([srcId, targets]) => {
|
|
175
|
+
const src = this.entities.get(srcId);
|
|
176
|
+
return src && src.kind === 'test_suite' && targets.some(t => t.targetId === id);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
if (!isTested) {
|
|
180
|
+
signals.push({
|
|
181
|
+
code: 'ARCH_CRITICAL_TEST_GAP',
|
|
182
|
+
severity: 'HIGH',
|
|
183
|
+
category: 'testing',
|
|
184
|
+
title: 'Test Coverage Gap on High-Centrality Component',
|
|
185
|
+
message: `Critical component "${entity.name}" (risk score ${entity.blastRadius?.riskScore || 0.8}, ${this.inDegree.get(id)} callers) has no direct test suite coverage in the architecture graph.`,
|
|
186
|
+
entities: [id],
|
|
187
|
+
recommendation:
|
|
188
|
+
'Add unit and integration tests covering the public interfaces of this component.',
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
timestamp: new Date().toISOString(),
|
|
196
|
+
summary: {
|
|
197
|
+
totalSignals: signals.length,
|
|
198
|
+
critical: signals.filter(s => s.severity === 'CRITICAL').length,
|
|
199
|
+
high: signals.filter(s => s.severity === 'HIGH').length,
|
|
200
|
+
medium: signals.filter(s => s.severity === 'MEDIUM').length,
|
|
201
|
+
low: signals.filter(s => s.severity === 'LOW').length,
|
|
202
|
+
},
|
|
203
|
+
signals,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
findCycles() {
|
|
208
|
+
const visited = new Set();
|
|
209
|
+
const recStack = new Set();
|
|
210
|
+
const cycles = [];
|
|
211
|
+
const pathStack = [];
|
|
212
|
+
|
|
213
|
+
const dfs = nodeId => {
|
|
214
|
+
visited.add(nodeId);
|
|
215
|
+
recStack.add(nodeId);
|
|
216
|
+
pathStack.push(nodeId);
|
|
217
|
+
|
|
218
|
+
const neighbors = this.adjList.get(nodeId) || [];
|
|
219
|
+
for (const { targetId } of neighbors) {
|
|
220
|
+
if (!visited.has(targetId)) {
|
|
221
|
+
dfs(targetId);
|
|
222
|
+
} else if (recStack.has(targetId)) {
|
|
223
|
+
// Found cycle
|
|
224
|
+
const cycleStartIndex = pathStack.indexOf(targetId);
|
|
225
|
+
if (cycleStartIndex !== -1) {
|
|
226
|
+
const cycle = pathStack.slice(cycleStartIndex);
|
|
227
|
+
cycles.push([...cycle, targetId]);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
pathStack.pop();
|
|
233
|
+
recStack.delete(nodeId);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
for (const nodeId of this.entities.keys()) {
|
|
237
|
+
if (!visited.has(nodeId)) {
|
|
238
|
+
dfs(nodeId);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return cycles;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// ── Standalone CLI ────────────────────────────────────────────────────────────
|
|
247
|
+
if (require.main === module) {
|
|
248
|
+
const t = timer();
|
|
249
|
+
const repoRoot = process.cwd();
|
|
250
|
+
const modelFile = path.join(repoRoot, '.agent', 'history', 'architecture-model.json');
|
|
251
|
+
|
|
252
|
+
console.log(banner('Tribunal Architectural Health & Risk Auditor'));
|
|
253
|
+
|
|
254
|
+
if (!fs.existsSync(modelFile)) {
|
|
255
|
+
console.error(
|
|
256
|
+
` ${RED}✖ architecture-model.json not found.${RESET} Run architecture_extractor.js first.`,
|
|
257
|
+
);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const model = JSON.parse(fs.readFileSync(modelFile, 'utf8'));
|
|
262
|
+
const auditor = new ArchitectureHealthAuditor(model);
|
|
263
|
+
const report = auditor.audit();
|
|
264
|
+
|
|
265
|
+
console.log(` Signals Found: ${report.summary.totalSignals}`);
|
|
266
|
+
console.log(
|
|
267
|
+
` Critical Violations: ${report.summary.critical > 0 ? RED : GREEN}${report.summary.critical}${RESET}`,
|
|
268
|
+
);
|
|
269
|
+
console.log(
|
|
270
|
+
` High Risk Issues: ${report.summary.high > 0 ? YELLOW : GREEN}${report.summary.high}${RESET}`,
|
|
271
|
+
);
|
|
272
|
+
console.log(
|
|
273
|
+
` Medium Smells: ${report.summary.medium > 0 ? CYAN : GREEN}${report.summary.medium}${RESET}`,
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
if (report.signals.length > 0) {
|
|
277
|
+
console.log(`\n ${BOLD}Top Architectural Signals:${RESET}`);
|
|
278
|
+
for (const s of report.signals.slice(0, 8)) {
|
|
279
|
+
const color = s.severity === 'CRITICAL' ? RED : s.severity === 'HIGH' ? YELLOW : CYAN;
|
|
280
|
+
console.log(` ${color}[${s.severity}]${RESET} ${BOLD}${s.title}${RESET}`);
|
|
281
|
+
console.log(` ${DIM}${s.message}${RESET}`);
|
|
282
|
+
console.log(` ${GREEN}Fix:${RESET} ${s.recommendation}\n`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
console.log(
|
|
287
|
+
` ${GREEN}${BOX.check} Architectural Health Audit Complete${RESET} in ${formatMs(t())}\n`,
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
module.exports = {
|
|
292
|
+
ArchitectureHealthAuditor,
|
|
293
|
+
};
|