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,270 +1,303 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* architecture_verifier.js — Tribunal Zero-Trust Architecture Verifier
|
|
4
|
-
* ═════════════════════════════════════════════════════════════════════════════
|
|
5
|
-
* Evaluates architectural models against ground-truth source code bytes.
|
|
6
|
-
*
|
|
7
|
-
* Capabilities:
|
|
8
|
-
* - Verifies all source citations (file exists, line valid, no path escapes)
|
|
9
|
-
* - Detects Stale Evidence via SHA-256 drift verification
|
|
10
|
-
* - Verifies AST Symbol and Relationship Call Sites
|
|
11
|
-
* - Assigns Epistemic Confidence Levels (L1 to L5)
|
|
12
|
-
* - Surfaces Architectural Contradictions as first-class disputable records
|
|
13
|
-
* - Prevents unverified agent claims from masquerading as verified facts
|
|
14
|
-
*
|
|
15
|
-
* Emits: .agent/history/architecture-verification.json
|
|
16
|
-
* Zero external dependencies.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
'use strict';
|
|
20
|
-
|
|
21
|
-
const fs = require('fs');
|
|
22
|
-
const path = require('path');
|
|
23
|
-
const crypto = require('crypto');
|
|
24
|
-
const { GREEN, YELLOW, CYAN, RED, DIM, RESET, BOX, banner, timer, formatMs } = require('./_colors');
|
|
25
|
-
|
|
26
|
-
function computeSha256(str) {
|
|
27
|
-
return crypto
|
|
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
|
-
this.results.stats.
|
|
73
|
-
this.results.confidenceDistribution['
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this.results.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
this.results.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
if (
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
console.log(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* architecture_verifier.js — Tribunal Zero-Trust Architecture Verifier
|
|
4
|
+
* ═════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
* Evaluates architectural models against ground-truth source code bytes.
|
|
6
|
+
*
|
|
7
|
+
* Capabilities:
|
|
8
|
+
* - Verifies all source citations (file exists, line valid, no path escapes)
|
|
9
|
+
* - Detects Stale Evidence via SHA-256 drift verification
|
|
10
|
+
* - Verifies AST Symbol and Relationship Call Sites
|
|
11
|
+
* - Assigns Epistemic Confidence Levels (L1 to L5)
|
|
12
|
+
* - Surfaces Architectural Contradictions as first-class disputable records
|
|
13
|
+
* - Prevents unverified agent claims from masquerading as verified facts
|
|
14
|
+
*
|
|
15
|
+
* Emits: .agent/history/architecture-verification.json
|
|
16
|
+
* Zero external dependencies.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
'use strict';
|
|
20
|
+
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const crypto = require('crypto');
|
|
24
|
+
const { GREEN, YELLOW, CYAN, RED, DIM, RESET, BOX, banner, timer, formatMs } = require('./_colors');
|
|
25
|
+
|
|
26
|
+
function computeSha256(str) {
|
|
27
|
+
return crypto
|
|
28
|
+
.createHash('sha256')
|
|
29
|
+
.update(str || '')
|
|
30
|
+
.digest('hex');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
class ArchitectureVerifier {
|
|
34
|
+
constructor(repoRoot = process.cwd(), options = {}) {
|
|
35
|
+
this.repoRoot = path.resolve(repoRoot);
|
|
36
|
+
this.options = { strict: false, ...options };
|
|
37
|
+
this.results = {
|
|
38
|
+
verified: true,
|
|
39
|
+
timestamp: new Date().toISOString(),
|
|
40
|
+
stats: {
|
|
41
|
+
totalEntities: 0,
|
|
42
|
+
verifiedEntities: 0,
|
|
43
|
+
staleEntities: 0,
|
|
44
|
+
fabricatedEntities: 0,
|
|
45
|
+
totalRelations: 0,
|
|
46
|
+
verifiedRelations: 0,
|
|
47
|
+
contradictedRelations: 0,
|
|
48
|
+
},
|
|
49
|
+
confidenceDistribution: { L1: 0, L2: 0, L3: 0, L4: 0, L5: 0 },
|
|
50
|
+
contradictions: [],
|
|
51
|
+
diagnostics: [],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
verifyModel(model) {
|
|
56
|
+
if (!model || !Array.isArray(model.entities)) {
|
|
57
|
+
throw new Error('Invalid model: expected an object with entities array.');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const { entities, relationships = [], contradictions = [] } = model;
|
|
61
|
+
this.results.stats.totalEntities = entities.length;
|
|
62
|
+
this.results.stats.totalRelations = relationships.length;
|
|
63
|
+
|
|
64
|
+
// Entity verification map for fast lookup
|
|
65
|
+
const entityIndex = new Map();
|
|
66
|
+
|
|
67
|
+
// 1. Verify Entity Sources & Ground Truth
|
|
68
|
+
for (const entity of entities) {
|
|
69
|
+
entityIndex.set(entity.id, entity);
|
|
70
|
+
const entityVerification = this.verifyEntity(entity);
|
|
71
|
+
if (entityVerification.status === 'verified') {
|
|
72
|
+
this.results.stats.verifiedEntities++;
|
|
73
|
+
this.results.confidenceDistribution[entity.confidence || 'L1']++;
|
|
74
|
+
} else if (entityVerification.status === 'stale') {
|
|
75
|
+
this.results.stats.staleEntities++;
|
|
76
|
+
this.results.confidenceDistribution['L3']++;
|
|
77
|
+
this.results.diagnostics.push({
|
|
78
|
+
severity: 'warning',
|
|
79
|
+
code: 'ARCH_EVIDENCE_STALE',
|
|
80
|
+
entityId: entity.id,
|
|
81
|
+
message: `Evidence has drifted for entity "${entity.name}" (${entity.id}). Content hash does not match.`,
|
|
82
|
+
details: entityVerification.details,
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
this.results.stats.fabricatedEntities++;
|
|
86
|
+
this.results.confidenceDistribution['L5']++;
|
|
87
|
+
this.results.verified = false;
|
|
88
|
+
this.results.diagnostics.push({
|
|
89
|
+
severity: 'error',
|
|
90
|
+
code: 'ARCH_EVIDENCE_FABRICATED',
|
|
91
|
+
entityId: entity.id,
|
|
92
|
+
message: `Evidence does not exist in repository for entity "${entity.name}" (${entity.id}).`,
|
|
93
|
+
details: entityVerification.details,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 2. Verify Relationships & Call Sites
|
|
99
|
+
for (const rel of relationships) {
|
|
100
|
+
const relVerification = this.verifyRelationship(rel, entityIndex);
|
|
101
|
+
if (relVerification.status === 'verified') {
|
|
102
|
+
this.results.stats.verifiedRelations++;
|
|
103
|
+
} else if (relVerification.status === 'contradicted') {
|
|
104
|
+
this.results.stats.contradictedRelations++;
|
|
105
|
+
this.results.verified = false;
|
|
106
|
+
this.results.contradictions.push({
|
|
107
|
+
id: `conflict.${rel.id}`,
|
|
108
|
+
relationshipId: rel.id,
|
|
109
|
+
sourceId: rel.sourceId,
|
|
110
|
+
targetId: rel.targetId,
|
|
111
|
+
conflictType: relVerification.conflictType || 'unreachable_call_path',
|
|
112
|
+
claimedRelation: rel.relationType,
|
|
113
|
+
reason: relVerification.reason,
|
|
114
|
+
confidence: 'L5',
|
|
115
|
+
});
|
|
116
|
+
this.results.diagnostics.push({
|
|
117
|
+
severity: 'error',
|
|
118
|
+
code: 'ARCH_RELATION_CONTRADICTED',
|
|
119
|
+
relationId: rel.id,
|
|
120
|
+
message: `Contradiction detected in relationship ${rel.sourceId} -> ${rel.targetId}: ${relVerification.reason}`,
|
|
121
|
+
});
|
|
122
|
+
} else {
|
|
123
|
+
this.results.diagnostics.push({
|
|
124
|
+
severity: 'warning',
|
|
125
|
+
code: 'ARCH_RELATION_UNVERIFIED',
|
|
126
|
+
relationId: rel.id,
|
|
127
|
+
message: `Relationship ${rel.sourceId} -> ${rel.targetId} lacks direct call-site evidence.`,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 3. Reconcile explicit contradictions passed in model
|
|
133
|
+
for (const c of contradictions) {
|
|
134
|
+
this.results.contradictions.push(c);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return this.results;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
verifyEntity(entity) {
|
|
141
|
+
if (!entity.sources || !entity.sources.length) {
|
|
142
|
+
return { status: 'unverified', details: { reason: 'No sources declared' } };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
let anyStale = false;
|
|
146
|
+
let anyMissing = false;
|
|
147
|
+
|
|
148
|
+
for (const src of entity.sources) {
|
|
149
|
+
const check = this.verifySourceFile(src.file, src.startLine, src.snippet, src.contentHash);
|
|
150
|
+
if (!check.exists) anyMissing = true;
|
|
151
|
+
if (check.stale) anyStale = true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (anyMissing)
|
|
155
|
+
return { status: 'fabricated', details: { reason: 'Cited file or line does not exist' } };
|
|
156
|
+
if (anyStale) return { status: 'stale', details: { reason: 'File content hash has drifted' } };
|
|
157
|
+
return { status: 'verified', details: {} };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
verifyRelationship(rel, entityIndex) {
|
|
161
|
+
const source = entityIndex.get(rel.sourceId);
|
|
162
|
+
const target = entityIndex.get(rel.targetId);
|
|
163
|
+
|
|
164
|
+
if (!source) {
|
|
165
|
+
return {
|
|
166
|
+
status: 'contradicted',
|
|
167
|
+
conflictType: 'missing_source_entity',
|
|
168
|
+
reason: `Source entity ${rel.sourceId} not found.`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (!target) {
|
|
172
|
+
return {
|
|
173
|
+
status: 'contradicted',
|
|
174
|
+
conflictType: 'missing_target_entity',
|
|
175
|
+
reason: `Target entity ${rel.targetId} not found.`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Check evidence call site if present
|
|
180
|
+
if (rel.evidence && rel.evidence.length > 0) {
|
|
181
|
+
for (const ev of rel.evidence) {
|
|
182
|
+
const check = this.verifySourceFile(ev.file, ev.startLine, ev.snippet, ev.contentHash);
|
|
183
|
+
if (!check.exists) {
|
|
184
|
+
return {
|
|
185
|
+
status: 'contradicted',
|
|
186
|
+
conflictType: 'fabricated_call_site',
|
|
187
|
+
reason: `Evidence file ${ev.file} does not exist for relation.`,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return { status: 'verified' };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// If relation is an import or route, check if source imports target
|
|
195
|
+
return { status: 'unverified', reason: 'No call-site evidence' };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
verifySourceFile(relPath, lineNum, expectedSnippet, expectedHash) {
|
|
199
|
+
const fullPath = path.resolve(this.repoRoot, relPath);
|
|
200
|
+
|
|
201
|
+
// Path escape boundary defense
|
|
202
|
+
const normalizedRepo = path.resolve(this.repoRoot);
|
|
203
|
+
if (!fullPath.startsWith(normalizedRepo)) {
|
|
204
|
+
return { exists: false, reason: 'Path traversal escape detected' };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (!fs.existsSync(fullPath)) {
|
|
208
|
+
return { exists: false, reason: 'File does not exist' };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
let content;
|
|
212
|
+
try {
|
|
213
|
+
content = fs.readFileSync(fullPath, 'utf8');
|
|
214
|
+
} catch (_e) {
|
|
215
|
+
return { exists: false, reason: 'File could not be read' };
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const lines = content.split('\n');
|
|
219
|
+
if (lineNum !== undefined && lineNum !== null) {
|
|
220
|
+
if (lineNum < 1 || lineNum > lines.length) {
|
|
221
|
+
return {
|
|
222
|
+
exists: false,
|
|
223
|
+
reason: `Line ${lineNum} out of range (file has ${lines.length} lines)`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (expectedHash) {
|
|
228
|
+
const actualLine = lines[lineNum - 1] || '';
|
|
229
|
+
const actualHash = computeSha256(actualLine).substring(0, 16);
|
|
230
|
+
const actualFileHash = computeSha256(content).substring(0, 16);
|
|
231
|
+
if (actualHash !== expectedHash && actualFileHash !== expectedHash) {
|
|
232
|
+
return { exists: true, stale: true, reason: 'Content hash mismatch' };
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return { exists: true, stale: false };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
saveReport(outputPath) {
|
|
241
|
+
const defaultPath = path.join(
|
|
242
|
+
this.repoRoot,
|
|
243
|
+
'.agent',
|
|
244
|
+
'history',
|
|
245
|
+
'architecture-verification.json',
|
|
246
|
+
);
|
|
247
|
+
const dest = outputPath || defaultPath;
|
|
248
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
249
|
+
fs.writeFileSync(dest, JSON.stringify(this.results, null, 2), 'utf8');
|
|
250
|
+
return dest;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ── Standalone CLI ────────────────────────────────────────────────────────────
|
|
255
|
+
if (require.main === module) {
|
|
256
|
+
const t = timer();
|
|
257
|
+
const repoRoot = process.argv[2] || process.cwd();
|
|
258
|
+
const modelFile = path.join(repoRoot, '.agent', 'history', 'architecture-model.json');
|
|
259
|
+
|
|
260
|
+
console.log(banner('Tribunal Architecture Zero-Trust Verifier'));
|
|
261
|
+
|
|
262
|
+
if (!fs.existsSync(modelFile)) {
|
|
263
|
+
console.error(
|
|
264
|
+
` ${RED}✖ architecture-model.json not found.${RESET} Run architecture_extractor.js first.`,
|
|
265
|
+
);
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const model = JSON.parse(fs.readFileSync(modelFile, 'utf8'));
|
|
270
|
+
const verifier = new ArchitectureVerifier(repoRoot);
|
|
271
|
+
const results = verifier.verifyModel(model);
|
|
272
|
+
const reportPath = verifier.saveReport();
|
|
273
|
+
|
|
274
|
+
const isOk =
|
|
275
|
+
results.verified && results.diagnostics.filter(d => d.severity === 'error').length === 0;
|
|
276
|
+
const statusColor = isOk ? GREEN : RED;
|
|
277
|
+
const statusIcon = isOk ? BOX.check : BOX.cross_mark;
|
|
278
|
+
|
|
279
|
+
console.log(
|
|
280
|
+
` ${statusColor}${statusIcon} Verification ${isOk ? 'PASSED' : 'FLAGGED ISSUES'}${RESET} in ${formatMs(t())}`,
|
|
281
|
+
);
|
|
282
|
+
console.log(
|
|
283
|
+
` ${DIM}Entities Verified:${RESET} ${GREEN}${results.stats.verifiedEntities}${RESET} / ${results.stats.totalEntities}`,
|
|
284
|
+
);
|
|
285
|
+
console.log(
|
|
286
|
+
` ${DIM}Stale Evidence:${RESET} ${results.stats.staleEntities > 0 ? YELLOW : GREEN}${results.stats.staleEntities}${RESET}`,
|
|
287
|
+
);
|
|
288
|
+
console.log(
|
|
289
|
+
` ${DIM}Contradictions Surfaced:${RESET} ${results.contradictions.length > 0 ? RED : GREEN}${results.contradictions.length}${RESET}`,
|
|
290
|
+
);
|
|
291
|
+
console.log(
|
|
292
|
+
` ${DIM}Confidence (L1 Facts):${RESET} ${CYAN}${results.confidenceDistribution.L1}${RESET}`,
|
|
293
|
+
);
|
|
294
|
+
console.log(` ${DIM}Saved Report:${RESET} ${CYAN}${reportPath}${RESET}\n`);
|
|
295
|
+
|
|
296
|
+
if (!isOk && process.argv.includes('--strict')) {
|
|
297
|
+
process.exit(1);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
module.exports = {
|
|
302
|
+
ArchitectureVerifier,
|
|
303
|
+
};
|