tryassay 0.6.0 → 0.11.0

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 (103) hide show
  1. package/dist/api/pricing-enforcer.d.ts +45 -0
  2. package/dist/api/pricing-enforcer.js +144 -0
  3. package/dist/api/pricing-enforcer.js.map +1 -0
  4. package/dist/api/server.d.ts +28 -0
  5. package/dist/api/server.js +265 -0
  6. package/dist/api/server.js.map +1 -0
  7. package/dist/api/team-session.d.ts +59 -0
  8. package/dist/api/team-session.js +240 -0
  9. package/dist/api/team-session.js.map +1 -0
  10. package/dist/cli.js +123 -2
  11. package/dist/cli.js.map +1 -1
  12. package/dist/commands/api.d.ts +4 -0
  13. package/dist/commands/api.js +50 -0
  14. package/dist/commands/api.js.map +1 -0
  15. package/dist/commands/runtime.d.ts +61 -0
  16. package/dist/commands/runtime.js +554 -0
  17. package/dist/commands/runtime.js.map +1 -1
  18. package/dist/runtime/agent-spawner.d.ts +56 -0
  19. package/dist/runtime/agent-spawner.js +217 -0
  20. package/dist/runtime/agent-spawner.js.map +1 -0
  21. package/dist/runtime/agents/coordinator-agent.d.ts +20 -0
  22. package/dist/runtime/agents/coordinator-agent.js +182 -0
  23. package/dist/runtime/agents/coordinator-agent.js.map +1 -0
  24. package/dist/runtime/agents/ops-agent.d.ts +11 -0
  25. package/dist/runtime/agents/ops-agent.js +113 -0
  26. package/dist/runtime/agents/ops-agent.js.map +1 -0
  27. package/dist/runtime/agents/research-agent.d.ts +11 -0
  28. package/dist/runtime/agents/research-agent.js +114 -0
  29. package/dist/runtime/agents/research-agent.js.map +1 -0
  30. package/dist/runtime/agents/test-agent.d.ts +11 -0
  31. package/dist/runtime/agents/test-agent.js +114 -0
  32. package/dist/runtime/agents/test-agent.js.map +1 -0
  33. package/dist/runtime/capability-registry.d.ts +62 -0
  34. package/dist/runtime/capability-registry.js +191 -0
  35. package/dist/runtime/capability-registry.js.map +1 -0
  36. package/dist/runtime/collusion-detector.d.ts +35 -0
  37. package/dist/runtime/collusion-detector.js +97 -0
  38. package/dist/runtime/collusion-detector.js.map +1 -0
  39. package/dist/runtime/domain-coverage-analyzer.d.ts +24 -0
  40. package/dist/runtime/domain-coverage-analyzer.js +178 -0
  41. package/dist/runtime/domain-coverage-analyzer.js.map +1 -0
  42. package/dist/runtime/human-escalation.d.ts +41 -0
  43. package/dist/runtime/human-escalation.js +122 -0
  44. package/dist/runtime/human-escalation.js.map +1 -0
  45. package/dist/runtime/kill-switch.d.ts +51 -0
  46. package/dist/runtime/kill-switch.js +185 -0
  47. package/dist/runtime/kill-switch.js.map +1 -0
  48. package/dist/runtime/layer2-guardian.d.ts +81 -0
  49. package/dist/runtime/layer2-guardian.js +263 -0
  50. package/dist/runtime/layer2-guardian.js.map +1 -0
  51. package/dist/runtime/multi-agent-loop.d.ts +37 -0
  52. package/dist/runtime/multi-agent-loop.js +411 -0
  53. package/dist/runtime/multi-agent-loop.js.map +1 -0
  54. package/dist/runtime/prompt-safety-analyzer.d.ts +17 -0
  55. package/dist/runtime/prompt-safety-analyzer.js +230 -0
  56. package/dist/runtime/prompt-safety-analyzer.js.map +1 -0
  57. package/dist/runtime/rollback-manager.d.ts +50 -0
  58. package/dist/runtime/rollback-manager.js +157 -0
  59. package/dist/runtime/rollback-manager.js.map +1 -0
  60. package/dist/runtime/rule-canary-deployer.d.ts +69 -0
  61. package/dist/runtime/rule-canary-deployer.js +289 -0
  62. package/dist/runtime/rule-canary-deployer.js.map +1 -0
  63. package/dist/runtime/rule-conflict-detector.d.ts +48 -0
  64. package/dist/runtime/rule-conflict-detector.js +214 -0
  65. package/dist/runtime/rule-conflict-detector.js.map +1 -0
  66. package/dist/runtime/rule-meta-verifier.d.ts +18 -0
  67. package/dist/runtime/rule-meta-verifier.js +275 -0
  68. package/dist/runtime/rule-meta-verifier.js.map +1 -0
  69. package/dist/runtime/rule-proposal-manager.d.ts +95 -0
  70. package/dist/runtime/rule-proposal-manager.js +190 -0
  71. package/dist/runtime/rule-proposal-manager.js.map +1 -0
  72. package/dist/runtime/safety-enforcer.d.ts +35 -0
  73. package/dist/runtime/safety-enforcer.js +165 -0
  74. package/dist/runtime/safety-enforcer.js.map +1 -0
  75. package/dist/runtime/safety-status.d.ts +48 -0
  76. package/dist/runtime/safety-status.js +119 -0
  77. package/dist/runtime/safety-status.js.map +1 -0
  78. package/dist/runtime/shared-memory.d.ts +47 -0
  79. package/dist/runtime/shared-memory.js +151 -0
  80. package/dist/runtime/shared-memory.js.map +1 -0
  81. package/dist/runtime/specialized-agent.d.ts +5 -0
  82. package/dist/runtime/specialized-agent.js +37 -0
  83. package/dist/runtime/specialized-agent.js.map +1 -1
  84. package/dist/runtime/stall-detector.d.ts +13 -0
  85. package/dist/runtime/stall-detector.js +121 -0
  86. package/dist/runtime/stall-detector.js.map +1 -0
  87. package/dist/runtime/tool-approval.d.ts +51 -0
  88. package/dist/runtime/tool-approval.js +148 -0
  89. package/dist/runtime/tool-approval.js.map +1 -0
  90. package/dist/runtime/tool-sandbox.d.ts +43 -0
  91. package/dist/runtime/tool-sandbox.js +394 -0
  92. package/dist/runtime/tool-sandbox.js.map +1 -0
  93. package/dist/runtime/tool-verifier.d.ts +18 -0
  94. package/dist/runtime/tool-verifier.js +323 -0
  95. package/dist/runtime/tool-verifier.js.map +1 -0
  96. package/dist/runtime/trust-manager.d.ts +33 -3
  97. package/dist/runtime/trust-manager.js +128 -26
  98. package/dist/runtime/trust-manager.js.map +1 -1
  99. package/dist/runtime/types.d.ts +652 -0
  100. package/dist/runtime/verification-intensity.d.ts +34 -0
  101. package/dist/runtime/verification-intensity.js +104 -0
  102. package/dist/runtime/verification-intensity.js.map +1 -0
  103. package/package.json +1 -1
