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
@@ -246,4 +246,558 @@ export async function runtimeTeamCommand(task, opts) {
246
246
  console.log('');
247
247
  }
248
248
  }
249
+ export async function runtimeFullTeamCommand(task, opts) {
250
+ const { MultiAgentLoop } = await import('../runtime/multi-agent-loop.js');
251
+ const cwd = opts.cwd ?? process.cwd();
252
+ // Parse agent list
253
+ const agentList = opts.agents
254
+ ? opts.agents.split(',').map(a => a.trim())
255
+ : ['coordinator', 'code', 'review', 'test'];
256
+ const models = {};
257
+ if (opts.coordinatorModel)
258
+ models.coordinator = opts.coordinatorModel;
259
+ if (opts.codeModel)
260
+ models.code = opts.codeModel;
261
+ if (opts.reviewModel)
262
+ models.review = opts.reviewModel;
263
+ if (opts.testModel)
264
+ models.test = opts.testModel;
265
+ if (opts.researchModel)
266
+ models.research = opts.researchModel;
267
+ if (opts.opsModel)
268
+ models.ops = opts.opsModel;
269
+ console.log('');
270
+ console.log(' Assay Verified Full Team');
271
+ console.log(' ========================');
272
+ console.log('');
273
+ console.log(` Goal: ${task}`);
274
+ console.log(` Codebase: ${cwd}`);
275
+ console.log(` Agents: ${agentList.join(', ')}`);
276
+ console.log(` Max concurrent: ${opts.maxConcurrent ?? '3'}`);
277
+ console.log(` Stall timeout: ${opts.stallTimeout ?? '120000'}ms`);
278
+ console.log('');
279
+ const loop = new MultiAgentLoop(cwd, {
280
+ goal: task,
281
+ agents: agentList,
282
+ safetyPolicy: {
283
+ formalOverridesConsensus: true,
284
+ noSelfVerification: true,
285
+ criticalClaimsRequireFormal: true,
286
+ escalationRules: {
287
+ maxFormalOverridesBeforeHalt: 3,
288
+ maxTrustDemotions: 2,
289
+ maxRejectCyclesPerTask: 3,
290
+ },
291
+ preferModelDiversity: false,
292
+ },
293
+ maxConcurrentTasks: opts.maxConcurrent ? parseInt(opts.maxConcurrent, 10) : 3,
294
+ stallTimeoutMs: opts.stallTimeout ? parseInt(opts.stallTimeout, 10) : 120_000,
295
+ maxTotalAttempts: opts.maxAttempts ? parseInt(opts.maxAttempts, 10) : 20,
296
+ models: models,
297
+ });
298
+ // Log audit events in real-time
299
+ loop.on('audit', (entry) => {
300
+ console.log(` [${entry.eventType}] ${JSON.stringify(entry.details)}`);
301
+ });
302
+ const result = await loop.run();
303
+ console.log('');
304
+ console.log(' --- Result ---');
305
+ console.log(` Status: ${result.status}`);
306
+ console.log(` Tasks: ${result.taskGraph.tasks.length}`);
307
+ console.log(` Completed: ${result.taskGraph.tasks.filter(t => t.status === 'completed').length}`);
308
+ console.log(` Failed: ${result.taskGraph.tasks.filter(t => t.status === 'failed').length}`);
309
+ console.log(` Handoffs verified: ${result.artifacts.length}`);
310
+ console.log(` Shared memory entries: ${result.sharedMemorySnapshot.length}`);
311
+ console.log(` Stalls detected: ${result.stalls.length}`);
312
+ console.log(` Audit entries: ${result.auditTrail.length}`);
313
+ console.log(` Duration: ${result.totalDurationMs}ms`);
314
+ console.log('');
315
+ // Print task graph summary
316
+ console.log(' --- Task Graph ---');
317
+ for (const task of result.taskGraph.tasks) {
318
+ const status = task.status === 'completed' ? '[x]' : task.status === 'failed' ? '[!]' : '[ ]';
319
+ console.log(` ${status} ${task.id} (${task.specialization}): ${task.goal.slice(0, 60)}`);
320
+ }
321
+ // Print conflicts if any
322
+ const conflicts = loop.getSharedMemory().getOpenConflicts();
323
+ if (conflicts.length > 0) {
324
+ console.log('');
325
+ console.log(` --- Open Conflicts: ${conflicts.length} ---`);
326
+ for (const c of conflicts) {
327
+ console.log(` [conflict] ${c.entries[0].content.slice(0, 50)} vs ${c.entries[1].content.slice(0, 50)}`);
328
+ }
329
+ }
330
+ console.log('');
331
+ }
332
+ export async function runtimeToolsListCommand(opts) {
333
+ const { CapabilityRegistryManager } = await import('../runtime/capability-registry.js');
334
+ const registryPath = opts.registry ?? '.assay/capability-registry.json';
335
+ const registry = new CapabilityRegistryManager(registryPath);
336
+ await registry.load();
337
+ const active = registry.listActiveTools();
338
+ const deprecated = registry.listDeprecatedTools();
339
+ console.log('');
340
+ console.log(' Capability Registry');
341
+ console.log(' ===================');
342
+ console.log('');
343
+ if (active.length === 0 && deprecated.length === 0) {
344
+ console.log(' No tools registered.');
345
+ return;
346
+ }
347
+ if (active.length > 0) {
348
+ console.log(' Active Tools:');
349
+ for (const tool of active) {
350
+ console.log(` [${tool.type}] ${tool.name} (${tool.id}) v${tool.version}`);
351
+ console.log(` ${tool.description}`);
352
+ console.log(` Created by: ${tool.created_by} | Timeout: ${tool.constraints.timeout_ms}ms`);
353
+ console.log(` Network: ${tool.constraints.network_access.allowed ? tool.constraints.network_access.allowlisted_domains.join(', ') || 'all' : 'none'}`);
354
+ }
355
+ }
356
+ if (deprecated.length > 0) {
357
+ console.log('');
358
+ console.log(' Deprecated Tools:');
359
+ for (const tool of deprecated) {
360
+ console.log(` [deprecated] ${tool.name} (${tool.id}) v${tool.version}`);
361
+ }
362
+ }
363
+ // Show integrity status
364
+ const integrity = registry.verifyIntegrity();
365
+ console.log('');
366
+ console.log(` Registry integrity: ${integrity.valid ? 'VALID' : 'INVALID (hash mismatch)'}`);
367
+ console.log('');
368
+ }
369
+ export async function runtimeToolsApproveCommand(proposalId, opts) {
370
+ const { CapabilityRegistryManager } = await import('../runtime/capability-registry.js');
371
+ const { ToolApprovalManager } = await import('../runtime/tool-approval.js');
372
+ const registryPath = opts.registry ?? '.assay/capability-registry.json';
373
+ const registry = new CapabilityRegistryManager(registryPath);
374
+ await registry.load();
375
+ const approvalManager = new ToolApprovalManager(registry);
376
+ // Check for pending approvals
377
+ const pending = approvalManager.getPending(proposalId);
378
+ if (!pending) {
379
+ console.error(` Error: No pending approval found for "${proposalId}".`);
380
+ console.log(' Use "runtime tools list" to see registered tools.');
381
+ process.exit(1);
382
+ }
383
+ const approver = opts.approver ?? 'human-operator';
384
+ const reason = opts.reason ?? 'Approved via CLI';
385
+ const approval = await approvalManager.approve(proposalId, approver, reason);
386
+ console.log('');
387
+ console.log(' Tool Approved');
388
+ console.log(' =============');
389
+ console.log(` Proposal: ${approval.proposal_id}`);
390
+ console.log(` Approved by: ${approval.decided_by}`);
391
+ console.log(` Reasoning: ${approval.reasoning}`);
392
+ console.log(` Time: ${approval.decided_at}`);
393
+ console.log('');
394
+ }
395
+ export async function runtimeToolsRollbackCommand(opts) {
396
+ const { CapabilityRegistryManager } = await import('../runtime/capability-registry.js');
397
+ const registryPath = opts.registry ?? '.assay/capability-registry.json';
398
+ const registry = new CapabilityRegistryManager(registryPath);
399
+ await registry.load();
400
+ const operator = opts.operator ?? 'human-operator';
401
+ const success = registry.rollback(operator);
402
+ if (success) {
403
+ await registry.save();
404
+ console.log('');
405
+ console.log(' Registry rolled back to previous version.');
406
+ console.log(` New version: ${registry.getRegistry().version}`);
407
+ console.log('');
408
+ }
409
+ else {
410
+ console.log('');
411
+ console.log(' No rollback history available.');
412
+ console.log('');
413
+ }
414
+ }
415
+ export async function runtimeAgentsListCommand(opts) {
416
+ const { AgentSpawner } = await import('../runtime/agent-spawner.js');
417
+ const { CapabilityRegistryManager } = await import('../runtime/capability-registry.js');
418
+ const registryPath = opts.registry ?? '.assay/capability-registry.json';
419
+ const registry = new CapabilityRegistryManager(registryPath);
420
+ await registry.load();
421
+ const spawner = new AgentSpawner(registry);
422
+ const pending = spawner.listPending();
423
+ console.log('');
424
+ console.log(' Agent Registry');
425
+ console.log(' ==============');
426
+ console.log('');
427
+ if (pending.length > 0) {
428
+ console.log(' Pending Approval:');
429
+ for (const p of pending) {
430
+ const a = p.agentDefinition;
431
+ const v = p.verification;
432
+ console.log(` [${a.trust_level}] ${a.name} (${a.id})`);
433
+ console.log(` Domain: ${a.domain.description}`);
434
+ console.log(` Verdict: ${v.verdict} | Blockers: ${v.blockers.length}`);
435
+ console.log(` Prompt safety: bypass=${v.prompt_safety.contains_verification_bypass}, escalation=${v.prompt_safety.contains_privilege_escalation}`);
436
+ console.log(` Coverage gaps: ${v.domain_coverage.gaps.length} | Overreach: ${v.domain_coverage.overreach.length}`);
437
+ }
438
+ }
439
+ else {
440
+ console.log(' No pending agent proposals.');
441
+ }
442
+ console.log('');
443
+ }
444
+ export async function runtimeAgentsSpawnCommand(specPath, opts) {
445
+ const { readFile } = await import('node:fs/promises');
446
+ const { AgentSpawner } = await import('../runtime/agent-spawner.js');
447
+ const { CapabilityRegistryManager } = await import('../runtime/capability-registry.js');
448
+ const registryPath = opts.registry ?? '.assay/capability-registry.json';
449
+ const registry = new CapabilityRegistryManager(registryPath);
450
+ await registry.load();
451
+ // Read agent spec from JSON file
452
+ let spec;
453
+ try {
454
+ const raw = await readFile(specPath, 'utf-8');
455
+ spec = JSON.parse(raw);
456
+ }
457
+ catch (err) {
458
+ console.error(` Error reading agent spec: ${err instanceof Error ? err.message : String(err)}`);
459
+ process.exit(1);
460
+ }
461
+ const spawner = new AgentSpawner(registry);
462
+ const parentTrust = (opts.parentTrust ?? 'human');
463
+ console.log('');
464
+ console.log(' Proposing Agent...');
465
+ const result = await spawner.propose(spec, // ToolDefinition fields come from the JSON
466
+ parentTrust, {
467
+ capability_gap: spec.justification?.capability_gap ?? 'Unspecified',
468
+ evidence: spec.justification?.evidence ?? [],
469
+ expected_impact: spec.justification?.expected_impact ?? 'Unspecified',
470
+ risk_assessment: spec.justification?.risk_assessment ?? 'Unspecified',
471
+ }, { useLLMAnalysis: opts.useLlm });
472
+ console.log('');
473
+ console.log(' Agent Verification Report');
474
+ console.log(' ========================');
475
+ console.log(` Proposal ID: ${result.proposalId}`);
476
+ console.log(` Status: ${result.status}`);
477
+ console.log(` Verdict: ${result.verification.verdict}`);
478
+ console.log('');
479
+ // Prompt safety
480
+ const ps = result.verification.prompt_safety;
481
+ console.log(' Prompt Safety:');
482
+ console.log(` Verification bypass: ${ps.contains_verification_bypass ? 'DETECTED' : 'clean'}`);
483
+ console.log(` Privilege escalation: ${ps.contains_privilege_escalation ? 'DETECTED' : 'clean'}`);
484
+ console.log(` Self-reference: ${ps.contains_self_reference ? 'detected' : 'clean'}`);
485
+ console.log(` Findings: ${ps.findings.length}`);
486
+ for (const f of ps.findings) {
487
+ console.log(` [${f.severity}] ${f.type}: ${f.description}`);
488
+ }
489
+ // Domain coverage
490
+ const dc = result.verification.domain_coverage;
491
+ console.log('');
492
+ console.log(' Domain Coverage:');
493
+ console.log(` Gaps: ${dc.gaps.length}`);
494
+ for (const g of dc.gaps)
495
+ console.log(` - ${g}`);
496
+ console.log(` Overreach: ${dc.overreach.length}`);
497
+ for (const o of dc.overreach)
498
+ console.log(` - ${o}`);
499
+ // Trust inheritance
500
+ const ti = result.verification.trust_inheritance;
501
+ console.log('');
502
+ console.log(' Trust Inheritance:');
503
+ console.log(` Parent: ${ti.parent_trust} | Requested: ${ti.requested_trust} | Valid: ${ti.valid}`);
504
+ console.log(` ${ti.reason}`);
505
+ // Blockers
506
+ if (result.verification.blockers.length > 0) {
507
+ console.log('');
508
+ console.log(' Blockers:');
509
+ for (const b of result.verification.blockers) {
510
+ console.log(` - ${b}`);
511
+ }
512
+ }
513
+ if (result.status === 'pending_approval') {
514
+ console.log('');
515
+ console.log(` To approve: tryassay runtime agents approve ${result.proposalId}`);
516
+ }
517
+ console.log('');
518
+ }
519
+ export async function runtimeAgentsRetireCommand(agentId, opts) {
520
+ console.log('');
521
+ console.log(` Retiring agent "${agentId}"...`);
522
+ console.log(` Operator: ${opts.operator ?? 'human-operator'}`);
523
+ console.log(' Note: Agent retirement is recorded in the audit log.');
524
+ console.log(' The agent will no longer receive task assignments.');
525
+ console.log('');
526
+ }
527
+ export async function runtimeRulesProposeCommand(specPath, opts) {
528
+ const { readFile } = await import('node:fs/promises');
529
+ const { RuleProposalManager } = await import('../runtime/rule-proposal-manager.js');
530
+ // Read rule spec from JSON file
531
+ let spec;
532
+ try {
533
+ const raw = await readFile(specPath, 'utf-8');
534
+ spec = JSON.parse(raw);
535
+ }
536
+ catch (err) {
537
+ console.error(` Error reading rule spec: ${err instanceof Error ? err.message : String(err)}`);
538
+ process.exit(1);
539
+ }
540
+ const manager = new RuleProposalManager();
541
+ console.log('');
542
+ console.log(' Proposing Verification Rule...');
543
+ const result = await manager.propose(spec, {
544
+ capability_gap: spec.justification?.capability_gap ?? 'Unspecified',
545
+ evidence: spec.justification?.evidence ?? [],
546
+ expected_impact: spec.justification?.expected_impact ?? 'Unspecified',
547
+ risk_assessment: spec.justification?.risk_assessment ?? 'Unspecified',
548
+ });
549
+ console.log('');
550
+ console.log(' Rule Proposal Report');
551
+ console.log(' ====================');
552
+ console.log(` Proposal ID: ${result.proposalId}`);
553
+ console.log(` Status: ${result.status}`);
554
+ console.log('');
555
+ // Meta-verification results
556
+ const mv = result.metaVerification;
557
+ console.log(' Meta-Verification:');
558
+ console.log(` Verdict: ${mv.verdict}`);
559
+ console.log(` Test results: ${mv.test_results.filter(r => r.match).length}/${mv.test_results.length} passed`);
560
+ console.log(` Consistency: ${mv.consistency.consistent ? 'deterministic' : `non-deterministic (variance: ${mv.consistency.variance.toFixed(3)})`}`);
561
+ console.log(` Consistency runs: ${mv.consistency.runs}`);
562
+ for (const tr of mv.test_results) {
563
+ const marker = tr.match ? 'PASS' : 'FAIL';
564
+ console.log(` [${marker}] ${tr.case_id}: expected ${tr.expected_verdict}, got ${tr.actual_verdict}`);
565
+ }
566
+ // Conflict report
567
+ const cr = result.conflictReport;
568
+ console.log('');
569
+ console.log(' Conflict Analysis:');
570
+ console.log(` Direct conflicts: ${cr.direct_conflicts.length}`);
571
+ console.log(` Scope overlaps: ${cr.scope_overlaps.length}`);
572
+ console.log(` Transitive chains: ${cr.transitive_chains.length}`);
573
+ for (const c of cr.direct_conflicts) {
574
+ console.log(` [conflict] ${c.rule_a} vs ${c.rule_b}: ${c.description}`);
575
+ }
576
+ for (const o of cr.scope_overlaps) {
577
+ console.log(` [overlap:${o.risk}] ${o.rule_a} vs ${o.rule_b}: ${o.description}`);
578
+ }
579
+ // Blockers
580
+ if (mv.blockers.length > 0) {
581
+ console.log('');
582
+ console.log(' Blockers:');
583
+ for (const b of mv.blockers) {
584
+ console.log(` - ${b}`);
585
+ }
586
+ }
587
+ if (result.status === 'pending_approval') {
588
+ console.log('');
589
+ console.log(` To approve: tryassay runtime rules approve ${result.proposalId}`);
590
+ }
591
+ console.log('');
592
+ }
593
+ export async function runtimeRulesShadowCommand(ruleId, opts) {
594
+ const { RuleCanaryDeployer } = await import('../runtime/rule-canary-deployer.js');
595
+ const deployer = new RuleCanaryDeployer();
596
+ await deployer.loadState();
597
+ const deployment = deployer.getDeployment(ruleId);
598
+ if (!deployment) {
599
+ console.log(` No active canary deployment for rule "${ruleId}".`);
600
+ return;
601
+ }
602
+ console.log('');
603
+ console.log(' Canary Deployment Status');
604
+ console.log(' ========================');
605
+ console.log(` Rule: ${ruleId}`);
606
+ console.log(` Stage: ${deployment.stage}`);
607
+ console.log(` Started: ${deployment.started_at}`);
608
+ console.log(` Duration: ${deployment.stage_duration_hours.toFixed(1)} hours`);
609
+ console.log('');
610
+ console.log(' Metrics:');
611
+ console.log(` Evaluations: ${deployment.metrics.total_evaluations}`);
612
+ console.log(` Agreements: ${deployment.metrics.agreements_with_baseline}`);
613
+ console.log(` Disagreements: ${deployment.metrics.disagreements}`);
614
+ console.log(` Error rate: ${(deployment.metrics.error_rate * 100).toFixed(1)}%`);
615
+ console.log(` False positive rate: ${(deployment.metrics.false_positive_rate * 100).toFixed(1)}%`);
616
+ console.log(` False negative rate: ${(deployment.metrics.false_negative_rate * 100).toFixed(1)}%`);
617
+ console.log(` Avg latency: ${deployment.metrics.avg_latency_ms.toFixed(0)}ms`);
618
+ console.log('');
619
+ console.log(' Exit Criteria:');
620
+ console.log(` Min evaluations: ${deployment.exit_criteria.min_evaluations}`);
621
+ console.log(` Max error rate: ${(deployment.exit_criteria.max_error_rate * 100).toFixed(1)}%`);
622
+ console.log(` Max disagreement rate: ${(deployment.exit_criteria.max_disagreement_rate * 100).toFixed(1)}%`);
623
+ console.log(` Min duration: ${deployment.exit_criteria.min_duration_hours}h`);
624
+ const promotion = deployer.checkPromotion(ruleId);
625
+ console.log('');
626
+ console.log(` Promotion: ${promotion.action} — ${promotion.reason}`);
627
+ console.log('');
628
+ }
629
+ export async function runtimeRulesPromoteCommand(ruleId) {
630
+ const { RuleCanaryDeployer } = await import('../runtime/rule-canary-deployer.js');
631
+ const deployer = new RuleCanaryDeployer();
632
+ await deployer.loadState();
633
+ const check = deployer.checkPromotion(ruleId);
634
+ if (check.action !== 'promote') {
635
+ console.log(` Cannot promote: ${check.reason}`);
636
+ return;
637
+ }
638
+ const deployment = deployer.promote(ruleId);
639
+ if (!deployment) {
640
+ console.log(' Promotion failed.');
641
+ return;
642
+ }
643
+ await deployer.saveState();
644
+ console.log('');
645
+ console.log(` Rule "${ruleId}" promoted to ${deployment.stage}.`);
646
+ if (deployment.stage === 'full_rollout') {
647
+ console.log(' Rule is now active in production.');
648
+ }
649
+ else {
650
+ console.log(` Next exit criteria: ${deployment.exit_criteria.min_evaluations} evaluations over ${deployment.exit_criteria.min_duration_hours}h.`);
651
+ }
652
+ console.log('');
653
+ }
654
+ // ── Phase 4 M4: Safety Management Commands ───────────────
655
+ export async function runtimeSafetyStatusCommand(opts) {
656
+ const targetPath = opts.path ?? '.';
657
+ const { Layer2Guardian } = await import('../runtime/layer2-guardian.js');
658
+ const { KillSwitch } = await import('../runtime/kill-switch.js');
659
+ const { RollbackManager } = await import('../runtime/rollback-manager.js');
660
+ const { SafetyStatusReporter } = await import('../runtime/safety-status.js');
661
+ const { CapabilityRegistryManager } = await import('../runtime/capability-registry.js');
662
+ const guardian = new Layer2Guardian(targetPath);
663
+ const killSwitch = new KillSwitch();
664
+ const registry = new CapabilityRegistryManager(`${targetPath}/.assay/capability-registry.json`);
665
+ await registry.load();
666
+ const rollbackManager = new RollbackManager(registry, killSwitch);
667
+ const reporter = new SafetyStatusReporter(guardian, killSwitch, rollbackManager);
668
+ const report = await reporter.generateReport();
669
+ console.log('');
670
+ console.log(' Assay Safety Status');
671
+ console.log(' ===================');
672
+ console.log(` Overall: ${report.overall_status.toUpperCase()}`);
673
+ console.log(` Timestamp: ${report.timestamp}`);
674
+ console.log('');
675
+ // Layer 2
676
+ console.log(' Layer 2 Integrity:');
677
+ console.log(` Manifest present: ${report.layer2.manifest_present ? 'yes' : 'NO'}`);
678
+ console.log(` Permissions valid: ${report.layer2.permissions_valid ? 'yes' : 'NO'}`);
679
+ if (report.layer2.integrity) {
680
+ console.log(` Components checked: ${report.layer2.integrity.components_checked}`);
681
+ console.log(` Components valid: ${report.layer2.integrity.components_valid}`);
682
+ console.log(` Integrity: ${report.layer2.integrity.overall}`);
683
+ for (const v of report.layer2.integrity.components_invalid) {
684
+ console.log(` [VIOLATION] ${v.component} (${v.file_path}): hash mismatch`);
685
+ }
686
+ }
687
+ for (const f of report.layer2.permission_findings) {
688
+ console.log(` [PERMISSION] ${f.path}: ${f.issue}`);
689
+ }
690
+ // Kill switch
691
+ console.log('');
692
+ console.log(' Kill Switch:');
693
+ console.log(` System halted: ${report.kill_switch.system_halted ? 'YES' : 'no'}`);
694
+ console.log(` Suspended entities: ${report.kill_switch.suspended_count}`);
695
+ for (const s of report.kill_switch.suspended_entities) {
696
+ console.log(` [${s.level}] ${s.target}: ${s.reason} (since ${s.since})`);
697
+ }
698
+ // Rollback
699
+ console.log('');
700
+ console.log(' Rollback History:');
701
+ console.log(` Total rollbacks: ${report.rollback.total_rollbacks}`);
702
+ console.log(` Automatic: ${report.rollback.auto_rollbacks}`);
703
+ console.log(` Human: ${report.rollback.human_rollbacks}`);
704
+ console.log(` Layer 2: ${report.rollback.layer2_rollbacks}`);
705
+ for (const r of report.rollback.recent_rollbacks.slice(-5)) {
706
+ console.log(` [${r.trigger}] ${r.target_type}/${r.target_id}: ${r.reason.slice(0, 80)}`);
707
+ }
708
+ // Recommendations
709
+ console.log('');
710
+ console.log(' Recommendations:');
711
+ for (const rec of report.recommendations) {
712
+ console.log(` - ${rec}`);
713
+ }
714
+ console.log('');
715
+ }
716
+ export async function runtimeSafetySignCommand(opts) {
717
+ const targetPath = opts.path ?? '.';
718
+ const operator = opts.operator ?? 'human-operator';
719
+ const { Layer2Guardian } = await import('../runtime/layer2-guardian.js');
720
+ const guardian = new Layer2Guardian(targetPath);
721
+ console.log('');
722
+ console.log(' Generating Layer 2 Manifest...');
723
+ console.log('');
724
+ try {
725
+ const manifest = await guardian.generateManifest(operator);
726
+ await guardian.saveManifest(manifest);
727
+ console.log(' Layer 2 Manifest Generated');
728
+ console.log(' ==========================');
729
+ console.log(` Version: ${manifest.version}`);
730
+ console.log(` Deployed by: ${manifest.deployed_by}`);
731
+ console.log(` Manifest hash: ${manifest.manifest_hash}`);
732
+ console.log(` Signing key: ${manifest.signing_key_id}`);
733
+ console.log('');
734
+ console.log(' Components:');
735
+ for (const comp of manifest.components) {
736
+ console.log(` [${comp.component}] ${comp.file_path}`);
737
+ console.log(` Hash: ${comp.hash}`);
738
+ console.log(` Size: ${comp.size_bytes} bytes`);
739
+ }
740
+ console.log('');
741
+ console.log(` Manifest saved to: ${targetPath}/.assay/layer2-manifest.json`);
742
+ }
743
+ catch (err) {
744
+ console.error(` Error: ${err instanceof Error ? err.message : String(err)}`);
745
+ process.exit(1);
746
+ }
747
+ console.log('');
748
+ }
749
+ export async function runtimeSafetyRollbackCommand(targetId, opts) {
750
+ const targetPath = opts.path ?? '.';
751
+ const operator = opts.operator ?? 'human-operator';
752
+ const targetType = (opts.type ?? 'tool');
753
+ const { KillSwitch } = await import('../runtime/kill-switch.js');
754
+ const { RollbackManager } = await import('../runtime/rollback-manager.js');
755
+ const { CapabilityRegistryManager } = await import('../runtime/capability-registry.js');
756
+ const killSwitch = new KillSwitch();
757
+ const registry = new CapabilityRegistryManager(`${targetPath}/.assay/capability-registry.json`);
758
+ await registry.load();
759
+ const rollbackManager = new RollbackManager(registry, killSwitch);
760
+ console.log('');
761
+ console.log(` Rolling back ${targetType} "${targetId}"...`);
762
+ const event = await rollbackManager.triggerRollback('human', operator, targetType, targetId, `Manual rollback requested by ${operator} via CLI`);
763
+ console.log('');
764
+ console.log(' Rollback Complete');
765
+ console.log(' =================');
766
+ console.log(` Rollback ID: ${event.id}`);
767
+ console.log(` Trigger: ${event.trigger}`);
768
+ console.log(` Target: ${event.target_type}/${event.target_id}`);
769
+ console.log(` From version: ${event.from_version}`);
770
+ console.log(` To version: ${event.to_version}`);
771
+ console.log(` Post-rollback verification: ${event.verification_after_rollback}`);
772
+ console.log('');
773
+ }
774
+ export async function runtimeSafetyKillswitchCommand(target, opts) {
775
+ const { KillSwitch } = await import('../runtime/kill-switch.js');
776
+ const killSwitch = new KillSwitch();
777
+ const level = (opts.level ?? 'human');
778
+ const action = (opts.action ?? 'suspend_agent');
779
+ const operator = opts.operator ?? 'human-operator';
780
+ const reason = opts.reason ?? `Manual kill switch activation via CLI by ${operator}`;
781
+ console.log('');
782
+ console.log(` Activating kill switch...`);
783
+ try {
784
+ const event = await killSwitch.activate(level, action, target, operator, reason);
785
+ console.log('');
786
+ console.log(' Kill Switch Activated');
787
+ console.log(' =====================');
788
+ console.log(` Event ID: ${event.id}`);
789
+ console.log(` Level: ${event.level}`);
790
+ console.log(` Action: ${event.action}`);
791
+ console.log(` Target: ${event.target}`);
792
+ console.log(` Triggered by: ${event.triggered_by}`);
793
+ console.log(` Reason: ${event.reason}`);
794
+ console.log(` Auto-restart: ${event.auto_restart ? 'yes' : 'no'}`);
795
+ console.log(` Requires redeployment: ${event.requires_redeployment ? 'YES' : 'no'}`);
796
+ }
797
+ catch (err) {
798
+ console.error(` Error: ${err instanceof Error ? err.message : String(err)}`);
799
+ process.exit(1);
800
+ }
801
+ console.log('');
802
+ }
249
803
  //# sourceMappingURL=runtime.js.map