Commit Graph

186 Commits

Author SHA1 Message Date
jgrusewski
d4e46aba94 feat(ml-alpha): multi_horizon_heads kernel (128->5 sigmoid)
Per-horizon P(up) at h ∈ {30, 100, 300, 1000, 6000} snapshots forward.
Single-block 5-thread kernel; each thread is its own 128-dim dot
product + sigmoid. No atomicAdd.

Tests (5/5 pass on sm_86) assert invariants only:
  - sigmoid output ∈ [0, 1] for all heads
  - zero weights + zero bias → 0.5 exactly
  - bias = +20 → saturates near 1
  - bias = -20 → saturates near 0
  - per-head independence (mixed-bias configuration)

Addendum updated to explicitly state no-CPU-mirror discipline per
feedback_no_cpu_test_fallbacks.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 21:51:48 +02:00
jgrusewski
d3b60b2ef3 build(ml-alpha): multi-cubin build.rs + placeholder kernels + local MappedF32Buffer
Cargo.toml: drops gbdt; adds memmap2 + approx; keeps ml-core only
(cannot depend on ml: would cycle since ml depends on ml-alpha for
the Mamba2 gate baseline).

build.rs: compiles 7 cubins (mamba2_alpha + 6 new placeholders)
with -O3 --use_fast_math --ftz --fmad. Skips kernels whose source
isn't present yet so partial check-ins work. Every env::var paired
with rerun-if-env-changed per the canonical build pearl.

src/pinned_mem.rs: local copy of MappedF32Buffer (mirrors
ml::cuda_pipeline::mapped_pinned::MappedF32Buffer). Drives the only
permitted CPU<->GPU path per feedback_no_htod_htoh_only_mapped_pinned.
Eventually the move-to-ml-core refactor will deduplicate; out of
scope for the Phase A branch.

Addendum: updates the import path to ml_alpha::pinned_mem.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 21:35:35 +02:00
jgrusewski
2deec0cf91 plan(ml-alpha): Phase A API addendum — cudarc 0.19 canonical patterns
Plan 1 was written against an older cudarc device-centric API. cudarc 0.19
moved alloc/launch ownership to the stream (partly for CUDA Graph capture
hygiene). This addendum pins:

- MlDevice -> CudaContext -> CudaStream construction
- Cubin load + module + function caching
- MappedF32Buffer staging -> DtoD-async -> CudaSlice (canonical CPU->GPU)
- Slow-path readback via DtoD into a staging MappedF32Buffer
- launch_builder(&func).arg(...).launch(cfg) idiom
- IsvBus and MappedPinnedSnapshotSlot/FillSlot using the real
  MappedF32Buffer API (host_slice_mut, read_all, dev_ptr field)
- CUDA Graph A capture via stream.begin_capture / end_capture / instantiate

Plan 1 kernel .cu source, CPU oracles, finite-diff thresholds, smoke
criteria, and gate logic are unchanged. Only Rust binding code uses
these patterns.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 21:31:53 +02:00
jgrusewski
056b4abe52 plan(ml-alpha): three-plan rollout for CfC+PPO greenfield
Plan 1 (Phase A, ~3000 lines): ml-alpha library scaffold, ISV bus,
mapped-pinned slots, CUDA build.rs, six perception kernels with
bit-equiv tests, AdamW + BCE, Graph A capture, Phase A trainer +
binary, CfC-vs-Mamba2 gate. Bite-sized 5-step TDD across 18 tasks.

Plan 2 (Phase B, ~780 lines): build_state, policy_forward (CfC
actor+critic), sample_action, replay buffer, multi-env rollout, GAE,
advantage_normalize, fused PPO loss, EWC, Graphs B+C, seven ISV
controllers, kill-switch, atomic weights swap, walk-forward CV across
6 folds. 19 tasks; tasks 2+ use compressed Step 2-5 TDD cycle pending
re-detail at the Plan 1 gate boundary.

Plan 3 (live, ~560 lines): IBKR adapter audit, AlphaPpoStrategy in
trading_agent_service, cold-start 4-state FSM, disconnect/failure
handling, observability, alpha-control IPC + fxt CLI, restart
semantics, paper trading harness (5 days), $1k live deploy with
manual ack gate, 5-day live window. 10 tasks.

Each plan has gate-pass criteria gating the next. On failure: post-
mortem + spec delta, no advance.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 20:48:14 +02:00
jgrusewski
2fe76f2f34 docs(phase-e-4-a): execution status + T10 backward_from_h_enriched patch sketch
Two documentation deliverables produced while T14 backtest runs:

1. Plan update (specs/2026-05-15-phase-e-4-a-temporal-foundation.md):
   adds 'Execution Status' section reflecting actual T1-T14
   progression. T5 deferred (real MBP-10 peek), T9 skipped (GRN
   moved to E.4.B per integration notes), T10 partial (new C51
   grad-input kernel landed but Mamba2 backward wiring deferred),
   T14 in flight. Documents the 4 execution learnings:
   research-first saved a week of duplicate kernel work; cheap
   falsification experiments (Path 2, Path 3) avoided expensive
   investments; C51 borrow was the largest single Sharpe-lift in
   the session; GpuTensor/CudaSlice interop friction is the real
   integration cost.

2. T10 patch sketch (specs/2026-05-15-t10-mamba2-backward-from-h-enriched.md):
   ready-to-apply patch for ml-alpha::Mamba2Block adding a new
   public method backward_from_h_enriched(cache, d_h_enriched).
   Bypasses the W_out projection backward, accepts the
   [B, hidden_dim] gradient from C51's grad-input kernel directly,
   zero-initialises dw_out/db_out (AdamW step on zero grad is a
   no-op with correct moment decay — effectively freezes W_out
   params which is correct semantics since Phase E never uses
   them). Includes the smoke binary wiring snippet that consumes
   the new method via launch_alpha_c51_grad_input → Mamba2
   backward → AdamW step. Application gated on T14 backtest
   validation — if frozen Mamba2 already lifts Sharpe, T10
   becomes optimisation rather than prerequisite.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 22:08:31 +02:00
jgrusewski
eb9047fc30 docs(phase-e): E.4 temporal encoder design + E.4.A implementation plan
Design doc (specs/): TFT-style architecture for Phase E execution
policy — sliding window → Mamba2 SSM → GRN trunk → MoE regime gate
→ C51 head → Thompson selector. Two core pillars added per user:
  A) Full L1-L10 LOB depth input via hybrid MBP-10 peek
  B) ISV-continual-learning: controllers fire at training AND
     inference; Q-net weights frozen at inference but effective
     policy adapts via ISV modulation

Plan doc (plans/): 14-task implementation plan for E.4.A foundation
(window buffer + L1-L10 depth + Mamba2 forward+backward + ISV-eval
controllers). Falsification gates: smoke R_mean improvement ≥ 50%,
backtest cost=0 Sharpe ≥ +8 (no regression vs C51-flat +10.41),
half-tick Sharpe ≥ -8 (closes 5pt+ of 10pt gap to Phase 1d.4
baseline -4.0).

TGGN (foxhunt Temporal Graph Gated Network) explicitly deferred to
Phase E.5+: existing CPU graph implementation + GPU adapter at
ml-supervised/src/tgnn/ — marginal benefit for single-instrument ES
futures vs the TFT-Mamba2 stack; revisit for multi-instrument
extension or production HFT inference layer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 20:42:35 +02:00
jgrusewski
9c26e78cdc docs(phase-e): implementation plan for execution-layer RL policy
32 tasks across 5 milestones (E.0 foundation → E.4 shadow-mode), with
locked design decisions from three rounds of focused research memos:
- Q1 (fill sim): medium-tier Poisson regression from 5.2M trade tape
- Q2 (reward): terminal-only, n-step credit (consumes ISV slot 517)
- Q3 (alpha trust): implicit calibrated trust via state features
- Q4 (state window): current snapshot + 2 short-horizon scalars
- Q5 (sizing): hybrid decoupled fractional Kelly × Phase E attenuation

Trainer choice: DQN primary (Rainbow + Munchausen target), PPO control
on H=600 truncated only if kill criteria fire. Exploration: ε-greedy
with kill-criteria gate at end of week 2; NoisyNet escalation (4-6 days
due to dead scaffolding in our codebase) if criteria fail; RND beyond
that.

ISV consumption: 5 existing slots (n_step=517, γ=43-46, ε=41, Kelly=280,
reward_caps=452-453); new block 539..550 reserved for Phase E (10 in
active use, 2 spare). One new controller (stacker-threshold
engagement-rate-self-correction at slot 543).

Hardcoded by design: Kelly contract cap (Category-1 safety),
kill-criteria thresholds (circuit breakers). All other knobs are
ISV-driven per pearl_controller_anchors_isv_driven.

Decisive gates at week 1 (H=600 kill criteria), week 4 (composition
backtest Sharpe at half-tick > 0), and week 5 (shadow-vs-backtest
PnL within 30%).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 10:42:14 +02:00
jgrusewski
5d79bf0b22 docs(phase1d): implementation plan for regime-gated tick reasoning + memory accumulator
26 tasks across 5 milestones (1d.0 through 1d.4) with decisive falsification
gates at each. Anchors to commit db874b184 (Phase 1c validation) and references
real APIs: ml::trainers::mamba2, ml-alpha::training, backtesting::strategies.

Each task is bite-sized (TDD steps + commit). Decisive gates:
- 1d.0: best calibrated Brier ≤ 0.250
- 1d.1: Mamba AUC > 0.72 at K=100
- 1d.2: Mamba AUC > 0.55 at K=6000 (DECISIVE for two-head architecture)
- 1d.3: regime-gated conditional accuracy > 0.65
- 1d.4: out-of-sample Sharpe > 1.5

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 01:13:42 +02:00
jgrusewski
bc3ebb5fb0 docs(claude): foxhunt agents & skills implementation plan — 14 tasks
14-task plan covering: foundation hook router (Task 1), 5 auditor agents
(Tasks 2-5, 13), 5 workflow skills (Tasks 6-10), 2 maintenance skills
(Tasks 11-12), end-to-end acceptance check (Task 14). Tasks 2-5, 6-8, 9-10,
11-12 fan out in parallel. Task 13 (sp-critical-reviewer) composes the four
domain auditors and is built last.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 22:19:28 +02:00
jgrusewski
e1aef53373 docs(sp20): plan accuracy errata for Phase 2 (Tasks 2.0/2.1/2.2/2.3/2.4)
Append a "Plan Accuracy Errata" section to the SP19+20 plan
documenting the 6 deviations from the original Phase 2 plan that
emerged during implementation. Each entry captures the gap, the
decision made, and the rationale, so future implementers see what
was actually built vs what was specified.

