feat(context): add @atr provider for AI agent threat scanning#12194
feat(context): add @atr provider for AI agent threat scanning#12194eeee2345 wants to merge 4 commits into
Conversation
Introduces ATRSecurityContextProvider that loads the Agent Threat Rules ruleset (optional 'agent-threat-rules' npm dependency) and surfaces HIGH/CRITICAL matches for the current file as chat context items. Mirrors ProblemsContextProvider structure; lazy-imports the dependency so users who don't install it see a friendly install hint instead. Zero network calls, zero telemetry.
|
All contributors have signed the CLA ✍️ ✅ |
There was a problem hiding this comment.
2 issues found across 3 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="core/context/providers/ATRSecurityContextProvider.ts">
<violation number="1" location="core/context/providers/ATRSecurityContextProvider.ts:49">
P2: Failed engine initialization is cached permanently, so the provider cannot recover or retry after a transient load failure.</violation>
<violation number="2" location="core/context/providers/ATRSecurityContextProvider.ts:104">
P2: Empty open files are incorrectly treated as missing files due to a falsy check on `file.contents`.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
|
I have read the CLA Document and I hereby sign the CLA recheck |
|
I have read the CLA Document and I hereby sign the CLA |
…ovider Three small fixes in one pass: 1. Cubic P2: failed engine initialization was cached permanently. If the first call to getEngine() threw (e.g. transient dynamic-import failure or the optional dependency being installed mid-session), enginePromise stayed pinned to the rejected promise and every subsequent call returned the same rejection. Now the catch block resets enginePromise to null so the next invocation can retry. 2. Cubic P2: empty open files were treated as missing files. The old `if (!file || !file.contents)` evaluated to true on a freshly-opened empty file (contents is the empty string, which is falsy) and surfaced the "no file to scan" message. Now the check uses `typeof file.contents !== "string"` so empty files are scanned (zero matches is itself a useful signal). 3. Prettier: existing `highSeverity = matches.filter(...)` had a line break inside the arrow function that prettier 3.3.3 reformats to a single line under default printWidth. Applied prettier --write to close that nit so prettier-check passes. Test seams (__setEngine, __setEngineError, __resetEngine) are unaffected. Signed-off-by: Adam Lin <adam@agentthreatrule.org>
|
@cubic-dev-ai — pushed 14947d5 addressing both P2 findings on
Same push also applies |
@eeee2345 Both fixes look correct in the commit. Engine retry (line 49): Clearing Empty file check (line 104): Prettier: The single-line The test matrix should re-evaluate green from here — all four test cases (match surfacing, benign/clean, missing dependency, no open file) are already wired and passed on the first push. Nothing in this commit breaks those seams. |
CI surfaced two TypeScript build errors after the prettier fix landed:
1. TS2307 on line 51: `Cannot find module 'agent-threat-rules'`.
The dependency is optional (not in core/package.json), so the static
string literal in `await import("agent-threat-rules")` triggers
tsc's module-resolution check at build time. Switching to a variable
for the module name keeps tsc from resolving against an installed
package while the actual dynamic import still works at runtime; the
surrounding try/catch handles the not-installed case unchanged.
2. TS2339 on line 56: `Property 'createRequire' does not exist on type
'{ default: typeof Module; ... }'`. The dynamic `await import("node:module")`
typed the result with only the default export visible. Moving
`createRequire` (and `dirname`/`join`) to static top-of-file imports
resolves the type while keeping the same runtime behavior — these
are Node stdlib modules and were never optional.
Test seams (__setEngine, __setEngineError, __resetEngine) and runtime
behavior are unchanged. The previous P2 fixes (engine-init clearing on
failure, `typeof file.contents !== "string"` check) are preserved.
Signed-off-by: Adam Lin <adam@agentthreatrule.org>
binary-checks and vscode-checks failed with TS1343: 'import.meta' is
only allowed under ES2020+ module targets. binary/tsconfig.json and
extensions/vscode/tsconfig.json both use `"module": "commonjs"` (with
ES2022 target), and they type-check across the core/ source tree via
project references, so a direct `import.meta.url` in core/ rejects
their builds even though core/'s own tsconfig.npm.json uses ESNext.
Defer the import.meta access through `new Function("return
import.meta.url")` so tsc only sees a string-literal eval. At runtime
the IIFE returns the URL under ESM (core/ npm build), or falls back to
`__filename` under CommonJS (binary/, vscode/). The provider itself
only runs at runtime inside core/ — binary/vscode just need to type-
check the source without rejecting it.
Verified that the file now compiles under both module targets locally
(tsc against binary/tsconfig.json and core/tsconfig.npm.json).
Signed-off-by: Adam Lin <adam@agentthreatrule.org>
|
For reviewer context — the single remaining CI failure is unrelated to this PR: That test lives in This looks like a pre-existing flaky onboarding test rather than something caused by the ATR provider. The same |
Summary
Adds an
@atrcontext provider that scans the currently open file against the Agent Threat Rules (ATR) ruleset — 314 MIT-licensed YAML rules for AI agent threats (prompt injection, MCP tool poisoning, context exfiltration, skill-package compromise).Invoking
@atrin chat attaches each HIGH/CRITICAL rule match as a context item so the model sees the finding alongside the code.Why this fits Continue
ProblemsContextProvider— reads current-file state, returns oneContextItemper finding.agent-threat-rulesis lazily imported. Users who don't install it see a one-line install hint; no bundle-size impact for users who don't use@atr.@problems(TS/lint diagnostics);@atrtargets AI-specific attack patterns that static analyzers don't cover.Context on ATR
ATR is an open detection standard for AI agent threats. The ruleset is already integrated into two upstream ecosystems:
Benchmarks: 97.1% recall on NVIDIA garak's 666 in-the-wild jailbreak corpus; 100% recall on a 498-sample labeled SKILL.md benchmark; 0 false positives on a 432-sample benign skill corpus.
Source: https://github.com/Agent-Threat-Rule/agent-threat-rules
Paper: https://doi.org/10.5281/zenodo.19178002
Files
core/context/providers/ATRSecurityContextProvider.tscore/context/providers/ATRSecurityContextProvider.test.tscore/context/providers/index.tsTests
Covers: HIGH/CRITICAL match surfacing, benign file reports "clean", missing dependency returns friendly install hint, missing open file handled gracefully.
Alternatives considered
If maintainers prefer external packaging over an in-tree provider, I can ship this as
@continuedev/context-atr(or in the ATR org) using Continue'sCustomContextProviderpath. Opening here first to gauge preference — happy to pivot to an external package + a small docs PR linking to it.Also happy to split into two PRs (provider + tests) or narrow scope if that fits the review cadence better.
Summary by cubic
Adds a new
@atrcontext provider that scans the current file with the Agent Threat Rules and surfaces HIGH/CRITICAL findings as chat context items. Uses local rules fromagent-threat-rules, no network calls.New Features
ATRSecurityContextProviderand register as@atr.Bug Fixes
agent-threat-rulesimport (avoids TS2307) and move Node imports to top-of-file to resolve TS2339.import.meta.urlaccess to support non-ES2020/CommonJS subprojects (avoids TS1343), with a safe__filenamefallback.Written for commit 97ed375. Summary will update on new commits. Review in cubic