// DAEV Fixtures — 7 canonical vulnerability cases + 12-audit history

const mkFinding = (o) => ({ signals:{miller:3.1,zipf:-1.02,system:'S2'}, ...o });

const FIX_SQLI = {
  id:'sqli', lang:'python', label:'SQL injection', audit_id:'a_0x9f2e.sqli',
  lines:[
    "# payments/checkout.py — order lookup endpoint",
    "from __future__ import annotations",
    "from typing import Optional",
    "from dataclasses import dataclass",
    "import logging",
    "from flask import Flask, request, jsonify, abort",
    "from sqlalchemy import create_engine",
    "",
    "from app.audit import audit_log",
    "from app.middleware import require_auth, rate_limit",
    "from app.metrics import counter, histogram",
    "",
    "log = logging.getLogger(__name__)",
    "engine = create_engine('postgresql://app@db/orders', pool_pre_ping=True)",
    "app = Flask(__name__)",
    "",
    "@dataclass",
    "class Order:",
    "    id: int",
    "    user_id: int",
    "    total_cents: int",
    "    status: str",
    "",
    "def _row_to_order(row) -> Order:",
    "    return Order(id=row[0], user_id=row[1], total_cents=row[2], status=row[3])",
    "",
    "@app.route('/orders/<order_id>', methods=['GET'])",
    "@require_auth",
    "@rate_limit(per_minute=120)",
    "def get_order(order_id: str):",
    "    counter('orders.lookup').inc()",
    "    user = request.args.get('user')",
    "",
    "    with histogram('orders.query_ms').time():",
    "        with engine.connect() as conn:",
    "            # build query against orders table",
    "            query = f\"SELECT id, user_id, total_cents, status FROM orders WHERE id = {order_id}\"",
    "            row = conn.execute(query).fetchone()",
    "",
    "    if row is None:",
    "        return jsonify({'error': 'not_found'}), 404",
    "",
    "    order = _row_to_order(row)",
    "    audit_log.write(actor=user, action='order_read', target=order.id)",
    "    return jsonify({",
    "        'id': order.id,",
    "        'user_id': order.user_id,",
    "        'total_cents': order.total_cents,",
    "        'status': order.status,",
    "    })",
    "",
    "@app.errorhandler(500)",
    "def server_error(e):",
    "    log.exception('order lookup crashed')",
    "    return jsonify({'error': 'internal'}), 500",
  ],
  finding: mkFinding({
    id:'SEC-0001', title:'SQL injection via request order_id',
    severity:'critical', category:'security', line:37, hops:4, confidence:0.95, cwe:'CWE-89',
    explanation:"Untrusted order_id from the URL path is interpolated into an f-string SQL query and passed to engine.execute. A counterfactual where order_id is bound as a parameter breaks the taint chain — confirming the f-string interpolation on line 37 is the causal enabler. The @require_auth decorator authenticates the caller but does not sanitize the path parameter.",
    path:['n1','n2','n3','n5'],
    fix:{ before:'query = f"SELECT id, user_id, total_cents, status FROM orders WHERE id = {order_id}"\nrow = conn.execute(query).fetchone()',
          after: 'query = text("SELECT id, user_id, total_cents, status FROM orders WHERE id = :oid")\nrow = conn.execute(query, {"oid": order_id}).fetchone()' },
    signals:{miller:3.2,zipf:-1.08,system:'S2'},
  }),
};
FIX_SQLI.graph={
  nodes:[
    {id:'n1',label:'order_id (path)',kind:'source',role:'http_input',line:30,taint:true},
    {id:'n2',label:'order_id (param)',kind:'definition',role:'binding',line:30,taint:true},
    {id:'n3',label:'f"SELECT...{order_id}"',kind:'transform',role:'interpolation',line:37,taint:true},
    {id:'n4',label:'@require_auth',kind:'use',role:'guard',line:28,taint:false},
    {id:'n5',label:'conn.execute',kind:'sink',role:'db_query',line:38,taint:true},
    {id:'n6',label:'row',kind:'definition',role:'binding',line:38,taint:false},
    {id:'n7',label:'jsonify(order)',kind:'use',role:'response',line:46,taint:false},
  ],
  edges:[
    {id:'e1',from:'n1',to:'n2',kind:'def-use',taint:true},
    {id:'e2',from:'n2',to:'n3',kind:'def-use',taint:true},
    {id:'e3',from:'n3',to:'n5',kind:'def-use',taint:true},
    {id:'e4',from:'n4',to:'n5',kind:'control-dep',taint:false},
    {id:'e5',from:'n5',to:'n6',kind:'def-use',taint:false},
    {id:'e6',from:'n6',to:'n7',kind:'def-use',taint:false},
    {id:'e7',from:'n1',to:'n3',kind:'synthetic-flow',taint:false},
  ],
  positions:{ n1:{x:0.10,y:0.22},n2:{x:0.28,y:0.22},n3:{x:0.50,y:0.38},
    n4:{x:0.50,y:0.12},n5:{x:0.72,y:0.38},n6:{x:0.72,y:0.66},n7:{x:0.90,y:0.66} },
};

