Package Exports
- agent-gov-core
- agent-gov-core/schemas/finding.schema.json
- agent-gov-core/test-utils
Readme
agent-gov-core
Shared primitives for the AI-agent governance suite — a small library that ScopeTrail, PolicyMesh, CapabilityEcho, TaskBound, and SessionTrail all consume so common parsers, locators, and the Finding schema live in one place instead of five.
Zero runtime dependencies. ESM, TypeScript, target ES2022.
Install
npm install agent-gov-coreThe canonical Finding
Every tool in the suite emits findings against the same schema. The kind field is a namespaced string <tool>.<slug> so a downstream meta-reviewer can dedupe across tools.
import { kind, type Finding } from 'agent-gov-core';
const finding: Finding = {
tool: 'scope_trail',
kind: kind('scope_trail', 'permission_allow_widened'),
severity: 'high',
message: 'Claude permission allowlist now includes Bash(npm *).',
location: { file: '.claude/settings.json', line: 12 },
};The JSON schema at schemas/finding.schema.json enforces the dotted-kind shape — any tool emitting unprefixed kinds will fail validation.
What's in the library
Finding schema and helpers
Finding,Severity,ToolKind,FindingLocation— canonical typesSEVERITIES,TOOL_KINDS— runtime arrays of the enum valuesisSeverity(v),isToolKind(v),isNamespacedKind(v)— type guardskind(tool, name)— build a namespaced kind without hand-assembling the dotted stringcreateFinding({tool, name, severity, message, ...})— convenience constructor that callskind()andfingerprintFinding()for youfingerprintFinding(finding)— 16-character hex hash of(kind, file, line, column). Stable across runs and message rewordings, so a meta-reviewer can dedupevalidateFinding(value)— runtime check againstschemas/finding.schema.json, returns{ ok, errors[] }
Config readers
readJsonObjectWithSource(path)— JSONC reader, string-aware comment + trailing-comma stripping, position-preservingstripJsonComments(text)— same logic exposed for in-memory textreadTomlObject(path)— TOML reader (sections, arrays of tables, inline tables, multi-line strings, dotted/quoted keys)parseToml(text)— same exposed for text
Line locators
lineOfJsonKey(text, key)— 1-based line of"key":lineOfJsonStringValue(text, value, scope?)— 1-based line of a JSON-encoded value, optionally scoped to a byte rangelineOfTomlKey(text, dottedKey)— 1-based line of a TOML key
MCP command normalization
normalizeMcpCommand({ command, args, url, serverUrl, env, cwd })— canonical identity string for an MCP server entry. Drops neutral flags (-y,--yes), resolves npx/uvx invocations, includes env+cwd in the identity. Used to dedupemcp_command_mismatchfalse positives when servers are equivalent but syntactically different (npx -y foo@1.2.3vsnpx foo@1.2.3).
Shell tokenization
tokenizeShell(command)— quote-aware split on;,|,&&,||plus trivial obfuscation neutralization (c""url→curl,c\\url→curl)getCommandHead(subcommand)— extract the leading verb after tokenization
GitHub Action helpers
rankSeverity(s)— numeric ranknone=0 … critical=4passesSeverityThreshold(s, threshold),anyAtOrAbove(findings, threshold)— fail-on plumbingemitFindingAnnotation(f)— render a Finding as a::warning file=…,line=…,title=…::…GitHub workflow annotation
Test fixtures (agent-gov-core/test-utils)
Secondary entry point used by consumer test suites. Zero overhead in production — only loaded when test files import it.
writeFiles(dir, { relPath: content })— write a map of files underdir, creating parent directoriesmakeGitRepo({ initialFiles?, initialMessage? })→{ repo, commit, head, git, cleanup }— temp repo on branchmainwith placeholder identity;commit()writes files and commits, returning the new SHAmakeOldNewFixture({ old, new })→{ old, new, cleanup }— two sibling temp directories for diff-mode CLI tests
Principles
- Zero runtime dependencies. Real TOML, JSONC, MCP normalization, shell tokenization — all hand-written or vendored, no transitive supply chain.
- MIT. No telemetry. No network calls anywhere in the library.
- Semver, with the contract frozen at v1.0. Until then, minor versions may include breaking changes (the v0.2 schema regex tightening is one example).
- Per-tool reasoning stays in each tool. This library is the substrate, not the orchestrator.
Used by
- ScopeTrail — agent permission drift in PRs (
scope_trail.*findings) - PolicyMesh — cross-surface agent policy contradictions (
policy_mesh.*) - CapabilityEcho — capability drift through code, not config (
capability_echo.*) - TaskBound — scope creep after the agent runs (
task_bound.*) - SessionTrail — runtime behavior across agent session transcripts (
session_trail.*)
License
MIT.