@@ -0,0 +1,113 @@
1
+ // ============================================================
2
+ // Ops Agent — Handles deployment verification, health checks,
3
+ // and infrastructure operations
4
+ // ============================================================
5
+ import { SpecializedAgent, } from '../specialized-agent.js';
6
+ export class OpsAgent extends SpecializedAgent {
7
+ constructor(messageBus, opts) {
8
+ super('ops-agent', 'ops', [
9
+ { name: 'deploy_verify', description: 'Verify deployment configuration and results', tools: ['file_read', 'shell'] },
10
+ { name: 'health_check', description: 'Run health checks against running services', tools: ['shell'] },
11
+ { name: 'infra_audit', description: 'Audit infrastructure configuration', tools: ['file_read'] },
12
+ ], messageBus, { model: opts?.model, initialTrust: 'untrusted' });
13
+ }
14
+ onMessage(_message) {
15
+ // Ops agent primarily receives task assignments
16
+ }
17
+ async executeTask(task) {
18
+ const contextSnippets = task.contextRefs
19
+ .map(ref => `Context: ${ref.summary}\n${ref.content ?? ''}`)
20
+ .join('\n\n');
21
+ const systemPrompt = `You are an Ops Agent — a specialized AI that handles deployment verification and infrastructure operations.
22
+
23
+ Your job: Given deployment tasks or health check requirements, produce structured operational results.
24
+
25
+ Rules:
26
+ 1. Every deployment verification must include pre-conditions and post-conditions.
27
+ 2. Health checks must specify what endpoints/services were checked and their status.
28
+ 3. Report rollback recommendations if any check fails.
29
+ 4. Flag security misconfigurations (exposed secrets, missing auth, open ports).
30
+ 5. State claims explicitly — they will be verified.
31
+
32
+ Respond with JSON:
33
+ {
34
+ "checks": [
35
+ {
36
+ "name": "...",
37
+ "target": "...",
38
+ "status": "pass" | "fail" | "warn",
39
+ "details": "...",
40
+ "rollbackRecommendation": "..." | null
41
+ }
42
+ ],
43
+ "deploymentManifest": { "files": ["..."], "envVars": ["..."], "services": ["..."] } | null,
44
+ "summary": "...",
45
+ "claims": ["..."]
46
+ }`;
47
+ const userPrompt = `OPS TASK: ${task.goal}
48
+
49
+ CONSTRAINTS:
50
+ ${task.constraints.map(c => `- ${c}`).join('\n')}
51
+
52
+ CONTEXT:
53
+ ${contextSnippets || 'No additional context provided.'}
54
+
55
+ Execute the ops task now. Be explicit about what was checked and what the results are.`;
56
+ try {
57
+ const { content } = await this.callClaude(systemPrompt, userPrompt);
58
+ const parsed = this.parseOpsResponse(content);
59
+ const artifactType = parsed.checks.length > 0 ? 'health_check' : 'deploy_result';
60
+ const failedChecks = parsed.checks.filter(c => c.status === 'fail');
61
+ const artifact = this.makeArtifact(artifactType, content, {
62
+ metadata: {
63
+ checkCount: parsed.checks.length,
64
+ passCount: parsed.checks.filter(c => c.status === 'pass').length,
65
+ failCount: failedChecks.length,
66
+ warnCount: parsed.checks.filter(c => c.status === 'warn').length,
67
+ },
68
+ });
69
+ return {
70
+ taskId: task.taskId,
71
+ status: failedChecks.length > 0 ? 'blocked' : 'completed',
72
+ artifacts: [artifact],
73
+ summary: parsed.summary,
74
+ claimsAboutArtifacts: parsed.claims,
75
+ blockers: failedChecks.length > 0
76
+ ? failedChecks.map(c => `${c.name}: ${c.details}`)
77
+ : undefined,
78
+ };
79
+ }
80
+ catch (err) {
81
+ return {
82
+ taskId: task.taskId,
83
+ status: 'failed',
84
+ artifacts: [],
85
+ summary: `Ops task failed: ${err instanceof Error ? err.message : String(err)}`,
86
+ claimsAboutArtifacts: [],
87
+ blockers: [err instanceof Error ? err.message : String(err)],
88
+ };
89
+ }
90
+ }
91
+ parseOpsResponse(raw) {
92
+ let cleaned = raw.trim();
93
+ if (cleaned.startsWith('```')) {
94
+ cleaned = cleaned.replace(/^```(?:json)?\s*/, '').replace(/\s*```$/, '');
95
+ }
96
+ try {
97
+ const parsed = JSON.parse(cleaned);
98
+ return {
99
+ checks: Array.isArray(parsed.checks) ? parsed.checks : [],
100
+ summary: typeof parsed.summary === 'string' ? parsed.summary : 'No summary',
101
+ claims: Array.isArray(parsed.claims) ? parsed.claims : [],
102
+ };
103
+ }
104
+ catch {
105
+ return {
106
+ checks: [],
107
+ summary: 'Failed to parse ops response',
108
+ claims: [],
109
+ };
110
+ }
111
+ }
112
+ }
113
+ //# sourceMappingURL=ops-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops-agent.js","sourceRoot":"","sources":["../../../src/runtime/agents/ops-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { SpecializedAgent, type TaskAssignmentPayload, type TaskResultPayload } from '../specialized-agent.js';
2
+ import type { AgentMessage } from '../types.js';
3
+ import type { MessageBus } from '../message-bus.js';
4
+ export declare class ResearchAgent extends SpecializedAgent {
5
+ constructor(messageBus: MessageBus, opts?: {
6
+ model?: string;
7
+ });
8
+ protected onMessage(_message: AgentMessage): void;
9
+ executeTask(task: TaskAssignmentPayload): Promise<TaskResultPayload>;
10
+ private parseResearchResponse;
11
+ }
@@ -0,0 +1,114 @@
1
+ // ============================================================
2
+ // Research Agent — Investigates problems, reads docs, provides
3
+ // sourced findings with citations and confidence levels
4
+ // ============================================================
5
+ import { SpecializedAgent, } from '../specialized-agent.js';
6
+ export class ResearchAgent extends SpecializedAgent {
7
+ constructor(messageBus, opts) {
8
+ super('research-agent', 'research', [
9
+ { name: 'investigate', description: 'Investigate problems and error messages', tools: ['file_read'] },
10
+ { name: 'read_docs', description: 'Read documentation and API references', tools: ['file_read'] },
11
+ { name: 'search_codebase', description: 'Search codebase for patterns and usage', tools: ['file_read'] },
12
+ ], messageBus, { model: opts?.model, initialTrust: 'untrusted' });
13
+ }
14
+ onMessage(_message) {
15
+ // Research agent primarily receives questions and task assignments
16
+ }
17
+ async executeTask(task) {
18
+ const contextSnippets = task.contextRefs
19
+ .map(ref => `Context: ${ref.summary}\n${ref.content ?? ''}`)
20
+ .join('\n\n');
21
+ const systemPrompt = `You are a Research Agent — a specialized AI that investigates problems and provides sourced findings.
22
+
23
+ Your job: Given a question or problem, research it thoroughly and provide findings with citations.
24
+
25
+ Rules:
26
+ 1. Every finding MUST include a source citation (file path, URL, or documentation reference).
27
+ 2. State confidence level for each finding: high (verified against source), medium (inferred from context), low (best guess).
28
+ 3. Unsourced claims must be explicitly marked as "unsourced — needs verification."
29
+ 4. Distinguish between facts (from docs/code) and inferences (your reasoning).
30
+ 5. If you cannot find an answer, say so clearly — do not fabricate sources.
31
+
32
+ Respond with JSON:
33
+ {
34
+ "findings": [
35
+ {
36
+ "claim": "...",
37
+ "source": "...",
38
+ "sourceType": "file" | "documentation" | "codebase_pattern" | "inference" | "unsourced",
39
+ "confidence": "high" | "medium" | "low",
40
+ "evidence": "..."
41
+ }
42
+ ],
43
+ "summary": "...",
44
+ "claims": ["..."],
45
+ "unanswered": ["..."]
46
+ }`;
47
+ const userPrompt = `RESEARCH TASK: ${task.goal}
48
+
49
+ CONSTRAINTS:
50
+ ${task.constraints.map(c => `- ${c}`).join('\n')}
51
+
52
+ CONTEXT:
53
+ ${contextSnippets || 'No additional context provided.'}
54
+
55
+ Research this now. Cite your sources. Flag anything you cannot verify.`;
56
+ try {
57
+ const { content } = await this.callClaude(systemPrompt, userPrompt);
58
+ const parsed = this.parseResearchResponse(content);
59
+ const artifact = this.makeArtifact('research_finding', content, {
60
+ metadata: {
61
+ findingCount: parsed.findings.length,
62
+ unansweredCount: parsed.unanswered.length,
63
+ confidenceCounts: {
64
+ high: parsed.findings.filter(f => f.confidence === 'high').length,
65
+ medium: parsed.findings.filter(f => f.confidence === 'medium').length,
66
+ low: parsed.findings.filter(f => f.confidence === 'low').length,
67
+ },
68
+ },
69
+ });
70
+ return {
71
+ taskId: task.taskId,
72
+ status: parsed.unanswered.length > 0 && parsed.findings.length === 0 ? 'blocked' : 'completed',
73
+ artifacts: [artifact],
74
+ summary: parsed.summary,
75
+ claimsAboutArtifacts: parsed.claims,
76
+ blockers: parsed.unanswered.length > 0 ? parsed.unanswered : undefined,
77
+ };
78
+ }
79
+ catch (err) {
80
+ return {
81
+ taskId: task.taskId,
82
+ status: 'failed',
83
+ artifacts: [],
84
+ summary: `Research failed: ${err instanceof Error ? err.message : String(err)}`,
85
+ claimsAboutArtifacts: [],
86
+ blockers: [err instanceof Error ? err.message : String(err)],
87
+ };
88
+ }
89
+ }
90
+ parseResearchResponse(raw) {
91
+ let cleaned = raw.trim();
92
+ if (cleaned.startsWith('```')) {
93
+ cleaned = cleaned.replace(/^```(?:json)?\s*/, '').replace(/\s*```$/, '');
94
+ }
95
+ try {
96
+ const parsed = JSON.parse(cleaned);
97
+ return {
98
+ findings: Array.isArray(parsed.findings) ? parsed.findings : [],
99
+ summary: typeof parsed.summary === 'string' ? parsed.summary : 'No summary',
100
+ claims: Array.isArray(parsed.claims) ? parsed.claims : [],
101
+ unanswered: Array.isArray(parsed.unanswered) ? parsed.unanswered : [],
102
+ };
103
+ }
104
+ catch {
105
+ return {
106
+ findings: [],
107
+ summary: 'Failed to parse research response',
108
+ claims: [],
109
+ unanswered: [],
110
+ };
111
+ }
112
+ }
113
+ }
114
+ //# sourceMappingURL=research-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research-agent.js","sourceRoot":"","sources":["../../../src/runtime/agents/research-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { SpecializedAgent, type TaskAssignmentPayload, type TaskResultPayload } from '../specialized-agent.js';
2
+ import type { AgentMessage } from '../types.js';
3
+ import type { MessageBus } from '../message-bus.js';
4
+ export declare class TestAgent extends SpecializedAgent {
5
+ constructor(messageBus: MessageBus, opts?: {
6
+ model?: string;
7
+ });
8
+ protected onMessage(_message: AgentMessage): void;
9
+ executeTask(task: TaskAssignmentPayload): Promise<TaskResultPayload>;
10
+ private parseTestResponse;
11
+ }
@@ -0,0 +1,114 @@
1
+ // ============================================================
2
+ // Test Agent — Writes tests, runs suites, reports coverage
3
+ // with test quality verification (meaningful vs trivial)
4
+ // ============================================================
5
+ import { SpecializedAgent, } from '../specialized-agent.js';
6
+ export class TestAgent extends SpecializedAgent {
7
+ constructor(messageBus, opts) {
8
+ super('test-agent', 'test', [
9
+ { name: 'write_tests', description: 'Write unit and integration tests', tools: ['file_write'] },
10
+ { name: 'run_tests', description: 'Run test suites and report results', tools: ['shell'] },
11
+ { name: 'coverage', description: 'Analyze code coverage', tools: ['shell', 'file_read'] },
12
+ ], messageBus, { model: opts?.model, initialTrust: 'untrusted' });
13
+ }
14
+ onMessage(_message) {
15
+ // Test agent primarily receives task assignments
16
+ }
17
+ async executeTask(task) {
18
+ const contextSnippets = task.contextRefs
19
+ .map(ref => `Context: ${ref.summary}\n${ref.content ?? ''}`)
20
+ .join('\n\n');
21
+ const systemPrompt = `You are a Test Agent — a specialized AI that writes and analyzes tests.
22
+
23
+ Your job: Given code and requirements, produce meaningful tests with real assertions.
24
+
25
+ Rules:
26
+ 1. Every test must verify actual behavior, not just assert(true).
27
+ 2. Minimize mocking — prefer real function calls over mock objects.
28
+ 3. Cover edge cases: empty inputs, null/undefined, boundary values, error paths.
29
+ 4. State what each test verifies as explicit claims (these will be quality-checked).
30
+ 5. Include at least one negative test (expected failure case).
31
+ 6. Report mock usage honestly — how many mocks vs real interactions.
32
+
33
+ Respond with JSON:
34
+ {
35
+ "testFiles": [{ "path": "...", "content": "...", "language": "..." }],
36
+ "summary": "...",
37
+ "claims": ["..."],
38
+ "testQuality": {
39
+ "totalTests": <number>,
40
+ "meaningfulTests": <number>,
41
+ "trivialTests": <number>,
42
+ "mockCount": <number>,
43
+ "realInteractionCount": <number>
44
+ }
45
+ }`;
46
+ const userPrompt = `TASK: ${task.goal}
47
+
48
+ CONSTRAINTS:
49
+ ${task.constraints.map(c => `- ${c}`).join('\n')}
50
+
51
+ CONTEXT:
52
+ ${contextSnippets || 'No additional context provided.'}
53
+
54
+ Write meaningful tests now. Remember: trivial tests (assert true, no-op mocks) will be detected and rejected.`;
55
+ try {
56
+ const { content } = await this.callClaude(systemPrompt, userPrompt);
57
+ const parsed = this.parseTestResponse(content);
58
+ const artifacts = parsed.testFiles.map(f => this.makeArtifact('test_file', f.content, {
59
+ path: f.path,
60
+ language: f.language,
61
+ metadata: {
62
+ testQuality: parsed.testQuality,
63
+ },
64
+ }));
65
+ return {
66
+ taskId: task.taskId,
67
+ status: 'completed',
68
+ artifacts,
69
+ summary: parsed.summary,
70
+ claimsAboutArtifacts: parsed.claims,
71
+ };
72
+ }
73
+ catch (err) {
74
+ return {
75
+ taskId: task.taskId,
76
+ status: 'failed',
77
+ artifacts: [],
78
+ summary: `Test generation failed: ${err instanceof Error ? err.message : String(err)}`,
79
+ claimsAboutArtifacts: [],
80
+ blockers: [err instanceof Error ? err.message : String(err)],
81
+ };
82
+ }
83
+ }
84
+ parseTestResponse(raw) {
85
+ let cleaned = raw.trim();
86
+ if (cleaned.startsWith('```')) {
87
+ cleaned = cleaned.replace(/^```(?:json)?\s*/, '').replace(/\s*```$/, '');
88
+ }
89
+ try {
90
+ const parsed = JSON.parse(cleaned);
91
+ return {
92
+ testFiles: Array.isArray(parsed.testFiles) ? parsed.testFiles : [],
93
+ summary: typeof parsed.summary === 'string' ? parsed.summary : 'No summary',
94
+ claims: Array.isArray(parsed.claims) ? parsed.claims : [],
95
+ testQuality: {
96
+ totalTests: typeof parsed.testQuality?.totalTests === 'number' ? parsed.testQuality.totalTests : 0,
97
+ meaningfulTests: typeof parsed.testQuality?.meaningfulTests === 'number' ? parsed.testQuality.meaningfulTests : 0,
98
+ trivialTests: typeof parsed.testQuality?.trivialTests === 'number' ? parsed.testQuality.trivialTests : 0,
99
+ mockCount: typeof parsed.testQuality?.mockCount === 'number' ? parsed.testQuality.mockCount : 0,
100
+ realInteractionCount: typeof parsed.testQuality?.realInteractionCount === 'number' ? parsed.testQuality.realInteractionCount : 0,
101
+ },
102
+ };
103
+ }
104
+ catch {
105
+ return {
106
+ testFiles: [{ path: 'test.ts', content: raw, language: 'typescript' }],
107
+ summary: 'Raw test output (failed to parse structured response)',
108
+ claims: [],
109
+ testQuality: { totalTests: 0, meaningfulTests: 0, trivialTests: 0, mockCount: 0, realInteractionCount: 0 },
110
+ };
111
+ }
112
+ }
113
+ }
114
+ //# sourceMappingURL=test-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-agent.js","sourceRoot":"","sources":["../../../src/runtime/agents/test-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { CapabilityRegistry, ToolDefinition, ModificationLogEntry } from './types.js';
2
+ export declare class CapabilityRegistryManager {
3
+ private registry;
4
+ private registryPath;
5
+ private versionHistory;
6
+ constructor(registryPath: string);
7
+ /**
8
+ * Load the registry from disk. Creates an empty one if not found.
9
+ */
10
+ load(): Promise<void>;
11
+ /**
12
+ * Save the registry to disk with updated manifest hash.
13
+ */
14
+ save(): Promise<void>;
15
+ /**
16
+ * Get the current registry state (readonly snapshot).
17
+ */
18
+ getRegistry(): CapabilityRegistry;
19
+ /**
20
+ * Add a new tool to the registry.
21
+ * The tool must have status 'approved' before calling this.
22
+ */
23
+ addTool(tool: ToolDefinition, approvedBy: string, proposalId: string): void;
24
+ /**
25
+ * Deprecate a tool. It remains in the registry but is no longer active.
26
+ */
27
+ deprecateTool(toolId: string, deprecatedBy: string, _reason: string): void;
28
+ /**
29
+ * Rollback the registry to the previous version.
30
+ * Returns true if rollback succeeded, false if no history available.
31
+ */
32
+ rollback(rolledBackBy: string): boolean;
33
+ /**
34
+ * Find a tool by ID across active and deprecated pools.
35
+ */
36
+ findTool(toolId: string): ToolDefinition | undefined;
37
+ /**
38
+ * List all active tools.
39
+ */
40
+ listActiveTools(): readonly ToolDefinition[];
41
+ /**
42
+ * List all deprecated tools.
43
+ */
44
+ listDeprecatedTools(): readonly ToolDefinition[];
45
+ /**
46
+ * Get the modification history.
47
+ */
48
+ getModificationHistory(): readonly ModificationLogEntry[];
49
+ /**
50
+ * Verify registry integrity by recomputing the manifest hash.
51
+ */
52
+ verifyIntegrity(): {
53
+ valid: boolean;
54
+ expected: string;
55
+ actual: string;
56
+ };
57
+ private createEmptyRegistry;
58
+ private pushHistory;
59
+ private incrementVersion;
60
+ private logModification;
61
+ private computeManifestHash;
62
+ }
@@ -0,0 +1,191 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Capability Registry
3
+ // Stores and manages tools with version tracking, rollback,
4
+ // and cryptographic integrity verification.
5
+ // ============================================================
6
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
7
+ import { dirname } from 'node:path';
8
+ import { createHash } from 'node:crypto';
9
+ // ── CapabilityRegistryManager ──────────────────────────────
10
+ export class CapabilityRegistryManager {
11
+ registry;
12
+ registryPath;
13
+ versionHistory = [];
14
+ constructor(registryPath) {
15
+ this.registryPath = registryPath;
16
+ this.registry = this.createEmptyRegistry();
17
+ }
18
+ /**
19
+ * Load the registry from disk. Creates an empty one if not found.
20
+ */
21
+ async load() {
22
+ try {
23
+ const raw = await readFile(this.registryPath, 'utf-8');
24
+ const parsed = JSON.parse(raw);
25
+ this.registry = parsed;
26
+ }
27
+ catch {
28
+ // File doesn't exist or is invalid — start fresh
29
+ this.registry = this.createEmptyRegistry();
30
+ }
31
+ }
32
+ /**
33
+ * Save the registry to disk with updated manifest hash.
34
+ */
35
+ async save() {
36
+ this.registry.manifest_hash = this.computeManifestHash();
37
+ await mkdir(dirname(this.registryPath), { recursive: true });
38
+ await writeFile(this.registryPath, JSON.stringify(this.registry, null, 2), 'utf-8');
39
+ }
40
+ /**
41
+ * Get the current registry state (readonly snapshot).
42
+ */
43
+ getRegistry() {
44
+ return {
45
+ ...this.registry,
46
+ tools: {
47
+ active: [...this.registry.tools.active],
48
+ deprecated: [...this.registry.tools.deprecated],
49
+ },
50
+ modifications: [...this.registry.modifications],
51
+ };
52
+ }
53
+ /**
54
+ * Add a new tool to the registry.
55
+ * The tool must have status 'approved' before calling this.
56
+ */
57
+ addTool(tool, approvedBy, proposalId) {
58
+ if (tool.status !== 'approved') {
59
+ throw new Error(`Cannot add tool with status "${tool.status}". Must be "approved".`);
60
+ }
61
+ // Check for duplicate IDs
62
+ if (this.findTool(tool.id)) {
63
+ throw new Error(`Tool "${tool.id}" already exists in registry.`);
64
+ }
65
+ // Save version history for rollback
66
+ this.pushHistory();
67
+ // Activate the tool
68
+ const activeTool = { ...tool, status: 'active' };
69
+ this.registry.tools.active.push(activeTool);
70
+ // Log the modification
71
+ this.logModification(proposalId, 'tool', 'added', tool.id, approvedBy);
72
+ }
73
+ /**
74
+ * Deprecate a tool. It remains in the registry but is no longer active.
75
+ */
76
+ deprecateTool(toolId, deprecatedBy, _reason) {
77
+ const index = this.registry.tools.active.findIndex(t => t.id === toolId);
78
+ if (index === -1) {
79
+ throw new Error(`Tool "${toolId}" not found in active tools.`);
80
+ }
81
+ this.pushHistory();
82
+ const tool = this.registry.tools.active[index];
83
+ this.registry.tools.active.splice(index, 1);
84
+ const deprecated = { ...tool, status: 'deprecated' };
85
+ this.registry.tools.deprecated.push(deprecated);
86
+ this.logModification(`deprecate-${toolId}`, 'tool', 'deprecated', toolId, deprecatedBy);
87
+ }
88
+ /**
89
+ * Rollback the registry to the previous version.
90
+ * Returns true if rollback succeeded, false if no history available.
91
+ */
92
+ rollback(rolledBackBy) {
93
+ const previous = this.versionHistory.pop();
94
+ if (!previous)
95
+ return false;
96
+ const currentVersion = this.registry.version;
97
+ this.registry = previous;
98
+ // Log the rollback (on the restored version)
99
+ this.logModification(`rollback-from-${currentVersion}`, 'tool', 'rolled_back', 'registry', rolledBackBy);
100
+ return true;
101
+ }
102
+ /**
103
+ * Find a tool by ID across active and deprecated pools.
104
+ */
105
+ findTool(toolId) {
106
+ return this.registry.tools.active.find(t => t.id === toolId)
107
+ ?? this.registry.tools.deprecated.find(t => t.id === toolId);
108
+ }
109
+ /**
110
+ * List all active tools.
111
+ */
112
+ listActiveTools() {
113
+ return this.registry.tools.active;
114
+ }
115
+ /**
116
+ * List all deprecated tools.
117
+ */
118
+ listDeprecatedTools() {
119
+ return this.registry.tools.deprecated;
120
+ }
121
+ /**
122
+ * Get the modification history.
123
+ */
124
+ getModificationHistory() {
125
+ return this.registry.modifications;
126
+ }
127
+ /**
128
+ * Verify registry integrity by recomputing the manifest hash.
129
+ */
130
+ verifyIntegrity() {
131
+ const actual = this.computeManifestHash();
132
+ return {
133
+ valid: actual === this.registry.manifest_hash,
134
+ expected: this.registry.manifest_hash,
135
+ actual,
136
+ };
137
+ }
138
+ // ── Private helpers ──────────────────────────────────────
139
+ createEmptyRegistry() {
140
+ return {
141
+ version: '0.0.1',
142
+ last_modified: new Date().toISOString(),
143
+ modified_by: 'system',
144
+ tools: { active: [], deprecated: [] },
145
+ manifest_hash: '',
146
+ layer2_hash: '',
147
+ modifications: [],
148
+ };
149
+ }
150
+ pushHistory() {
151
+ // Deep clone the current state for rollback
152
+ const snapshot = JSON.parse(JSON.stringify(this.registry));
153
+ this.versionHistory.push(snapshot);
154
+ // Keep at most 10 versions for rollback
155
+ if (this.versionHistory.length > 10) {
156
+ this.versionHistory.shift();
157
+ }
158
+ }
159
+ incrementVersion() {
160
+ const parts = this.registry.version.split('.').map(Number);
161
+ parts[2] = (parts[2] ?? 0) + 1;
162
+ return parts.join('.');
163
+ }
164
+ logModification(proposalId, type, action, targetId, approvedBy) {
165
+ const previousVersion = this.registry.version;
166
+ const newVersion = this.incrementVersion();
167
+ this.registry.modifications.push({
168
+ timestamp: new Date().toISOString(),
169
+ proposal_id: proposalId,
170
+ type,
171
+ action,
172
+ target_id: targetId,
173
+ approved_by: approvedBy,
174
+ registry_version_before: previousVersion,
175
+ registry_version_after: newVersion,
176
+ });
177
+ this.registry.version = newVersion;
178
+ this.registry.last_modified = new Date().toISOString();
179
+ this.registry.modified_by = approvedBy;
180
+ }
181
+ computeManifestHash() {
182
+ // Hash everything except the manifest_hash field itself
183
+ const data = {
184
+ version: this.registry.version,
185
+ tools: this.registry.tools,
186
+ modifications: this.registry.modifications,
187
+ };
188
+ return createHash('sha256').update(JSON.stringify(data)).digest('hex');
189
+ }
190
+ }
191
+ //# sourceMappingURL=capability-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-registry.js","sourceRoot":"","sources":["../../src/runtime/capability-registry.ts"],"names":[],"mappings":"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"}