const FIX_CMDI = {
  id:'cmdi', lang:'python', label:'Command injection', audit_id:'a_0x9e11.cmdi',
  lines:[
    "# infra/ssh_executor.py — remote diagnostic runner",
    "from __future__ import annotations",
    "import logging",
    "import subprocess",
    "import shlex",
    "from typing import Optional",
    "from flask import Flask, request, jsonify",
    "",
    "from app.middleware import require_admin, audit_action",
    "from app.config import SSH_DEFAULT_TIMEOUT, ALLOWED_HOSTS",
    "",
    "log = logging.getLogger(__name__)",
    "app = Flask(__name__)",
    "",
    "DIAG_COMMANDS = {",
    "    'ping':       'ping -c 1 -W 2',",
    "    'traceroute': 'traceroute -m 8',",
    "    'dns':        'dig +short',",
    "}",
    "",
    "def _resolve_command(diag: str) -> Optional[str]:",
    "    if diag not in DIAG_COMMANDS:",
    "        return None",
    "    return DIAG_COMMANDS[diag]",
    "",
    "@app.route('/admin/diag/run', methods=['POST'])",
    "@require_admin",
    "@audit_action('diag.run')",
    "def run_diagnostic():",
    "    payload = request.get_json(force=True)",
    "    diag    = payload.get('diag', 'ping')",
    "    host    = payload.get('host', '')",
    "",
    "    base = _resolve_command(diag)",
    "    if base is None:",
    "        return jsonify({'error': 'unknown_diag'}), 400",
    "",
    "    # Build full shell command",
    "    cmd = base + ' ' + host",
    "",
    "    try:",
    "        out = subprocess.check_output(",
    "            cmd,",
    "            shell=True,",
    "            timeout=SSH_DEFAULT_TIMEOUT,",
    "            stderr=subprocess.STDOUT,",
    "        )",
    "    except subprocess.CalledProcessError as e:",
    "        log.warning('diag failed: %s', e.output)",
    "        return jsonify({'error': 'diag_failed', 'detail': e.output.decode()}), 500",
    "    except subprocess.TimeoutExpired:",
    "        return jsonify({'error': 'timeout'}), 504",
    "",
    "    return jsonify({",
    "        'diag': diag,",
    "        'host': host,",
    "        'output': out.decode(errors='replace'),",
    "    })",
  ],
  finding: mkFinding({
    id:'SEC-0002', title:'Command injection via subprocess shell=True',
    severity:'critical', category:'security', line:42, hops:3, confidence:0.94, cwe:'CWE-78',
    explanation:"User-controlled `host` from the JSON payload is concatenated into a shell command and passed to subprocess.check_output with shell=True. The DIAG_COMMANDS allowlist gates the verb but not the argument. A counterfactual with shell=False + argv list eliminates shell metacharacter interpretation. The @require_admin guard limits the audience but admin-credential compromise turns a single token leak into RCE.",
    path:['n1','n2','n3','n4'],
    fix:{ before:"cmd = base + ' ' + host\nout = subprocess.check_output(cmd, shell=True, ...)",
          after: "argv = shlex.split(base) + [host]\nout = subprocess.check_output(argv, shell=False, ...)" },
    signals:{miller:2.8,zipf:-0.97,system:'S2'},
  }),
};
FIX_CMDI.graph={
  nodes:[
    {id:'n1',label:'payload.host',kind:'source',role:'http_input',line:32,taint:true},
    {id:'n2',label:'host',kind:'definition',role:'binding',line:32,taint:true},
    {id:'n3',label:"base + ' ' + host",kind:'transform',role:'concat',line:39,taint:true},
    {id:'n4',label:'subprocess.check_output',kind:'sink',role:'shell_exec',line:42,taint:true},
    {id:'n5',label:'shell=True',kind:'gate',role:'mode',line:44,taint:false},
    {id:'n6',label:'@require_admin',kind:'use',role:'guard',line:27,taint:false},
    {id:'n7',label:'out',kind:'definition',role:'binding',line:42,taint:false},
  ],
  edges:[
    {id:'e1',from:'n1',to:'n2',kind:'def-use',taint:true},
    {id:'e2',from:'n2',to:'n3',kind:'def-use',taint:true},
    {id:'e3',from:'n3',to:'n4',kind:'def-use',taint:true},
    {id:'e4',from:'n5',to:'n4',kind:'control-dep',taint:false},
    {id:'e5',from:'n6',to:'n4',kind:'control-dep',taint:false},
    {id:'e6',from:'n4',to:'n7',kind:'def-use',taint:false},
  ],
  positions:{ n1:{x:0.08,y:0.30},n2:{x:0.28,y:0.30},n3:{x:0.50,y:0.45},
    n4:{x:0.74,y:0.45},n5:{x:0.74,y:0.18},n6:{x:0.50,y:0.78},n7:{x:0.92,y:0.70} },
};

