diff --git a/package-lock.json b/package-lock.json index c68bf42..cb77b8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.2.3", "license": "MIT", "dependencies": { - "agent-gov-core": "github:Conalh/agent-gov-core#v0.1.2" + "agent-gov-core": "github:Conalh/agent-gov-core#v0.2.0" }, "bin": { "taskbound": "dist/index.js" diff --git a/package.json b/package.json index 8710a43..7db6a39 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "test": "node --test test/*.test.mjs" }, "dependencies": { - "agent-gov-core": "github:Conalh/agent-gov-core#v0.1.2" + "agent-gov-core": "github:Conalh/agent-gov-core#v0.2.0" }, "devDependencies": { "@types/node": "^24.0.0", diff --git a/src/detectors/capability-signals.ts b/src/detectors/capability-signals.ts index 229b8af..8d6243c 100644 --- a/src/detectors/capability-signals.ts +++ b/src/detectors/capability-signals.ts @@ -58,7 +58,7 @@ function detectFetch(added: AddedLine): Finding[] { return [ { - kind: 'external_fetch_added', + kind: 'task_bound.external_fetch_added', category: 'capability', severity: 'medium', file: added.file, @@ -77,7 +77,7 @@ function detectSubprocess(added: AddedLine): Finding[] { return [ { - kind: 'subprocess_spawn_added', + kind: 'task_bound.subprocess_spawn_added', category: 'capability', severity: 'high', file: added.file, @@ -102,7 +102,7 @@ function compareLifecycleScripts(file: string, oldText: string, newText: string) const line = lineOfJsonKey(newText, key) ?? lineOfJsonStringValue(newText, newValue); findings.push({ - kind: 'lifecycle_script_changed', + kind: 'task_bound.lifecycle_script_changed', category: 'lifecycle', severity: 'high', file, @@ -114,7 +114,7 @@ function compareLifecycleScripts(file: string, oldText: string, newText: string) if (/(?:curl[^\n|]*\|\s*(?:ba)?sh|wget[^\n|]*\|\s*sh|Invoke-Expression|iex\s*\()/i.test(newValue)) { findings.push({ - kind: 'script_pipe_to_shell', + kind: 'task_bound.script_pipe_to_shell', category: 'lifecycle', severity: 'critical', file, diff --git a/src/detectors/dependency-drift.ts b/src/detectors/dependency-drift.ts index bc78d9b..0845d20 100644 --- a/src/detectors/dependency-drift.ts +++ b/src/detectors/dependency-drift.ts @@ -34,7 +34,7 @@ function compareDependencies(file: string, oldText: string, newText: string): Fi for (const [name, version] of Object.entries(newDeps)) { if (!(name in oldDeps)) { findings.push({ - kind: 'dependency_added', + kind: 'task_bound.dependency_added', category: 'dependency', severity: 'medium', file, @@ -48,7 +48,7 @@ function compareDependencies(file: string, oldText: string, newText: string): Fi if (oldDeps[name] !== version) { findings.push({ - kind: 'dependency_changed', + kind: 'task_bound.dependency_changed', category: 'dependency', severity: 'low', file, diff --git a/src/detectors/env-drift.ts b/src/detectors/env-drift.ts index 7a4bd44..93d7609 100644 --- a/src/detectors/env-drift.ts +++ b/src/detectors/env-drift.ts @@ -10,7 +10,7 @@ export function detectEnvDrift(changedFiles: ChangedFile[]): Finding[] { } findings.push({ - kind: 'env_file_changed', + kind: 'task_bound.env_file_changed', category: 'env', severity: 'high', file: changed.file, diff --git a/src/detectors/file-scope.ts b/src/detectors/file-scope.ts index e660977..4c9b337 100644 --- a/src/detectors/file-scope.ts +++ b/src/detectors/file-scope.ts @@ -14,7 +14,7 @@ export function detectFileScope(context: DiffContext, resolvedScope?: InferredSc const sensitiveLabel = getSensitiveSurfaceLabel(changed.file); if (sensitiveLabel && !scope.mentionsSensitiveSurfaces) { findings.push({ - kind: 'sensitive_surface_touched', + kind: 'task_bound.sensitive_surface_touched', category: 'sensitive_surface', severity: 'high', file: changed.file, @@ -34,7 +34,7 @@ export function detectFileScope(context: DiffContext, resolvedScope?: InferredSc } findings.push({ - kind: 'out_of_scope_file', + kind: 'task_bound.out_of_scope_file', category: 'scope', severity: isSensitiveSurface(changed.file) ? 'high' : 'medium', file: changed.file, diff --git a/test/cli-output.test.mjs b/test/cli-output.test.mjs index 23ab2a9..33ed9b5 100644 --- a/test/cli-output.test.mjs +++ b/test/cli-output.test.mjs @@ -41,9 +41,9 @@ test('CLI flags scope creep for CSS task with CI, MCP, and package changes', asy assert.equal(report.rating, 'critical'); assert.ok(report.findingCount >= 5); assert.ok(report.taskScopeSummary.some((entry) => entry.includes('css'))); - assert.ok(report.findings.some((finding) => finding.kind === 'sensitive_surface_touched')); - assert.ok(report.findings.some((finding) => finding.kind === 'dependency_added')); - assert.ok(report.findings.some((finding) => finding.kind === 'script_pipe_to_shell')); + assert.ok(report.findings.some((finding) => finding.kind === 'task_bound.sensitive_surface_touched')); + assert.ok(report.findings.some((finding) => finding.kind === 'task_bound.dependency_added')); + assert.ok(report.findings.some((finding) => finding.kind === 'task_bound.script_pipe_to_shell')); }); test('CLI emits Markdown task scope summary', async () => { @@ -128,7 +128,7 @@ test('CLI writes supplemental report files from one review', async () => { assert.match(stdout, /::warning file=\.mcp\.json/); assert.match(markdown, /# TaskBound scope review: CRITICAL/); assert.equal(json.rating, 'critical'); - assert.ok(json.findings.some((finding) => finding.kind === 'script_pipe_to_shell')); + assert.ok(json.findings.some((finding) => finding.kind === 'task_bound.script_pipe_to_shell')); } finally { await rm(outputDir, { recursive: true, force: true }); } @@ -186,7 +186,7 @@ test('additional scope context affects out-of-scope file findings', async () => ); const report = JSON.parse(stdout); const apiFileScopeFinding = report.findings.find( - (finding) => finding.kind === 'out_of_scope_file' && finding.file === 'src/api/client.ts' + (finding) => finding.kind === 'task_bound.out_of_scope_file' && finding.file === 'src/api/client.ts' ); assert.equal(report.scopeMatchCount, 2); @@ -255,7 +255,7 @@ test('CLI applies .taskbound.yml per-rule severity overrides', async () => { const report = JSON.parse(stdout); assert.equal(report.rating, 'high'); - assert.equal(report.findings.find((finding) => finding.kind === 'script_pipe_to_shell')?.severity, 'high'); + assert.equal(report.findings.find((finding) => finding.kind === 'task_bound.script_pipe_to_shell')?.severity, 'high'); }); test('CLI does not treat repository test fixture package files as install surfaces', async () => { @@ -269,9 +269,9 @@ test('CLI does not treat repository test fixture package files as install surfac ); const report = JSON.parse(stdout); - assert.equal(report.findings.some((finding) => finding.kind === 'script_pipe_to_shell'), false); - assert.equal(report.findings.some((finding) => finding.kind === 'lifecycle_script_changed'), false); - assert.equal(report.findings.some((finding) => finding.kind === 'dependency_added'), false); + assert.equal(report.findings.some((finding) => finding.kind === 'task_bound.script_pipe_to_shell'), false); + assert.equal(report.findings.some((finding) => finding.kind === 'task_bound.lifecycle_script_changed'), false); + assert.equal(report.findings.some((finding) => finding.kind === 'task_bound.dependency_added'), false); }); @@ -285,8 +285,8 @@ test('capability signal findings expose stable kind and category fields', async { cwd: packageRoot } ); const report = JSON.parse(stdout); - const capabilityFinding = report.findings.find((finding) => finding.kind === 'external_fetch_added'); + const capabilityFinding = report.findings.find((finding) => finding.kind === 'task_bound.external_fetch_added'); - assert.equal(capabilityFinding?.kind, 'external_fetch_added'); + assert.equal(capabilityFinding?.kind, 'task_bound.external_fetch_added'); assert.equal(capabilityFinding?.category, 'capability'); }); diff --git a/test/fixtures/configured-severity/new/.taskbound.yml b/test/fixtures/configured-severity/new/.taskbound.yml index 8e5c636..d64802c 100644 --- a/test/fixtures/configured-severity/new/.taskbound.yml +++ b/test/fixtures/configured-severity/new/.taskbound.yml @@ -1,2 +1,2 @@ severity: - script_pipe_to_shell: high + task_bound.script_pipe_to_shell: high diff --git a/test/fixtures/configured-severity/old/.taskbound.yml b/test/fixtures/configured-severity/old/.taskbound.yml index 8e5c636..d64802c 100644 --- a/test/fixtures/configured-severity/old/.taskbound.yml +++ b/test/fixtures/configured-severity/old/.taskbound.yml @@ -1,2 +1,2 @@ severity: - script_pipe_to_shell: high + task_bound.script_pipe_to_shell: high diff --git a/test/git-review.test.mjs b/test/git-review.test.mjs index f3f1b16..e82bdd1 100644 --- a/test/git-review.test.mjs +++ b/test/git-review.test.mjs @@ -64,8 +64,8 @@ test('CLI reviews scope creep between git refs', async () => { const report = JSON.parse(stdout); assert.equal(report.rating, 'critical'); - assert.ok(report.findings.some((finding) => finding.kind === 'sensitive_surface_touched')); - assert.ok(report.findings.some((finding) => finding.kind === 'dependency_added')); + assert.ok(report.findings.some((finding) => finding.kind === 'task_bound.sensitive_surface_touched')); + assert.ok(report.findings.some((finding) => finding.kind === 'task_bound.dependency_added')); } finally { await rm(repo, { recursive: true, force: true }); } diff --git a/test/scope-infer.test.mjs b/test/scope-infer.test.mjs index 65ade32..0bc3fd3 100644 --- a/test/scope-infer.test.mjs +++ b/test/scope-infer.test.mjs @@ -48,7 +48,7 @@ test('file scope detector flags sensitive surfaces for CSS task', () => { addedLines: [] }); - assert.ok(findings.some((finding) => finding.kind === 'sensitive_surface_touched' && finding.file === '.mcp.json')); - assert.ok(findings.some((finding) => finding.kind === 'sensitive_surface_touched' && finding.file === 'package.json')); + assert.ok(findings.some((finding) => finding.kind === 'task_bound.sensitive_surface_touched' && finding.file === '.mcp.json')); + assert.ok(findings.some((finding) => finding.kind === 'task_bound.sensitive_surface_touched' && finding.file === 'package.json')); assert.equal(findings.some((finding) => finding.file === 'styles/header.css'), false); });