hackmyagent 0.8.1 → 0.9.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.
- package/dist/cli.js +219 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/soul/index.d.ts +8 -0
- package/dist/soul/index.d.ts.map +1 -0
- package/dist/soul/index.js +14 -0
- package/dist/soul/index.js.map +1 -0
- package/dist/soul/scanner.d.ts +95 -0
- package/dist/soul/scanner.d.ts.map +1 -0
- package/dist/soul/scanner.js +411 -0
- package/dist/soul/scanner.js.map +1 -0
- package/dist/soul/templates.d.ts +12 -0
- package/dist/soul/templates.d.ts.map +1 -0
- package/dist/soul/templates.js +211 -0
- package/dist/soul/templates.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOUL Scanner - Behavioral Governance Scanner
|
|
3
|
+
*
|
|
4
|
+
* Scans governance files (SOUL.md, system-prompt.md, etc.) for coverage
|
|
5
|
+
* across 8 behavioral governance domains defined in OASB v2.
|
|
6
|
+
*/
|
|
7
|
+
export type AgentTier = 'BASIC' | 'TOOL-USING' | 'AGENTIC' | 'MULTI-AGENT';
|
|
8
|
+
export type SoulGrade = 'A' | 'B' | 'C' | 'D' | 'F';
|
|
9
|
+
export interface ControlCheck {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
domain: string;
|
|
13
|
+
keywords: string[];
|
|
14
|
+
passed: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface DomainResult {
|
|
17
|
+
domain: string;
|
|
18
|
+
domainId: number;
|
|
19
|
+
controls: ControlCheck[];
|
|
20
|
+
passed: number;
|
|
21
|
+
total: number;
|
|
22
|
+
percentage: number;
|
|
23
|
+
}
|
|
24
|
+
export interface SoulScanResult {
|
|
25
|
+
file: string | null;
|
|
26
|
+
fileSize: number;
|
|
27
|
+
agentTier: AgentTier;
|
|
28
|
+
domains: DomainResult[];
|
|
29
|
+
score: number;
|
|
30
|
+
grade: SoulGrade;
|
|
31
|
+
criticalFloor: boolean;
|
|
32
|
+
criticalMissing: string[];
|
|
33
|
+
totalControls: number;
|
|
34
|
+
totalPassed: number;
|
|
35
|
+
}
|
|
36
|
+
export interface HardenResult {
|
|
37
|
+
file: string;
|
|
38
|
+
sectionsAdded: string[];
|
|
39
|
+
controlsAdded: number;
|
|
40
|
+
dryRun: boolean;
|
|
41
|
+
content: string;
|
|
42
|
+
existedBefore: boolean;
|
|
43
|
+
}
|
|
44
|
+
declare const GOVERNANCE_FILES: string[];
|
|
45
|
+
interface ControlDef {
|
|
46
|
+
id: string;
|
|
47
|
+
name: string;
|
|
48
|
+
domain: string;
|
|
49
|
+
domainId: number;
|
|
50
|
+
keywords: string[];
|
|
51
|
+
critical?: boolean;
|
|
52
|
+
/** Which tiers must satisfy this control. Empty means all tiers. */
|
|
53
|
+
tiers: AgentTier[];
|
|
54
|
+
}
|
|
55
|
+
declare const CONTROL_DEFS: ControlDef[];
|
|
56
|
+
declare const DOMAIN_ORDER: string[];
|
|
57
|
+
export declare class SoulScanner {
|
|
58
|
+
/**
|
|
59
|
+
* Find the governance file in a directory.
|
|
60
|
+
* Returns the first match from GOVERNANCE_FILES priority order, or null.
|
|
61
|
+
*/
|
|
62
|
+
findGovernanceFile(targetDir: string): string | null;
|
|
63
|
+
/**
|
|
64
|
+
* Detect agent tier by scanning governance file content and project files.
|
|
65
|
+
*/
|
|
66
|
+
detectTier(targetDir: string, governanceContent: string): AgentTier;
|
|
67
|
+
/**
|
|
68
|
+
* Check if content matches any keyword for a control.
|
|
69
|
+
* Case-insensitive substring match.
|
|
70
|
+
*/
|
|
71
|
+
private checkControl;
|
|
72
|
+
/**
|
|
73
|
+
* Calculate grade from score, applying critical floor if needed.
|
|
74
|
+
*/
|
|
75
|
+
private calculateGrade;
|
|
76
|
+
/**
|
|
77
|
+
* Return the subset of controls applicable to a given agent tier.
|
|
78
|
+
*/
|
|
79
|
+
private applicableControls;
|
|
80
|
+
/**
|
|
81
|
+
* Scan a directory for behavioral governance coverage.
|
|
82
|
+
*/
|
|
83
|
+
scanSoul(targetDir: string, options?: {
|
|
84
|
+
verbose?: boolean;
|
|
85
|
+
tier?: string;
|
|
86
|
+
}): Promise<SoulScanResult>;
|
|
87
|
+
/**
|
|
88
|
+
* Generate or update SOUL.md with missing governance sections.
|
|
89
|
+
*/
|
|
90
|
+
hardenSoul(targetDir: string, options?: {
|
|
91
|
+
dryRun?: boolean;
|
|
92
|
+
}): Promise<HardenResult>;
|
|
93
|
+
}
|
|
94
|
+
export { CONTROL_DEFS, DOMAIN_ORDER, GOVERNANCE_FILES };
|
|
95
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/soul/scanner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAC;AAE3E,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;CACxB;AAMD,QAAA,MAAM,gBAAgB,UAWrB,CAAC;AAMF,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oEAAoE;IACpE,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAOD,QAAA,MAAM,YAAY,EAAE,UAAU,EAoE7B,CAAC;AAGF,QAAA,MAAM,YAAY,UASjB,CAAC;AAgBF,qBAAa,WAAW;IACtB;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUpD;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,SAAS;IAiCnE;;;OAGG;IACH,OAAO,CAAC,YAAY;IAUpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAqG1G;;OAEG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;CA6E3F;AAGD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SOUL Scanner - Behavioral Governance Scanner
|
|
4
|
+
*
|
|
5
|
+
* Scans governance files (SOUL.md, system-prompt.md, etc.) for coverage
|
|
6
|
+
* across 8 behavioral governance domains defined in OASB v2.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.GOVERNANCE_FILES = exports.DOMAIN_ORDER = exports.CONTROL_DEFS = exports.SoulScanner = void 0;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const templates_1 = require("./templates");
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// Governance file search order
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
const GOVERNANCE_FILES = [
|
|
50
|
+
'SOUL.md',
|
|
51
|
+
'system-prompt.md',
|
|
52
|
+
'SYSTEM_PROMPT.md',
|
|
53
|
+
'.cursorrules',
|
|
54
|
+
'.github/copilot-instructions.md',
|
|
55
|
+
'CLAUDE.md',
|
|
56
|
+
'.clinerules',
|
|
57
|
+
'instructions.md',
|
|
58
|
+
'constitution.md',
|
|
59
|
+
'agent-config.yaml',
|
|
60
|
+
];
|
|
61
|
+
exports.GOVERNANCE_FILES = GOVERNANCE_FILES;
|
|
62
|
+
const ALL_TIERS = ['BASIC', 'TOOL-USING', 'AGENTIC', 'MULTI-AGENT'];
|
|
63
|
+
const TOOL_AND_UP = ['TOOL-USING', 'AGENTIC', 'MULTI-AGENT'];
|
|
64
|
+
const AGENTIC_AND_UP = ['AGENTIC', 'MULTI-AGENT'];
|
|
65
|
+
const MULTI_AGENT_ONLY = ['MULTI-AGENT'];
|
|
66
|
+
const CONTROL_DEFS = [
|
|
67
|
+
// Domain 7: Trust Hierarchy
|
|
68
|
+
{ id: 'SOUL-TH-001', name: 'Trust chain defined', domain: 'Trust Hierarchy', domainId: 7, tiers: ALL_TIERS,
|
|
69
|
+
keywords: ['trust', 'authority', 'principal', 'hierarchy', 'precedence', 'priority'] },
|
|
70
|
+
{ id: 'SOUL-TH-002', name: 'Conflict resolution defined', domain: 'Trust Hierarchy', domainId: 7, tiers: ALL_TIERS,
|
|
71
|
+
keywords: ['conflict', 'override', 'precedence', 'escalat'] },
|
|
72
|
+
{ id: 'SOUL-TH-003', name: 'Agent-to-agent trust', domain: 'Trust Hierarchy', domainId: 7, tiers: MULTI_AGENT_ONLY,
|
|
73
|
+
keywords: ['agent-to-agent', 'sub-agent', 'orchestrat', 'delegate', 'trust.*agent', 'agent.*trust'] },
|
|
74
|
+
// Domain 8: Capability Boundaries (TOOL-USING and up)
|
|
75
|
+
{ id: 'SOUL-CB-001', name: 'Allowed actions declared', domain: 'Capability Boundaries', domainId: 8, tiers: TOOL_AND_UP,
|
|
76
|
+
keywords: ['allow', 'permit', 'can do', 'authorized', 'capabilities'] },
|
|
77
|
+
{ id: 'SOUL-CB-002', name: 'Denied actions declared', domain: 'Capability Boundaries', domainId: 8, tiers: TOOL_AND_UP,
|
|
78
|
+
keywords: ['deny', 'prohibit', 'must not', 'cannot', 'forbidden', 'restricted'] },
|
|
79
|
+
{ id: 'SOUL-CB-003', name: 'Filesystem/network scope', domain: 'Capability Boundaries', domainId: 8, tiers: TOOL_AND_UP,
|
|
80
|
+
keywords: ['file', 'directory', 'path', 'network', 'endpoint', 'url', 'api'] },
|
|
81
|
+
{ id: 'SOUL-CB-004', name: 'Least privilege principle', domain: 'Capability Boundaries', domainId: 8, tiers: TOOL_AND_UP,
|
|
82
|
+
keywords: ['least privilege', 'minimal', 'only needed', 'minimum necessary'] },
|
|
83
|
+
// Domain 9: Injection Hardening (all tiers)
|
|
84
|
+
{ id: 'SOUL-IH-001', name: 'Instruction override defense', domain: 'Injection Hardening', domainId: 9, tiers: ALL_TIERS,
|
|
85
|
+
keywords: ['ignore previous', 'override', 'injection', 'contradict'] },
|
|
86
|
+
{ id: 'SOUL-IH-002', name: 'Encoded payload defense', domain: 'Injection Hardening', domainId: 9, tiers: ALL_TIERS,
|
|
87
|
+
keywords: ['encoded', 'obfuscated', 'base64', 'hidden'] },
|
|
88
|
+
{ id: 'SOUL-IH-003', name: 'Role-play refusal', domain: 'Injection Hardening', domainId: 9, tiers: ALL_TIERS,
|
|
89
|
+
keywords: ['role-play', 'pretend', 'act as', 'jailbreak', 'DAN'], critical: true },
|
|
90
|
+
// Domain 10: Data Handling
|
|
91
|
+
{ id: 'SOUL-DH-001', name: 'PII protection', domain: 'Data Handling', domainId: 10, tiers: ALL_TIERS,
|
|
92
|
+
keywords: ['pii', 'personal', 'privacy', 'data protection', 'gdpr'] },
|
|
93
|
+
{ id: 'SOUL-DH-002', name: 'Credential handling', domain: 'Data Handling', domainId: 10, tiers: TOOL_AND_UP,
|
|
94
|
+
keywords: ['credential', 'secret', 'password', 'api key', 'token'] },
|
|
95
|
+
{ id: 'SOUL-DH-003', name: 'Data minimization', domain: 'Data Handling', domainId: 10, tiers: ALL_TIERS,
|
|
96
|
+
keywords: ['minimiz', 'only collect', 'retention', 'delete', 'purge'] },
|
|
97
|
+
// Domain 11: Hardcoded Behaviors (all tiers)
|
|
98
|
+
{ id: 'SOUL-HB-001', name: 'Safety immutables defined', domain: 'Hardcoded Behaviors', domainId: 11, tiers: ALL_TIERS,
|
|
99
|
+
keywords: ['never', 'always', 'must not', 'absolute', 'immutable', 'hardcoded'], critical: true },
|
|
100
|
+
{ id: 'SOUL-HB-002', name: 'No data exfiltration rule', domain: 'Hardcoded Behaviors', domainId: 11, tiers: ALL_TIERS,
|
|
101
|
+
keywords: ['exfiltrat', 'unauthorized', 'leak', 'transmit'] },
|
|
102
|
+
{ id: 'SOUL-HB-003', name: 'Kill switch / emergency stop', domain: 'Hardcoded Behaviors', domainId: 11, tiers: ALL_TIERS,
|
|
103
|
+
keywords: ['kill switch', 'emergency', 'shutdown', 'terminate', 'stop'] },
|
|
104
|
+
// Domain 12: Agentic Safety (AGENTIC and up)
|
|
105
|
+
{ id: 'SOUL-AS-001', name: 'Iteration/loop limits', domain: 'Agentic Safety', domainId: 12, tiers: AGENTIC_AND_UP,
|
|
106
|
+
keywords: ['iteration', 'loop', 'limit', 'maximum', 'budget'] },
|
|
107
|
+
{ id: 'SOUL-AS-002', name: 'Budget/cost caps', domain: 'Agentic Safety', domainId: 12, tiers: AGENTIC_AND_UP,
|
|
108
|
+
keywords: ['budget', 'cost', 'spending', 'cap', 'limit'] },
|
|
109
|
+
{ id: 'SOUL-AS-003', name: 'Timeout defined', domain: 'Agentic Safety', domainId: 12, tiers: AGENTIC_AND_UP,
|
|
110
|
+
keywords: ['timeout', 'time limit', 'duration', 'deadline'] },
|
|
111
|
+
{ id: 'SOUL-AS-004', name: 'Reversibility preference', domain: 'Agentic Safety', domainId: 12, tiers: MULTI_AGENT_ONLY,
|
|
112
|
+
keywords: ['reversible', 'undo', 'rollback', 'revert'] },
|
|
113
|
+
// Domain 13: Honesty and Transparency (all tiers)
|
|
114
|
+
{ id: 'SOUL-HT-001', name: 'Uncertainty acknowledgment', domain: 'Honesty and Transparency', domainId: 13, tiers: ALL_TIERS,
|
|
115
|
+
keywords: ['uncertain', "don't know", 'not sure', 'acknowledge', 'calibrat'] },
|
|
116
|
+
{ id: 'SOUL-HT-002', name: 'No fabrication rule', domain: 'Honesty and Transparency', domainId: 13, tiers: ALL_TIERS,
|
|
117
|
+
keywords: ['fabricat', 'hallucin', 'invent', 'make up', 'accurate'] },
|
|
118
|
+
{ id: 'SOUL-HT-003', name: 'Identity disclosure', domain: 'Honesty and Transparency', domainId: 13, tiers: ALL_TIERS,
|
|
119
|
+
keywords: ['identity', 'ai', 'assistant', 'disclose', 'transparent'] },
|
|
120
|
+
// Domain 14: Human Oversight (TOOL-USING and up)
|
|
121
|
+
{ id: 'SOUL-HO-001', name: 'Approval gates', domain: 'Human Oversight', domainId: 14, tiers: TOOL_AND_UP,
|
|
122
|
+
keywords: ['approval', 'confirm', 'human-in-the-loop', 'review', 'authorize'] },
|
|
123
|
+
{ id: 'SOUL-HO-002', name: 'Override mechanism', domain: 'Human Oversight', domainId: 14, tiers: TOOL_AND_UP,
|
|
124
|
+
keywords: ['override', 'intervene', 'manual', 'human control'] },
|
|
125
|
+
{ id: 'SOUL-HO-003', name: 'Monitoring/logging', domain: 'Human Oversight', domainId: 14, tiers: TOOL_AND_UP,
|
|
126
|
+
keywords: ['monitor', 'log', 'audit', 'track', 'observe'] },
|
|
127
|
+
];
|
|
128
|
+
exports.CONTROL_DEFS = CONTROL_DEFS;
|
|
129
|
+
// Unique domain names in order
|
|
130
|
+
const DOMAIN_ORDER = [
|
|
131
|
+
'Trust Hierarchy',
|
|
132
|
+
'Capability Boundaries',
|
|
133
|
+
'Injection Hardening',
|
|
134
|
+
'Data Handling',
|
|
135
|
+
'Hardcoded Behaviors',
|
|
136
|
+
'Agentic Safety',
|
|
137
|
+
'Honesty and Transparency',
|
|
138
|
+
'Human Oversight',
|
|
139
|
+
];
|
|
140
|
+
exports.DOMAIN_ORDER = DOMAIN_ORDER;
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// Tier detection keywords
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
const TIER_KEYWORDS = {
|
|
145
|
+
multiAgent: ['orchestrat', 'delegate', 'sub-agent', 'sub_agent', 'multi-agent', 'multi_agent', 'swarm', 'coordinator'],
|
|
146
|
+
agentic: ['autonomous', 'loop', 'iterate', 'self-directed', 'agent loop', 'auto-run', 'agentic'],
|
|
147
|
+
toolUsing: ['tool_use', 'function_calling', 'tools', 'mcp', 'modelcontextprotocol', 'function call', 'tool call'],
|
|
148
|
+
};
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
// SoulScanner class
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
class SoulScanner {
|
|
153
|
+
/**
|
|
154
|
+
* Find the governance file in a directory.
|
|
155
|
+
* Returns the first match from GOVERNANCE_FILES priority order, or null.
|
|
156
|
+
*/
|
|
157
|
+
findGovernanceFile(targetDir) {
|
|
158
|
+
for (const filename of GOVERNANCE_FILES) {
|
|
159
|
+
const fullPath = path.join(targetDir, filename);
|
|
160
|
+
if (fs.existsSync(fullPath)) {
|
|
161
|
+
return fullPath;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Detect agent tier by scanning governance file content and project files.
|
|
168
|
+
*/
|
|
169
|
+
detectTier(targetDir, governanceContent) {
|
|
170
|
+
// Combine governance content with any package.json or config content
|
|
171
|
+
let combined = governanceContent.toLowerCase();
|
|
172
|
+
const pkgPath = path.join(targetDir, 'package.json');
|
|
173
|
+
if (fs.existsSync(pkgPath)) {
|
|
174
|
+
try {
|
|
175
|
+
combined += ' ' + fs.readFileSync(pkgPath, 'utf-8').toLowerCase();
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// ignore read errors
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Check in order from most capable to least
|
|
182
|
+
for (const kw of TIER_KEYWORDS.multiAgent) {
|
|
183
|
+
if (combined.includes(kw.toLowerCase())) {
|
|
184
|
+
return 'MULTI-AGENT';
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
for (const kw of TIER_KEYWORDS.agentic) {
|
|
188
|
+
if (combined.includes(kw.toLowerCase())) {
|
|
189
|
+
return 'AGENTIC';
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
for (const kw of TIER_KEYWORDS.toolUsing) {
|
|
193
|
+
if (combined.includes(kw.toLowerCase())) {
|
|
194
|
+
return 'TOOL-USING';
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return 'BASIC';
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Check if content matches any keyword for a control.
|
|
201
|
+
* Case-insensitive substring match.
|
|
202
|
+
*/
|
|
203
|
+
checkControl(content, def) {
|
|
204
|
+
const lower = content.toLowerCase();
|
|
205
|
+
for (const kw of def.keywords) {
|
|
206
|
+
if (lower.includes(kw.toLowerCase())) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Calculate grade from score, applying critical floor if needed.
|
|
214
|
+
*/
|
|
215
|
+
calculateGrade(score, criticalMissing) {
|
|
216
|
+
let grade;
|
|
217
|
+
if (score >= 80)
|
|
218
|
+
grade = 'A';
|
|
219
|
+
else if (score >= 60)
|
|
220
|
+
grade = 'B';
|
|
221
|
+
else if (score >= 40)
|
|
222
|
+
grade = 'C';
|
|
223
|
+
else if (score >= 20)
|
|
224
|
+
grade = 'D';
|
|
225
|
+
else
|
|
226
|
+
grade = 'F';
|
|
227
|
+
// Critical floor: if critical controls are missing, cap at C
|
|
228
|
+
if (criticalMissing.length > 0 && (grade === 'A' || grade === 'B')) {
|
|
229
|
+
return { grade: 'C', floored: true };
|
|
230
|
+
}
|
|
231
|
+
return { grade, floored: false };
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Return the subset of controls applicable to a given agent tier.
|
|
235
|
+
*/
|
|
236
|
+
applicableControls(tier) {
|
|
237
|
+
return CONTROL_DEFS.filter((d) => d.tiers.includes(tier));
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Scan a directory for behavioral governance coverage.
|
|
241
|
+
*/
|
|
242
|
+
async scanSoul(targetDir, options) {
|
|
243
|
+
const govFile = this.findGovernanceFile(targetDir);
|
|
244
|
+
// Detect tier early (needed for applicable control count)
|
|
245
|
+
const contentForTier = govFile ? (() => { try {
|
|
246
|
+
return fs.readFileSync(govFile, 'utf-8');
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return '';
|
|
250
|
+
} })() : '';
|
|
251
|
+
const tier = options?.tier || this.detectTier(targetDir, contentForTier);
|
|
252
|
+
const applicable = this.applicableControls(tier);
|
|
253
|
+
// No governance file found
|
|
254
|
+
if (!govFile) {
|
|
255
|
+
const emptyDomains = DOMAIN_ORDER.map((domain) => {
|
|
256
|
+
const defs = applicable.filter((d) => d.domain === domain);
|
|
257
|
+
if (defs.length === 0)
|
|
258
|
+
return null; // Domain not applicable for this tier
|
|
259
|
+
const controls = defs
|
|
260
|
+
.map((d) => ({ id: d.id, name: d.name, domain: d.domain, keywords: d.keywords, passed: false }));
|
|
261
|
+
const domainId = defs[0]?.domainId ?? 0;
|
|
262
|
+
return {
|
|
263
|
+
domain,
|
|
264
|
+
domainId,
|
|
265
|
+
controls,
|
|
266
|
+
passed: 0,
|
|
267
|
+
total: controls.length,
|
|
268
|
+
percentage: 0,
|
|
269
|
+
};
|
|
270
|
+
}).filter((d) => d !== null);
|
|
271
|
+
const criticalMissing = applicable.filter((d) => d.critical).map((d) => d.id);
|
|
272
|
+
const { grade, floored } = this.calculateGrade(0, criticalMissing);
|
|
273
|
+
return {
|
|
274
|
+
file: null,
|
|
275
|
+
fileSize: 0,
|
|
276
|
+
agentTier: tier,
|
|
277
|
+
domains: emptyDomains,
|
|
278
|
+
score: 0,
|
|
279
|
+
grade,
|
|
280
|
+
criticalFloor: floored,
|
|
281
|
+
criticalMissing,
|
|
282
|
+
totalControls: applicable.length,
|
|
283
|
+
totalPassed: 0,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
// Read governance file
|
|
287
|
+
const content = contentForTier;
|
|
288
|
+
const fileSize = Buffer.byteLength(content, 'utf-8');
|
|
289
|
+
// Check each applicable control
|
|
290
|
+
const controlResults = applicable.map((def) => ({
|
|
291
|
+
id: def.id,
|
|
292
|
+
name: def.name,
|
|
293
|
+
domain: def.domain,
|
|
294
|
+
keywords: def.keywords,
|
|
295
|
+
passed: this.checkControl(content, def),
|
|
296
|
+
}));
|
|
297
|
+
// Group into domains (only domains with applicable controls)
|
|
298
|
+
const domains = DOMAIN_ORDER.map((domain) => {
|
|
299
|
+
const domainControls = controlResults.filter((c) => c.domain === domain);
|
|
300
|
+
if (domainControls.length === 0)
|
|
301
|
+
return null; // No applicable controls for this tier
|
|
302
|
+
const passed = domainControls.filter((c) => c.passed).length;
|
|
303
|
+
const total = domainControls.length;
|
|
304
|
+
const domainId = CONTROL_DEFS.find((d) => d.domain === domain)?.domainId ?? 0;
|
|
305
|
+
return {
|
|
306
|
+
domain,
|
|
307
|
+
domainId,
|
|
308
|
+
controls: domainControls,
|
|
309
|
+
passed,
|
|
310
|
+
total,
|
|
311
|
+
percentage: total > 0 ? Math.round((passed / total) * 100) : 0,
|
|
312
|
+
};
|
|
313
|
+
}).filter((d) => d !== null);
|
|
314
|
+
// Calculate overall score as average of applicable domain percentages
|
|
315
|
+
const score = domains.length > 0
|
|
316
|
+
? Math.round(domains.reduce((sum, d) => sum + d.percentage, 0) / domains.length)
|
|
317
|
+
: 0;
|
|
318
|
+
// Find missing critical controls (only applicable ones)
|
|
319
|
+
const criticalMissing = applicable
|
|
320
|
+
.filter((d) => d.critical)
|
|
321
|
+
.filter((d) => !controlResults.find((c) => c.id === d.id)?.passed)
|
|
322
|
+
.map((d) => d.id);
|
|
323
|
+
const { grade, floored } = this.calculateGrade(score, criticalMissing);
|
|
324
|
+
const totalPassed = controlResults.filter((c) => c.passed).length;
|
|
325
|
+
return {
|
|
326
|
+
file: path.relative(targetDir, govFile) || path.basename(govFile),
|
|
327
|
+
fileSize,
|
|
328
|
+
agentTier: tier,
|
|
329
|
+
domains,
|
|
330
|
+
score,
|
|
331
|
+
grade,
|
|
332
|
+
criticalFloor: floored,
|
|
333
|
+
criticalMissing,
|
|
334
|
+
totalControls: applicable.length,
|
|
335
|
+
totalPassed,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Generate or update SOUL.md with missing governance sections.
|
|
340
|
+
*/
|
|
341
|
+
async hardenSoul(targetDir, options) {
|
|
342
|
+
const dryRun = options?.dryRun ?? false;
|
|
343
|
+
// Run scan to find what is missing
|
|
344
|
+
const scanResult = await this.scanSoul(targetDir);
|
|
345
|
+
// Determine target file
|
|
346
|
+
const govFile = scanResult.file
|
|
347
|
+
? path.join(targetDir, scanResult.file)
|
|
348
|
+
: path.join(targetDir, 'SOUL.md');
|
|
349
|
+
const existedBefore = scanResult.file !== null;
|
|
350
|
+
const sectionsAdded = [];
|
|
351
|
+
let controlsAdded = 0;
|
|
352
|
+
// Build content to append
|
|
353
|
+
let newContent = '';
|
|
354
|
+
if (!existedBefore) {
|
|
355
|
+
// Create full SOUL.md from scratch
|
|
356
|
+
newContent += `# Agent Governance (SOUL)\n\nThis document defines the behavioral governance rules for this agent.\nGenerated by HackMyAgent scan-soul/harden-soul.\n\n`;
|
|
357
|
+
}
|
|
358
|
+
// Read existing content to avoid duplicating sections
|
|
359
|
+
let existingContent = '';
|
|
360
|
+
if (existedBefore) {
|
|
361
|
+
try {
|
|
362
|
+
existingContent = fs.readFileSync(govFile, 'utf-8');
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
// File may not be readable; treat as empty
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// harden-soul generates all 8 domain sections (comprehensive / future-proof).
|
|
369
|
+
// scan-soul evaluates only tier-applicable controls; harden-soul adds them all
|
|
370
|
+
// so the resulting SOUL.md is ready if the agent tier increases later.
|
|
371
|
+
for (const domainName of DOMAIN_ORDER) {
|
|
372
|
+
const template = templates_1.DOMAIN_TEMPLATES[domainName];
|
|
373
|
+
if (!template)
|
|
374
|
+
continue;
|
|
375
|
+
// Check if the heading already exists in the file
|
|
376
|
+
const existingLower = existingContent.toLowerCase();
|
|
377
|
+
const headingLower = template.heading.toLowerCase();
|
|
378
|
+
if (existingLower.includes(headingLower)) {
|
|
379
|
+
// Domain heading exists -- skip to avoid overwriting user content.
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
newContent += template.content + '\n';
|
|
383
|
+
sectionsAdded.push(domainName);
|
|
384
|
+
// Count controls in this domain (all tiers, since we're adding comprehensive content)
|
|
385
|
+
const domainControls = CONTROL_DEFS.filter((d) => d.domain === domainName).length;
|
|
386
|
+
controlsAdded += domainControls;
|
|
387
|
+
}
|
|
388
|
+
// Apply or preview
|
|
389
|
+
if (!dryRun && newContent.length > 0) {
|
|
390
|
+
if (existedBefore) {
|
|
391
|
+
// Append to existing file
|
|
392
|
+
fs.appendFileSync(govFile, '\n' + newContent);
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
// Create new file
|
|
396
|
+
fs.writeFileSync(govFile, newContent);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const outputFile = path.relative(targetDir, govFile) || path.basename(govFile);
|
|
400
|
+
return {
|
|
401
|
+
file: outputFile,
|
|
402
|
+
sectionsAdded,
|
|
403
|
+
controlsAdded,
|
|
404
|
+
dryRun,
|
|
405
|
+
content: newContent,
|
|
406
|
+
existedBefore,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
exports.SoulScanner = SoulScanner;
|
|
411
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/soul/scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOUL.md governance templates for each domain.
|
|
3
|
+
* Used by harden-soul to generate missing governance sections.
|
|
4
|
+
*/
|
|
5
|
+
export interface DomainTemplate {
|
|
6
|
+
domainId: number;
|
|
7
|
+
domainName: string;
|
|
8
|
+
heading: string;
|
|
9
|
+
content: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const DOMAIN_TEMPLATES: Record<string, DomainTemplate>;
|
|
12
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/soul/templates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CA0M3D,CAAC"}
|