const FIX_PATHTRAV = {
  id:'pathtrav', lang:'python', label:'Path traversal', audit_id:'a_0x9d04.pathtrav',
  lines:[
    "from flask import Flask, request","import os","",
    "app = Flask(__name__)","",
    "@app.route('/file')","def read_file():",
    "    name = request.args.get('name')",
    "    with open(f'/var/data/{name}', 'r') as f:",
    "        return f.read()",
  ],
  finding: mkFinding({
    id:'SEC-0003', title:'Path traversal via unsanitized filename',
    severity:'high', category:'security', line:9, hops:3, confidence:0.88, cwe:'CWE-22',
    explanation:"request.args.get('name') is interpolated into a filesystem path with no canonicalization. A counterfactual using os.path.realpath plus a prefix check eliminates the escape vector.",
    path:['n1','n2','n3','n4'],
    fix:{ before:"with open(f'/var/data/{name}', 'r') as f:\n    return f.read()",
          after: "safe = os.path.realpath(os.path.join('/var/data', name))\nif not safe.startswith('/var/data/'): abort(400)\nwith open(safe) as f: return f.read()" },
    signals:{miller:3.5,zipf:-1.12,system:'S2'},
  }),
};
FIX_PATHTRAV.graph={
  nodes:[
    {id:'n1',label:'request.args.get',kind:'source',role:'http_input',line:8,taint:true},
    {id:'n2',label:'name',kind:'definition',role:'binding',line:8,taint:true},
    {id:'n3',label:'f"/var/data/{name}"',kind:'transform',role:'path_concat',line:9,taint:true},
    {id:'n4',label:'open',kind:'sink',role:'file_read',line:9,taint:true},
    {id:'n5',label:'f.read',kind:'use',role:'response',line:10,taint:false},
  ],
  edges:[
    {id:'e1',from:'n1',to:'n2',kind:'def-use',taint:true},
    {id:'e2',from:'n2',to:'n3',kind:'def-use',taint:true},
    {id:'e3',from:'n3',to:'n4',kind:'def-use',taint:true},
    {id:'e4',from:'n4',to:'n5',kind:'def-use',taint:false},
  ],
  positions:{ n1:{x:0.10,y:0.4},n2:{x:0.30,y:0.4},n3:{x:0.52,y:0.4},n4:{x:0.74,y:0.4},n5:{x:0.92,y:0.4} },
};

const FIX_HARDCODED = {
  id:'hardcoded', lang:'python', label:'Hardcoded credentials', audit_id:'a_0x9c87.hardcoded',
  lines:[
    "# db config","DATABASE_HOST = 'prod-db-01.internal'",
    "DATABASE_USER = 'root'",
    "DATABASE_PASSWORD = 'SuperSecret123!'",
    "DATABASE_NAME = 'app_prod'",
  ],
  finding: mkFinding({
    id:'SEC-0004', title:'Hardcoded credentials in source',
    severity:'medium', category:'security', line:4, hops:0, confidence:0.99, cwe:'CWE-798',
    explanation:"Literal credential committed to repository. No causal flow required — presence alone is a policy finding. Counterfactual: load from os.environ or a secrets manager instead.",
    path:['n1'],
    fix:{ before:"DATABASE_PASSWORD = 'SuperSecret123!'",
          after: "DATABASE_PASSWORD = os.environ['DB_PASSWORD']  # load at boot" },
    signals:{miller:1.5,zipf:-0.82,system:'S1'},
  }),
};
FIX_HARDCODED.graph={
  nodes:[
    {id:'n1',label:'DATABASE_PASSWORD',kind:'definition',role:'constant',line:4,taint:true},
    {id:'n2',label:"'SuperSecret123!'",kind:'source',role:'literal',line:4,taint:true},
  ],
  edges:[{id:'e1',from:'n2',to:'n1',kind:'def-use',taint:true}],
  positions:{ n1:{x:0.70,y:0.5},n2:{x:0.25,y:0.5} },
};

const FIX_SAFE = {
  id:'safe', lang:'python', label:'Clean (parameterized)', audit_id:'a_0x9bf2.safe',
  lines:[
    "from flask import Flask, request","import sqlite3","",
    "app = Flask(__name__)","","@app.route('/user')","def get_user():",
    "    uid = request.args.get('id')","    if not uid.isdigit():",
    "        return {'error':'bad id'}, 400",
    "    conn = sqlite3.connect('app.db')",
    "    row = conn.execute(",
    "        'SELECT * FROM users WHERE id = ?', (uid,)",
    "    ).fetchone()","    return {'user': row}",
  ],
  finding: null,
};
FIX_SAFE.graph={
  nodes:[
    {id:'n1',label:'request.args.get',kind:'source',role:'http_input',line:8,taint:true},
    {id:'n2',label:'uid',kind:'definition',role:'binding',line:8,taint:true},
    {id:'n3',label:'uid.isdigit',kind:'sanitizer',role:'validate',line:9,taint:false},
    {id:'n4',label:'SELECT ... ?',kind:'transform',role:'param_query',line:13,taint:false},
    {id:'n5',label:'conn.execute(?, args)',kind:'sink',role:'db_query',line:13,taint:false},
    {id:'n6',label:'row',kind:'definition',role:'binding',line:12,taint:false},
  ],
  edges:[
    {id:'e1',from:'n1',to:'n2',kind:'def-use',taint:true},
    {id:'e2',from:'n2',to:'n3',kind:'def-use',taint:true},
    {id:'e3',from:'n3',to:'n5',kind:'control-dep',taint:false},
    {id:'e4',from:'n4',to:'n5',kind:'def-use',taint:false},
    {id:'e5',from:'n5',to:'n6',kind:'def-use',taint:false},
  ],
  positions:{ n1:{x:0.10,y:0.30},n2:{x:0.28,y:0.30},n3:{x:0.48,y:0.30},
    n4:{x:0.48,y:0.66},n5:{x:0.72,y:0.48},n6:{x:0.92,y:0.48} },
};

const FIX_XSS = {
  id:'xss-js', lang:'typescript', label:'React XSS', audit_id:'a_0x9ae5.xss-js',
  lines:[
    "// frontend/Profile.tsx — public profile page",
    "import React, { useEffect, useState } from 'react'",
    "import { useParams } from 'react-router-dom'",
    "import { Skeleton } from '@/ui/skeleton'",
    "import { Avatar } from '@/ui/avatar'",
    "import { useAnalytics } from '@/lib/analytics'",
    "import { fetchProfile } from '@/api/profiles'",
    "",
    "type ProfileData = {",
    "  id:        string",
    "  handle:    string",
    "  avatar:    string",
    "  bio:       string   // user-controlled markdown rendered as HTML server-side",
    "  followers: number",
    "  following: number",
    "}",
    "",
    "export default function Profile() {",
    "  const { handle } = useParams<{ handle: string }>()",
    "  const [data, setData] = useState<ProfileData | null>(null)",
    "  const [loading, setLoading] = useState(true)",
    "  const track = useAnalytics()",
    "",
    "  useEffect(() => {",
    "    if (!handle) return",
    "    fetchProfile(handle)",
    "      .then(p => { setData(p); track('profile_viewed', { handle }) })",
    "      .finally(() => setLoading(false))",
    "  }, [handle, track])",
    "",
    "  if (loading) return <Skeleton className='profile-skel' />",
    "  if (!data)   return <p>Profile not found.</p>",
    "",
    "  return (",
    "    <article className='profile'>",
    "      <header className='profile-head'>",
    "        <Avatar src={data.avatar} alt={data.handle} />",
    "        <div>",
    "          <h1>@{data.handle}</h1>",
    "          <p className='profile-meta'>",
    "            <strong>{data.followers}</strong> followers ·",
    "            <strong>{data.following}</strong> following",
    "          </p>",
    "        </div>",
    "      </header>",
    "",
    "      {/* bio is markdown rendered to HTML on the server */}",
    "      <section",
    "        className='profile-bio'",
    "        dangerouslySetInnerHTML={{ __html: data.bio }}",
    "      />",
    "    </article>",
    "  )",
    "}",
  ],
  finding: mkFinding({
    id:'SEC-0005', title:'XSS via dangerouslySetInnerHTML on untrusted bio',
    severity:'high', category:'security', line:48, hops:2, confidence:0.92, cwe:'CWE-79',
    explanation:"data.bio is sourced from fetchProfile (server response) and rendered through dangerouslySetInnerHTML without sanitization. The server-side markdown renderer is documented as 'safe HTML' but does not escape on-error fallback paths. Counterfactual: render as text, or pass bio through DOMPurify before injection. Either breaks the causal XSS path. The TypeScript type system gives the false impression of safety because `string` enforces shape but not provenance.",
    path:['n1','n2','n3'],
    fix:{ before:"<section\n  className='profile-bio'\n  dangerouslySetInnerHTML={{ __html: data.bio }}\n/>",
          after: "// Option A — render as text:\n<section className='profile-bio'>{data.bio}</section>\n\n// Option B — sanitize first:\nimport DOMPurify from 'dompurify'\n<section\n  className='profile-bio'\n  dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(data.bio) }}\n/>" },
    signals:{miller:2.6,zipf:-1.01,system:'S2'},
  }),
};
FIX_XSS.graph={
  nodes:[
    {id:'n1',label:'fetchProfile(handle)',kind:'source',role:'remote_response',line:25,taint:true},
    {id:'n2',label:'data.bio',kind:'definition',role:'binding',line:33,taint:true},
    {id:'n3',label:'{__html: data.bio}',kind:'transform',role:'html_object',line:49,taint:true},
    {id:'n4',label:'dangerouslySetInnerHTML',kind:'sink',role:'dom_write',line:49,taint:true},
  ],
  edges:[
    {id:'e1',from:'n1',to:'n2',kind:'def-use',taint:true},
    {id:'e2',from:'n2',to:'n3',kind:'def-use',taint:true},
    {id:'e3',from:'n3',to:'n4',kind:'def-use',taint:true},
  ],
  positions:{ n1:{x:0.10,y:0.5},n2:{x:0.36,y:0.5},n3:{x:0.62,y:0.5},n4:{x:0.88,y:0.5} },
};

