fix: feat: persist red-team cross-patterns in repo for continuity across runs (#853)
- Move CROSS_PATTERNS_FILE from /tmp/red-team-cross-patterns.jsonl to tools/red-team/cross-patterns.jsonl (repo-tracked path) - Remove the reset (> file) at sweep start so patterns accumulate across runs - Generate a SWEEP_ID (sweep-YYYYMMDD-HHMMSS) at sweep start and stamp each new entry with sweep_id for traceability - Deduplicate on (pattern, candidate, result): entries already present in the file are skipped; intra-batch duplicates are also suppressed - Create tools/red-team/ directory with .gitkeep - Add mkdir -p guards in both scripts so the directory is created on first run Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3d8bbb0975
commit
fe3a3d7d94
3 changed files with 35 additions and 6 deletions
|
|
@ -11,7 +11,7 @@ INJECT="$REPO_ROOT/tools/push3-transpiler/inject.sh"
|
|||
ATTACKS_OUT="$REPO_ROOT/onchain/script/backtesting/attacks"
|
||||
PROGRESS_FILE="/tmp/red-team-sweep-progress.json"
|
||||
MEMORY_FILE="$REPO_ROOT/tmp/red-team-memory.jsonl"
|
||||
CROSS_PATTERNS_FILE="/tmp/red-team-cross-patterns.jsonl"
|
||||
CROSS_PATTERNS_FILE="$REPO_ROOT/tools/red-team/cross-patterns.jsonl"
|
||||
SWEEP_TSV="/tmp/sweep-results.tsv"
|
||||
OPT_SOL="$REPO_ROOT/onchain/src/OptimizerV3.sol"
|
||||
TIMEOUT_PER="${1:-3600}"
|
||||
|
|
@ -22,9 +22,11 @@ die() { log "FATAL: $*" >&2; exit 1; }
|
|||
[[ -f "$INJECT" ]] || die "inject.sh not found at $INJECT"
|
||||
|
||||
mkdir -p "$ATTACKS_OUT"
|
||||
mkdir -p "$(dirname "$CROSS_PATTERNS_FILE")"
|
||||
|
||||
# Reset cross-patterns file for this sweep invocation (prevents stale data from prior runs)
|
||||
> "$CROSS_PATTERNS_FILE"
|
||||
# Generate a unique sweep ID for traceability across runs
|
||||
SWEEP_ID="sweep-$(date -u +%Y%m%d-%H%M%S)"
|
||||
log "Sweep ID: $SWEEP_ID"
|
||||
|
||||
# Load progress
|
||||
completed=()
|
||||
|
|
@ -217,11 +219,12 @@ PYEOF
|
|||
# 4c. Extract abstract patterns into cross-candidate file, then clear raw memory
|
||||
if [[ -f "$MEMORY_FILE" && -s "$MEMORY_FILE" ]]; then
|
||||
set +e
|
||||
_extract_out=$(python3 - "$MEMORY_FILE" "$CROSS_PATTERNS_FILE" <<'PYEOF'
|
||||
_extract_out=$(python3 - "$MEMORY_FILE" "$CROSS_PATTERNS_FILE" "$SWEEP_ID" <<'PYEOF'
|
||||
import json, sys
|
||||
|
||||
mem_file = sys.argv[1]
|
||||
cross_file = sys.argv[2]
|
||||
sweep_id = sys.argv[3] if len(sys.argv) > 3 else "unknown"
|
||||
|
||||
new_entries = []
|
||||
with open(mem_file) as f:
|
||||
|
|
@ -237,11 +240,36 @@ if not new_entries:
|
|||
print("No memory entries to extract")
|
||||
sys.exit(0)
|
||||
|
||||
# Load existing (pattern, candidate, result) keys for deduplication
|
||||
existing_keys = set()
|
||||
try:
|
||||
with open(cross_file) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line:
|
||||
try:
|
||||
e = json.loads(line)
|
||||
existing_keys.add((e.get("pattern", ""), e.get("candidate", ""), e.get("result", "")))
|
||||
except Exception:
|
||||
pass
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
appended = 0
|
||||
skipped = 0
|
||||
with open(cross_file, 'a') as f:
|
||||
for e in new_entries:
|
||||
key = (e.get("pattern", ""), e.get("candidate", ""), e.get("result", ""))
|
||||
if key in existing_keys:
|
||||
skipped += 1
|
||||
continue
|
||||
e["sweep_id"] = sweep_id
|
||||
existing_keys.add(key) # prevent intra-batch duplicates
|
||||
f.write(json.dumps(e) + '\n')
|
||||
appended += 1
|
||||
|
||||
print(f"Extracted {len(new_entries)} entr{'y' if len(new_entries)==1 else 'ies'} to cross-patterns file")
|
||||
total = appended + skipped
|
||||
print(f"Extracted {appended} new entr{'y' if appended==1 else 'ies'} ({skipped} duplicate{'s' if skipped!=1 else ''} skipped) to cross-patterns file")
|
||||
PYEOF
|
||||
)
|
||||
_py_exit=$?
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ REPORT_DIR="$REPO_ROOT/tmp"
|
|||
REPORT="$REPORT_DIR/red-team-report.txt"
|
||||
STREAM_LOG="$REPORT_DIR/red-team-stream.jsonl"
|
||||
MEMORY_FILE="$REPO_ROOT/tmp/red-team-memory.jsonl"
|
||||
CROSS_PATTERNS_FILE="/tmp/red-team-cross-patterns.jsonl"
|
||||
CROSS_PATTERNS_FILE="$REPO_ROOT/tools/red-team/cross-patterns.jsonl"
|
||||
ATTACK_EXPORT="$REPORT_DIR/red-team-attacks.jsonl"
|
||||
ATTACK_SNAPSHOTS="$REPORT_DIR/red-team-snapshots.jsonl"
|
||||
DEPLOYMENTS="$REPO_ROOT/onchain/deployments-local.json"
|
||||
|
|
@ -581,6 +581,7 @@ PROMPT=${PROMPT//\{\{MEMORY_SECTION\}\}/$MEMORY_SECTION}
|
|||
# ── 7. Create output directory and run the agent ───────────────────────────────
|
||||
mkdir -p "$REPORT_DIR"
|
||||
mkdir -p "$(dirname "$MEMORY_FILE")"
|
||||
mkdir -p "$(dirname "$CROSS_PATTERNS_FILE")"
|
||||
|
||||
log "Spawning Claude red-team agent (timeout: ${CLAUDE_TIMEOUT}s)..."
|
||||
log " Report will be written to: $REPORT"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue