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>
188 lines
7.3 KiB
Bash
Executable File
188 lines
7.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# audit-wiring.sh — enforce "every kernel/slot/head/action fully wired"
|
|
# per SP20 §0.2.
|
|
#
|
|
# Walks all four manifests:
|
|
# * kernels.txt → every entry has a registration in build.rs KERNELS
|
|
# AND a `.launch_builder(&self.<name>_fn)` site
|
|
# in src/trainer/integrated.rs
|
|
# * slots.txt → every entry has a write site (seed in rl_isv_write
|
|
# OR write in a .cu kernel) AND a read site
|
|
# (read in a .cu kernel)
|
|
# * heads.txt → every entry has src/heads/<name>.rs AND forward
|
|
# call AND backward call in the trainer
|
|
# * actions.txt → every entry has a branch in
|
|
# cuda/actions_to_market_targets.cu OR a handler
|
|
# in an override kernel
|
|
#
|
|
# Exit codes:
|
|
# 0 — zero violations
|
|
# 1 — one or more violations
|
|
# 2 — usage error
|
|
# Note: NOT using `set -e` — many grep|head|wc pipelines naturally
|
|
# return non-zero (SIGPIPE on head consuming early, grep no-match).
|
|
# We handle exit codes explicitly via `|| true` and `|| echo 0` on
|
|
# the suspect pipelines, and bookkeep `violations` for the final
|
|
# exit code.
|
|
set -uo pipefail
|
|
|
|
ROOT=$(git rev-parse --show-toplevel)
|
|
M="$ROOT/scripts/audit-manifest"
|
|
BUILD_RS="$ROOT/crates/ml-alpha/build.rs"
|
|
TRAINER="$ROOT/crates/ml-alpha/src/trainer/integrated.rs"
|
|
ISV_SLOTS="$ROOT/crates/ml-alpha/src/rl/isv_slots.rs"
|
|
COMMON_RS="$ROOT/crates/ml-alpha/src/rl/common.rs"
|
|
ACTIONS_KERNEL="$ROOT/crates/ml-alpha/cuda/actions_to_market_targets.cu"
|
|
HEADS_DIR="$ROOT/crates/ml-alpha/src/heads"
|
|
CUDA_DIR="$ROOT/crates/ml-alpha/cuda"
|
|
|
|
violations=0
|
|
|
|
read_manifest() {
|
|
local file="$1"
|
|
if [[ -f "$file" ]]; then
|
|
grep -vE '^\s*(#|$)' "$file" | awk '{print $1}'
|
|
fi
|
|
}
|
|
|
|
# ─── 1. KERNELS ─────────────────────────────────────────────
|
|
echo "audit-wiring: KERNELS"
|
|
while IFS= read -r kernel; do
|
|
[[ -z "$kernel" ]] && continue
|
|
cu_file="$CUDA_DIR/${kernel}.cu"
|
|
if [[ ! -f "$cu_file" ]]; then
|
|
echo " VIOLATION kernel $kernel: source file missing ($cu_file)"
|
|
violations=$((violations + 1))
|
|
continue
|
|
fi
|
|
# build.rs registration
|
|
if ! grep -qE "\"${kernel}\"" "$BUILD_RS"; then
|
|
echo " VIOLATION kernel $kernel: not registered in build.rs KERNELS"
|
|
violations=$((violations + 1))
|
|
fi
|
|
# trainer field
|
|
if ! grep -qE "${kernel}_fn[: ,]" "$TRAINER"; then
|
|
echo " VIOLATION kernel $kernel: no <name>_fn field in trainer"
|
|
violations=$((violations + 1))
|
|
fi
|
|
# trainer launch site
|
|
if ! grep -qE "launch_builder\(&self\.${kernel}_fn\)" "$TRAINER"; then
|
|
echo " VIOLATION kernel $kernel: no launch site in trainer"
|
|
violations=$((violations + 1))
|
|
fi
|
|
done < <(read_manifest "$M/kernels.txt")
|
|
|
|
# ─── 2. SLOTS ───────────────────────────────────────────────
|
|
echo "audit-wiring: SLOTS"
|
|
while IFS= read -r slot; do
|
|
[[ -z "$slot" ]] && continue
|
|
# slot defined in isv_slots.rs?
|
|
if ! grep -qE "pub const ${slot}\s*:\s*usize" "$ISV_SLOTS"; then
|
|
echo " VIOLATION slot $slot: no `pub const` definition in isv_slots.rs"
|
|
violations=$((violations + 1))
|
|
continue
|
|
fi
|
|
# Extract numeric slot index for cross-kernel grep
|
|
slot_idx=$(awk -v name="$slot" '
|
|
$0 ~ "pub const " name "[[:space:]]*:[[:space:]]*usize" {
|
|
if (match($0, /=[[:space:]]*[0-9]+/)) {
|
|
v = substr($0, RSTART, RLENGTH)
|
|
gsub(/[^0-9]/, "", v)
|
|
print v; exit
|
|
}
|
|
}' "$ISV_SLOTS")
|
|
[[ -z "$slot_idx" ]] && slot_idx="-1"
|
|
# producer: seeded in rl_isv_write list OR written by a .cu kernel
|
|
producer_seed=0
|
|
producer_kernel=0
|
|
if grep -qE "isv_slots::${slot}" "$TRAINER"; then
|
|
producer_seed=1
|
|
fi
|
|
# kernel writes via isv[INDEX] = ... or isv[<num>] = ...
|
|
if grep -qrE "isv\[(${slot}|${slot_idx})\][[:space:]]*=" "$CUDA_DIR" 2>/dev/null; then
|
|
producer_kernel=1
|
|
fi
|
|
if [[ $producer_seed -eq 0 && $producer_kernel -eq 0 ]]; then
|
|
echo " VIOLATION slot $slot (idx $slot_idx): no producer (not seeded in rl_isv_write, not written by any kernel)"
|
|
violations=$((violations + 1))
|
|
fi
|
|
# consumer: read by some .cu (isv[INDEX] in non-assignment context)
|
|
# Heuristic: count distinct .cu files containing the slot reference
|
|
# in a context that's NOT immediately followed by `=` (assignment).
|
|
# Pattern `isv[X][^=]` matches isv[X] where next char isn't `=`.
|
|
read_only_files=$(grep -lrE "isv\[(${slot}|${slot_idx})\][^=]" "$CUDA_DIR" 2>/dev/null | wc -l)
|
|
if [[ $read_only_files -eq 0 ]]; then
|
|
echo " VIOLATION slot $slot (idx $slot_idx): no consumer (no kernel reads it in non-assignment context)"
|
|
violations=$((violations + 1))
|
|
fi
|
|
done < <(read_manifest "$M/slots.txt")
|
|
|
|
# ─── 3. HEADS ───────────────────────────────────────────────
|
|
echo "audit-wiring: HEADS"
|
|
while IFS= read -r head; do
|
|
[[ -z "$head" ]] && continue
|
|
head_rs="$HEADS_DIR/${head}.rs"
|
|
if [[ ! -f "$head_rs" ]]; then
|
|
echo " VIOLATION head $head: module file missing ($head_rs)"
|
|
violations=$((violations + 1))
|
|
continue
|
|
fi
|
|
if ! grep -qE "fn forward" "$head_rs"; then
|
|
echo " VIOLATION head $head: no fn forward in module"
|
|
violations=$((violations + 1))
|
|
fi
|
|
if ! grep -qE "fn backward" "$head_rs"; then
|
|
echo " VIOLATION head $head: no fn backward in module"
|
|
violations=$((violations + 1))
|
|
fi
|
|
# Adam step + LR controller — grep for the head's forward call site
|
|
# in the trainer (loose heuristic).
|
|
if ! grep -qE "${head}_head" "$TRAINER"; then
|
|
echo " VIOLATION head $head: no ${head}_head field or call in trainer"
|
|
violations=$((violations + 1))
|
|
fi
|
|
done < <(read_manifest "$M/heads.txt")
|
|
|
|
# ─── 4. ACTIONS ─────────────────────────────────────────────
|
|
echo "audit-wiring: ACTIONS"
|
|
while IFS= read -r action; do
|
|
[[ -z "$action" ]] && continue
|
|
# Action enum entry
|
|
if ! grep -qE "${action}\s*=\s*[0-9]+" "$COMMON_RS"; then
|
|
echo " VIOLATION action $action: not in Action enum in common.rs"
|
|
violations=$((violations + 1))
|
|
continue
|
|
fi
|
|
# Get action index
|
|
action_idx=$(awk -v name="$action" '
|
|
$0 ~ name "[[:space:]]*=[[:space:]]*[0-9]+" {
|
|
if (match($0, /=[[:space:]]*[0-9]+/)) {
|
|
v = substr($0, RSTART, RLENGTH)
|
|
gsub(/[^0-9]/, "", v)
|
|
print v; exit
|
|
}
|
|
}' "$COMMON_RS")
|
|
[[ -z "$action_idx" ]] && action_idx="-1"
|
|
# Handler in actions_to_market_targets.cu: branch `action == <idx>`
|
|
if ! grep -qE "action[[:space:]]*==[[:space:]]*${action_idx}\b" "$ACTIONS_KERNEL"; then
|
|
# Could be handled in override kernel — check across all .cu files
|
|
handler_count=$(grep -lrE "(action|actions\[[^]]*\])[[:space:]]*==[[:space:]]*${action_idx}\b" "$CUDA_DIR" 2>/dev/null | wc -l)
|
|
if [[ "$handler_count" -eq 0 ]]; then
|
|
echo " VIOLATION action $action (idx $action_idx): no handler in actions_to_market_targets or override kernels"
|
|
violations=$((violations + 1))
|
|
fi
|
|
fi
|
|
done < <(read_manifest "$M/actions.txt")
|
|
|
|
echo
|
|
echo "audit-wiring: $violations violation(s)"
|
|
|
|
if [[ $violations -gt 0 ]]; then
|
|
echo
|
|
echo "Per SP20 §0.2: every kernel/slot/head/action MUST have producer + consumer in same commit."
|
|
exit 1
|
|
fi
|
|
|
|
echo "audit-wiring: PASS"
|
|
exit 0
|