const FIX_CMDI_JS = {
  id:'cmdi-js', lang:'javascript', label:'Node child_process', audit_id:'a_0x99d2.cmdi-js',
  lines:[
    "const express = require('express')",
    "const { exec } = require('child_process')",
    "const app = express()","",
    "app.get('/diag', (req, res) => {",
    "  const target = req.query.host",
    "  exec(`traceroute ${target}`, (err, stdout) => {",
    "    res.send(stdout)",
    "  })","})",
  ],
  finding: mkFinding({
    id:'SEC-0006', title:'Command injection via child_process exec',
    severity:'critical', category:'security', line:7, hops:3, confidence:0.94, cwe:'CWE-78',
    explanation:"req.query.host flows into exec's template literal with no validation. Counterfactual using execFile with argv array eliminates shell interpretation.",
    path:['n1','n2','n3'],
    fix:{ before:"exec(`traceroute ${target}`, (err, stdout) => { ... })",
          after: "execFile('traceroute', [target], (err, stdout) => { ... })" },
    signals:{miller:2.9,zipf:-0.99,system:'S2'},
  }),
};
FIX_CMDI_JS.graph={
  nodes:[
    {id:'n1',label:'req.query.host',kind:'source',role:'http_input',line:6,taint:true},
    {id:'n2',label:'target',kind:'definition',role:'binding',line:6,taint:true},
    {id:'n3',label:'exec(`traceroute ${target}`)',kind:'sink',role:'shell_exec',line:7,taint:true},
  ],
  edges:[
    {id:'e1',from:'n1',to:'n2',kind:'def-use',taint:true},
    {id:'e2',from:'n2',to:'n3',kind:'def-use',taint:true},
  ],
  positions:{ n1:{x:0.15,y:0.5},n2:{x:0.45,y:0.5},n3:{x:0.80,y:0.5} },
};