Gaps documented:

  1. Task 2.0 (label-at-open infrastructure) was NEW — split out from
     Task 2.2 to land buffer + alloc + reset + write site atomically
     before Task 2.2's consumer ships. Sign convention mapping detail
     captured (kernel emits {0, 1, -1}, SP20 spec uses {-1, 0, +1}).

  2. Per-env alpha plumbing was not in Task 2.2 plan scope — built in
     Task 2.2 (NOT deferred to Phase 4) to preserve the
     `feedback_no_partial_refactor` contract atomicity. Touches 5
     files in one commit.

  3. Per-bar SP18 D-leg sites — KEEP for Phase 2 per `feedback_no_stubs`.
     Plan's wording "DELETE [these helpers]" was overbroad; only the
     trade-close-site call is deleted. The phantom
     `compute_sp12_reward_with_cost` doesn't exist as a function (the
     SP12 v3 reward is the inlined block).

  4. `sp20_compute_event_reward` placement — new dedicated
     `sp20_reward.cuh` header (NOT inside `experience_kernels.cu`,
     NOT inside `trade_physics.cuh`). Mirrors the
     compute_asymmetric_capped_pnl / compute_min_hold_penalty
     header-only pattern; needed for GPU oracle test wrapper to share
     the function bit-for-bit per `feedback_no_cpu_test_fallbacks`.

  5. Task 2.3 was subsumed by Task 2.2 — the existing Path C chain
     consumes the new `alpha` field automatically once `alpha_per_env`
     is wired; no separate `sp20_emas_compute` producer call needed.

  6. `min_hold_*` kernel-arg trio cleanup deferred to Task 2.4 — the 3
     kernel args were deleted in Task 2.2 (per `feedback_no_hiding`)
     but the upstream producer chain (`min_hold_temperature_update_kernel`,
     ISV[460], `read_min_hold_temperature_from_isv`, `config.min_hold_*`)
     deferred to Task 2.4 because it touches SP14 ISV slot registry +
     StateResetRegistry + ISV layout fingerprint bump.

Implementation-level details remain in `docs/dqn-wire-up-audit.md`
Task 2.0 / 2.1 / 2.2 entries; this errata is the plan-level
"what was actually built vs what was specified".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:30:33 +02:00
jgrusewski
235e838422 feat(sp20): Phase 1.4 (Path C) — kernel-arg refactor + aggregation kernel + wire-up
Atomic Phase 1.4 commit per `feedback_no_partial_refactor`. Wires the
SP20 fused-producer chain (Stats → Aggregate → EMAs → Controllers) into
GpuExperienceCollector's per-rollout-step path with one new aggregation
kernel + Phase 1.2 EMA kernel-signature refactor + production wire-up
+ tests + audit/spec/plan amendments, all in one commit.

## Path C decision rationale

The Phase 1.2 EMA kernel originally took 9 scalar value-args. The Phase
1.4 wire-up site (per-rollout-step in GpuExperienceCollector) needs to
feed per-env GPU-resident trade signals (trade_close_per_sample,
step_ret_per_sample, hold_at_exit_per_sample, packed factored
actions_out) into the kernel — forbidden via host sync
(`feedback_cpu_is_read_only`) and via memcpy_dtoh/htod
(`feedback_no_htod_htoh_only_mapped_pinned`). Path C refactors the EMA
kernel to take a device struct pointer (`SP20EmaInputs* ema_inputs`) +
adds an aggregation kernel that writes the struct on the GPU. Phase 1.2
had zero production consumers yet, so the sig change + Phase 1.4 wire-up
land atomically.

## What this commit contains

1. **EMA kernel signature refactor** (Phase 1.2 → Path C):
   `sp20_emas_compute_kernel.cu` swaps 9 scalar args for a single
   `const SP20EmaInputs* __restrict__ ema_inputs` device pointer.
   Math semantics bit-identical. Rust `EmaInputs` mirrored as
   `#[repr(C)]` byte-for-byte; new `pack_inputs_into_f32_view` helper
   for tests + collectors that fill the struct via a mapped-pinned
   f32-aliased buffer.

2. **New aggregation kernel** (`sp20_aggregate_inputs_kernel.cu`):
   Per-env arrays (sliced to current rollout step) + sp20_stats outputs
   (p50/std) + aux_dir_acc_reduce_kernel output [0] → SP20EmaInputs
   struct. Block tree-reduce (4 stripes × bdim × 4 bytes shmem); no
   atomicAdd. Aggregation rules per spec §4.5:
   - is_close = OR over envs
   - is_win = (≥ 0.5 of closed envs were wins)
   - trade_duration = round(mean(hold_at_exit) over closed envs)
   - action_is_hold = strict majority (count*2 > n_envs) HOLD
   - alpha = 0.0  (Phase 2 forward ref — reward kernel)
   - per_bar_hold_reward = 0.0  (Phase 3.2 forward ref — Hold-cost dual)
   - aux_logits_p50/std/dir_acc forwarded from upstream

3. **Production wire-up in GpuExperienceCollector**:
   4 kernel handles + 4 mapped-pinned buffers (struct fields, alloc,
   init); per-rollout-step launch sequence after env_step (step 5c):
   `Stats → Aggregate → EMAs → Controllers`. All on the same stream;
   stream-implicit producer→consumer ordering. Gated on
   `isv_signals_dev_ptr != 0 && trainer_params_ptr != 0` (matches the
   existing SP14-β EGF chain pattern).

4. **Fold-boundary reset**:
   3 new RegistryEntry records (sp20_ema_inputs_buf,
   sp20_emas_internal_buf, sp20_emas_obs_count_buf) + 13 new dispatch
   arms in training_loop.rs (10 SP20 ISV slot resets + 3 buffer resets).
   Closes the pre-existing `every_fold_and_soft_reset_entry_has_dispatch_arm`
   regression (was failing on fresh check after the SP20 ISV slot
   registrations landed in commit 4249ebc96).

5. **HEALTH_DIAG emit**:
   Per-epoch `HEALTH_DIAG[N]: sp20_isv [loss_cap=… alpha_ema=…
   wr_ema=… hold_cost_scale=… target_hold_pct=… hold_pct_ema=…
   hold_reward_ema=… n_step=… aux_conf_threshold=… aux_gate_temp=…]`
   right after the existing q_disagreement_diag emit.

6. **Tests** (5 test files, all green on RTX 3050 Ti sm_86):
   - sp20_emas_compute_test.rs (4 GPU oracle): updated to use the
     post-Path-C buffer-arg API (mapped-pinned f32-aliased struct).
   - sp20_aggregate_inputs_test.rs (NEW, 6 GPU oracle): aggregation
     rule coverage including the Phase 2 / Phase 3.2 placeholder
     contract.
   - sp20_phase1_4_wireup_test.rs (NEW, 2 GPU oracle): end-to-end
     4-kernel chain integration test.
   - sp20_stats_compute_test.rs (4 GPU oracle): unchanged, regression.
   - sp20_controllers_compute_test.rs (7 GPU oracle): unchanged,
     regression.
   - 18 lib unit tests across the SP20 launchers.

7. **Phase 2 / Phase 3.2 forward references**:
   The `alpha` (Phase 2) and `per_bar_hold_reward` (Phase 3.2) fields
   are emitted as 0.0 placeholders and documented at:
   - `sp20_aggregate_inputs_kernel.cu:46-52` (in-kernel docstring)
   - `sp20_aggregate_inputs.rs:46-49` (launcher docstring)
   - `dqn-wire-up-audit.md` "Phase 2 / Phase 3.2 forward references"
   These are NOT stubs — Phase 2 / 3.2 will replace the kernel's 0.0
   writes with real signals atomically with their respective producers.
   The original Task 2.3 (host-side aggregation) is **subsumed** by
   the GPU-side aggregation kernel.

## Hard rules

- `feedback_no_partial_refactor` — kernel sig change + aggregation
  kernel + production wire-up + tests + audit/spec/plan amendments
  in one atomic commit
- `feedback_no_atomicadd` — aggregation kernel uses block tree-reduce
- `feedback_no_cpu_compute_strict` — every aggregation lives on GPU
- `feedback_no_htod_htoh_only_mapped_pinned` — every Phase 1.4 buffer
  is mapped-pinned with `cuMemHostAlloc(DEVICEMAP)` reachable via
  `dev_ptr`; no memcpy_dtoh/htod
- `pearl_first_observation_bootstrap` — counter-based bootstrap
  preserved; placeholder writes (0.0) keep the ALPHA / HOLD_REWARD
  EMAs at 0.0 sentinel until Phase 2 / 3.2 wire real producers
- `pearl_no_host_branches_in_captured_graph` — every kernel is single-
  block; no host branches; safe to capture in the per-step CUDA Graph
- `pearl_tests_must_prove_not_lock_observations` — integration test
  asserts invariants (slots populate, bounds respected) rather than
  locked observed values

## Verification

- `cargo check -p ml --features cuda` clean
- 18 lib unit tests for SP20 launchers pass
- 23 GPU oracle tests across 5 test files pass on RTX 3050 Ti (sm_86)
- `every_fold_and_soft_reset_entry_has_dispatch_arm` regression test
  now passes (was failing pre-change)
- 14 baseline lib test failures unchanged (none introduced by this
  commit)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 20:49:07 +02:00
jgrusewski
4e21c38b85 fixup(sp20): Phase 1.1 K=3 → K=2 retarget (production aux head is K=2)
The Phase 1.1 sp20_stats_compute kernel (de922c6a4) assumed the SP14-C aux
head emits 3-class logits {short, hold, long} with baseline 1/3. This was
an error in the SP19+20 spec — production aux head emits K=2 logits
{down, up} per gpu_aux_heads.rs:61 (AUX_NEXT_BAR_K = 2, established by
SP13 B1.1a). Wiring K=2 production aux into the K=3 kernel = OOB reads +
corrupt stats.

Retargets the kernel + launcher + tests to K=2 atomically per
feedback_no_partial_refactor:

