Files
foxhunt/scripts/audit-isv.sh
jgrusewski 40855bfd62 docs(sp20): trader-grade trade management spec + audit infrastructure
Adds SP20 — full production trader-management system in one
greenfield commit (3-4 weeks of implementation work to follow):

  * Tier 0: multi-resolution time-scaled market features (3 horizons)
  * Tier 1: trade-arc awareness (4 features per batch)
  * Tier 2: per-unit trail-stop (entry + trail + stop per unit)
  * Tier 3: pyramiding + partial profit-taking (HalfFlat actions,
            N_ACTIONS=9→11)
  * Tier 4: Forward-Return-Distribution head + confidence gate +
            per-batch anti-martingale sizing + position heat cap +
            vol-adjusted defaults

Spec went through critical-review pass (v1→v2→v3):
  * v1: 3 tiers, side-channel features, single-gate acceptance
  * v2: 5 tiers added partial-flat + anti-mart + multi-res + checklist
  * v3: foundational fixes for 4 CRIT + 6 SIG + 6 MIN findings
        (per-unit pyramid state, encoder-input injection vs side-channel,
         FRD head replaces survivor-biased checklist, override stack
         ordering, per-batch anti-mart, real-time multi-res scales,
         P-1 ceiling falsification gate, multi-tier acceptance)

§0 Foundational Principles (NEW, non-negotiable):
  * §0.1 every numerical constant ISV-resident (no hardcoded #defines
         in new kernels; structural-dim exception only)
  * §0.2 every kernel/slot/head/action fully wired in same commit
  * §0.3 diagnostics baked in at birth (every observable in JSONL)
  * §0.4 per-phase ship-gate: all three audits must pass

Audit infrastructure shipped with the spec:
  * scripts/audit-isv.sh      — greps new .cu for hardcoded #defines
  * scripts/audit-wiring.sh   — verifies kernels/slots/heads/actions
                                have producer + consumer in code
  * scripts/audit-diag.sh     — runs local 100-step smoke, validates
                                manifest-listed jq paths present in JSONL
  * scripts/audit-manifest/   — per-phase append manifests (kernels,
                                slots, heads, actions, diag-fields)

Naming discipline: audit scripts and manifest are SP-agnostic (no
`sp20-` prefix) per new pearl `feedback_no_sp_or_version_prefixes_in_file_names`
— they'll serve future SPs too. SP numbers belong only in
docs/superpowers/{specs,plans}/ filenames.

Audit scripts dogfooded — already caught two real violations on
existing code that the formal review missed:
  * audit-isv: KL_EMA_ALPHA=0.05f hardcoded in rl_q_pi_distill_grad.cu
  * audit-wiring: TrailTighten action (a7) has no handler in any
                  kernel (per pearl_dead_trail_stop_actions_a7_a8)

These violations are SP20 P5/P10 fix targets.

User decision recorded in spec §3 P-1: ceiling-falsification phase
intentionally skipped — SP20 is the architectural launchpad for
the broader trader system regardless of whether current arch could
be pushed further at 1M steps. P-1 may be revisited as standalone
work after SP20 ships.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 16:28:39 +02:00

106 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# audit-isv.sh — enforce "every numerical constant is ISV-resident"
# per SP20 §0.1.
#
# Walks scripts/audit-manifest/kernels.txt and greps each listed .cu
# for `#define NAME VALUE` lines where VALUE is a numeric literal.
# Flags any define whose NAME is NOT in the structural-dim allowlist
# AND does NOT end in `_INDEX` (ISV slot pointer).
#
# Exit codes:
# 0 — zero violations
# 1 — one or more violations found
# 2 — usage / setup error
#
# Allowlist for structural-dim names (compile-time required for buffer
# layouts / atom support / shared memory):
ALLOWED_NAMES=(
"N_ACTIONS"
"Q_N_ATOMS"
"HIDDEN_DIM"
"REGIME_DIM"
"MAX_UNITS"
"BLOCK_DIM"
"GRID_DIM"
"BLOCK_SIZE"
"WARP_SIZE"
"BLOCK_X" "BLOCK_Y" "BLOCK_Z"
"MAX_WINDOW_ENTRIES"
)
set -euo pipefail
ROOT=$(git rev-parse --show-toplevel)
MANIFEST="$ROOT/scripts/audit-manifest/kernels.txt"
CUDA_DIR="$ROOT/crates/ml-alpha/cuda"
if [[ ! -f "$MANIFEST" ]]; then
echo "ERROR: manifest not found: $MANIFEST" >&2
exit 2
fi
# Read manifest into array, skipping blank lines and comments.
mapfile -t kernels < <(grep -vE '^\s*(#|$)' "$MANIFEST" | awk '{print $1}')
if [[ ${#kernels[@]} -eq 0 ]]; then
echo "audit-isv: manifest empty — no kernels to audit. PASS."
exit 0
fi
# Build a regex of allowed names + `_INDEX` suffix pattern.
allowed_regex=""
for name in "${ALLOWED_NAMES[@]}"; do
allowed_regex="${allowed_regex}|^${name}$"
done
allowed_regex="(${allowed_regex#|}|_INDEX$)"
violations=0
total_defines=0
echo "audit-isv: auditing ${#kernels[@]} kernel(s) from manifest..."
echo
for kernel in "${kernels[@]}"; do
cu_file="$CUDA_DIR/${kernel}.cu"
if [[ ! -f "$cu_file" ]]; then
echo "ERROR: kernel listed in manifest but file missing: $cu_file" >&2
violations=$((violations + 1))
continue
fi
# Extract `#define NAME VALUE` where VALUE is a numeric literal
# (integer or float, optional `f` suffix, optional sign).
# Skip macros that contain function-like () bodies — those are
# parameterized templates, not constants.
while IFS= read -r line; do
# Strip leading whitespace
trimmed="${line#"${line%%[![:space:]]*}"}"
# Parse: #define NAME VALUE
if [[ "$trimmed" =~ ^\#define[[:space:]]+([A-Z_][A-Z0-9_]*)[[:space:]]+([+-]?[0-9]+(\.[0-9]+)?f?)$ ]]; then
name="${BASH_REMATCH[1]}"
value="${BASH_REMATCH[2]}"
total_defines=$((total_defines + 1))
if [[ "$name" =~ $allowed_regex ]]; then
: # allowed
else
echo " VIOLATION $kernel: #define $name $value (should be ISV slot)"
violations=$((violations + 1))
fi
fi
done < "$cu_file"
done
echo
echo "audit-isv: scanned $total_defines numeric #defines, found $violations violation(s)."
if [[ $violations -gt 0 ]]; then
echo
echo "Per SP20 §0.1: every numerical constant in new kernels must be ISV-resident."
echo "Add an RL_*_INDEX slot to crates/ml-alpha/src/rl/isv_slots.rs,"
echo "seed via rl_isv_write at trainer init, and read from the slot in the kernel."
exit 1
fi
echo "audit-isv: PASS"
exit 0