// CAUSAL-ONLY fixture: SAST returns clean, DAEV catches a TOCTOU race via
// counterfactual reasoning over interleaved control flow. The differentiator.
const FIX_RACECOND = {
  id:'racecond', lang:'python', label:'TOCTOU race · causal-only', audit_id:'a_0x9aab.racecond',
  lines:[
    "# billing/redeem.py — promo code redemption endpoint",
    "from __future__ import annotations",
    "import logging",
    "from dataclasses import dataclass",
    "from typing import Optional",
    "from datetime import datetime, timezone",
    "from flask import Flask, request, jsonify",
    "from sqlalchemy.orm import Session",
    "",
    "from app.db import get_session",
    "from app.middleware import require_auth, audit_action",
    "from app.models import PromoCode, User, CreditLedger",
    "from app.metrics import counter",
    "",
    "log = logging.getLogger(__name__)",
    "app = Flask(__name__)",
    "",
    "@dataclass",
    "class RedeemResult:",
    "    ok:        bool",
    "    code:      str",
    "    credit:    int  # cents added to user balance",
    "    error:     Optional[str] = None",
    "",
    "def is_valid(session: Session, code: str) -> Optional[PromoCode]:",
    "    \"\"\"Return the PromoCode row if it exists, is unredeemed, and not expired.\"\"\"",
    "    pc = session.query(PromoCode).filter(PromoCode.code == code).first()",
    "    if pc is None:",
    "        return None",
    "    if pc.redeemed_at is not None:",
    "        return None",
    "    if pc.expires_at < datetime.now(timezone.utc):",
    "        return None",
    "    return pc",
    "",
    "def apply_credit(session: Session, user: User, pc: PromoCode) -> int:",
    "    \"\"\"Mark the code as redeemed and credit the user's ledger.\"\"\"",
    "    pc.redeemed_at = datetime.now(timezone.utc)",
    "    pc.redeemed_by = user.id",
    "    session.add(CreditLedger(",
    "        user_id=user.id,",
    "        delta_cents=pc.credit_cents,",
    "        source='promo',",
    "        ref=pc.code,",
    "    ))",
    "    session.commit()",
    "    return pc.credit_cents",
    "",
    "@app.route('/billing/redeem', methods=['POST'])",
    "@require_auth",
    "@audit_action('promo.redeem')",
    "def redeem():",
    "    user    = request.user                    # injected by @require_auth",
    "    payload = request.get_json(force=True)",
    "    code    = (payload.get('code') or '').strip().upper()",
    "    counter('billing.redeem.attempted').inc()",
    "",
    "    if not code:",
    "        return jsonify({'ok': False, 'error': 'missing_code'}), 400",
    "",
    "    session = get_session()",
    "    pc = is_valid(session, code)",
    "    if pc is None:",
    "        counter('billing.redeem.invalid').inc()",
    "        return jsonify({'ok': False, 'error': 'invalid_or_expired'}), 400",
    "",
    "    # validate-then-use without a lock — racy under concurrent requests",
    "    credit = apply_credit(session, user, pc)",
    "    counter('billing.redeem.applied').inc()",
    "",
    "    return jsonify({",
    "        'ok':     True,",
    "        'code':   pc.code,",
    "        'credit': credit,",
    "    })",
  ],
  finding: mkFinding({
    id:'CAUS-0001', title:'TOCTOU race — validate-then-use without lock (causal-only)',
    severity:'high', category:'logic', line:65, hops:3, confidence:0.92, cwe:'CWE-367',
    explanation:"SAST cannot reach this — every line is syntactically valid Python and there is no taint sink in the SAST sense. The causal model identifies the temporal gap between is_valid(session, code) on line 61 and apply_credit on line 65. A counterfactual interleaving — two concurrent /billing/redeem POSTs with the same valid code — proves both calls pass is_valid (the row's redeemed_at is still None for both), then both calls execute apply_credit, double-crediting the user. The defect is structural (missing row-level lock or unique constraint on redeemed_at), not lexical. Fix is a SELECT … FOR UPDATE inside is_valid, or a database-level uniqueness constraint that fails the second commit.",
    path:['n1','n2','n3','n5'],
    fix:{ before:"pc = is_valid(session, code)\nif pc is None: ...\n# RACE WINDOW — no lock between check and use\ncredit = apply_credit(session, user, pc)",
          after: "with session.begin():\n    pc = (\n        session.query(PromoCode)\n               .filter(PromoCode.code == code)\n               .with_for_update()      # SELECT ... FOR UPDATE\n               .first()\n    )\n    if pc is None or pc.redeemed_at or pc.expires_at < now():\n        return jsonify({'ok': False, 'error': 'invalid_or_expired'}), 400\n    credit = apply_credit(session, user, pc)" },
    signals:{miller:4.1,zipf:-0.84,system:'S2'},
  }),
};
FIX_RACECOND.graph={
  nodes:[
    {id:'n1',label:'payload.code',kind:'source',role:'http_input',line:55,taint:true},
    {id:'n2',label:'code',kind:'definition',role:'binding',line:55,taint:true},
    {id:'n3',label:'is_valid(session,code)',kind:'transform',role:'check',line:61,taint:false},
    {id:'n4',label:'guard',kind:'use',role:'control',line:62,taint:false},
    {id:'n5',label:'apply_credit(session,user,pc)',kind:'sink',role:'state_mutation',line:65,taint:true},
    {id:'n6',label:'CreditLedger insert',kind:'use',role:'persist',line:39,taint:true},
    {id:'n7',label:'jsonify({ok,code,credit})',kind:'use',role:'response',line:69,taint:false},
  ],
  edges:[
    {id:'e1',from:'n1',to:'n2',kind:'def-use',taint:true},
    {id:'e2',from:'n2',to:'n3',kind:'def-use',taint:false},
    {id:'e3',from:'n3',to:'n4',kind:'control-dep',taint:false},
    {id:'e4',from:'n2',to:'n5',kind:'def-use',taint:true},
    {id:'e5',from:'n5',to:'n6',kind:'def-use',taint:true},
    {id:'e6',from:'n5',to:'n7',kind:'def-use',taint:false},
    {id:'e7',from:'n3',to:'n5',kind:'temporal-gap',taint:false},
  ],
  positions:{ n1:{x:0.08,y:0.30},n2:{x:0.26,y:0.30},n3:{x:0.46,y:0.18},
    n4:{x:0.46,y:0.55},n5:{x:0.66,y:0.30},n6:{x:0.86,y:0.18},n7:{x:0.86,y:0.55} },
};