- Kernel: SP20_K_CLASSES 3→2; SP20_UNIFORM_K3 0.333…→SP20_UNIFORM_K2 0.5f;
  Pass A reads 2 logits (was 3); aux_conf range [0, 1/2] (was [0, 2/3]).
- Launcher: AUX_K_CLASSES 3→2; renamed unit test
  aux_k_classes_is_three → aux_k_classes_matches_production_aux_head.
- Tests: rewrote CPU oracle for K=2 input shape and 0.5 baseline; updated
  expected p50/std ranges; redesigned heterogeneous-distribution test to
  use ramped (not lockstep) clusters — K=2's saturated softmax in the hot
  half collapses every row to bin 255, triggering the
  pearl_sp4_histogram_warp_tile_undercount trap; ramped clusters distribute
  bin indices across each warp's 32 lanes so the histogram path matches
  the CPU oracle within bin_width tolerance.

Phase 1.2 (sp20_emas_compute) and Phase 1.3 (sp20_controllers_compute)
consume the scalar [p50, std] outputs and do NOT carry the K dimension.
Both regression suites verified passing unmodified:
- sp20_emas_compute_test: 4 GPU + 1 unit, all pass.
- sp20_controllers_compute_test: 7 GPU, all pass.

Verification (RTX 3050 Ti, sm_86):
- sp20_stats_compute_test: 4 GPU oracle + 4 launcher unit, all pass.
- cargo check -p ml --features cuda: clean (pre-existing warnings only).

Spec + plan amended at top with "AMENDED 2026-05-09" notes; audit doc
Phase 1.1 entry has a "K=2 fixup" subsection documenting the change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 19:46:17 +02:00
jgrusewski
99332003a4 plan(sp19+20): WR-first reward implementation plan
Implements the spec at docs/superpowers/specs/2026-05-09-sp19-20-wr-first-design.md
(commit 9d9ca3e6e). 38 top-level tasks across 8 phases:

- Pre-Phase: branch + worktree + 10 ISV slot reservations
- Phase 0: 7 behavioral test stubs (failing scaffold)
- Phase 1: 3 ISV producer kernels (stats, EMAs, controllers)
- Phase 2: Reward kernel + atomic SP18 D-leg / SP12 v3 replacement
- Phase 3: Hold opp-cost dual emission + replay buffer schema
- Phase 4: n-step credit distributor + SP18 B-leg trace reset fix
- Phase 5: Aux→Q confidence gate at Bellman target
- Phase 6: 7 behavioral tests pass — L40S deployment gate
- Phase 7: L40S smoke + 50e×3s×3f full validation + close-out

Plan follows TDD discipline (write failing test → run-fail → implement →
run-pass → commit) with bite-sized 2-5 minute steps. All file paths
exact, all kernel code complete, no placeholders.

Self-review confirmed: spec coverage complete, no placeholders, type
consistency across phases (Sp20EmasInputs, ISV slot constants, aux_conf
schema field).
2026-05-09 18:04:00 +02:00
jgrusewski
44e1f58b69 docs(sp18): copy spec + plan to feat/sp18-combined branch
Mirrors the SP17 PP.1 plan-copy pattern. Plan and spec source-of-truth
live on the sister `feat/sp17-dueling-q-network` worktree; this commit
copies them onto the SP18 branch so subsequent commits reference local
paths.

Spec: docs/superpowers/specs/2026-05-08-sp18-reward-shape-hold-attractor-design.md
Plan: docs/superpowers/plans/2026-05-08-sp18-reward-shape-hold-attractor.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 00:25:06 +02:00
jgrusewski
509035dea6 docs(sp17): copy plan file to feat/sp17-dueling branch
Plan was authored on sister worktree (sp15-phase1-honest-numbers) by
the SP17 planner agent; copying it to feat/sp17-dueling so future task
references in commit messages and audit-doc entries resolve from this
branch.

No content change vs sister-worktree copy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 20:57:28 +02:00
jgrusewski
641aa0dfde fix(sp16-t3): Wiener-optimal adaptive α per pearl — hold_cost_scale + min_hold_temperature
Per train-multi-seed-hjzss validation: SP16 T1+T2 chain was structurally
landed but BEHAVIORALLY INERT in 5-epoch smoke (bit-identical to pfh9n
baseline through epoch 3). Root cause: hardcoded `alpha = 0.05f` in both
producer kernels violates feedback_isv_for_adaptive_bounds AND prevents
convergence in short runs (~60 epochs needed from cold start).

Fix per pearl_wiener_optimal_adaptive_alpha:
  α = diff_var / (diff_var + sample_var + ε)

Where sample_var = running variance of target signal (Welford accumulator)
and diff_var = running variance of consecutive one-step differences.

Cold-start: target jumps 1.0 → 6.4 → 7.0 → high diff_var → α ≈ 0.6+
            → near-bootstrap responsiveness in epochs 1-3
Steady-state: signal stabilizes → diff_var drops → α decays naturally
              → smoothing emerges without hardcoded constant

Adds 12 new ISV slots (6 per producer):
- HCS_TARGET_MEAN/M2, HCS_DIFF_MEAN/M2, HCS_PREV_TARGET, HCS_SAMPLE_COUNT
- MHT_TARGET_MEAN/M2, MHT_DIFF_MEAN/M2, MHT_PREV_TARGET, MHT_SAMPLE_COUNT

ISV_TOTAL_DIM 462 → 474.

Both kernels migrated atomically. Pearl-A bootstrap preserved (sentinel
on prev_blended triggers REPLACE; cold-start α=1.0 when N<3 samples).
Defensive bounds [WELFORD_ALPHA_MIN=0.01, WELFORD_ALPHA_MAX=0.95] on the
Wiener-derived α to guard against denormal/underflow corner cases.

HEALTH_DIAG[N] emit extended with `alpha=...` and `sample_count=...` for
direct trajectory observation in validation smoke.

Behavioral tests verify:
- α high during signal jumps (>0.3 at epoch 3 post-cold-start)
- α low in steady state (mean tail α<0.4 under converging signal)
- Pearl-A bootstrap fires on first observation (Welford state advances
  regardless of REPLACE branch)
- α stays within [WELFORD_ALPHA_MIN, WELFORD_ALPHA_MAX] over 50 epochs
  (post-cold-start; cold-start α=1.0 by design)
- No 0.05f hardcoded literal remains in blend math (regression-locked
  via host-only string scan)

