UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

95 lines (94 loc) • 2.72 kB
import { extractSymbols } from "../tools/fs/repo-map.js"; import { compileAllowList, compiledEntryName } from "./allow-entry.js"; import { thrownText } from "./thrown-value.js"; export function decideAutoPromote(i) { if (i.tripwire.escalate) return "needs_human"; if (i.touchesIrreversibleTool) return "needs_human"; if (!i.statisticsPresent) return "needs_human"; if (i.concurringSignals.size < 2) return "needs_human"; const g1ok = i.oracle.protected && i.oracle.isolationClass === "out_of_process"; const g2ok = i.record.gate2Verdict === "present_positive"; const allGatesPresentPassing = g1ok && g2ok && i.gate4Armed; if (!allGatesPresentPassing) { return (i.oracle.protected && i.oracle.isolationClass === "in_process_probe_only" && g2ok && i.gate4Armed) ? "candidate_only" : "needs_human"; } return "auto_promote"; } export const FROZEN_DENYLIST_FLOOR = new Set([ "child_process", "execSync", "spawnSync", "exec(", "spawn(", "shell", "/bin/sh", "/bin/bash", "bash -c", "sh -c", "eval(", "Function(", "require(", "import(", "fetch(", "curl", "wget", "http://", "https://", "nc ", "netcat", "base64", "atob(", "btoa(", "fromCharCode", "|", "&&", ";", "`", "$(", ">>", ">", "<", ]); export function deriveTripwire(artifactText, declared, profileTokens) { const reasons = []; let escalate = false; try { const allow = new Set(compileAllowList(declared.allowedTools ?? [], "allow").rows.map((r) => compiledEntryName(r.compiled))); const symbols = extractSymbols(artifactText); for (const sym of symbols) { if (!allow.has(sym)) { escalate = true; reasons.push(`symbol-drift: surfaced symbol "${sym}" not in declared.allowedTools`); } } } catch (e) { return { escalate: true, reasons: [...reasons, `symbol-drift scan threw (fail-closed): ${thrownText(e)}`], }; } try { const tokens = new Set([...FROZEN_DENYLIST_FLOOR, ...(profileTokens ?? [])]); for (const token of tokens) { if (token.length > 0 && artifactText.includes(token)) { escalate = true; reasons.push(`denylist: raw-byte token "${token}" present in artifact`); } } } catch (e) { return { escalate: true, reasons: [...reasons, `denylist scan threw (fail-closed): ${thrownText(e)}`], }; } return { escalate, reasons }; }