// Slice 6.4.5.2 Phase 12 (BUG-74): synthetic _user fixture for the custom
// paste mode. Starts with a placeholder snippet; AuditInput's textarea
// keeps fx.lines in sync as the user types so the existing handleRunAudit
// path (`submitInlineAudit(fx.lines.join('\n'), ...)`) just works.
const FIX_USER = {
  id: '_user',
  lang: 'python',
  label: 'Custom paste',
  audit_id: 'a_0x9000.user',
  lines: [
    '# Paste your Python code here.',
    '# Click Audit to run /switzerland/gate fast mode against the live backend.',
    'def example(name):',
    '    return "hello, " + name',
  ],
  finding: null,
  graph: { nodes: [], edges: [], positions: {} },
};

window.DAEV_FIXTURES = {
  sqli:FIX_SQLI, cmdi:FIX_CMDI, pathtrav:FIX_PATHTRAV, hardcoded:FIX_HARDCODED,
  safe:FIX_SAFE, 'xss-js':FIX_XSS, 'cmdi-js':FIX_CMDI_JS, racecond:FIX_RACECOND,
  '_user': FIX_USER,
};

// 12-audit history (dashboard mock)
window.DAEV_AUDITS = [
  { id:'a_0x9aab.racecond',  title:'billing/redeem.py · redeem_code',         verdict:'UNSAFE',        fix:'racecond',  mode:'full', lang:'python',     ts:'just now',   dur:'8.4s',  nodes:6,  hops:3, llm:54 },
  { id:'a_0x9f2e.sqli',      title:'payments/checkout.py · create_order',     verdict:'UNSAFE',        fix:'sqli',      mode:'fast', lang:'python',     ts:'2m ago',     dur:'6.1s',  nodes:7,  hops:4, llm:73 },
  { id:'a_0x9e11.cmdi',      title:'infra/ssh_executor.go · run_remote',      verdict:'UNSAFE',        fix:'cmdi',      mode:'full', lang:'python',     ts:'8m ago',     dur:'42.3s', nodes:6,  hops:3, llm:68 },
  { id:'a_0x9d04.pathtrav',  title:'storage/s3_proxy.py · serve_file',        verdict:'UNSAFE',        fix:'pathtrav',  mode:'fast', lang:'python',     ts:'14m ago',    dur:'5.8s',  nodes:5,  hops:3, llm:81 },
  { id:'a_0x9c87.hardcoded', title:'config/secrets.py · db_credentials',      verdict:'NEEDS_REVIEW',  fix:'hardcoded', mode:'fast', lang:'python',     ts:'32m ago',    dur:'3.1s',  nodes:2,  hops:0, llm:12 },
  { id:'a_0x9bf2.safe',      title:'payments/checkout.py · create_order (v2)',verdict:'SAFE',          fix:'safe',      mode:'fast', lang:'python',     ts:'1h ago',     dur:'4.2s',  nodes:6,  hops:0, llm:22 },
  { id:'a_0x9ae5.xss-js',    title:'frontend/Profile.tsx · render_bio',       verdict:'UNSAFE',        fix:'xss-js',    mode:'full', lang:'typescript', ts:'3h ago',     dur:'38.7s', nodes:3,  hops:2, llm:64 },
  { id:'a_0x99d2.cmdi-js',   title:'ops/diag.js · traceroute_handler',        verdict:'UNSAFE',        fix:'cmdi-js',   mode:'full', lang:'javascript', ts:'5h ago',     dur:'44.8s', nodes:3,  hops:3, llm:79 },
  { id:'a_0x98a1.auth',      title:'auth/jwt_verify.ts · verify_token',       verdict:'NEEDS_REVIEW',  fix:'sqli',      mode:'full', lang:'typescript', ts:'yesterday',  dur:'38.7s', nodes:11, hops:2, llm:54 },
  { id:'a_0x97b3.deser',     title:'queue/worker.py · process_message',       verdict:'UNSAFE',        fix:'cmdi',      mode:'full', lang:'python',     ts:'yesterday',  dur:'51.2s', nodes:9,  hops:5, llm:71 },
  { id:'a_0x9612.query',     title:'api/search.py · query_index',             verdict:'SAFE',          fix:'safe',      mode:'fast', lang:'python',     ts:'2d ago',     dur:'3.8s',  nodes:5,  hops:0, llm:18 },
  { id:'a_0x9521.upload',    title:'media/upload.py · save_avatar',           verdict:'NEEDS_REVIEW',  fix:'pathtrav',  mode:'fast', lang:'python',     ts:'5d ago',     dur:'5.6s',  nodes:6,  hops:2, llm:44 },
  { id:'a_0x9404.jwt',       title:'webhooks/stripe_webhook.py · handle',     verdict:'SAFE',          fix:'safe',      mode:'fast', lang:'typescript', ts:'1w ago',     dur:'4.0s',  nodes:5,  hops:0, llm:29 },
];