5 GPU + host tests pass: sp16_phase3_alpha_high_during_signal_jump,
alpha_low_in_steady_state, pearl_a_bootstrap_first_obs,
alpha_naturally_bounded, no_hardcoded_alpha. sp14 + sp15 oracle suites
unchanged (34 GPU tests + 4 host tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 18:56:58 +02:00
jgrusewski
0426ce8887 fix(sp16-p1): MIN_HOLD_TEMPERATURE signal swap to hold-rate overrun + slot 330 non-bug closure
Per train-multi-seed-pfh9n post-mortem follow-up: slot 460 stuck at 50
in Fold 1 was NOT a launch-lifecycle bug. Producer fires per-epoch but
kernel had early-return guard on AUX_DIR_ACC_SHORT_EMA (slot 373) at
sentinel 0.5. Slot 373 reset on fold boundary; aux dir-acc EMA either
didn't fire or settled within ε of 0.5 → kernel kept early-returning.

Fix: drop slot 373 dependency entirely. Drive temperature from observed
hold-rate vs target overrun:

  overrun = max(0, observed_hold_rate - target_hold_rate)
  overrun_norm = clamp(overrun / max(target, 0.01), 0, 1)
  new_temp = TEMP_MIN + (TEMP_MAX - TEMP_MIN) × overrun_norm
  blended_temp = Welford EMA α=0.05 with Pearl-A bootstrap

When over-holding: temp HIGH → exit ramp permissive (matches design intent).
When at/under target: temp LOW → exit penalty strict.

Survives fold reset: hold-rate measurement starts fresh with real data
immediately, no chained-input-sentinel masking.

Slot 330 (KELLY_WARMUP_FLOOR) investigated and confirmed NON-BUG: producer
behaves correctly per pearl_kelly_cap_signal_driven_floors cross-fold-
persistence. floor=0 post-warmup is correct steady state.

Behavioral tests:
- sp16_phase1_min_hold_temp_climbs_with_hold_overrun
- sp16_phase1_min_hold_temp_strict_when_at_target
- sp16_phase1_min_hold_temp_strict_when_under_target
- sp16_phase1_min_hold_temp_no_longer_reads_slot_373

Instrumentation: HEALTH_DIAG[N]: min_hold_temp_diag obs/target/overrun/temp.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 15:24:12 +02:00
jgrusewski
b26b189925 feat(sp14-c.5b): atomic contract migration — h_s2 → h_s2_aux + revert zero-fills
Atomic flip of the aux heads' input from Q's GRN trunk output `save_h_s2`
to the SEPARATE aux trunk's output `h_s2_aux`. The aux trunk now trains
its own w1/w2/w3/b1/b2/b3 from CE loss (next-bar + regime); Q's encoder
is structurally protected by `aux_trunk_backward`'s missing `dx_in`
output param (encoder boundary stop-grad enforced at the kernel-set
level).

Reverts the C.0 stop-grad band-aid commits (`872bd7392`, `411a30473`):
the zero-fills in `aux_next_bar_backward` + `aux_regime_backward` Step 3
are replaced with the genuine SAXPY-back-to-input gradient
(`dh_s2_aux[b,j] = sum_k sh_dh_pre[k] * w1[k,j]`). The leak that
motivated stop-grad is now blocked structurally rather than by data
zero-fill — aux gradient flows through the aux trunk's own params, never
into Q's encoder.

Wired in this commit (atomic, ~330 LOC):
- 4 kernel signatures renamed `h_s2 → h_s2_aux` / `dh_s2_out → dh_s2_aux_out`
  (`aux_next_bar_forward`, `aux_regime_forward`, `aux_next_bar_backward`,
  `aux_regime_backward`); Rust wrappers in `gpu_aux_heads.rs` follow
- Trainer fwd: insert `aux_trunk_forward_ops.launch(...)` in
  `aux_heads_forward` Step 0, populating `h_s2_aux` from `save_h_s1`
  (encoder layer-1 output, dim=shared_h1=256). Both head fwds redirect
  input pointer from `save_h_s2` to `h_s2_aux`
- Trainer bwd: SAXPY both `aux_dh_s2_*_buf` into `dh_s2_aux_accum`
  (pre-zeroed each step via graph-safe `cuMemsetD32Async`); then
  `aux_trunk_backward_ops.launch(...)` propagates through w3/w2/w1 +
  b3/b2/b1; then `launch_aux_trunk_adam_update` applies global L2-norm
  clip + per-tensor Adam updates over 6 grad tensors
- Collector fwd: insert `exp_aux_trunk_forward_ops.launch(...)` after
  `forward_online_f32`, reading `exp_h_s1_f32` and writing `exp_h_s2_aux`;
  redirect `exp_aux_heads_fwd.forward_next_bar` input from
  `exp_h_s2_f32` to `exp_h_s2_aux`
- Pre-capture host-write of ISV-driven LR + grad-clip + step counter
  into mapped-pinned buffers in `launch_cublas_backward_to` (BEFORE
  `aux_heads_backward`); same `&mut self` pattern as `step_ofi_embed_adam`

Verification:
- `cargo check -p ml --tests` clean (1m02s, only pre-existing warnings)
- `aux_trunk_oracle_tests` + `sp14_oracle_tests` 12/12 pass:
  - aux_trunk gradient check: max_rel_err=1.33e-2 (tol=2e-2) — matches C.4 baseline
  - aux_trunk_backward_does_not_write_dx: kernel source clean of dx_in/dx_in_out
  - aux_sign_label_lookahead_mask: 60/100 masked, 40/100 valid
  - 9 other oracle tests pass bit-identically

Plan: docs/superpowers/plans/2026-05-07-sp14-layer-c-separate-aux-trunk.md §C.5b
Audit: docs/dqn-wire-up-audit.md "SP14 Layer C Phase C.5b" section
2026-05-08 03:01:13 +02:00
jgrusewski
c90de98594 feat(sp14-c.5a): allocate aux trunk fwd/bwd buffers + Adam launcher (dead code)
Phase C.5a — additive infrastructure for the aux trunk wire-up.
Allocates saved-fwd buffers (h_s2_aux, h_aux1, h_aux2),
gradient buffers (6× aux_trunk_*_grad), accumulator
(dh_s2_aux_accum), and dedicated Adam launcher
(launch_aux_trunk_adam_update) reading β1/β2/ε/LR/grad-clip from
ISV[444..449).

No contract change. No call sites for the new launcher yet.
C.5b atomically wires these in.

Phase C.5 was split (authorized 2026-05-08) after the original
implementer flagged ~600-800 LOC scope across 4 files with
correctness windows. C.5a is purely additive; C.5b is the genuine
~300 LOC atomic migration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 02:10:17 +02:00
jgrusewski
3b71d21834 feat(sp14-c): aux prediction horizon ISV-driven (multi-bar pivot)
Aux's original label was (p_{t+1} > p_t) — pure HFT-scale microstructure
noise that's unlearnable at our HFT-MFT trading frequency. Migrated to
(p_{t+H} > p_t) where H is read from ISV[AUX_PRED_HORIZON_BARS_INDEX=450].

Adaptive producer drives H from observed avg winning hold time:
- Pearl-A first-observation bootstrap: replace sentinel H=60 directly
  on first valid observation
- Steady-state Wiener-α EMA blend, slow (α=0.01) for stable horizon
  (no target-variance EMA available, fallback per
  pearl_wiener_optimal_adaptive_alpha)
- "No winning trades yet" guard keeps sentinel until first valid observation

Lookahead truncation: labels at t where t+H >= total_bars are masked
(sentinel -1, loss-reduce skips). The existing aux_next_bar_loss_reduce
in aux_heads_kernel.cu already supports the -1 mask convention via the
B_valid count — no new valid_mask parameter needed.

Step 5b finding: Case B — existing per-sample buffers
(hold_at_exit_per_sample, trade_profitable_per_sample) populated by
unified_env_step_core, but no aggregate ISV slot. Added new aggregator
slot AVG_WIN_HOLD_TIME_BARS_INDEX=451 + new producer kernel
avg_win_hold_time_update_kernel.cu (block-tree-reduce, no atomicAdd).
ISV_TOTAL_DIM bumped 450 → 452.

ATOMIC migration per feedback_no_partial_refactor: both label kernels
(aux_sign_label_kernel.cu trajectory + aux_sign_label_per_step_kernel.cu
per-rollout-step) migrated together to the new
(targets, bar_indices, isv, isv_h_idx, out_labels, total, total_bars)
signature. The lookahead host-passed scalar argument is removed; H is
read from ISV inside the kernel (broadcast value, single read per
thread, on-device clamp [1, 240]).

Producer chain (per-epoch boundary): new
GpuDqnTrainer::launch_aux_horizon_chain orchestrates
avg_win_hold_time_update → aux_horizon_update sequentially alongside
launch_kelly_cap_update at the existing epoch-boundary slot in
training_loop.rs.

Trunk math (C.2/C.3/C.4) unchanged — separate aux trunk is label-
agnostic. Validation in C.10 will use H=60 cold-start; the adaptive
producer drives H from real winning-trade observations.

Tests (8 oracle, 5 new + 3 preserved):
- aux_trunk_forward_matches_numpy_reference (C.3) ✓
- aux_trunk_backward_gradient_check (C.4) ✓
- aux_trunk_backward_does_not_write_dx (C.4) ✓
- aux_sign_label_h_bar_horizon (NEW) ✓
- aux_sign_label_lookahead_mask (NEW) ✓
- aux_horizon_pearl_a_bootstrap (NEW) ✓
- aux_horizon_converges_to_steady_target (NEW) ✓
- aux_horizon_holds_sentinel_with_no_winning_trades (NEW) ✓

8/8 pass on RTX 3050 Ti.

Phase C.4b of SP14 Layer C separate-aux-trunk refactor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:37:39 +02:00
jgrusewski
35935ae441 plan(sp15): fix 3 critical compile-breakers from third review
Targeted fixes per user direction (option 3 of "fix critical only,
accept rest as execution-time gaps"):

1. build.rs cubin manifest is 1:1 source-to-cubin (verified: list of
   .cu filenames, NOT (source, name) tuples). Fixed Phase 3.1 Step 5
   to use single manifest entry; both kernels load from SAME module
   via get_function() with their symbolic names.

2. egf_anchor_p1 helper in sp4_histogram_p99.cuh: replaced the
   `return 0.0f` stub with the full ~80-line body. Pass 1 + Pass 2
   byte-identical to sp4_histogram_p99 (mirrored verbatim from the
   existing sibling). Pass 3 walks cumulative-from-bottom for p1
   instead of cumulative-from-top for p99. Returns lower-edge of the
   first bin reaching 1% threshold.

3. Added Task 4.2.5: `fxt evaluate` subcommand (PREREQUISITE for 4.3).
   Verified that bin/fxt/src/main.rs Commands enum has no Evaluate
   variant. Without this task, eval-final-template.yaml fails at
   runtime. Full subcommand shown: bin/fxt/src/evaluate.rs with 5
   flags (--checkpoint-dir, --quarter, --seeds, --output-dir,
   --report-card-md), report card markdown emitter per spec §10.5.

5 IMPORTANT and 2 NIT issues from review remain documented as
execution-time friction; subagent-driven-development's spec-compliance
reviewer between tasks is expected to catch them per-task.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 10:32:10 +02:00
jgrusewski
eb5e19d670 plan(sp15): rewrite v2 — fix all 16 reviewer-flagged issues
Rewrite of 2026-05-06-sp15-trader-discipline-and-recovery.md from v1
(commit 0178a53ab) which had 16 reviewer-flagged issues including
5 critical compile-breakers and 8 important plan-failure violations.

CRITICAL fixes:
- Real GATE1_OPEN_STATE_INDEX (slot 391) — was wrong GATE1_STATE_INDEX
- Real PS_PEAK_EQUITY/PS_PREV_EQUITY (state_layout.cuh slots 7+9) —
   no invented CUMULATIVE_EQUITY_INDEX
- Real sp4_histogram_p99<BLOCK_SIZE> block-tree-reduce pattern, no
   atomicAdd_block (was feedback_no_atomicadd violation)
- Real evaluate_dqn_graphed pattern (gpu_backtest_evaluator.rs:1143) —
   no nonexistent evaluate_on_val_slice
- Real services/ml_training_service/src/main.rs path — was wrong

IMPORTANT fixes:
- Fork from current main 0178a53ab, not stale 5417e2756
- Phase 0.B has explicit case-(a)/case-(b) branches driven by 0.A
   diagnostic conclusion
- Phase 2B uses TEMPLATE + 17-row differential table — every test fully
   specified, no compressed bullets
- Phase 3 each teaching gets full TDD: write test → run-fail → kernel
   (full code) → launcher → consumer → run-pass → commit (5+ steps)
- Phase 3.5 each mechanism same TDD pattern with full kernel code
- Plasticity 3.5.4 specifies TWO-STEP recovery (Flat first, then
   cooldown) + Kaiming-He init (not Xavier — architecturally appropriate)
- Phase 4.3 includes FULL eval-final-template.yaml (not 4 bullets)
- 4 EGF constants replaced (not 3 — verified all four in
   alpha_grad_compute_kernel.cu lines 142,143,144,147)
- Behavioral_suite test target ordering fixed (Cargo.toml entry lands
   before tests run against it)

Stats: 4947 lines, ~270 [- [ ]] step checkboxes, 0 todo!() in test
bodies, every kernel shown in compilable form.

Self-review section maps every spec section to implementing task,
verifies all cross-references against verified codebase facts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:58:30 +02:00
jgrusewski
0178a53ab0 plan(sp15): trader discipline and recovery implementation plan
Implementation plan for SP15 spec at docs/superpowers/specs/2026-05-06-trader-
discipline-and-recovery-design.md (commit 5417e2756).

Six phases ~4900 LOC, Approach B parallel-where-independent (~10-15 days realistic):
- P.1 Branch + sub-worktrees scaffolding
- 0.0 sp15_isv_slots.rs lands FIRST on sp15 (slots 397-442, ISV_TOTAL_DIM 396→443)
- Phase 0 (3 sub-tasks): EGF diagnostic + ISV-driven retune + anchor test 2.21
- Phase 1 (7 sub-tasks): unified sharpe, cost-net (commission+spread+OFI), DD,
   8 baselines fused trunk, dd_pct trunk concat (LAYOUT BREAK), CLI flags,
   test slice consumption
- Phase 2 (2A scaffold + 2B 17 tests + 2C 5 tests paired with 3.5)
- Phase 3 (5 teachings sequential): r_quality/r_discipline split, explicit cost,
   quadratic DD, regret signal, confidence-aware Hold floor (sigmoid)
- Phase 3.5 (4 mechanisms): asymmetric DD reward, cooldown gate, plasticity
   injection (TWO-STEP: Flat + cooldown, Kaiming-He init), recovery PER curriculum
- Phase 4 (4 sub-tasks): pre-flight, L40S Q1-Q7+Q8 walk-forward, sealed Q9 eval-
   only workflow, production-track gate

Each task: TDD-discipline (write failing test → run-fail → implement → run-pass
→ commit). Per-commit discipline rule: Phase 2 behavioral test + wire-up audit
+ pearl candidate. Sub-worktree merge model: each phase merges back to sp15
atomically; sp15 merges to main only after Phase 4 production-track gate passes.

Self-review: spec coverage table maps every section to its implementing task.
Some derivative tasks (3.2-3.5) summarized as templated bullets per writing-
plans pattern for skilled-implementer derivative work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:11:35 +02:00
jgrusewski
037c24116d plan(sp14): implementation plan for spec v3
Two-sub-project plan:
- Layer A (4 tasks, ~50 LOC): C51 atom-floor, set_aux_weight clamp lift,
  stagnation warmup gate, smoke validation
- Layer B (15 tasks, ~1180 LOC): 13 ISV slots, 4 kernels (q_disagreement,
  alpha_grad, gradient_hack_detect, dir_concat_qaux), forward wire,
  backward gradient gating, orchestrator wire-up, HEALTH_DIAG, tests, smoke

Each task has bite-sized TDD steps (write failing test, run fail,
implement, run pass, commit) per the writing-plans skill conventions.
Phase 0 verification tasks (A.0, B.0) anchor against current code at
HEAD 40e737a18+ before edits.

19 total tasks across 2 layers. Each layer commits independently as
an atomic feature; intermediate per-task commits during Layer B keep
the wire safety-protected (forward concat lands before backward gating
in B.9 → B.10 sequence).

8 explicit kill criteria for Smoke A2-B per spec B.7.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 17:36:56 +02:00
jgrusewski
0ad5b6fa42 chore(sp13): script bug fix + Layer B implementation notes
While P0b smoke (train-sw4ws on bdc5cb8bb) runs, two prep items:

(A) scripts/argo-train.sh — add `ci-training` to the L40S sm_89 case
    arm. Bare `ci-training` is an L40S pool alias in some clusters;
    previously defaulted to sm_90 (Hopper), causing train-mnpf7 to
    deploy with wrong-arch cubins (terminated + resubmitted manually).
    Now both `*l40s*` and bare `ci-training` resolve correctly.

(C) docs/superpowers/plans/...sp13...md — Layer B section expanded
    with concrete codebase locations discovered during P0a:
    - aux_heads_kernel.cu, aux_heads_loss_ema_kernel.cu locations
    - aux_nb_label_buf populated as column 0 of next_states (log_return)
    - F1/F2 regression history note (don't alias the label buffer)
    - aux_pred_to_isv_tanh_kernel.cu is a P0a placeholder per its own
      header — Layer B should rewrite to read softmax logit-diff
    - dir_acc kernel + oracle tests need softmax-read updates
    - Layer B + P0b combined rationale post-P0a empirics

Saves the next implementer ~30 min of re-investigation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 08:27:49 +02:00
jgrusewski
ba83fcd1f5 docs(sp13): v3 spec + plan — Hold-pricing replaces Hold-elimination
P0a.T3 v2 implementer's audit revealed `DirectionAction` enum doesn't exist; the
codebase uses an 8-variant fused `ExposureLevel` (ShortSmall/Half/Full, Hold,
LongSmall/Half/Full, Flat) with cross-crate consumers across 77 files and 32+
test files pinning the 8-variant invariant. Atomic Hold elimination would
cascade massively.

User insight (2026-05-04): Hold being FREE is the bug, not Hold itself. MFT
trading legitimately needs multi-bar holds; we want the model to use them
deliberately, not as a CQL-bias lazy default. Holding isn't free in the real
world — broker fees, margin interest, opportunity cost.

v3 reframes as Hold-pricing:
- 4-way action space stays; ExposureLevel::Hold stays; no cross-crate cascade
- 3 new ISV slots (380-382): HOLD_COST_INDEX, HOLD_RATE_TARGET_INDEX,
  HOLD_RATE_OBSERVED_EMA_INDEX
- Hold-rate observer: small GPU kernel + Pearls A+D smoothing
- Hold-cost controller: 5-line deficit-driven formula
  (excess > target → cost rises 1×→5× base; observed ≤ target → relax)
- Per-bar reward subtraction at action == DIR_HOLD site
- 2 GPU oracle tests for the controller

P0a.T3 cuts from ~250 LOC + 32-test cascade → ~120 LOC additive. T1+T2
already-staged work unchanged. T4/T5/Layer B/C/D structure preserved.

Tension with pearl_event_driven_reward_density_alignment acknowledged in
spec — per-bar Hold cost is exposure-NEGATIVE (away from Hold), models real
economic carry, ISV-bounded by controller. Inverse of the pearl's failure
mode. Faithful reward modeling, not artificial shaping.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 23:18:58 +02:00
jgrusewski
0ca45ef61d docs(sp13): v2 spec + plan after critical review
Spec v2 supersedes v1 with five major fixes from the critical review:
- Drop alpha-vs-benchmark reward (mathematically tautological — Long trades had
  alpha = -costs always against always-long benchmark)
- Split Phase 0 into 0a (Hold-only, clean test of user hypothesis) + 0b (aux
  amplification probe, only if 0a partial), avoiding the v1 confounded experiment
- Bound direction-skill bonus relative to |alpha| (cap_ratio × |alpha|) to prevent
  reward gaming on small-alpha correct-direction losers; spec adds 8-quadrant
  worked-example matrix verifying the no-negative-EV invariant
- Replace 5-epoch absolute-threshold gate with 10-epoch trajectory criterion to
  avoid false-negatives from aux head underconvergence
- Aux_w controller adds dual-EMA stagnation detector (decays toward base when
  no improvement) — prevents permanent destabilization of Q-head in
  data-limited case

Plan v2 mirrors spec changes:
- Phase 0a (Hold elimination + dir_acc instrumentation, ~300 LOC, 1 atomic commit)
- Phase 0b (aux_w controller replacement, conditional, ~80 LOC)
- Layer B (aux head regression -> binary classification, ~120 LOC)
- Layer C (skill bonus + luck discount with calibrated bounds, ~150 LOC)
- Layer D (30-epoch validation + 3 new pearls)

ISV slot allocation [372..380): drops slot 371 (BENCHMARK_PNL_CUMULATIVE),
adds 374 (AUX_DIR_ACC_LONG_EMA — stagnation), 379 (SKILL_BONUS_CAP_RATIO).

Plan integrates Explore-agent touch-list (50-70 sites) with corrected enum
ordering: Short=0, Long=1, Flat=2 (preserves codebase Short-first convention,
avoids 30+ stale-comment churn). Adds direction-bias signal handling at
experience_kernels.cu:5159 (Hold's 0.5 softening gate vanishes -> [1, 1, 0]).

Three new pearls planned for Layer D close-out:
- pearl_redefine_success_for_predictive_skill
- pearl_skill_bonus_must_be_alpha_bounded (calibration lesson)
- pearl_reward_quadrant_audit_required (meta-pearl)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 22:24:16 +02:00
jgrusewski
e0d3abd9d2 plan(sp11): patch all 5 violations + 2 gaps from review
feedback_no_htod_htoh_only_mapped_pinned (tests not exempt):
  - All test fixtures converted from htod_copy/dtoh_sync_copy to
    MappedF32Buffer with host_slice / host_slice_mut access.
  - Novelty hash buffer + projection matrix changed from
    cudarc::CudaSlice<f32> + alloc_zeros to MappedF32Buffer.

feedback_no_cpu_forwards (CPU is read-only):
  - Projection matrix initialization changed from host-side StdRng +
    host_slice_mut writes to a one-shot GPU init kernel
    (novelty_simhash_proj_init_kernel) using Philox seeded from
    config.seed. No host RNG, no host writes.

feedback_no_cpu_compute_strict (saboteur multiplication):
  - B1 step 5 reverted from Rust-side `read_isv_slot * scale` to
    GPU-side: pass base scale + ISV pointer + slot index to the
    saboteur perturbation kernel; multiplication happens on-device.

feedback_trust_code_not_docs (grad-ratio terminology):
  - Spec §3.3.1 "per-component grad EMA" was wrong — SP4 grad-balancer
    is per-branch (4 slots), not per-reward-component. Renamed:
      reward_component_grad_ratio_compute_kernel
        → reward_component_mag_ratio_compute_kernel
      REWARD_COMPONENT_GRAD_RATIO_BASE
        → REWARD_COMPONENT_MAG_RATIO_BASE
    Source: existing REWARD_POPART_EMA_INDEX..+6 (per-component reward
    magnitude EMAs from SP4 reward_component_ema_kernel). Semantic
    equivalent for the controller's exploit/diversify blend.

feedback_no_stubs (dead parameter):
  - Removed `eps_div_idx_unused` from mag_ratio kernel signature.

Saboteur engagement: missing producer specified
  - Spec §3.3.1's two-reward-arrays formulation replaced with single
    `saboteur_delta_reward_buf` produced by the saboteur perturbation
    kernel itself (single reward computation, diff emitted as side
    output). Engagement kernel signature simplified to one input array.

PNL_REWARD_MAGNITUDE_EMA_INDEX (slot 359): producer wired
  - mag-ratio kernel mirrors `isv[REWARD_POPART_EMA_INDEX]` to
    scratch_out[6]; chained apply_pearls_ad targets slot 359.

Replay sample kernel location specified
  - graph_utility_kernels.cu:71 (gather_f32_scalar). New sibling kernel
    `gather_replay_reward_with_curiosity` defined; replaces the existing
    scalar gather (no legacy alias per feedback_no_legacy_aliases).
    novelty_simhash_lookup runs before, novelty_simhash_update after.

A2 controller test placeholders → full GPU oracle assertions
  - Three controller tests (z=0 midpoint, weight renorm, saboteur clamp)
    have full mapped-pinned fixtures with assertions on weight sum,
    individual values, post-clamp bounds.

Plan now passes:
  - feedback_no_htod_htoh_only_mapped_pinned (tests + production)
  - feedback_no_cpu_forwards (CPU never writes/computes for GPU)
  - feedback_no_cpu_compute_strict (all multiplications GPU-side)
  - feedback_no_atomicadd (race-tolerated non-atomic, safety documented)
  - feedback_no_partial_refactor (Layer B atomic; saboteur kernel sig
    change touches all callers in the same commit)
  - feedback_no_stubs (no dead parameters)
  - feedback_trust_code_not_docs (corrected spec terminology)
  - feedback_wire_everything_up (every new field has init + producer)
  - feedback_no_legacy_aliases (old gather_f32_scalar replaced, deleted)

1447 lines, +268 from previous version.
2026-05-04 00:40:36 +02:00
jgrusewski
d8b44e0829 plan(sp11): implementation plan for reward-as-controlled-subsystem
Task-by-task plan for the SP11 spec at HEAD 9395b983c. Three layers:

Layer A (3 commits, additive infrastructure, no behavior change):
  A0 — 20 ISV slots [340..360) + 20 reset entries + novelty-hash arm
  A1 — 3 canary producers (val_sharpe_delta, saboteur_engagement,
       reward_component_grad_ratio) with Pearls A+D chained
  A2 — controller kernel + SimHash novelty buffer; HEALTH_DIAG sp11_reward

Layer B (1 atomic commit, ~750 LOC):
  B1 — every consumer migrates: cf_weight (mse + c51), audit-discovered
       shaping sites, saboteur multiplier, replay-time curiosity bonus,
       novelty hash lookup+update scheduled at replay

Layer C (validation + close-out):
  C1-C2 — local + L40S smoke; T10 3×3×50 full validation
  C3-C5 — Fix 39 audit doc, pearl_reward_as_controlled_subsystem, MEMORY.md
  C6 — merge to main

Plan provides exact file paths, kernel signatures, GPU oracle test
skeletons, commit messages, and validation pass criteria from spec
§9.1-9.3. ~1550 LOC total estimate; ~3 hours subagent work plus
validation wall-clock (smoke ~25 min, T10 ~4 hr).

Spec: docs/superpowers/specs/2026-05-04-sp11-reward-as-controlled-subsystem.md
2026-05-04 00:27:28 +02:00
jgrusewski
bcbd16f8c5 plan(sp7): v2 — fix 5 self-review violations from v1
Critical re-review of v1 caught:

1. Task 6 retained Pearl 2 kernel signature with (void) no-op args
   "to save 3-site cascade" — that's the partial-refactor anti-pattern
   feedback_no_partial_refactor explicitly forbids. v2 does the full
   contract change: signature shrinks 9→6 args, launcher migrates
   atomically.

2. SCRATCH_PEARL_2_C51/_CQL/_ENS would become orphan constants —
   feedback_wire_everything_up says delete or wire. v2 deletes them in
   T6.

3. Audit-doc updates were separated into a single late commit — would
   fail check_audit_doc_updates pre-commit gate on T1-T6. v2 folds Fix
   31 stub into T1 and extends it commit-by-commit.

4. T5 referenced grad_decomp_*_result_dev_ptr field names that don't
   exist — actual layout is one shared 27-float pinned buffer with
   per-component byte offsets (iqn=0, cql_sx=24, c51=36). v2 uses
   pointer arithmetic from grad_decomp_result_dev_ptr.

5. Tasks 1, 2, 4 had "if file shape X then Y, otherwise Z" placeholder
   branches — writing-plans skill forbids these. v2 has concrete patches
   based on reading the actual files.

Also corrected: T2 fixes the stale "regime_stability allocator"
description in state_reset_registry.rs alongside the new entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:35:07 +02:00
jgrusewski
30f7032d12 plan(sp7): implementation plan for loss-balance controller
10 tasks: ISV slots → reset registry → kernel → build manifest → trainer
load+launcher → Pearl 2 retreat → atomic launch+consumer+stale-doc →
audit doc + memory pearl → L40S 5-epoch smoke verify → L40S 50-epoch
full validation.

Each task is producer-only or atomic-pair commits per
feedback_no_partial_refactor. Verification gates (cargo check, cuda
build, smoke acceptance criteria) embedded in each task.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:20:33 +02:00
jgrusewski
6b01b70c3e docs(sp6): implementation plan — 3-sub-project parallel refactor (Pearls 2, 3, 5)
Three independent sub-projects (one per Pearl), each an atomic commit,
each running in its own git worktree (sp6-pearl-2/3/5). Pearl 2 expands
compute_adaptive_budgets() to per-branch [f32;4] arrays + trunk-mean
scalars, dispatches branch-correction SAXPY sub-launches. Pearl 3
replaces noise_sigma: f32 with noise_sigma_per_branch: [f32;4] in
ExperienceCollectorConfig and extends add_advantage_noise to per-branch
lookup. Pearl 5 adds 4-branch tau buffer triplets to GpuIqnHead, runs
4 IQN forward passes per step (Approach B), each contributing
iqn_trunk/4 to prevent 4x gradient accumulation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 01:47:07 +02:00
jgrusewski
11979d7c08 docs(sp5): comprehensive implementation plan — 4 layers, ~21 tasks
SP5 implementation plan covering:
  Layer A: 8 per-pearl commits (Tasks A0-A8)
    A0: ISV slot constants foundation
    A1: Pearl 1 per-branch atom span + Q-stats source
    A2: Pearl 3 per-branch NoisyNet σ
    A3: Pearl 2 per-branch loss budget (after Pearls 1+3)
    A4: Pearl 4 per-group Adam β/β/ε
    A5: Pearl 5 per-branch IQN τ schedule
    A6: Pearl 6 cross-fold-persistent Kelly
    A7: Pearl 8 per-direction trail distance
    A8: Pearl 1-ext per-branch num_atoms

  Layer B: 1 atomic commit (Task B1) — 11 consumer migrations

  Layer C: validation + cleanup (Tasks C1-C6)
    C1: Local GPU unit tests
    C2: L40S 5-epoch smoke
    C3: L40S 3-seed × 50-epoch full validation
    C4: Pearl 7 investigation (post-validation)
    C5: Audit doc + 8 memory pearls
    C6: Layer C commit

  Layer D: separate atomic commit (Tasks D1-D4)
    D1: PnL aggregation kernel
    D2: Health composition kernel
    D3: Training metrics EMA kernel
    D4: Layer D atomic commit

Total: 21 numbered tasks, ~110 ISV slots, 9-11 producer kernels,
11 consumer migrations.

Plan follows SP4's high-fidelity-for-Task-A1 + differential-pattern-
for-A2-A8 structure. Each task has concrete file paths, code blocks,
verification commands, exact commit messages.

Self-review:
  - Spec coverage: all 9 pearls + 4 layers covered
  - No TBD/TODO placeholders in step bodies
  - Type/slot consistency verified across tasks

Refs: docs/superpowers/specs/2026-05-01-sp5-magnitude-differentiation-and-eval-collapse-design.md (HEAD 6e6e0fa11)
2026-05-01 20:01:27 +02:00
jgrusewski
24accea774 fix(sp4): migrate fast/slow grad-norm EMA update to GPU per feedback_no_cpu_compute_strict
Layer C close-out C1 redesigned. Original plan claimed
grad_norm_slow_ema_pinned was orphan post-Mech-6 migration; verification
surfaced a SECOND live consumer (fold_warmup_factor_update, commit
4ef1d8ebb) that legitimately reads the slow EMA as cross-fold
steady-state baseline.

The actual defect: the EMA UPDATE at update_adaptive_clip:22720-22737
was host-side `(1-α)*prev + α*obs` arithmetic — exactly the pattern
feedback_no_cpu_compute_strict (saved 2026-05-01) strictly forbids.

Migrated:
  - New `update_grad_norm_emas_kernel.cu` — single-thread fused fast+slow
    EMA update kernel. Reads `grad_norm_buf[0]`, updates two mapped-pinned
    EMA scalars via dev_ptr. `__threadfence_system()` ensures the
    `fold_warmup_factor_kernel` consumer sees freshly-written values.
  - `launch_update_grad_norm_emas` Rust launcher chained on the
    producer's stream — graph-capture-compatible, no host sync.
  - update_adaptive_clip's host-side `unsafe { ... }` block replaced
    with the GPU launcher call (warn-and-continue on launch failure
    mirroring the launch_h_s2_rms_ema / launch_fold_warmup_factor
    per-step ISV producer pattern at training_loop.rs:3450/3464).

Preserved:
  - grad_norm_slow_ema_pinned mapped-pinned buffer (cross-fold persistent;
    legitimate consumer is fold_warmup_factor_update).
  - Fixed-α design (FAST_ALPHA=0.1, SLOW_ALPHA=0.001) — Pearls A+D
    adaptive α would defeat the cross-fold-baseline semantic the warmup
    factor depends on.
  - Cold-start sentinel (`prev ≤ 0.0` ⇒ assign obs directly) — same
    formula as the deleted host code.
  - Host-side update_adaptive_clip early-return guard — kernel only
    launches when observed_grad_norm is finite and > 0.
  - grad_norm_emas_step_count host counter — scalar control-flow
    metadata for warmup-window gating, not compute.

Plan/spec docs updated to remove stale "orphan" claim. State-reset
registry doc-comment + field doc-comments updated to reflect GPU-only
update path. fold_warmup_factor_kernel docstring no longer describes
its grad-norm EMA inputs as host-side-fed.

Build clean, sp4 + state_reset_registry lib tests pass (11/11), 16/16
SP4 producer GPU tests pass on RTX 3050 Ti. No behavior change — pure
architectural fix.

Refs: SP4 Layer C C1 redesigned (was: retire). Original plan
docs/superpowers/plans/2026-04-30-sp4-signal-driven-magnitude-control.md
lines 2184-2221.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 14:07:10 +02:00
jgrusewski
c06169136c docs(sp4): implementation plan for signal-driven magnitude control
Comprehensive 3-layer implementation plan for the SP4 spec at
docs/superpowers/specs/2026-04-30-sp4-signal-driven-magnitude-control-design.md.

Layer A — additive infrastructure (Tasks A1-A18, no behavior change):
- A1: 40 ISV slot index constants in new sp4_isv_slots.rs module
- A2: wiener_state_buf (141 floats) + clamp_engage_per_block_buf (2048 ints)
- A3: Pearls A+D shared helper (sp4_wiener_ema.rs) + 5 unit tests
- A4: linear-histogram p99 device function (sp4_histogram_p99.cuh) + GPU test
- A5-A9: 5 producer kernels (target_q + atom_pos × 4 branches + param_group_oracle
   × 8 groups + grad_norm + h_s2 = 15 fused producers per Pearl B)
- A10-A11: wire 4 captured-graph + 10 cold-path launch sites
- A12: 181 StateResetRegistry entries (40 ISV + 141 Wiener-state float +
   2048 Pearl C int)
- A13: retrofit 7 existing pre-SP4 producers with Pearls A+D
- A14-A15: Pearl C engagement counter in 5 Adam kernels + host-side
   rate-deficit EMA + force-bump trigger
- A16-A18: 40-test integration validation + L40S regression smoke + audit
   doc draft

Layer B — atomic consumer migration (Task B1, ONE coordinated commit):
- Mech 1, 2, 5, 6, 9, 10 consumers flip simultaneously to ISV-driven
- Adam kernels' weight_decay arg from ISV[WD_RATE[group]]
- L1 lambda from ISV[L1_LAMBDA_TRUNK_INDEX]
- HyperParams config fields removed
- Per `feedback_no_partial_refactor`

Layer C — validation + cleanup (Tasks C1-C5):
- C1: retire grad_norm_slow_ema infrastructure (Mech 6 migrated away)
- C2: remove dead Mech 5 fused-kernel parameters
- C3: L40S smoke validation against spec pass criteria
- C4: comprehensive Invariant 7 audit-doc entry
- C5: 5 new pearl memory entries + SP4 close-out project entry

Estimated effort: 3500-4500 LOC across ~25 commits, 1.5-2 weeks of focused
work, 1 L40S smoke validation. Bite-sized TDD tasks with exact file paths,
complete code blocks, and exact build/test commands per task.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 21:48:03 +02:00
jgrusewski
9b35fe9d45 plan(dqn): SP2 + SP3 implementation — fused NaN kernel + 5-mechanism Q-stability
Implementation plan for the approved combined design spec
(commit ed727b51c). Three phases:

Phase A — SP2 (5 tasks A1-A5 + Gate 1 smoke task A6):
- A1: Append dqn_nan_check_fused_f32_kernel to dqn_utility_kernels.cu
- A2: Add nan_check_buf_ptrs / nan_check_buf_lens device buffers (separate
      ptr + len arrays per the design fork resolution; cleaner than packed)
- A3: populate_nan_check_meta + launch_nan_check_fused_f32 wrappers
- A4: Replace 8 individual check_nan_f32 calls with single fused launch
- A5: Audit doc Phase E + wire-up Invariant 7 entries
- A6: Gate 1 smoke — F0 ≥ 53.08 (must pass before Phase B)

Phase B — SP3 (8 tasks B1-B8 + Gate 2 smoke task B9):
- B1: Slot 36-47 diagnostic accessors (Adam m/v + weight slice + target_q + atoms)
- B2: Mech 1 — target_q clip after compute_denoise_target_q (single-point)
- B3: Mech 2 — C51 atom-position growth bounds in EMA-update kernel
- B4: Mech 3 — hard target sync (DQN main + IQN) at fold boundary
- B5: Mech 4 — comprehensive Adam EMA reset at fold transitions
- B6: Mech 5 — fused kernel extended to 24 slots with inline threshold-by-
      slot-index logic (no per-step HtoD; q_abs_ref_eff passed as single arg)
- B7: Name table entries for slots 36-47 (both halt_nan + halt_grad_collapse)
- B8: Audit doc Phase F + wire-up Invariant 7 entries
- B9: Gate 2 smoke — full SP1 7-criterion validation

Phase C — Closure (2 tasks C1-C2):
- C1: project_sp2_sp3_resolved.md memory entry + SP1 closure update
- C2: Audit doc closure + wire-up final entry + push

Operating principles enforced throughout:
- ISV-driven bounds (Q_ABS_REF=16, ε on multiplier per SP1 pearl)
- No new ISV slots
- No DtoD/HtoD per step (inline-compute resolution for thresholds)
- Permanent diagnostic always-on (no debug flags)
- Per-task commits during dev; SP3 mechanisms ship together
- F0 paper-review documented per ISV bound

Plan covers ~1000 LOC across multiple commits, 2 L40S smokes (Gate 1 +
Gate 2), 4-7 days estimated. Self-review confirms full spec coverage.
2026-04-30 08:49:36 +02:00
jgrusewski
05958d3a0c plan(dqn): SP1 numerical stability — F1 NaN root-cause investigation
Implementation plan for SP1 (Sub-project 1 of 3) of the numerical
stability investigation. Follows the γ + β methodology from the spec
at docs/superpowers/specs/2026-04-29-numerical-stability-investigation-design.md.

8 tasks across 4 phases:
- Phase A (Task 1): γ read-only audit producing docs/dqn-backward-nan-audit.md
- Phase B (Tasks 2-5): always-landing β instrumentation expanding
  nan_flags_buf 24→48 with 12 new backward-kernel NaN check slots
  + 12 reserved slots for future coverage
- Phase C (Task 6): surgical fix(es), content-driven by audit + smoke
  topology, ISV-driven for any dynamic bound (mandatory)
- Phase D (Task 7): multi-fold L40S smoke validation against 7 pass
  criteria (F0 ≥ 95% baseline, F1+F2 monotone improvement, zero
  NaN-CLAMPED-TO-ZERO, all 48 NaN flag slots remain at zero)
- Closure (Task 8): audit doc closure, memory entry, SP2/SP3 handoff

Operating principles (mandatory per spec):
- No deferrals — anomalies discovered during investigation get fixed
  within SP1, not punted to SP2/SP3
- Combined RELATED fixes ship as rich commits (per
  feedback_no_partial_refactor)
- ISV-driven design for any dynamic bound

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 23:21:26 +02:00
jgrusewski
5de5e546a4 fix(dqn): Plan C T2 amendment — match production adaptive C51 support
Plan C as authored assumed:
  - c51_probs_dir = post-softmax probabilities (didn't exist on collector;
    only raw exp_b_logits is materialised)
  - atom_values = single global linear support (production uses per-sample
    per-direction adaptive [v_min, v_max, delta_z] + optional atom_positions)
  - iqn_quantiles_dir = rollout-side IQN inference (doesn't exist; IQN is
    training-only)

Amended kernel signature uses the production architecture:
  - b_logits_dir [N, b0_size, n_atoms] — raw direction-branch logits
  - per_sample_support [N, b0_size, 3] — adaptive per-direction support
  - atom_positions [b0_size, n_atoms] — non-linear positions (NULL = linear)
  - n_atoms

Direction-branch Thompson is now single-distribution over C51 (with adaptive
support), not joint C51+IQN. Single-distribution still provides the
principled posterior sample that fixes the UCB selector/target asymmetry —
the goal of Plan C is preserved, just sourced from the existing rollout-time
distribution instead of a non-existent IQN inference path.

New device-inline helpers: softmax_c51_inline, compute_atom_values_inline.

Plan + audit doc updated. Phase 0 standalone test kernel gained two new
entry points (direction_thompson_v2_test, argmax_eq_v2_test) matching the
amended production API; original Plan A entry points retained for tests
0.B-0.F. Tasks 3+4 (buffer wiring) unblocked — collector/evaluator already
have per_sample_support_buf and exp_b_logits in production.
2026-04-29 17:26:22 +02:00
jgrusewski
fc4addaabf spec+plan(moe): correct gate input dim 42 → STATE_DIM=128
T1.6 implementer correctly identified that the gate input dim is
ml_core::state_layout::STATE_DIM=128, not the literal 42 the spec/plan
incorrectly stated. The 42-dim figure was the bar-feature subset; the
actual state vector is 128-dim (42 features + portfolio + MTF + OFI
padded to 128 for cuBLAS alignment).

Updated spec §3 architecture diagram, §4.1 gate subnetwork description
+ parameter count (3,272 → 8,776), and plan header architecture line.
Implementation in commit 28c707f6a is correct; this commit just makes
the spec match the implementation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:22:40 +02:00
jgrusewski
76e55047ec spec+plan(moe): add no-HtoD/HtoH constraint; mapped pinned only
Per feedback_no_htod_htoh_only_mapped_pinned.md (newly recorded): every
CPU<->GPU path in this redesign uses mapped pinned memory exclusively.
No cudaMemcpy HtoD, no Vec-to-Vec defensive copies, including in test
code. CPU is strictly read-only on the production surface.

Plan changes:
- New Task 2.0 promotes MappedF32Buffer / MappedI32Buffer from
  distributional_q_tests.rs local definitions to a shared
  crates/ml/src/cuda_pipeline/mapped_pinned.rs module so all kernel
  test wrappers (Test 0.F, upcoming MoE tests) share one
  implementation. Adds write_from_slice helper for direct host_ptr
  write (no memcpy).
- Task 2.1 test wrapper rewritten to allocate mapped pinned buffers
  + write to host_ptr + read GPU-written output via host_ptr. No more
  memcpy_stod / memcpy_dtov in test code.

Spec: new section 6.4 codifies the mapped-pinned-only constraint and
references the shared module + reference implementation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:46:41 +02:00
jgrusewski
69141d6266 plan(dqn): MoE regime redesign — bite-sized implementation plan
Implementation plan for the approved MoE spec at
docs/superpowers/specs/2026-04-27-moe-regime-redesign-design.md.

6 phases:
- Phase 0: use_* flag cleanup + count_bonus refactor (precondition,
  partially in stash@{0})
- Phase 1: MoE infrastructure (additive — moe_lambda hyperparameter,
  9 ISV slots, MoeGate/MoeExpert skeletons, params_buf layout extension)
- Phase 2: 4 new CUDA kernels (mixture forward/backward,
  load_balance_loss, expert_util_ema_update) with TDD unit tests
- Phase 3: wire MoE into the training graph (forward, backward, loss
  aggregation, ISV producer launch, HEALTH_DIAG aux_moe line)
- Phase 4: atomic deletion of vestigial RegimeConditionalDQN (per
  feedback_no_partial_refactor.md)
- Phase 5: Layer 3/5 tests + L40S 30-epoch validation with explicit
  kill criteria

Each task has bite-sized steps (2-5 min each) with exact file paths,
copy-pasteable code, exact commands, and TDD pattern (test fails first,
implement to make pass, commit).

Self-review: spec section coverage verified, no placeholders, type
consistency verified across phases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:42:07 +02:00
jgrusewski
3c61ee52ce plan(dqn): Thompson sampling rollout — Plans A+B+C+D (4 sequential phases)
Implementation plans for the distributional-RL aggregation spec
(docs/superpowers/specs/2026-04-26-distributional-rl-aggregation-design.md).

Plan A — Phase 0: TDD hypothesis verification (8 tasks)
  - Standalone GPU test kernel: sample_c51_inverse_cdf,
    sample_iqn_quantile_interp, compute_e_c51, compute_e_iqn,
    thompson_direction_test, argmax_eq_test
  - 6 unit tests (5 GPU + 1 CPU synthetic edge)
  - GPU integration on converged checkpoint (Test 0.F)

Plan B — Phase 1: existing-lever audit (8 tasks)
  - 6 unit tests covering B.2/CF/PopArt/Q-target audit fixture
  - Exit gate: all 6 PASS = no reward-shaping bug; Phase 2 unblocked

Plan C — Phase 2: Thompson sampling integration (11 tasks)
  - Direction branch of experience_action_select rewritten:
    eps-greedy + Boltzmann → Thompson (training) + argmax E[Q] (eval)
  - C51 + IQN buffers wired to gpu_dqn_trainer + gpu_backtest_evaluator
  - train_active_frac HEALTH_DIAG instrumentation
  - 4 GPU-direct tests against production kernel
  - Aggregation Contract table + memory pearl

Plan D — Phase 3: long verification + dead-code cleanup (8 tasks)
  - Test 3.A: regression anchor against original C51 Flat bias
  - L4: 1 seed × 6 folds × 30 epoch (~1 hour)
  - L5: 5 seed × 6 fold matrix per Plan 5 Task 5 (Tier 1+2+3 PASS)
  - Direction-only eps_dir adaptive boost + Boltzmann tau-floor cleanup
    (per feedback_no_partial_refactor.md)
  - nsys regression check; final architecture/spec footer

Plans gated sequentially: each phase exit gate must pass before next.
2026-04-27 08:10:42 +02:00
jgrusewski
e9100073b9 plan(dqn-v2): Plan 4 Task 2c GRN — further decomposed into 2c.1/2c.2/2c.3+4/2c.5
A first dispatch of monolithic Task 2c was refused with a second scope
assessment that surfaced three architectural facts beyond what 2a/2b
had captured:

(d) attn_layer_norm_bwd_dx is a SIMPLIFIED element-wise approximation
    (d_x = d_out * gamma / std), not the full LN Jacobian. Reusing
    it in the GRN backward would propagate the approximation into
    trunk gradients silently. Task 2c.1 must write a new full
    Jacobian: (1/D) * rstd * (D * d_out_g - sum_d(d_out_g) -
    normed * sum_d(d_out_g * normed)).

(e) IQN target-trunk migration is not a clean swap. iqn_compute_
    target_h_s2 reproduces the legacy LeakyReLU trunk independently
    in CUDA. Deleting it requires a target_encoder_forward_only
    extraction on the target path (Task 4-style refactor on the
    target side). Sub-task in itself.

(f) Three relu_mask removal sites have three different save-buffer
    lifetimes (online trunk per-step, IQN-aux per-step in different
    trainer, target-sync per-target-update). Three plumbing tasks,
    not one.

Decomposition:
- 2c.1: grn_kernel.cu with full LN Jacobian backward + GLU + ELU +
  residual-add. Module compiles standalone (additive, dead code).
- 2c.2: gpu_grn.rs Rust wrapper with 5 save-for-backward state
  buffers per block (not 3 as the prior plan suggested).
- 2c.3+4: ATOMIC commit — compute_param_sizes 86→95 + fingerprint
  rewrite + xavier init for 13 new tensors + all 98 padded_byte_
  offset migrations + 3 relu_mask sites with different save-buffer
  plumbing each + iqn target trunk delete + target_encoder_forward_
  only + mag_concat RMS-match adaptive ISV.
- 2c.5: docs flip.

No code changes. Plan-doc only.
2026-04-25 11:53:10 +02:00
jgrusewski
c0d3d7b2ff plan(dqn-v2): Plan 4 Task 2 GRN — decomposed into 2a/2b/2c with reality checks
After a first dispatch attempt of monolithic Task 2 (GRN ADOPT) was
correctly refused with a thorough scope assessment, this revision
records the decomposition and the structural facts that drove it:

1. layout_fingerprint_seed() only fingerprints ISV slots, not
   param-tensor layout. The "fingerprint will auto-update" assumption
   in the original Task 2 spec was wrong for param-tensor reshuffles.
2. compute_param_sizes has 86 tensors (docstring saying 42 is stale).
   Inserting GRN's 9 sub-tensors shifts 82 downstream tensors and
   98 padded_byte_offset call sites.
3. At least 12 kernels consume h_s2 expecting ReLU non-negativity.
   GRN's LayerNorm output is zero-mean (signed). Per-consumer
   verification needed before swap.
4. crates/ml-supervised::tft::gated_residual is incompatible as a
   port: different formula (sigmoid gate, not GLU split) and
   incompatible tensor abstraction. New CUDA kernels from scratch.

Decomposition:
- Task 2a (research, no code): audit h_s2 consumers for ReLU vs
  LayerNorm semantics. Output: per-consumer table.
- Task 2b (small, checkpoint break): extend fingerprint seed to
  include param-tensor names + sizes. Pearl-aligned: complete
  fingerprint coverage rather than partial.
- Task 2c (large, checkpoint break): GRN kernels + 98 call-site
  migration + h_s2 consumer shims (per 2a). Blocked on 2a+2b.

Recommended order updated to thread 2a → 2b → 2c. Tasks 1, 6, 3
remain independent of 2c and can land in parallel where useful.
Pearl rules section added documenting the safety constraints
applied throughout the plan.

No code changes. Plan-doc only.
2026-04-25 11:11:13 +02:00
jgrusewski
fab7758916 plan(dqn-v2): Plan 4 full-scope reality reconciliation
Comprehensive revision to match landed Plan 1+2+3 codebase state. Pattern
mirrors the Plan 3 second revision: per-task "Reality reconciliation"
blocks at the top of each task body identifying what's stale vs. landed,
with concrete file paths in the actual cuda_pipeline tree.

Added:
- Task dependency graph with recommended execution order:
  5 (light ISV) → 4 (refactor) → 2 (GRN ADOPT) → 1 (Full VSN) →
  6 (aux heads) → 3 (multi-Q IQN) → 7 (audit) → 8 (Argo)
- Per-task implementation surface with concrete trunk hooks:
  - Task 1: pre-h_s1 VSN gate in batched_forward.rs::forward_online_raw
  - Task 2: GRN audit confirms ADOPT branch (GRN absent from DQN trunk;
    only in ml-supervised TFT). Replaces h_s1/h_s2 Linear blocks.
  - Task 3: re-scoped — IQN already runs num_quantiles=32 with random τ.
    Task is CONSTRAINING to fixed τ ∈ {.05, .25, .5, .75, .95}.
  - Task 4: pure Rust API split (no kernel changes, no checkpoint break)
    around existing forward_online_raw structure
  - Task 5: split into Mode A (light, pre-Task-1, 3 ISV slots) and
    Mode B (full, post-Task-1, 7 ISV slots). Mode A recommended first.
  - Task 6: aux head loss scaled by ISV[LEARNING_HEALTH] per pearl
- Checkpoint-break consolidation note: Tasks 2/1/6/3 each break checkpoint
  compatibility; land in sequence with no Argo run between (one fingerprint
  shift per commit; final Argo at Task 8 amortizes retraining cost)
- Task 8 absorbs Plan 3's deferred Argo Tier 1 gate (combined validation)

No code changes.
2026-04-25 09:30:09 +02:00
jgrusewski
3bfbcd7137 plan(dqn-v2): Plan 4 reality reconciliation
Plan 4 was drafted 2026-04-24 against an earlier Plan 3 design. After
Plan 3 landed (commits 44539d8f4..3cb083f18), the pre-plan gate
referenced slot names that don't exist in the landed implementation:

- PLAN_PARAMS_0_EMA_INDEX → became READINESS_EMA_INDEX (Task 4)
- STATE_KL_THRESHOLD_EMA_INDEX → eliminated; Task 7 uses kernel-internal
  trailing-EMA-of-self pattern (no separate threshold slot)
- TEMPORAL_REWARD_{PERSIST,REGIME_SHIFT,CONSISTENCY}_EMA_INDEX → consolidated
  into rc[5] → ISV[68] REWARD_BONUS_EMA_INDEX via Plan 3 Task 6a/6b/6c

Updated:
- Pre-plan slot-existence check matches landed slot names
- Validation-doc gate softened: Plan 3 Argo Tier 1 PASS becomes OPTIONAL;
  local 5-epoch multi-fold smoke is the de-facto gate (user choice
  to proceed without burning Argo cycles)
- Status table at top shows landed Plan 3 baseline (ISV_TOTAL_DIM=87,
  PS_STRIDE=43, fingerprint at [85,86]) and per-task difficulty estimate
- Reality-reconciliation note documents the rename trail

No task body changes; subsequent commits will revise individual task
specs as they become next-up for execution.
2026-04-25 09:21:36 +02:00
jgrusewski
e1626876af plan(dqn-v2): mark Tasks 8+9 LANDED; 11/12 done 2026-04-25 09:15:43 +02:00
jgrusewski
0c48dc7192 plan(dqn-v2): mark Task 7 LANDED 2026-04-25 02:26:39 +02:00
jgrusewski
aa8e6f8ec1 plan(dqn-v2): mark Task 4 LANDED 2026-04-25 01:36:24 +02:00
jgrusewski
3af2c79def plan(dqn-v2): mark Task 6c LANDED 2026-04-25 01:11:04 +02:00