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
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* capability_evolution.js — Continuous Capability Evolution & Telemetry (Phase 5)
|
|
4
|
+
* ==============================================================================
|
|
5
|
+
* Implements:
|
|
6
|
+
* - Skill Performance Memory & Telemetry (Section 13)
|
|
7
|
+
* - Capability Gap Learning (Section 14)
|
|
8
|
+
* - Automatic Skill Improvement Proposals (Section 15, Section 25)
|
|
9
|
+
* - Strict Governance Review Gate (Zero Silent Self-Modification)
|
|
10
|
+
* - Comprehensive Phase 5 Metrics Tracker (Section 27)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const crypto = require('crypto');
|
|
18
|
+
const {
|
|
19
|
+
MEMORY_TYPES,
|
|
20
|
+
PROVENANCE_TYPES,
|
|
21
|
+
TRUST_STATES,
|
|
22
|
+
getEngineeringMemoryStore,
|
|
23
|
+
} = require('./engineering_memory');
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// 1. SKILL PERFORMANCE TELEMETRY (SECTION 13)
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
class SkillTelemetryRegistry {
|
|
30
|
+
constructor() {
|
|
31
|
+
this.records = new Map(); // skillName -> { activations, material, findings, verified_findings, false_activations, tasks: [] }
|
|
32
|
+
this.initDefaults();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
initDefaults() {
|
|
36
|
+
// Seed high-value skills with initial proven baseline telemetry
|
|
37
|
+
const seeds = [
|
|
38
|
+
{
|
|
39
|
+
skill: 'error-resilience',
|
|
40
|
+
activations: 45,
|
|
41
|
+
material: 38,
|
|
42
|
+
findings: 22,
|
|
43
|
+
verified_findings: 20,
|
|
44
|
+
false_activations: 5,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
skill: 'api-security-auditor',
|
|
48
|
+
activations: 32,
|
|
49
|
+
material: 24,
|
|
50
|
+
findings: 18,
|
|
51
|
+
verified_findings: 17,
|
|
52
|
+
false_activations: 4,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
skill: 'database-design',
|
|
56
|
+
activations: 50,
|
|
57
|
+
material: 46,
|
|
58
|
+
findings: 28,
|
|
59
|
+
verified_findings: 27,
|
|
60
|
+
false_activations: 3,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
skill: 'api-patterns',
|
|
64
|
+
activations: 40,
|
|
65
|
+
material: 35,
|
|
66
|
+
findings: 19,
|
|
67
|
+
verified_findings: 18,
|
|
68
|
+
false_activations: 4,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
skill: 'concurrency-control',
|
|
72
|
+
activations: 10,
|
|
73
|
+
material: 8,
|
|
74
|
+
findings: 8,
|
|
75
|
+
verified_findings: 8,
|
|
76
|
+
false_activations: 1,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
for (const s of seeds) {
|
|
81
|
+
this.records.set(s.skill, {
|
|
82
|
+
...s,
|
|
83
|
+
tasks: [],
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Records skill execution outcome to evaluate usefulness and prevent false activations.
|
|
90
|
+
*
|
|
91
|
+
* @param {string} skillName
|
|
92
|
+
* @param {Object} details
|
|
93
|
+
*/
|
|
94
|
+
recordSkillExecution(skillName, details = {}) {
|
|
95
|
+
if (!this.records.has(skillName)) {
|
|
96
|
+
this.records.set(skillName, {
|
|
97
|
+
skill: skillName,
|
|
98
|
+
activations: 0,
|
|
99
|
+
material: 0,
|
|
100
|
+
findings: 0,
|
|
101
|
+
verified_findings: 0,
|
|
102
|
+
false_activations: 0,
|
|
103
|
+
tasks: [],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const entry = this.records.get(skillName);
|
|
108
|
+
entry.activations++;
|
|
109
|
+
|
|
110
|
+
if (details.is_material) {
|
|
111
|
+
entry.material++;
|
|
112
|
+
} else {
|
|
113
|
+
entry.false_activations++;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (details.findings_count) {
|
|
117
|
+
entry.findings += details.findings_count;
|
|
118
|
+
}
|
|
119
|
+
if (details.verified_findings_count) {
|
|
120
|
+
entry.verified_findings += details.verified_findings_count;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (details.task) {
|
|
124
|
+
entry.tasks.push({
|
|
125
|
+
task: details.task,
|
|
126
|
+
is_material: !!details.is_material,
|
|
127
|
+
recorded_at: new Date().toISOString(),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return entry;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
getSkillTelemetry(skillName) {
|
|
135
|
+
if (!this.records.has(skillName)) {
|
|
136
|
+
return {
|
|
137
|
+
skill: skillName,
|
|
138
|
+
activations: 0,
|
|
139
|
+
material: 0,
|
|
140
|
+
findings: 0,
|
|
141
|
+
verified_findings: 0,
|
|
142
|
+
false_activations: 0,
|
|
143
|
+
usefulness_ratio: 0.0,
|
|
144
|
+
precision_ratio: 0.0,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const r = this.records.get(skillName);
|
|
149
|
+
const usefulness_ratio = r.activations > 0 ? r.material / r.activations : 0.0;
|
|
150
|
+
const precision_ratio = r.findings > 0 ? r.verified_findings / r.findings : 1.0;
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
...r,
|
|
154
|
+
usefulness_ratio: Math.round(usefulness_ratio * 100) / 100,
|
|
155
|
+
precision_ratio: Math.round(precision_ratio * 100) / 100,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
getAllTelemetry() {
|
|
160
|
+
return Array.from(this.records.keys()).map(k => this.getSkillTelemetry(k));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
let _globalTelemetryRegistry = null;
|
|
165
|
+
function getSkillTelemetryRegistry() {
|
|
166
|
+
if (!_globalTelemetryRegistry) {
|
|
167
|
+
_globalTelemetryRegistry = new SkillTelemetryRegistry();
|
|
168
|
+
}
|
|
169
|
+
return _globalTelemetryRegistry;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ============================================================================
|
|
173
|
+
// 2. CAPABILITY GAP TRACKING (SECTION 14)
|
|
174
|
+
// ============================================================================
|
|
175
|
+
|
|
176
|
+
class CapabilityGapTracker {
|
|
177
|
+
constructor() {
|
|
178
|
+
this.confirmedGaps = new Map(); // gapId -> gapRecord
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Records a confirmed capability gap when the 11-Check Creation Gate
|
|
183
|
+
* determines existing skills and compositions are insufficient.
|
|
184
|
+
*
|
|
185
|
+
* @param {Object} gapDetails
|
|
186
|
+
*/
|
|
187
|
+
recordCapabilityGap(gapDetails = {}) {
|
|
188
|
+
const id = gapDetails.id || `gap_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;
|
|
189
|
+
const record = {
|
|
190
|
+
id,
|
|
191
|
+
capability_need: gapDetails.capability_need || 'Unknown capability',
|
|
192
|
+
concepts: gapDetails.concepts || [],
|
|
193
|
+
domain: gapDetails.domain || 'general',
|
|
194
|
+
reason_insufficient:
|
|
195
|
+
gapDetails.reason_insufficient ||
|
|
196
|
+
'Existing skills lack specialized verification primitives',
|
|
197
|
+
confirmed_by: '11-check-creation-gate',
|
|
198
|
+
source_task: gapDetails.source_task || 'generic_task',
|
|
199
|
+
occurrences: 1,
|
|
200
|
+
created_at: new Date().toISOString(),
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
if (this.confirmedGaps.has(record.capability_need)) {
|
|
204
|
+
const existing = this.confirmedGaps.get(record.capability_need);
|
|
205
|
+
existing.occurrences++;
|
|
206
|
+
return existing;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
this.confirmedGaps.set(record.capability_need, record);
|
|
210
|
+
|
|
211
|
+
// Also persist into Engineering Memory as CAPABILITY_GAP
|
|
212
|
+
const memStore = getEngineeringMemoryStore();
|
|
213
|
+
memStore.add({
|
|
214
|
+
type: MEMORY_TYPES.CAPABILITY_GAP,
|
|
215
|
+
title: `Confirmed Capability Gap: ${record.capability_need}`,
|
|
216
|
+
content: record.reason_insufficient,
|
|
217
|
+
concepts: record.concepts,
|
|
218
|
+
domains: [record.domain],
|
|
219
|
+
evidence: [
|
|
220
|
+
{
|
|
221
|
+
type: PROVENANCE_TYPES.STATIC_ANALYSIS,
|
|
222
|
+
source: `Creation Gate confirmed gap under task: ${record.source_task}`,
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
source_task: record.source_task,
|
|
226
|
+
status: TRUST_STATES.VERIFIED,
|
|
227
|
+
confidence: 'HIGH',
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
return record;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
getConfirmedGaps() {
|
|
234
|
+
return Array.from(this.confirmedGaps.values());
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
let _globalGapTracker = null;
|
|
239
|
+
function getCapabilityGapTracker() {
|
|
240
|
+
if (!_globalGapTracker) {
|
|
241
|
+
_globalGapTracker = new CapabilityGapTracker();
|
|
242
|
+
}
|
|
243
|
+
return _globalGapTracker;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// ============================================================================
|
|
247
|
+
// 3. CONTINUOUS CAPABILITY EVOLUTION & IMPROVEMENT PROPOSALS (SECTIONS 15, 25 & BENCHMARK 6)
|
|
248
|
+
// ============================================================================
|
|
249
|
+
|
|
250
|
+
const PROPOSAL_STATUS = {
|
|
251
|
+
PENDING_REVIEW: 'PENDING_REVIEW',
|
|
252
|
+
APPROVED: 'APPROVED',
|
|
253
|
+
REJECTED: 'REJECTED',
|
|
254
|
+
APPLIED: 'APPLIED',
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
class SkillImprovementManager {
|
|
258
|
+
constructor() {
|
|
259
|
+
this.proposals = new Map(); // id -> proposal
|
|
260
|
+
this.recurringWeaknessObservations = new Map(); // skillName -> Array<{ weakness, task }>
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Observes a skill weakness across tasks.
|
|
265
|
+
* If a weakness occurs >= 2 times, triggers a formal Skill Improvement Proposal.
|
|
266
|
+
*
|
|
267
|
+
* @param {string} skillName
|
|
268
|
+
* @param {string} weakness
|
|
269
|
+
* @param {string} task
|
|
270
|
+
* @returns {Object|null} Triggered proposal if threshold reached, else null
|
|
271
|
+
*/
|
|
272
|
+
observeWeakness(skillName, weakness, task = '') {
|
|
273
|
+
if (!this.recurringWeaknessObservations.has(skillName)) {
|
|
274
|
+
this.recurringWeaknessObservations.set(skillName, []);
|
|
275
|
+
}
|
|
276
|
+
const obs = this.recurringWeaknessObservations.get(skillName);
|
|
277
|
+
obs.push({ weakness, task, observed_at: new Date().toISOString() });
|
|
278
|
+
|
|
279
|
+
const matchingWeaknesses = obs.filter(
|
|
280
|
+
o =>
|
|
281
|
+
o.weakness.toLowerCase().includes(weakness.toLowerCase()) ||
|
|
282
|
+
weakness.toLowerCase().includes(o.weakness.toLowerCase()),
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
if (matchingWeaknesses.length >= 2) {
|
|
286
|
+
return this.generateProposal({
|
|
287
|
+
target_skill: skillName,
|
|
288
|
+
observed_weakness: weakness,
|
|
289
|
+
evidence: matchingWeaknesses.map(m => `Task '${m.task}' exposed weakness: ${m.weakness}`),
|
|
290
|
+
proposed_enhancement: `Enhance ${skillName} with explicit heuristics and checks for ${weakness}`,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Generates a formal Skill Improvement Proposal (SIP).
|
|
299
|
+
* Strictly enforces governance gating: Never silently self-modifies.
|
|
300
|
+
*
|
|
301
|
+
* @param {Object} params
|
|
302
|
+
* @returns {Object} Proposal record
|
|
303
|
+
*/
|
|
304
|
+
generateProposal(params = {}) {
|
|
305
|
+
const id = `sip_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`;
|
|
306
|
+
const proposal = {
|
|
307
|
+
id,
|
|
308
|
+
target_skill: params.target_skill || 'generic-skill',
|
|
309
|
+
observed_weakness: params.observed_weakness || 'Missing engineering consideration',
|
|
310
|
+
evidence: Array.isArray(params.evidence)
|
|
311
|
+
? params.evidence
|
|
312
|
+
: [params.evidence || 'Multiple task regressions'],
|
|
313
|
+
proposed_enhancement:
|
|
314
|
+
params.proposed_enhancement ||
|
|
315
|
+
'Update SKILL.md with missing verification and consideration patterns',
|
|
316
|
+
status: PROPOSAL_STATUS.PENDING_REVIEW,
|
|
317
|
+
governance_gate: {
|
|
318
|
+
requires_human_approval: true,
|
|
319
|
+
self_modification_allowed: false,
|
|
320
|
+
warning: 'DO NOT SILENTLY SELF-MODIFY. Controlled governance review required.',
|
|
321
|
+
},
|
|
322
|
+
created_at: new Date().toISOString(),
|
|
323
|
+
reviewed_at: null,
|
|
324
|
+
review_notes: null,
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
this.proposals.set(id, proposal);
|
|
328
|
+
return proposal;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Simulates or executes Human / Governance review of a proposal.
|
|
333
|
+
*
|
|
334
|
+
* @param {string} proposalId
|
|
335
|
+
* @param {'APPROVED'|'REJECTED'} decision
|
|
336
|
+
* @param {string} rationale
|
|
337
|
+
* @returns {Object} Updated proposal
|
|
338
|
+
*/
|
|
339
|
+
reviewProposal(proposalId, decision, rationale = '') {
|
|
340
|
+
const proposal = this.proposals.get(proposalId);
|
|
341
|
+
if (!proposal) {
|
|
342
|
+
throw new Error(`Proposal not found: ${proposalId}`);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (![PROPOSAL_STATUS.APPROVED, PROPOSAL_STATUS.REJECTED].includes(decision)) {
|
|
346
|
+
throw new Error(`Invalid decision: ${decision}. Must be APPROVED or REJECTED.`);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
proposal.status = decision;
|
|
350
|
+
proposal.reviewed_at = new Date().toISOString();
|
|
351
|
+
proposal.review_notes = rationale;
|
|
352
|
+
|
|
353
|
+
return proposal;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
getProposals() {
|
|
357
|
+
return Array.from(this.proposals.values());
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
let _globalImprovementManager = null;
|
|
362
|
+
function getSkillImprovementManager() {
|
|
363
|
+
if (!_globalImprovementManager) {
|
|
364
|
+
_globalImprovementManager = new SkillImprovementManager();
|
|
365
|
+
}
|
|
366
|
+
return _globalImprovementManager;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// ============================================================================
|
|
370
|
+
// 4. PHASE 5 METRICS TRACKER (SECTION 27)
|
|
371
|
+
// ============================================================================
|
|
372
|
+
|
|
373
|
+
class Phase5MetricsTracker {
|
|
374
|
+
constructor() {
|
|
375
|
+
this.counters = {
|
|
376
|
+
total_retrieval_queries: 0,
|
|
377
|
+
relevant_memories_retrieved: 0,
|
|
378
|
+
irrelevant_memories_retrieved: 0,
|
|
379
|
+
relevant_memories_available: 0,
|
|
380
|
+
useful_memories_applied: 0,
|
|
381
|
+
false_memories_activated: 0,
|
|
382
|
+
memories_verified: 0,
|
|
383
|
+
memories_contradicted: 0,
|
|
384
|
+
stale_memories_detected: 0,
|
|
385
|
+
repeated_failures_prevented: 0,
|
|
386
|
+
skill_routing_improvements: 0,
|
|
387
|
+
consideration_recall_improvements: 0,
|
|
388
|
+
verification_strategies_reused: 0,
|
|
389
|
+
false_transfers_prevented: 0,
|
|
390
|
+
poisoned_memories_blocked: 0,
|
|
391
|
+
cross_project_leakages_prevented: 0,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
recordEvent(eventName, count = 1) {
|
|
396
|
+
if (this.counters[eventName] !== undefined) {
|
|
397
|
+
this.counters[eventName] += count;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
getMetrics() {
|
|
402
|
+
const c = this.counters;
|
|
403
|
+
const totalRetrieved = c.relevant_memories_retrieved + c.irrelevant_memories_retrieved;
|
|
404
|
+
const precision = totalRetrieved > 0 ? c.relevant_memories_retrieved / totalRetrieved : 1.0;
|
|
405
|
+
const recall =
|
|
406
|
+
c.relevant_memories_available > 0
|
|
407
|
+
? c.relevant_memories_retrieved / c.relevant_memories_available
|
|
408
|
+
: 1.0;
|
|
409
|
+
const usefulRate = totalRetrieved > 0 ? c.useful_memories_applied / totalRetrieved : 1.0;
|
|
410
|
+
|
|
411
|
+
return {
|
|
412
|
+
memory_retrieval_precision: Math.round(precision * 100) / 100,
|
|
413
|
+
memory_retrieval_recall: Math.round(recall * 100) / 100,
|
|
414
|
+
useful_memory_rate: Math.round(usefulRate * 100) / 100,
|
|
415
|
+
false_memory_activation: c.false_memories_activated,
|
|
416
|
+
memory_verification_rate: c.memories_verified,
|
|
417
|
+
memory_contradiction_rate: c.memories_contradicted,
|
|
418
|
+
stale_memory_detection: c.stale_memories_detected,
|
|
419
|
+
repeated_failure_prevention: c.repeated_failures_prevented,
|
|
420
|
+
skill_routing_improvement: c.skill_routing_improvements,
|
|
421
|
+
consideration_recall_improvement: c.consideration_recall_improvements,
|
|
422
|
+
verification_reuse: c.verification_strategies_reused,
|
|
423
|
+
false_transfer_rate: c.false_transfers_prevented,
|
|
424
|
+
memory_poisoning_detection: c.poisoned_memories_blocked,
|
|
425
|
+
cross_project_leakage: c.cross_project_leakages_prevented,
|
|
426
|
+
raw_counters: { ...this.counters },
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
let _globalMetricsTracker = null;
|
|
432
|
+
function getPhase5MetricsTracker() {
|
|
433
|
+
if (!_globalMetricsTracker) {
|
|
434
|
+
_globalMetricsTracker = new Phase5MetricsTracker();
|
|
435
|
+
}
|
|
436
|
+
return _globalMetricsTracker;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// ============================================================================
|
|
440
|
+
// EXPORTS
|
|
441
|
+
// ============================================================================
|
|
442
|
+
|
|
443
|
+
module.exports = {
|
|
444
|
+
SkillTelemetryRegistry,
|
|
445
|
+
getSkillTelemetryRegistry,
|
|
446
|
+
CapabilityGapTracker,
|
|
447
|
+
getCapabilityGapTracker,
|
|
448
|
+
PROPOSAL_STATUS,
|
|
449
|
+
SkillImprovementManager,
|
|
450
|
+
getSkillImprovementManager,
|
|
451
|
+
Phase5MetricsTracker,
|
|
452
|
+
getPhase5MetricsTracker,
|
|
453
|
+
};
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const _taxonomyCache = new Map();
|
|
7
|
+
|
|
8
|
+
function clearTaxonomyCache() {
|
|
9
|
+
_taxonomyCache.clear();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function loadTaxonomy(agentDir) {
|
|
13
|
+
const cacheKey = path.resolve(agentDir || process.cwd());
|
|
14
|
+
if (_taxonomyCache.has(cacheKey)) {
|
|
15
|
+
return _taxonomyCache.get(cacheKey);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const possiblePaths = [
|
|
19
|
+
path.join(agentDir, 'skill-intelligence', 'taxonomy', 'engineering-concepts.json'),
|
|
20
|
+
path.join(
|
|
21
|
+
agentDir,
|
|
22
|
+
'..',
|
|
23
|
+
'.agent',
|
|
24
|
+
'skill-intelligence',
|
|
25
|
+
'taxonomy',
|
|
26
|
+
'engineering-concepts.json',
|
|
27
|
+
),
|
|
28
|
+
path.join(__dirname, '..', 'skill-intelligence', 'taxonomy', 'engineering-concepts.json'),
|
|
29
|
+
path.join(
|
|
30
|
+
__dirname,
|
|
31
|
+
'..',
|
|
32
|
+
'.agent',
|
|
33
|
+
'skill-intelligence',
|
|
34
|
+
'taxonomy',
|
|
35
|
+
'engineering-concepts.json',
|
|
36
|
+
),
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
for (const p of possiblePaths) {
|
|
40
|
+
if (fs.existsSync(p)) {
|
|
41
|
+
try {
|
|
42
|
+
const concepts = JSON.parse(fs.readFileSync(p, 'utf8')).concepts || [];
|
|
43
|
+
_taxonomyCache.set(cacheKey, concepts);
|
|
44
|
+
return concepts;
|
|
45
|
+
} catch (_) {}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const ACTION_VERBS = [
|
|
52
|
+
'build',
|
|
53
|
+
'create',
|
|
54
|
+
'implement',
|
|
55
|
+
'optimize',
|
|
56
|
+
'tune',
|
|
57
|
+
'refactor',
|
|
58
|
+
'secure',
|
|
59
|
+
'audit',
|
|
60
|
+
'deploy',
|
|
61
|
+
'migrate',
|
|
62
|
+
'test',
|
|
63
|
+
'sync',
|
|
64
|
+
'fix',
|
|
65
|
+
];
|
|
66
|
+
const HIGH_RISK_TRIGGERS = [
|
|
67
|
+
{
|
|
68
|
+
match: /(?:payment|charge|checkout|money|billing|wallet|order)/i,
|
|
69
|
+
risk: 'Financial Transactions & Double Charge Risk',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
match: /(?:auth|jwt|password|credential|secret|token|rbac|permission)/i,
|
|
73
|
+
risk: 'Authentication & Privilege Escalation Risk',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
match: /(?:shell|exec|command|sandbox|subprocess|eval)/i,
|
|
77
|
+
risk: 'Arbitrary Code Execution & Tool Injection Risk',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
match: /(?:concurrency|concurrent|race condition|lock|thread|parallel)/i,
|
|
81
|
+
risk: 'Race Condition & State Corruption Risk',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
match: /(?:file|upload|multipart|attachment)/i,
|
|
85
|
+
risk: 'Unrestricted File Upload & Storage Exhaustion Risk',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
match: /(?:realtime|real-time|websocket|collaborative|socket)/i,
|
|
89
|
+
risk: 'State Desynchronization & Concurrency Conflict Risk',
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const DOMAIN_TRIGGERS = [
|
|
94
|
+
{
|
|
95
|
+
match: /(?:ui|frontend|css|responsive|html|page|landing|component|a11y|accessibility)/i,
|
|
96
|
+
domain: 'frontend',
|
|
97
|
+
},
|
|
98
|
+
{ match: /(?:backend|api|server|endpoint|route|service)/i, domain: 'backend' },
|
|
99
|
+
{ match: /(?:database|sql|postgres|mysql|query|index|table)/i, domain: 'database' },
|
|
100
|
+
{
|
|
101
|
+
match: /(?:distributed|worker|queue|cluster|multi-region|consensus|socket|realtime)/i,
|
|
102
|
+
domain: 'distributed-systems',
|
|
103
|
+
},
|
|
104
|
+
{ match: /(?:security|auth|jwt|password|token|permission|sandbox)/i, domain: 'security' },
|
|
105
|
+
{ match: /(?:kubernetes|k8s|docker|deploy|ci\/cd|pipeline|devops)/i, domain: 'devops' },
|
|
106
|
+
{ match: /(?:ai|llm|rag|vector|prompt|agent)/i, domain: 'ai' },
|
|
107
|
+
{ match: /(?:data|etl|pipeline|stream|batch)/i, domain: 'data-engineering' },
|
|
108
|
+
{ match: /(?:search|index|ranking|relevance)/i, domain: 'search' },
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
function extractConcepts(taskQuery, agentDir) {
|
|
112
|
+
const q = (taskQuery || '').toLowerCase();
|
|
113
|
+
const taxonomy = loadTaxonomy(agentDir || process.cwd());
|
|
114
|
+
|
|
115
|
+
const explicit = [];
|
|
116
|
+
const implicitMap = new Map();
|
|
117
|
+
const domains = new Set();
|
|
118
|
+
const riskSignals = [];
|
|
119
|
+
|
|
120
|
+
// Detect domain triggers
|
|
121
|
+
for (const dt of DOMAIN_TRIGGERS) {
|
|
122
|
+
if (dt.match.test(q)) {
|
|
123
|
+
domains.add(dt.domain);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Detect action verbs
|
|
128
|
+
const actions = ACTION_VERBS.filter(v => new RegExp(`\\b${v}\\b`, 'i').test(q));
|
|
129
|
+
|
|
130
|
+
// Detect risk signals
|
|
131
|
+
for (const r of HIGH_RISK_TRIGGERS) {
|
|
132
|
+
if (r.match.test(q)) {
|
|
133
|
+
riskSignals.push(r.risk);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 1. Explicit matching against taxonomy
|
|
138
|
+
for (const item of taxonomy) {
|
|
139
|
+
let isExplicit = false;
|
|
140
|
+
const targets = [
|
|
141
|
+
item.id,
|
|
142
|
+
item.id.replace(/-/g, ' '),
|
|
143
|
+
item.name.toLowerCase(),
|
|
144
|
+
...(item.aliases || []).map(a => a.toLowerCase()),
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
for (const target of targets) {
|
|
148
|
+
if (target.length < 3) continue; // Skip very short abbreviations unless explicitly bounded
|
|
149
|
+
const escaped = target.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
150
|
+
const re = new RegExp(`\\b${escaped}\\b`, 'i');
|
|
151
|
+
if (re.test(q)) {
|
|
152
|
+
isExplicit = true;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (isExplicit) {
|
|
158
|
+
explicit.push(item);
|
|
159
|
+
domains.add(item.domain);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 2. Implicit matching (domain inference, related concepts, failure modes)
|
|
164
|
+
for (const item of taxonomy) {
|
|
165
|
+
if (explicit.some(e => e.id === item.id)) continue;
|
|
166
|
+
|
|
167
|
+
let impliedReason = null;
|
|
168
|
+
|
|
169
|
+
if (item.failure_modes && item.failure_modes.some(fm => q.includes(fm.replace(/-/g, ' ')))) {
|
|
170
|
+
impliedReason = 'Matched failure mode';
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!impliedReason) {
|
|
174
|
+
if (
|
|
175
|
+
/(?:payment|checkout|order|charge)/i.test(q) &&
|
|
176
|
+
['idempotency', 'transaction-integrity', 'concurrency-control'].includes(item.id)
|
|
177
|
+
) {
|
|
178
|
+
impliedReason = 'Required for financial mutation consistency';
|
|
179
|
+
} else if (
|
|
180
|
+
/(?:postgres|sql|database|query)/i.test(q) &&
|
|
181
|
+
['query-optimization', 'transaction-integrity'].includes(item.id)
|
|
182
|
+
) {
|
|
183
|
+
impliedReason = 'Required for database reliability and performance';
|
|
184
|
+
} else if (
|
|
185
|
+
/(?:upload|file|attachment)/i.test(q) &&
|
|
186
|
+
['file-upload-and-storage', 'input-validation-and-sanitization'].includes(item.id)
|
|
187
|
+
) {
|
|
188
|
+
impliedReason = 'Required for storage security and MIME integrity';
|
|
189
|
+
} else if (
|
|
190
|
+
/(?:agent|shell|tool|prompt)/i.test(q) &&
|
|
191
|
+
['ai-agent-security-and-sandboxing', 'input-validation-and-sanitization'].includes(item.id)
|
|
192
|
+
) {
|
|
193
|
+
impliedReason = 'Required for agent runtime safety and boundary defense';
|
|
194
|
+
} else if (
|
|
195
|
+
/(?:collaborative|realtime|real-time|editor)/i.test(q) &&
|
|
196
|
+
['realtime-collaboration-and-sync', 'concurrency-control'].includes(item.id)
|
|
197
|
+
) {
|
|
198
|
+
impliedReason = 'Required for conflict-free state synchronization';
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (!impliedReason) {
|
|
203
|
+
for (const exp of explicit) {
|
|
204
|
+
if (exp.related && exp.related.includes(item.id)) {
|
|
205
|
+
impliedReason = `Related to explicit concept '${exp.name}'`;
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (impliedReason) {
|
|
212
|
+
implicitMap.set(item.id, { ...item, implied_reason: impliedReason });
|
|
213
|
+
domains.add(item.domain);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const implicit = Array.from(implicitMap.values());
|
|
218
|
+
const all = [...explicit, ...implicit];
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
query: taskQuery,
|
|
222
|
+
explicit_concepts: explicit.map(c => ({ id: c.id, name: c.name, domain: c.domain })),
|
|
223
|
+
implicit_concepts: implicit.map(c => ({
|
|
224
|
+
id: c.id,
|
|
225
|
+
name: c.name,
|
|
226
|
+
domain: c.domain,
|
|
227
|
+
reason: c.implied_reason,
|
|
228
|
+
})),
|
|
229
|
+
all_concepts: all,
|
|
230
|
+
domains: Array.from(domains),
|
|
231
|
+
actions,
|
|
232
|
+
risk_signals: riskSignals,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
module.exports = {
|
|
237
|
+
extractConcepts,
|
|
238
|
+
loadTaxonomy,
|
|
239
|
+
clearTaxonomyCache,
|
|
240
|
+
};
|