// Council data (shared across fixtures; attached at runtime)
window.DAEV_COUNCIL = {
  agents: [
    { id:'sec',  name:'SecurityAgent',       lens:'T-cell',             description:'SAST + CWE matching + dep risk',               stack:'Semgrep + Bandit + gap-fill', icon:'shield',   findings:3 },
    { id:'arch', name:'ArchitectureAgent',   lens:'B-cell',             description:'coupling, cohesion, design-pattern adherence', stack:'Radon + pyan + MoE domain prompts', icon:'e_gate', findings:1 },
    { id:'perf', name:'PerformanceAgent',    lens:'Innate',             description:'hot loops, async issues, allocation',          stack:'Lizard + profiler heuristics', icon:'zap',      findings:0 },
    { id:'caus', name:'CausalIntegrityAgent',lens:'Regulatory T-cell',  description:'full-DAG reasoning · spurious-correlation filter', stack:'DoWhy-GCM + causal-learn PC', icon:'e_transform', findings:2 },
    { id:'prop', name:'PropagationAgent',    lens:'Dendritic',          description:'blast radius · confidence decay per hop',      stack:'NetworkX + ConfidenceDecay=0.1/hop', icon:'share', findings:4 },
  ],
  rounds: [
    { id:0, name:'Independent Analysis', desc:'Each agent reasons in epistemic isolation. No cross-talk.' },
    { id:1, name:'Anonymized Cross-Review', desc:'Peer votes exchanged with identities redacted.' },
    { id:2, name:"Devil's Advocate", desc:'A challenge prompt tests the strongest finding.' },
    { id:3, name:'Sycophancy Correction', desc:'CONSENSAGENT protocol checks for deference, finalizes verdict.' },
  ],
};

// SAST battery fixture
window.DAEV_SAST = [
  { name:'Semgrep',     version:'1.152.0', desc:'Pattern-based static analysis', findings:4, runtime:'1.8s', severity:{critical:1,high:2,medium:1,low:0,info:0} },
  { name:'Bandit',      version:'1.9.3',   desc:'Python security linter',        findings:2, runtime:'0.9s', severity:{critical:1,high:0,medium:1,low:0,info:0} },
  { name:'Radon',       version:'6.0.1',   desc:'Cyclomatic complexity',         findings:1, runtime:'0.4s', severity:{critical:0,high:0,medium:0,low:1,info:0} },
  { name:'Lizard',      version:'1.21.0',  desc:'Function-level complexity',     findings:0, runtime:'0.3s', severity:{critical:0,high:0,medium:0,low:0,info:0} },
  { name:'Vulture',     version:'2.14',    desc:'Dead code detection',           findings:0, runtime:'0.2s', severity:{critical:0,high:0,medium:0,low:0,info:0} },
  { name:'Coverage.py', version:'7.13.4',  desc:'Test coverage analyzer',        findings:1, runtime:'0.6s', severity:{critical:0,high:0,medium:0,low:0,info:1} },
  { name:'pip-audit',   version:'2.10.0',  desc:'Dependency vulnerability scan', findings:0, runtime:'0.5s', severity:{critical:0,high:0,medium:0,low:0,info:0} },
];
