feat(aav): AAV expansion — Crescendo + TAP multi-turn attack strategies - #89
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR expands Lyrie’s local-first engine/runtime with new orchestration and provider abstractions, adds PoC-generation and daemon/coordinator infrastructure in @lyrie/core, introduces a Rust Shield stdin/stdout RPC surface, and adds a new @lyrie/agt-bridge workspace for AGT policy enforcement. In the broader codebase, these changes aim to support more autonomous/local execution paths while tightening governance and pentest workflows.
Changes:
- Added new local/provider-independence primitives: provider registry/adapters, prompt builder/system-prompt exports, deferred tool registry, coordinator/verifier/spawn/daemon utilities.
- Added pentest PoC-generation modules and wired richer PoC output into
stages-validator. - Added Rust Shield RPC support and introduced the AGT Bridge workspace/docs/tests.
Reviewed changes
Copilot reviewed 67 out of 67 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
packages/shield/src/rpc.rs |
Adds stdin/stdout JSON-RPC methods for file, tool-sequence, outbound-request, and status scanning. |
packages/shield/src/main.rs |
Wires new rpc CLI subcommand into the Rust Shield binary. |
packages/core/src/tools/tool-registry.ts |
Introduces deferred-loading tool registry and schema hydration/search logic. |
packages/core/src/tools/tool-registry.test.ts |
Adds unit tests for deferred tool registry behavior. |
packages/core/src/tools/tool-executor.ts |
Hooks tool executor into deferred registry and adds tool_search plus filtered formatter helpers. |
packages/core/src/pentest/stages-validator.ts |
Replaces hardcoded PoC generation with PoCGenerator and surfaces structured PoC detail. |
packages/core/src/pentest/poc-gen/types.ts |
Defines structured PoC output types, supported categories, and warning constants. |
packages/core/src/pentest/poc-gen/index.ts |
Implements PoC generator entrypoint, category routing, and Shield gating. |
packages/core/src/pentest/poc-gen/generators/xss.ts |
Adds XSS PoC generator. |
packages/core/src/pentest/poc-gen/generators/ssrf.ts |
Adds SSRF PoC generator. |
packages/core/src/pentest/poc-gen/generators/sqli.ts |
Adds SQLi PoC generator. |
packages/core/src/pentest/poc-gen/generators/rce.ts |
Adds RCE/shell-injection PoC generator. |
packages/core/src/pentest/poc-gen/generators/path-traversal.ts |
Adds path-traversal PoC generator. |
packages/core/src/pentest/poc-gen/generators/index.ts |
Re-exports PoC generators. |
packages/core/src/pentest/poc-gen/generators/deserialization.ts |
Adds insecure-deserialization PoC generator. |
packages/core/src/engine/system-prompt.ts |
Re-exports prompt primitives and adds minimal prompt builder helper. |
packages/core/src/engine/system-prompt.test.ts |
Tests minimal system prompt contents and exports. |
packages/core/src/engine/providers/ollama-lyrie.ts |
Adds LyrieProvider adapter for Ollama. |
packages/core/src/engine/providers/lyrie-provider.ts |
Introduces provider-independence interfaces, registry, and local-provider guard. |
packages/core/src/engine/providers/lyrie-provider.test.ts |
Tests provider registry/adapters and guard behavior. |
packages/core/src/engine/providers/lmstudio.ts |
Adds LyrieProvider adapter for LM Studio. |
packages/core/src/engine/providers/index.ts |
Exports new provider-independence layer and bootstrap helper. |
packages/core/src/engine/providers/hermes.ts |
Adds Hermes provider adapter and tool-call parsing/prompt shaping. |
packages/core/src/engine/prompt-builder.ts |
Adds static/dynamic prompt builder with cache boundary and deferred tool names. |
packages/core/src/engine/prompt-builder.test.ts |
Tests prompt boundary behavior and static prompt invariants. |
packages/core/src/engine/model-router.ts |
Integrates registry-based provider dispatch into model routing. |
packages/core/src/engine/lyrie-engine.ts |
Adds coordinator-mode tool filtering before tool-use dispatch. |
packages/core/src/engine/daemon.ts |
Adds proactive tick-based daemon loop and prompt contract. |
packages/core/src/engine/daemon.test.ts |
Tests daemon tick-loop behavior. |
packages/core/src/config.ts |
Adds new local/provider/coordinator configuration fields. |
packages/core/src/agents/verifier.ts |
Adds adversarial verifier prompt/parser utilities. |
packages/core/src/agents/verifier.test.ts |
Tests verifier parsing and PASS acceptance rules. |
packages/core/src/agents/spawn-modes.ts |
Adds fork/fresh sub-agent spawn policy helpers and ATP scope narrowing checks. |
packages/core/src/agents/spawn-modes.test.ts |
Tests spawn-mode validation and task augmentation. |
packages/core/src/agents/coordinator.ts |
Adds coordinator-only tool allowlist and prompt addendum. |
packages/core/src/agents/coordinator.test.ts |
Tests coordinator tool filtering and prompt behavior. |
packages/core/src/aav/strategies/tap.test.ts |
Adds TAP strategy tests. |
packages/core/src/aav/strategies/index.ts |
Exports Crescendo and TAP AAV strategies. |
packages/core/src/aav/strategies/crescendo.test.ts |
Adds Crescendo strategy tests. |
packages/agt-bridge/tests/policy.test.ts |
Adds AGT policy generator tests in the workspace root. |
packages/agt-bridge/src/types.ts |
Defines AGT bridge public types and policy schema. |
packages/agt-bridge/src/policy.ts |
Implements Lyrie scope → AGT policy translation. |
packages/agt-bridge/src/index.ts |
Exports AGT bridge public API. |
packages/agt-bridge/src/cli.ts |
Adds CLI helpers for AGT status/install/policy generation. |
packages/agt-bridge/src/bridge.ts |
Implements AGT availability detection, policy caching, and validation bridge. |
packages/agt-bridge/packages/agt-bridge/tests/policy.test.ts |
Adds duplicated nested AGT policy tests. |
packages/agt-bridge/packages/agt-bridge/src/types.ts |
Adds duplicated nested AGT types. |
packages/agt-bridge/packages/agt-bridge/src/policy.ts |
Adds duplicated nested AGT policy generator. |
packages/agt-bridge/packages/agt-bridge/src/index.ts |
Adds duplicated nested AGT exports. |
packages/agt-bridge/packages/agt-bridge/src/cli.ts |
Adds duplicated nested AGT CLI. |
packages/agt-bridge/packages/agt-bridge/src/bridge.ts |
Adds duplicated nested AGT bridge implementation. |
packages/agt-bridge/packages/agt-bridge/package.json |
Adds nested package manifest for duplicated AGT package copy. |
packages/agt-bridge/packages/agt-bridge/README.md |
Adds nested duplicated AGT package README. |
packages/agt-bridge/package.json |
Registers the AGT bridge workspace package manifest. |
packages/agt-bridge/README.md |
Adds AGT bridge package README. |
package.json |
Adds packages/agt-bridge to root workspaces. |
deploy/lyrie.local.yml |
Adds local-only deployment example using Hermes/Ollama and new engine options. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+115
to
+121
| export class LyrieProviderRegistry { | ||
| private providers: Map<string, LyrieProvider> = new Map(); | ||
|
|
||
| register(provider: LyrieProvider): void { | ||
| this.providers.set(provider.id, provider); | ||
| } | ||
|
|
Comment on lines
+68
to
+75
| export class LyrieCoordinator { | ||
| private allowed: Set<string>; | ||
| private appendRules?: string; | ||
|
|
||
| constructor(opts: CoordinatorOptions = {}) { | ||
| this.allowed = opts.allowedTools ?? COORDINATOR_ALLOWED_TOOLS; | ||
| this.appendRules = opts.appendRules; | ||
| } |
Comment on lines
+215
to
+224
| // ── Path 1: LyrieProviderRegistry (independence layer) ─────────────── | ||
| const registry = LyrieProviderRegistry.getInstance(); | ||
| const registryProvider: LyrieProvider | undefined = | ||
| registry.get(this.config.provider ?? "hermes") || | ||
| registry.get("hermes") || | ||
| registry.list()[0]; | ||
|
|
||
| if (registryProvider) { | ||
| const modelId = registryProvider.defaultModel; | ||
| console.log(`[ModelRouter] Registry dispatch → provider=${registryProvider.id} model=${modelId}`); |
Comment on lines
+93
to
+97
| const evidence = raw.evidence ?? ""; | ||
| if (evidence) { | ||
| const verdict = this.shield.scanRecalled(evidence); | ||
| if (verdict.blocked && verdict.severity === "high") { | ||
| return null; // evidence is a Shield self-fixture — no PoC emitted |
Comment on lines
+136
to
+143
| // If content provided, write to a temp file for scanning, or scan | ||
| // the existing path. We use the behavioral analyzer on the content | ||
| // and the file scanner on the path. | ||
| let threat = if let Some(ref content) = params.content { | ||
| shield.behavioral.analyze_command(content) | ||
| } else { | ||
| shield.scan_file(¶ms.path) | ||
| }; |
Comment on lines
+2
to
+19
| "name": "lyrie-agent", | ||
| "version": "0.9.0", | ||
| "description": "The world's first autonomous AI agent with built-in cybersecurity", | ||
| "author": "OTT Cybersecurity LLC <dev@lyrie.ai> (https://lyrie.ai)", | ||
| "license": "MIT", | ||
| "packageManager": "bun@1.3.11", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/overthetopseo/lyrie-agent.git" | ||
| }, | ||
| "homepage": "https://lyrie.ai", | ||
| "workspaces": [ | ||
| "packages/core", | ||
| "packages/agt-bridge", | ||
| "packages/gateway", | ||
| "packages/mcp", | ||
| "packages/ui" | ||
| ], |
Comment on lines
+219
to
+241
| "scan_outbound_request" => { | ||
| let params: ScanOutboundRequestParams = parse_params(&req.params)?; | ||
| let start = Instant::now(); | ||
|
|
||
| let url_result = shield.waf.check_url(¶ms.url); | ||
| let mut threats: Vec<String> = Vec::new(); | ||
|
|
||
| if url_result.blocked || url_result.threat_type.is_some() { | ||
| if let Some(desc) = &url_result.description { | ||
| threats.push(desc.clone()); | ||
| } | ||
| } | ||
|
|
||
| if let Some(body) = ¶ms.body { | ||
| if !body.is_empty() { | ||
| let body_result = shield.waf.check_request_body(body); | ||
| if body_result.blocked || body_result.threat_type.is_some() { | ||
| if let Some(desc) = &body_result.description { | ||
| threats.push(desc.clone()); | ||
| } | ||
| } | ||
| } | ||
| } |
Comment on lines
+38
to
+47
| export class ToolRegistry { | ||
| private tools: Map<string, Tool> = new Map(); | ||
| private alwaysLoaded: Set<string>; | ||
| private maxSearchResults: number; | ||
| /** Names that the agent has already fetched the schema for (per session). */ | ||
| private hydrated: Set<string> = new Set(); | ||
|
|
||
| constructor(cfg: ToolRegistryConfig = {}) { | ||
| this.alwaysLoaded = new Set(cfg.alwaysLoaded ?? ["tool_search", "agent_spawn"]); | ||
| this.maxSearchResults = cfg.maxSearchResults ?? 8; |
…ndo/TAP with existing strategy module Root cause of CI red on all 6 Lint & Test matrix jobs: PR #89's branch (feat/aav-crescendo-tap) had a stale bun.lock relative to its own package.json, so `bun install --frozen-lockfile` failed outright in CI before lint/build/test could even run (verified by reproducing locally against the original branch head b150146). The branch was also cut before GCG/AutoDAN/PAIR strategies were merged to main, so its crescendo.ts/tap.ts (class-based CrescendoStrategy/TAPStrategy API) fully diverged from main's already-merged crescendo.ts/tap.ts (older function-based runCrescendo/runTap API) — a real feature conflict, not just a trivial rebase. Resolution: rebuilt this branch from current ott/main (clean lockfile) and merged in the PR's improved class-based Crescendo/TAP implementation (real refusal detection, retry-capped escalation, calibrated scorer thresholds, 41 passing tests) in place of main's simpler heuristic version, while preserving main's GCG/AutoDAN/PAIR strategies untouched. - packages/core/src/aav/strategies/crescendo.ts, tap.ts (+tests): replaced with PR's calibrated implementation. - packages/core/src/aav/strategies/index.ts: export the new CrescendoStrategy/TAPStrategy classes and types alongside the existing GCGStrategy/AutoDANStrategy/runPair exports. - scripts/redteam.ts: updated --strategy crescendo|tap call sites from the old runCrescendo/runTap function API to `new CrescendoStrategy().attack(...)` / `new TAPStrategy().attack(...)` (only real external consumer of the old API in the repo). Verified locally: - packages/core: bun test -> 1650 pass / 0 fail (86 files) - packages/core/src/aav: bun test -> 138 pass / 0 fail (9 files) - packages/core/src/aav/strategies: bun test -> 47 pass / 0 fail - bun install --frozen-lockfile: passes - bun run scripts/doctor.ts: 14 ok / 2 warn / 0 error, exit 0 - bun run build (turbo, 5 packages): 5/5 successful - bun run test (turbo, all packages): 7/7 successful - bun run lint: pre-existing @lyrie/ui failure (next lint invoked with wrong project dir) reproduces identically on unmodified ott/main HEAD — not introduced by this PR, out of scope for this fix.
overthetopseo
force-pushed
the
feat/aav-crescendo-tap
branch
from
August 6, 2026 09:46
b150146 to
7b1cdd3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Expands Lyrie's Adversarial AI Validation (AAV) engine with Crescendo and TAP (Tree of Attacks with Pruning) multi-turn attack strategies, plus integrates the AGT Bridge and Rust Shield into a unified pipeline.
What It Does
Key Files
packages/core/src/hack/orchestrator.tspackages/agt-bridge/src/bridge.tspackages/agt-bridge/src/policy.tspackages/agt-bridge/src/validator.tspackages/core/src/engine/rust-shield-bridge.tspackages/core/src/engine/model-router.tsTests
Includes bridge and policy tests from AGT bridge, plus all engine-wiring tests.
Part of
Lyrie v1.0.0 feature set. See
feat/v1.0.0-integrationfor the full integration (1,099 tests passing).