#!/usr/bin/env bash # ============================================================================ # map-live.sh — BẢN ĐỒ TẤN CÔNG SỐNG cho pane TRÁI của tmux. # Đọc "bước hiện tại" từ file trạng thái (do run-all.sh ghi) và vẽ lại map: # ✓ xanh = bước đã xong # ▶ nhấp nháy vàng = bước đang chạy # · mờ = bước chưa tới # Dùng: bash map-live.sh [STEP_FILE] (mặc định /tmp/casan_step) # ============================================================================ STEP_FILE="${1:-${CASAN_STEP_FILE:-/tmp/casan_step}}" MODE_FILE="$STEP_FILE.mode" # run-all.sh ghi 'REAL' vào đây khi REAL=1 ESC=$'\e' HOME_="${ESC}[H"; CLR="${ESC}[2J"; EOL="${ESC}[K"; EOS="${ESC}[J" HIDE="${ESC}[?25l"; SHOW="${ESC}[?25h" RST="${ESC}[0m"; B="${ESC}[1m"; DIM="${ESC}[2m" GRN="${ESC}[32m"; YEL="${ESC}[93m"; CYN="${ESC}[36m"; MAG="${ESC}[95m" HLON="${ESC}[103m${ESC}[30m" # nền vàng sáng, chữ đen (khung nhấp-nháy BẬT) # Thứ tự tuyến tính để biết bước nào trước/sau (dùng cho ✓ và ·) # PIPELINE (lát cắt STEP1 thật) chỉ xuất hiện ở REAL=1, nằm ngay sau battery D. ORDER=(A1 A2 A3 A4 A5 A6 A7 A8 B1 B2 B3 B4 B5 D1 D2 D3 D4 D5 PIPELINE CHAIN) # Hàng hiển thị: "H||" hoặc "S||" DISPLAY=( "H||⭐ H4 · SECURITY" "S|A1|A1 direct injection" "S|A2|A2 novel paraphrase" "S|A3|A3 semantic classify" "S|A4|A4 obfuscation" "S|A5|A5 indirect artifact 🔥" "S|A6|A6 secret in input" "S|A7|A7 PII / credit card" "S|A8|A8 red-team recall" "H||⭐ H5 · GOVERNANCE" "S|B1|B1 audit tamper 🔥" "S|B2|B2 chain re-forge" "S|B3|B3 secret commit" "S|B4|B4 no-bypass" "S|B5|B5 tool-audit SoD" "H||⭐ H6 · AGENTOPS" "S|D1|D1 cost-spike 3× 🔥" "S|D2|D2 negative control" "S|D3|D3 drift detect" "S|D4|D4 telemetry thật" "S|D5|D5 hallucination" "H||🏭 PIPELINE THẬT (REAL=1)" "S|PIPELINE|STEP1 okr.srs qua harness" "H||🔥 CROSS-LAYER" "S|CHAIN|CHAIN · 4 lớp MAESTRO" ) idx_of() { local t="$1" i; for i in "${!ORDER[@]}"; do [ "${ORDER[$i]}" = "$t" ] && { echo "$i"; return; }; done; echo -1; } draw() { local cur="$1" blink="$2" local curIdx; curIdx="$(idx_of "$cur")" case "$cur" in SCORECARD|DONE) curIdx=${#ORDER[@]};; INTRO|"") curIdx=-1;; esac local is_real=0; [ -f "$MODE_FILE" ] && is_real=1 local out="${HOME_}" out+="${B}${CYN} CASAN · ATTACK MAP${RST}${EOL}"$'\n' out+="${DIM} tiến độ chạy theo terminal ▸ $( [ "$is_real" = 1 ] && printf 'REAL' || printf 'demo' )${RST}${EOL}"$'\n' out+="${EOL}"$'\n' local entry typ id label idx for entry in "${DISPLAY[@]}"; do IFS='|' read -r typ id label <<<"$entry" # Lát cắt PIPELINE chỉ hiển thị ở REAL=1 (header + row). if [ "$is_real" != 1 ] && { [ "$id" = "PIPELINE" ] || [ "$label" = "🏭 PIPELINE THẬT (REAL=1)" ]; }; then continue fi if [ "$typ" = "H" ]; then out+="${B}${MAG} $label${RST}${EOL}"$'\n' continue fi idx="$(idx_of "$id")" if [ "$idx" -lt "$curIdx" ]; then out+=" ${GRN}✓ ${label}${RST}${EOL}"$'\n' elif [ "$idx" -eq "$curIdx" ]; then if [ "$blink" = "1" ]; then out+=" ${HLON} ▶ ${label} ${RST}${EOL}"$'\n' else out+=" ${B}${YEL}▶ ${label}${RST}${EOL}"$'\n' fi else out+=" ${DIM}· ${label}${RST}${EOL}"$'\n' fi done out+="${EOL}"$'\n' if [ "$cur" = "DONE" ] || [ "$cur" = "SCORECARD" ]; then out+="${B}${GRN} ✔ HOÀN TẤT — PASS${RST}${EOL}"$'\n' fi out+="${DIM} OWASP·MAESTRO·ATLAS·NIST·ISO42001${RST}${EOS}" printf '%s' "$out" } cleanup() { printf '%s' "$SHOW"; } trap cleanup EXIT INT TERM printf '%s%s' "$HIDE" "$CLR" blink=0 while true; do cur="$(cat "$STEP_FILE" 2>/dev/null)" blink=$((1 - blink)) draw "$cur" "$blink" sleep 0.45 done