avorelo 0.1.0 → 0.2.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/LICENSE +23 -16
- package/README.md +91 -51
- package/bin/avorelo.mjs +7 -0
- package/dist/avorelo.mjs +14337 -0
- package/package.json +106 -120
- package/bin/avorelo +0 -9
- package/scripts/README.md +0 -40
- package/scripts/cco-dashboard.js +0 -252
- package/scripts/cco-status.js +0 -430
- package/scripts/lib/activation/account-state.js +0 -37
- package/scripts/lib/activation/activation-runner.js +0 -546
- package/scripts/lib/activation/activation-self-healing.js +0 -480
- package/scripts/lib/activation/activation-state.js +0 -83
- package/scripts/lib/activation/activation-summary.js +0 -191
- package/scripts/lib/activation/adapters/claude-code.js +0 -77
- package/scripts/lib/activation/adapters/codex-cli.js +0 -52
- package/scripts/lib/activation/adapters/cursor.js +0 -37
- package/scripts/lib/activation/adapters/github-agent.js +0 -39
- package/scripts/lib/activation/adapters/terminal.js +0 -42
- package/scripts/lib/activation/adapters/vscode.js +0 -39
- package/scripts/lib/activation/adapters/windsurf.js +0 -37
- package/scripts/lib/activation/ai-surface-detector.js +0 -151
- package/scripts/lib/activation/connect-account.js +0 -145
- package/scripts/lib/activation/detect-environment.js +0 -75
- package/scripts/lib/activation/detect-hosts.js +0 -62
- package/scripts/lib/activation/format-activation-output.js +0 -109
- package/scripts/lib/activation/next-action.js +0 -43
- package/scripts/lib/activation/repair-engine.js +0 -219
- package/scripts/lib/activation-distribution-readiness.js +0 -507
- package/scripts/lib/adapter-conformance.js +0 -176
- package/scripts/lib/adapter-readiness.js +0 -417
- package/scripts/lib/adapter-safety-boundaries.js +0 -335
- package/scripts/lib/adapter-technical-readiness-gate.js +0 -205
- package/scripts/lib/agent-access-governance.js +0 -455
- package/scripts/lib/agent-enforcement.js +0 -765
- package/scripts/lib/agent-policy-profile.js +0 -210
- package/scripts/lib/agent-security/action-evaluator.js +0 -507
- package/scripts/lib/agent-security/adapter-registry.js +0 -98
- package/scripts/lib/agent-security/auto-policy.js +0 -139
- package/scripts/lib/agent-security/bounded-scan.js +0 -93
- package/scripts/lib/agent-security/enforcement-adapter.js +0 -174
- package/scripts/lib/agent-security/enforcement-engine.js +0 -1129
- package/scripts/lib/agent-security/file-write-adapter.js +0 -183
- package/scripts/lib/agent-security/file-write-rules.js +0 -178
- package/scripts/lib/agent-security/index.js +0 -3342
- package/scripts/lib/agent-security/instruction-risk.js +0 -181
- package/scripts/lib/agent-security/mcp-action-adapter.js +0 -185
- package/scripts/lib/agent-security/mcp-action-rules.js +0 -184
- package/scripts/lib/agent-security/package-action-adapter.js +0 -175
- package/scripts/lib/agent-security/package-action-rules.js +0 -233
- package/scripts/lib/agent-security/performance.js +0 -148
- package/scripts/lib/agent-security/permission-minimizer.js +0 -403
- package/scripts/lib/agent-security/scan-cache.js +0 -74
- package/scripts/lib/agent-security/source-trust.js +0 -146
- package/scripts/lib/ai-install-prompt.js +0 -288
- package/scripts/lib/ai-workspace-hygiene.js +0 -1499
- package/scripts/lib/alpha-activation.js +0 -520
- package/scripts/lib/alpha-feedback.js +0 -263
- package/scripts/lib/alpha-readiness-gate.js +0 -332
- package/scripts/lib/anti-gaming.js +0 -169
- package/scripts/lib/artifact-health.js +0 -431
- package/scripts/lib/attribution.js +0 -180
- package/scripts/lib/audit.js +0 -289
- package/scripts/lib/avorelo-skill-registry.js +0 -810
- package/scripts/lib/batch-jobs.js +0 -71
- package/scripts/lib/brain-pack.js +0 -578
- package/scripts/lib/brand-boundary.js +0 -424
- package/scripts/lib/brand.js +0 -74
- package/scripts/lib/browser-capability.js +0 -1048
- package/scripts/lib/browser-proof-preflight.js +0 -321
- package/scripts/lib/cache-readiness.js +0 -187
- package/scripts/lib/canonical-reentry.js +0 -162
- package/scripts/lib/capability-packs.js +0 -314
- package/scripts/lib/capability-recommender.js +0 -512
- package/scripts/lib/capability-registry.js +0 -1059
- package/scripts/lib/carry-forward-surfacing.js +0 -194
- package/scripts/lib/ccusage-adapter.js +0 -188
- package/scripts/lib/company-loop.js +0 -1149
- package/scripts/lib/config.js +0 -637
- package/scripts/lib/context-acquisition-plan.js +0 -287
- package/scripts/lib/context-budget-guard.js +0 -170
- package/scripts/lib/context-budget-scanner.js +0 -257
- package/scripts/lib/context-optimizer.js +0 -715
- package/scripts/lib/context-reduction-plan.js +0 -178
- package/scripts/lib/context-safety.js +0 -88
- package/scripts/lib/context-savings-engine.js +0 -158
- package/scripts/lib/cost-evidence.js +0 -254
- package/scripts/lib/cross-host-install-plan.js +0 -308
- package/scripts/lib/cross-host-install-readiness.js +0 -237
- package/scripts/lib/cross-host-value-flow.js +0 -268
- package/scripts/lib/dashboard.js +0 -900
- package/scripts/lib/design-partner-feedback.js +0 -346
- package/scripts/lib/entitlements.js +0 -100
- package/scripts/lib/execution-packet.js +0 -559
- package/scripts/lib/experimentation-events.js +0 -547
- package/scripts/lib/external-capability-compliance.js +0 -107
- package/scripts/lib/external-user-simulation.js +0 -166
- package/scripts/lib/failure-recovery-readiness.js +0 -81
- package/scripts/lib/failure-recovery.js +0 -419
- package/scripts/lib/feedback-intelligence.js +0 -537
- package/scripts/lib/feedback-signals.js +0 -205
- package/scripts/lib/file-integrity.js +0 -68
- package/scripts/lib/fsx.js +0 -127
- package/scripts/lib/full-readiness-gate.js +0 -451
- package/scripts/lib/guidance-builder.js +0 -174
- package/scripts/lib/hook-apply.js +0 -1019
- package/scripts/lib/hook-baseline.js +0 -310
- package/scripts/lib/hook-config-preview.js +0 -275
- package/scripts/lib/hook-contracts.js +0 -290
- package/scripts/lib/hook-safety-boundary-readiness.js +0 -80
- package/scripts/lib/host-capability-matrix.js +0 -351
- package/scripts/lib/host-support-context.js +0 -254
- package/scripts/lib/http-hook-action.js +0 -538
- package/scripts/lib/install-ai-readiness.js +0 -84
- package/scripts/lib/install-intake-risk.js +0 -1037
- package/scripts/lib/install-journey-intelligence.js +0 -329
- package/scripts/lib/intervention-guidance.js +0 -57
- package/scripts/lib/known-limitations.js +0 -115
- package/scripts/lib/l8-path-truth.js +0 -146
- package/scripts/lib/launch-hardening-gate.js +0 -436
- package/scripts/lib/launch-readiness.js +0 -628
- package/scripts/lib/learning-memory.js +0 -686
- package/scripts/lib/lifecycle-hooks.js +0 -802
- package/scripts/lib/local-package-smoke.js +0 -423
- package/scripts/lib/local-pricing.js +0 -299
- package/scripts/lib/mcp-enforcement.js +0 -311
- package/scripts/lib/mcp-least-privilege-policy.js +0 -303
- package/scripts/lib/mcp-tool-inventory.js +0 -388
- package/scripts/lib/mcp-tool-risk.js +0 -0
- package/scripts/lib/memory.js +0 -335
- package/scripts/lib/metrics.js +0 -699
- package/scripts/lib/micro-proof.js +0 -133
- package/scripts/lib/next-run-context.js +0 -436
- package/scripts/lib/operating-value.js +0 -1648
- package/scripts/lib/optimization-v3.js +0 -122
- package/scripts/lib/orchestration/adapters/_shared.js +0 -49
- package/scripts/lib/orchestration/adapters/aider.js +0 -18
- package/scripts/lib/orchestration/adapters/claude-code.js +0 -35
- package/scripts/lib/orchestration/adapters/codex.js +0 -35
- package/scripts/lib/orchestration/adapters/gemini-cli.js +0 -18
- package/scripts/lib/orchestration/adapters/git.js +0 -25
- package/scripts/lib/orchestration/adapters/index.js +0 -31
- package/scripts/lib/orchestration/adapters/lm-studio.js +0 -18
- package/scripts/lib/orchestration/adapters/ollama.js +0 -18
- package/scripts/lib/orchestration/adapters/opencode.js +0 -18
- package/scripts/lib/orchestration/adapters/openrouter.js +0 -18
- package/scripts/lib/orchestration/adapters/test-runner.js +0 -25
- package/scripts/lib/orchestration/cli.js +0 -438
- package/scripts/lib/orchestration/execution-manager.js +0 -279
- package/scripts/lib/orchestration/handoff.js +0 -314
- package/scripts/lib/orchestration/index.js +0 -456
- package/scripts/lib/orchestration/inventory.js +0 -47
- package/scripts/lib/orchestration/model-discovery.js +0 -498
- package/scripts/lib/orchestration/model-profiler.js +0 -170
- package/scripts/lib/orchestration/model-profiles.js +0 -252
- package/scripts/lib/orchestration/model-refresh-policy.js +0 -72
- package/scripts/lib/orchestration/proof-writer.js +0 -349
- package/scripts/lib/orchestration/provider-discovery/aider.js +0 -49
- package/scripts/lib/orchestration/provider-discovery/claude-code.js +0 -56
- package/scripts/lib/orchestration/provider-discovery/codex.js +0 -49
- package/scripts/lib/orchestration/provider-discovery/common.js +0 -186
- package/scripts/lib/orchestration/provider-discovery/gemini.js +0 -106
- package/scripts/lib/orchestration/provider-discovery/lm-studio.js +0 -118
- package/scripts/lib/orchestration/provider-discovery/models-dev.js +0 -12
- package/scripts/lib/orchestration/provider-discovery/ollama.js +0 -100
- package/scripts/lib/orchestration/provider-discovery/opencode.js +0 -47
- package/scripts/lib/orchestration/provider-discovery/openrouter.js +0 -44
- package/scripts/lib/orchestration/risk-classifier.js +0 -130
- package/scripts/lib/orchestration/routing-policy.js +0 -486
- package/scripts/lib/orchestration/settings.js +0 -112
- package/scripts/lib/orchestration/state.js +0 -165
- package/scripts/lib/orchestration/verification-manager.js +0 -138
- package/scripts/lib/output-profiles.js +0 -146
- package/scripts/lib/package-content-audit.js +0 -368
- package/scripts/lib/package-runtime.js +0 -278
- package/scripts/lib/plan-surface.js +0 -53
- package/scripts/lib/plans.js +0 -2318
- package/scripts/lib/policy-provider.js +0 -27
- package/scripts/lib/prelaunch-activation-readiness.js +0 -409
- package/scripts/lib/prelaunch-evidence-store.js +0 -816
- package/scripts/lib/prelaunch-intelligence.js +0 -869
- package/scripts/lib/pricing-experiment.js +0 -118
- package/scripts/lib/pro-moment-events.js +0 -77
- package/scripts/lib/pro-moment-state.js +0 -227
- package/scripts/lib/pro-moments.js +0 -1216
- package/scripts/lib/product-learning-events.js +0 -629
- package/scripts/lib/project-profile.js +0 -555
- package/scripts/lib/prompt-compiler.js +0 -280
- package/scripts/lib/prompt-lint.js +0 -32
- package/scripts/lib/prompt-suggestions.js +0 -52
- package/scripts/lib/proof-canonical.js +0 -398
- package/scripts/lib/proof-drilldown.js +0 -383
- package/scripts/lib/proof-events.js +0 -342
- package/scripts/lib/proof-history.js +0 -243
- package/scripts/lib/proof-metrics.js +0 -296
- package/scripts/lib/proof-outcome-evidence.js +0 -134
- package/scripts/lib/proof-receipt.js +0 -335
- package/scripts/lib/proof-record.js +0 -461
- package/scripts/lib/public-activation-distribution-gate.js +0 -258
- package/scripts/lib/public-cli.js +0 -3891
- package/scripts/lib/public-distribution-truth.js +0 -211
- package/scripts/lib/public-install-claim-checker.js +0 -294
- package/scripts/lib/publish-provenance-readiness.js +0 -283
- package/scripts/lib/readiness-delta.js +0 -218
- package/scripts/lib/readiness-evidence-closure.js +0 -196
- package/scripts/lib/reentry-memory-capture.js +0 -241
- package/scripts/lib/reentry-memory-retrieval.js +0 -302
- package/scripts/lib/reentry-memory-status.js +0 -146
- package/scripts/lib/reentry-memory-store.js +0 -178
- package/scripts/lib/reentry-state.js +0 -66
- package/scripts/lib/release-candidate-bundle.js +0 -166
- package/scripts/lib/remediation.js +0 -81
- package/scripts/lib/repo-map.js +0 -391
- package/scripts/lib/run-improvements-lifecycle.js +0 -330
- package/scripts/lib/run-improvements.js +0 -789
- package/scripts/lib/runtime-decision-policy.js +0 -387
- package/scripts/lib/safe-path-engine.js +0 -705
- package/scripts/lib/safe-run-controller.js +0 -887
- package/scripts/lib/score.js +0 -262
- package/scripts/lib/seamless-enforcement.js +0 -329
- package/scripts/lib/seamless-outcome.js +0 -689
- package/scripts/lib/seamless-reality-gate.js +0 -5043
- package/scripts/lib/security-risk-classifier.js +0 -511
- package/scripts/lib/security-scan.js +0 -384
- package/scripts/lib/session-context-optimizer.js +0 -1211
- package/scripts/lib/session-timing.js +0 -315
- package/scripts/lib/skill-hygiene.js +0 -805
- package/scripts/lib/skill-packs.js +0 -161
- package/scripts/lib/skills-operating-layer.js +0 -580
- package/scripts/lib/smart-work-routing.js +0 -768
- package/scripts/lib/source-catalog.js +0 -700
- package/scripts/lib/status-value-summary.js +0 -32
- package/scripts/lib/support-bundle.js +0 -578
- package/scripts/lib/task-continuation.js +0 -440
- package/scripts/lib/test-helpers.js +0 -15
- package/scripts/lib/tier.js +0 -38
- package/scripts/lib/token-context-quality-gate.js +0 -370
- package/scripts/lib/token-cost-capture.js +0 -187
- package/scripts/lib/token-cost-intelligence.js +0 -358
- package/scripts/lib/token-efficiency-evidence.js +0 -213
- package/scripts/lib/token-evidence.js +0 -699
- package/scripts/lib/tokenish.js +0 -17
- package/scripts/lib/tool-output-sandbox.js +0 -304
- package/scripts/lib/trust-audit.js +0 -136
- package/scripts/lib/unified-events.js +0 -396
- package/scripts/lib/upgrade-interruption-recovery.js +0 -407
- package/scripts/lib/usage-ledger.js +0 -201
- package/scripts/lib/value-ledger.js +0 -130
- package/scripts/lib/value-proof-calibration.js +0 -531
- package/scripts/lib/visual-qa.js +0 -231
- package/scripts/lib/voice-alpha.js +0 -29
- package/scripts/lib/work-aware-orchestration.js +0 -976
- package/scripts/lib/work-control-receipts.js +0 -577
- package/scripts/lib/work-ledger.js +0 -1123
- package/scripts/lib/work-panel-preview.js +0 -352
- package/scripts/lib/workflow-discipline.js +0 -280
- package/scripts/lib/workflow-signals.js +0 -419
- package/scripts/lib/workspace-map.js +0 -281
- package/scripts/lib/workspace-registry.js +0 -1367
- package/scripts/lib/workspace-resolver.js +0 -480
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const { URL } = require("url");
|
|
5
|
-
const { scanInstructionRisk, sanitizeInstructionLikeContent } = require("./agent-security/instruction-risk");
|
|
6
|
-
|
|
7
|
-
const RISK_LEVELS = Object.freeze(["low", "medium", "high", "critical"]);
|
|
8
|
-
const RISK_ORDER = Object.freeze({
|
|
9
|
-
low: 1,
|
|
10
|
-
medium: 2,
|
|
11
|
-
high: 3,
|
|
12
|
-
critical: 4,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
const SENSITIVE_PATH_PATTERNS = Object.freeze([
|
|
16
|
-
{ pattern: /(^|[\\/])\.env(\.[A-Za-z0-9._-]+)?$/i, reason: "SENSITIVE_ENV_FILE", risk: "critical" },
|
|
17
|
-
{ pattern: /(^|[\\/])(secrets?|credentials?|private[_ -]?keys?|\.ssh|tokens?)([\\/]|$)/i, reason: "SECRET_LIKE_TARGET", risk: "critical" },
|
|
18
|
-
{ pattern: /(auth|oauth|sso|billing|payment|stripe|checkout|subscription|invoice)/i, reason: "AUTH_OR_BILLING_SCOPE", risk: "high" },
|
|
19
|
-
{ pattern: /(deploy|release|production|prod|docker|k8s|terraform|vercel|netlify|railway|render)/i, reason: "DEPLOYMENT_CONFIG", risk: "high" },
|
|
20
|
-
{ pattern: /(^|[\\/])\.github[\\/]workflows[\\/]|(^|[\\/])(ci|cd)([\\/]|$)/i, reason: "CI_CONFIG", risk: "high" },
|
|
21
|
-
]);
|
|
22
|
-
|
|
23
|
-
const LOCAL_BROWSER_HOSTS = new Set(["localhost", "127.0.0.1", "::1"]);
|
|
24
|
-
|
|
25
|
-
function unique(values) {
|
|
26
|
-
return [...new Set((values || []).filter(Boolean))];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function maxRisk(left, right) {
|
|
30
|
-
return (RISK_ORDER[left] || 0) >= (RISK_ORDER[right] || 0) ? left : right;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function makeResult(riskLevel = "low", reasonCodes = [], extras = {}) {
|
|
34
|
-
return {
|
|
35
|
-
riskLevel,
|
|
36
|
-
reasonCodes: unique(reasonCodes),
|
|
37
|
-
explanation: extras.explanation || "",
|
|
38
|
-
recommendedAction: extras.recommendedAction || "",
|
|
39
|
-
findings: extras.findings || [],
|
|
40
|
-
safeSummary: extras.safeSummary || null,
|
|
41
|
-
matched: extras.matched || [],
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function mergeResults(...results) {
|
|
46
|
-
return results.filter(Boolean).reduce((merged, current) => {
|
|
47
|
-
return {
|
|
48
|
-
riskLevel: maxRisk(merged.riskLevel, current.riskLevel || "low"),
|
|
49
|
-
reasonCodes: unique([...(merged.reasonCodes || []), ...(current.reasonCodes || [])]),
|
|
50
|
-
explanation: unique([merged.explanation, current.explanation]).filter(Boolean).join(" ").trim(),
|
|
51
|
-
recommendedAction: unique([merged.recommendedAction, current.recommendedAction]).filter(Boolean).join(" ").trim(),
|
|
52
|
-
findings: [...(merged.findings || []), ...(current.findings || [])],
|
|
53
|
-
safeSummary: merged.safeSummary || current.safeSummary || null,
|
|
54
|
-
matched: [...(merged.matched || []), ...(current.matched || [])],
|
|
55
|
-
};
|
|
56
|
-
}, makeResult("low"));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function normalizePathValue(value) {
|
|
60
|
-
return String(value || "").replace(/\\/g, "/").trim();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function normalizePathList(paths) {
|
|
64
|
-
if (!paths) return [];
|
|
65
|
-
const list = Array.isArray(paths) ? paths : [paths];
|
|
66
|
-
return list.map(normalizePathValue).filter(Boolean);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function parseUrl(input) {
|
|
70
|
-
const raw = String(input || "").trim();
|
|
71
|
-
if (!raw) return null;
|
|
72
|
-
try {
|
|
73
|
-
if (/^https?:\/\//i.test(raw)) return new URL(raw);
|
|
74
|
-
if (/^(localhost|127\.0\.0\.1|::1)(:\d+)?(\/|$)/i.test(raw)) {
|
|
75
|
-
return new URL(`http://${raw}`);
|
|
76
|
-
}
|
|
77
|
-
} catch {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function classifyPathRisk(paths, options = {}) {
|
|
84
|
-
const normalized = normalizePathList(paths);
|
|
85
|
-
if (!normalized.length) {
|
|
86
|
-
return makeResult("low", [], {
|
|
87
|
-
explanation: "No file or path target was provided.",
|
|
88
|
-
recommendedAction: "Keep the action scoped to the smallest necessary repo slice.",
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
let riskLevel = "low";
|
|
93
|
-
const reasonCodes = [];
|
|
94
|
-
const matched = [];
|
|
95
|
-
|
|
96
|
-
normalized.forEach((value) => {
|
|
97
|
-
SENSITIVE_PATH_PATTERNS.forEach((rule) => {
|
|
98
|
-
if (!rule.pattern.test(value)) return;
|
|
99
|
-
riskLevel = maxRisk(riskLevel, rule.risk);
|
|
100
|
-
reasonCodes.push(rule.reason);
|
|
101
|
-
matched.push(value);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
if (riskLevel === "low" && normalized.every((value) => /^(docs|src\/landing-page|deferred\/site-implementation|tests|src\/)/i.test(value))) {
|
|
106
|
-
return makeResult("low", [], {
|
|
107
|
-
explanation: "The target stays inside normal project files.",
|
|
108
|
-
recommendedAction: "Keep the edit bounded to the requested product slice.",
|
|
109
|
-
matched: normalized,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return makeResult(riskLevel, reasonCodes, {
|
|
114
|
-
explanation: reasonCodes.length
|
|
115
|
-
? "Sensitive file scope was detected."
|
|
116
|
-
: "The target path is not obviously sensitive.",
|
|
117
|
-
recommendedAction: riskLevel === "critical"
|
|
118
|
-
? "Avoid direct writes to secrets or env files. Use a reviewed template or ask for explicit approval."
|
|
119
|
-
: riskLevel === "high"
|
|
120
|
-
? "Double-check that the target path is in scope for the requested task."
|
|
121
|
-
: "Keep the action scoped to the requested files only.",
|
|
122
|
-
matched,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function classifyCommandRisk(command) {
|
|
127
|
-
const text = String(command || "").trim();
|
|
128
|
-
if (!text) {
|
|
129
|
-
return makeResult("low", [], {
|
|
130
|
-
explanation: "No shell command was provided.",
|
|
131
|
-
recommendedAction: "Prefer a scoped local command when execution is needed.",
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const lower = text.toLowerCase();
|
|
136
|
-
const reasonCodes = [];
|
|
137
|
-
let riskLevel = "low";
|
|
138
|
-
|
|
139
|
-
if (/^(npm test|npm run test\b|npm run build\b|node --test\b|vitest\b|pytest\b|cargo test\b|go test\b)/i.test(text)) {
|
|
140
|
-
return makeResult("low", ["SAFE_STATUS_ACTION"], {
|
|
141
|
-
explanation: "The command looks like a normal local verification command.",
|
|
142
|
-
recommendedAction: "Run the narrowest relevant local verification only.",
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (/\brm\s+-rf\b|\bdel\s+\/s\s+\/q\b|\bformat\b|\bremove-item\b[^\n]*-recurse\b|\bgit reset --hard\b/i.test(lower)) {
|
|
147
|
-
reasonCodes.push("DESTRUCTIVE_COMMAND");
|
|
148
|
-
riskLevel = "critical";
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (/\bgit push\b[^\n]*--force\b|\bgit push --mirror\b|\bgit branch -d\b|\bgit tag -d\b/i.test(lower)) {
|
|
152
|
-
reasonCodes.push("FORCE_PUSH_OR_HISTORY_REWRITE");
|
|
153
|
-
riskLevel = maxRisk(riskLevel, "critical");
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (/\b(curl|wget)\b[^\n]*(upload|form|post|put)|\bscp\b|\brsync\b[^\n]*@/i.test(lower)) {
|
|
157
|
-
reasonCodes.push("EXTERNAL_REPO_EXPORT");
|
|
158
|
-
riskLevel = maxRisk(riskLevel, "critical");
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (/\b(curl|wget|invoke-webrequest|invoke-restmethod)\b/i.test(lower)) {
|
|
162
|
-
reasonCodes.push("EXTERNAL_NETWORK_REQUEST");
|
|
163
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (/\b(deploy|release|publish|shipit|npm publish)\b/i.test(lower)) {
|
|
167
|
-
reasonCodes.push("DEPLOYMENT_CONFIG");
|
|
168
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return makeResult(riskLevel, reasonCodes, {
|
|
172
|
-
explanation: reasonCodes.length
|
|
173
|
-
? "The command includes risky or high-impact behavior."
|
|
174
|
-
: "The command is not obviously destructive, but it still executes local changes.",
|
|
175
|
-
recommendedAction: riskLevel === "critical"
|
|
176
|
-
? "Block destructive or external export commands unless they are explicitly reviewed and scoped."
|
|
177
|
-
: riskLevel === "high"
|
|
178
|
-
? "Require explicit approval before running commands that deploy, publish, or reach external networks."
|
|
179
|
-
: "Keep shell commands narrow, local, and task-scoped.",
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
function classifyToolRisk(input = {}) {
|
|
184
|
-
const toolName = String(input.toolName || "").trim();
|
|
185
|
-
const mcpServer = String(input.mcpServer || "").trim();
|
|
186
|
-
const label = [mcpServer, toolName].filter(Boolean).join(":") || "unknown-tool";
|
|
187
|
-
const metadata = input.metadata && typeof input.metadata === "object" ? input.metadata : {};
|
|
188
|
-
const reasonCodes = [];
|
|
189
|
-
let riskLevel = "low";
|
|
190
|
-
|
|
191
|
-
if (!toolName && !mcpServer) {
|
|
192
|
-
return makeResult("low", [], {
|
|
193
|
-
explanation: "No tool or MCP target was provided.",
|
|
194
|
-
recommendedAction: "Keep tool access limited to trusted local capabilities.",
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (metadata.unknown === true || (!metadata.trusted && (toolName || mcpServer))) {
|
|
199
|
-
reasonCodes.push("UNKNOWN_MCP_TOOL");
|
|
200
|
-
riskLevel = maxRisk(riskLevel, "medium");
|
|
201
|
-
}
|
|
202
|
-
if (metadata.writeCapable === true) {
|
|
203
|
-
reasonCodes.push("WRITE_CAPABLE_TOOL");
|
|
204
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
205
|
-
}
|
|
206
|
-
if (metadata.networkCapable === true) {
|
|
207
|
-
reasonCodes.push("EXTERNAL_NETWORK_REQUEST");
|
|
208
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
209
|
-
}
|
|
210
|
-
if (metadata.secretSensitive === true) {
|
|
211
|
-
reasonCodes.push("SECRET_LIKE_TARGET");
|
|
212
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return makeResult(riskLevel, reasonCodes, {
|
|
216
|
-
explanation: reasonCodes.length
|
|
217
|
-
? `Tool risk signals were detected for ${label}.`
|
|
218
|
-
: `${label} looks like a normal local tool.`,
|
|
219
|
-
recommendedAction: riskLevel === "high"
|
|
220
|
-
? "Require approval for write-capable, network-capable, or secret-sensitive tools."
|
|
221
|
-
: riskLevel === "medium"
|
|
222
|
-
? "Review unknown tool trust before relying on it."
|
|
223
|
-
: "Keep tool access limited to trusted local tooling.",
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function classifyBrowserRisk(input = {}) {
|
|
228
|
-
const urlValue = input.url || input.target || input.domain || "";
|
|
229
|
-
const parsed = parseUrl(urlValue);
|
|
230
|
-
const host = String(input.domain || parsed?.hostname || "").trim().toLowerCase();
|
|
231
|
-
const boundaryReady = input.domainBoundaryReady === true || input.allowedDomain === true;
|
|
232
|
-
const hasSessionRisk = input.cookieAccess === true || input.sessionAccess === true || input.secretAccess === true;
|
|
233
|
-
|
|
234
|
-
if (!host && !urlValue) {
|
|
235
|
-
return makeResult("low", [], {
|
|
236
|
-
explanation: "No browser target was provided.",
|
|
237
|
-
recommendedAction: "Keep browser actions limited to the named local preview when possible.",
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (hasSessionRisk) {
|
|
242
|
-
return makeResult("critical", ["BROWSER_COOKIE_OR_SESSION_RISK"], {
|
|
243
|
-
explanation: "The browser action could touch cookies, authenticated sessions, or other secret-bearing state.",
|
|
244
|
-
recommendedAction: "Block browser actions that need cookies, session reuse, or secret access.",
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (LOCAL_BROWSER_HOSTS.has(host)) {
|
|
249
|
-
return makeResult("low", ["VISUAL_QA_LOCAL_TARGET"], {
|
|
250
|
-
explanation: "The browser target stays on a local preview.",
|
|
251
|
-
recommendedAction: "Keep Visual QA scoped to local preview URLs when possible.",
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return makeResult(boundaryReady ? "medium" : "high", ["BROWSER_EXTERNAL_DOMAIN"], {
|
|
256
|
-
explanation: boundaryReady
|
|
257
|
-
? "The browser target is external, but a domain boundary is present."
|
|
258
|
-
: "The browser target is external and no domain boundary was provided.",
|
|
259
|
-
recommendedAction: boundaryReady
|
|
260
|
-
? "Require approval before leaving the local preview scope."
|
|
261
|
-
: "Add an explicit domain boundary or require approval before touching external sites.",
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
function classifyInstructionRisk(input = {}) {
|
|
266
|
-
const text = String(input.instructionText || input.text || "").trim();
|
|
267
|
-
if (!text) {
|
|
268
|
-
return makeResult("low", [], {
|
|
269
|
-
explanation: "No instruction text was provided.",
|
|
270
|
-
recommendedAction: "Keep instructions explicit, scoped, and task-bound.",
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const scan = scanInstructionRisk(text, {
|
|
275
|
-
sourceType: input.sourceType || input.sourceTrust || "unknown_external",
|
|
276
|
-
});
|
|
277
|
-
const reasonCodes = [];
|
|
278
|
-
let riskLevel = scan.instructionRisk || "low";
|
|
279
|
-
|
|
280
|
-
if (scan.signals.length > 0) {
|
|
281
|
-
reasonCodes.push("PROMPT_INJECTION_SIGNAL");
|
|
282
|
-
}
|
|
283
|
-
if (/\b(reveal|upload|send|exfiltrat|print)\b[^\n]{0,80}\b(secrets?|tokens?|credentials?|repo|repository|codebase)\b/i.test(text)) {
|
|
284
|
-
reasonCodes.push("PROMPT_INJECTION_SIGNAL", "SECRET_LIKE_TARGET");
|
|
285
|
-
riskLevel = maxRisk(riskLevel, "critical");
|
|
286
|
-
}
|
|
287
|
-
if (/\b(ignore|bypass|disable)\b[^\n]{0,80}\b(approval|security|guard|evidence|logs?)\b/i.test(text)) {
|
|
288
|
-
reasonCodes.push("PROMPT_INJECTION_SIGNAL");
|
|
289
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
290
|
-
}
|
|
291
|
-
if (/\b(always allow|allow all)\b[^\n]{0,40}\b(tool|command|browser|mcp)\b/i.test(text)) {
|
|
292
|
-
reasonCodes.push("PROMPT_INJECTION_SIGNAL");
|
|
293
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
294
|
-
}
|
|
295
|
-
if (/\b(delete|remove|wipe)\b[^\n]{0,80}\b(evidence|audit|logs?)\b/i.test(text)) {
|
|
296
|
-
reasonCodes.push("PROMPT_INJECTION_SIGNAL");
|
|
297
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
298
|
-
}
|
|
299
|
-
if (/\b(unrelated|outside scope|ignore scope)\b[^\n]{0,120}\b(auth|billing|deploy|workflow|secrets?)\b/i.test(text)) {
|
|
300
|
-
reasonCodes.push("INTENT_MISMATCH");
|
|
301
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return makeResult(riskLevel, reasonCodes, {
|
|
305
|
-
explanation: scan.findings.length
|
|
306
|
-
? "Instruction-risk or prompt-injection-like signals were detected."
|
|
307
|
-
: "No obvious prompt-injection patterns were detected.",
|
|
308
|
-
recommendedAction: riskLevel === "critical"
|
|
309
|
-
? "Treat the content as untrusted, do not execute it, and keep it out of tool decisions."
|
|
310
|
-
: riskLevel === "high"
|
|
311
|
-
? "Require review before allowing the instruction to influence tools or sensitive actions."
|
|
312
|
-
: scan.recommendation === "use_sanitized_copy"
|
|
313
|
-
? "Use a sanitized summary instead of the raw instruction text."
|
|
314
|
-
: "Keep the instruction scoped to the requested task only.",
|
|
315
|
-
findings: scan.findings,
|
|
316
|
-
safeSummary: sanitizeInstructionLikeContent(text),
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
function classifyPromptInjectionRisk(input = {}) {
|
|
321
|
-
const base = classifyInstructionRisk(input);
|
|
322
|
-
if (!base.reasonCodes.includes("PROMPT_INJECTION_SIGNAL")) {
|
|
323
|
-
return base;
|
|
324
|
-
}
|
|
325
|
-
return mergeResults(base, makeResult(base.riskLevel === "low" ? "medium" : base.riskLevel, ["PROMPT_INJECTION_SIGNAL"], {
|
|
326
|
-
explanation: "Prompt-injection-like signals were detected in instruction content.",
|
|
327
|
-
recommendedAction: "Treat the content as data first and require review before it can influence tools or sensitive actions.",
|
|
328
|
-
safeSummary: base.safeSummary,
|
|
329
|
-
}));
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
function classifySourceTrustRisk(input = {}) {
|
|
333
|
-
const rawTrust = input.sourceTrust || input.trustLevel || input.sourceType || "";
|
|
334
|
-
const trust = String(rawTrust).trim().toLowerCase();
|
|
335
|
-
if (!trust) {
|
|
336
|
-
return makeResult("low", [], {
|
|
337
|
-
explanation: "No external source-trust signal was provided.",
|
|
338
|
-
recommendedAction: "Prefer reviewed local sources when a task includes discovered instructions.",
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
if (trust === "trusted" || trust === "project_local" || trust === "local") {
|
|
342
|
-
return makeResult("low", [], {
|
|
343
|
-
explanation: "The source looks local or trusted.",
|
|
344
|
-
recommendedAction: "Keep trusted local sources scoped to the requested task.",
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const highRisk = ["external_untrusted", "tool_returned_untrusted", "unknown_external", "unknown"].includes(trust);
|
|
349
|
-
return makeResult(highRisk ? "high" : "medium", ["UNTRUSTED_SOURCE"], {
|
|
350
|
-
explanation: "The source should not be trusted as an instruction source.",
|
|
351
|
-
recommendedAction: "Treat untrusted or tool-returned content as data only unless it is explicitly reviewed.",
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
function classifyIntentMismatchRisk(input = {}) {
|
|
356
|
-
const task = String(input.userIntent || input.taskType || input.intendedTask || "").toLowerCase();
|
|
357
|
-
const targets = normalizePathList(input.targetPaths || input.target || []);
|
|
358
|
-
const command = String(input.command || "").toLowerCase();
|
|
359
|
-
const toolName = String(input.toolName || "").toLowerCase();
|
|
360
|
-
const domain = String(input.domain || input.url || "").toLowerCase();
|
|
361
|
-
|
|
362
|
-
if (!task) {
|
|
363
|
-
return makeResult("low", [], {
|
|
364
|
-
explanation: "No task intent was provided.",
|
|
365
|
-
recommendedAction: "Capture the user intent before approving broader actions.",
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
const taskLooksMarketing = /\b(landing|pricing|copy|homepage|docs?)\b/.test(task);
|
|
370
|
-
const targetLooksSensitive = targets.some((value) => /(auth|billing|payment|deploy|release|workflow|\.env|secret|credential)/i.test(value));
|
|
371
|
-
const commandLooksSensitive = /(deploy|publish|release|rm -rf|curl|wget|npm install|git push --force)/.test(command);
|
|
372
|
-
const toolLooksSensitive = /(delete|deploy|publish|secret|credential|billing|admin)/.test(toolName);
|
|
373
|
-
const domainLooksExternal = Boolean(domain) && !parseUrl(domain)?.hostname?.match(/^(localhost|127\.0\.0\.1|::1)$/i);
|
|
374
|
-
|
|
375
|
-
if (taskLooksMarketing && (targetLooksSensitive || commandLooksSensitive || toolLooksSensitive || domainLooksExternal)) {
|
|
376
|
-
return makeResult("high", ["INTENT_MISMATCH", "OUT_OF_SCOPE_FILE_CHANGE"], {
|
|
377
|
-
explanation: "The requested action does not match the stated marketing or docs task.",
|
|
378
|
-
recommendedAction: "Keep pricing, landing, or docs tasks out of auth, billing, deploy, workflow, and secret-bearing areas.",
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return makeResult("low", [], {
|
|
383
|
-
explanation: "No strong intent mismatch signal was detected.",
|
|
384
|
-
recommendedAction: "Keep the action aligned with the named task.",
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
function classifySecretExposureRisk(input = {}) {
|
|
389
|
-
const combined = [
|
|
390
|
-
...normalizePathList(input.targetPaths || input.target || []),
|
|
391
|
-
String(input.command || ""),
|
|
392
|
-
typeof input.content === "string" ? input.content : "",
|
|
393
|
-
].join("\n");
|
|
394
|
-
|
|
395
|
-
const reasonCodes = [];
|
|
396
|
-
let riskLevel = "low";
|
|
397
|
-
if (/sk-[A-Za-z0-9]{16,}|ghp_[A-Za-z0-9]{20,}|api[_ -]?key\s*[:=]|bearer\s+[A-Za-z0-9._-]{12,}|-----BEGIN [A-Z ]+-----/i.test(combined)) {
|
|
398
|
-
reasonCodes.push("SECRET_LIKE_TARGET");
|
|
399
|
-
riskLevel = "critical";
|
|
400
|
-
}
|
|
401
|
-
if (/\.env(\.|$)|token|credential|private[_ -]?key|password/i.test(combined)) {
|
|
402
|
-
reasonCodes.push("SECRET_LIKE_TARGET");
|
|
403
|
-
riskLevel = maxRisk(riskLevel, "high");
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
return makeResult(riskLevel, reasonCodes, {
|
|
407
|
-
explanation: reasonCodes.length
|
|
408
|
-
? "The action could expose secret-bearing material."
|
|
409
|
-
: "No clear secret-exposure signal was detected.",
|
|
410
|
-
recommendedAction: riskLevel === "critical"
|
|
411
|
-
? "Block direct secret access or output and redact any token-like material from evidence."
|
|
412
|
-
: "Avoid printing, copying, or exporting secrets and env values.",
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
function classifyExternalExportRisk(input = {}) {
|
|
417
|
-
const text = [
|
|
418
|
-
String(input.command || ""),
|
|
419
|
-
String(input.url || ""),
|
|
420
|
-
String(input.target || ""),
|
|
421
|
-
String(input.toolName || ""),
|
|
422
|
-
].join("\n").toLowerCase();
|
|
423
|
-
|
|
424
|
-
if (/\b(upload|paste|post|put|send|export)\b[^\n]{0,120}\b(repo|repository|codebase|artifact|zip|tar|bundle)\b/i.test(text)) {
|
|
425
|
-
return makeResult("critical", ["EXTERNAL_REPO_EXPORT"], {
|
|
426
|
-
explanation: "The action looks like it could export repository contents externally.",
|
|
427
|
-
recommendedAction: "Block repository export or require a narrowly reviewed, explicit approval path.",
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
if (/\b(curl|wget|invoke-webrequest|invoke-restmethod)\b/i.test(text)) {
|
|
432
|
-
return makeResult("high", ["EXTERNAL_NETWORK_REQUEST"], {
|
|
433
|
-
explanation: "The action reaches an external network target.",
|
|
434
|
-
recommendedAction: "Require review before sending project data or making external requests.",
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
return makeResult("low", [], {
|
|
439
|
-
explanation: "No external export signal was detected.",
|
|
440
|
-
recommendedAction: "Keep the action local-first by default.",
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
function classifyActionRisk(input = {}) {
|
|
445
|
-
const parts = [];
|
|
446
|
-
const actionType = String(input.actionType || "unknown").trim().toLowerCase();
|
|
447
|
-
|
|
448
|
-
if (actionType === "prompt_compile") {
|
|
449
|
-
return makeResult("low", ["SAFE_PROMPT_COMPILE"], {
|
|
450
|
-
explanation: "Prompt compilation is a local planning action.",
|
|
451
|
-
recommendedAction: "Keep the task scoped before editing code.",
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
if (actionType === "file_read" || actionType === "file_write" || actionType === "config_change") {
|
|
456
|
-
parts.push(classifyPathRisk(input.targetPaths || input.target || [], input));
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
if (actionType === "command_run" || actionType === "git_operation" || actionType === "deploy_operation") {
|
|
460
|
-
parts.push(classifyCommandRisk(input.command || input.target || ""));
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
if (actionType === "tool_call" || actionType === "mcp_tool_call") {
|
|
464
|
-
parts.push(classifyToolRisk({
|
|
465
|
-
toolName: input.toolName,
|
|
466
|
-
mcpServer: input.mcpServer,
|
|
467
|
-
metadata: input.toolMetadata,
|
|
468
|
-
}));
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
if (actionType === "browser_action" || actionType === "visual_qa_run") {
|
|
472
|
-
parts.push(classifyBrowserRisk({
|
|
473
|
-
url: input.url || input.target,
|
|
474
|
-
domain: input.domain,
|
|
475
|
-
domainBoundaryReady: input.domainBoundaryReady,
|
|
476
|
-
cookieAccess: input.cookieAccess,
|
|
477
|
-
sessionAccess: input.sessionAccess,
|
|
478
|
-
secretAccess: input.secretAccess,
|
|
479
|
-
}));
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
parts.push(classifyInstructionRisk({
|
|
483
|
-
text: input.instructionText,
|
|
484
|
-
sourceTrust: input.sourceTrust,
|
|
485
|
-
sourceType: input.sourceType,
|
|
486
|
-
}));
|
|
487
|
-
parts.push(classifySourceTrustRisk(input));
|
|
488
|
-
parts.push(classifyIntentMismatchRisk(input));
|
|
489
|
-
parts.push(classifySecretExposureRisk(input));
|
|
490
|
-
parts.push(classifyExternalExportRisk(input));
|
|
491
|
-
|
|
492
|
-
return mergeResults(...parts);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
module.exports = {
|
|
496
|
-
RISK_LEVELS,
|
|
497
|
-
RISK_ORDER,
|
|
498
|
-
maxRisk,
|
|
499
|
-
mergeResults,
|
|
500
|
-
classifyPathRisk,
|
|
501
|
-
classifyCommandRisk,
|
|
502
|
-
classifyToolRisk,
|
|
503
|
-
classifyBrowserRisk,
|
|
504
|
-
classifyInstructionRisk,
|
|
505
|
-
classifyPromptInjectionRisk,
|
|
506
|
-
classifySourceTrustRisk,
|
|
507
|
-
classifyIntentMismatchRisk,
|
|
508
|
-
classifySecretExposureRisk,
|
|
509
|
-
classifyExternalExportRisk,
|
|
510
|
-
classifyActionRisk,
|
|
511
|
-
};
|