plan(crt-a): remove fallbacks — greenfields, resolve properly
Per user direction: no fallbacks, greenfields, kernel updates acceptable.
Changes:
1. Task A0.5 ADDED — pre-planned task that fires if A0 investigation
finds forward_only is stateless K-window (Case 2) or has periodic
reset (Case 3). Refactors PerceptionTrainer to maintain persistent
SSM state and expose forward_step(snapshot, b) that advances by 1
event. Bit-identical to forward_only of equivalent window per a
new golden test in incremental_forward.rs.
This is NOT a fallback — it's a pre-planned task whose execution
is determined by actual investigation outcome. Case 1 → A0.5 is
a no-op. Case 2 or 3 → A0.5 fires in full. Either way the plan
proceeds without user-approval pause.
2. Task A2 reframed — Wiener-α conviction-EMA is a "load-bearing
component of continuous control," not a "minimal Phase B subset."
Without smoothing, event-rate trading is structurally incoherent.
3. Task A2 test fallback REMOVED — instead of "if helpers don't
exist, omit the unit test," the plan now says "add the helpers
properly to the public API." Step 1 audits the LobSimCuda public
API and adds missing accessors. Greenfields — accessors stay on
the API permanently if testing needs them.
4. Task A5 (conditional hyperactivity mitigation) DELETED. A2 is
designed correctly the first time with Wiener-α floor at 0.4. If
A4 cluster smoke shows hyperactivity, that's an A2 bug to fix
properly, not a tuning knob to nudge.
5. Scope contract updated — Phase A vs Phase B split is by code-path
responsibility (continuous control infrastructure vs multi-horizon
signal-driven policy), NOT by "shipping less to be safe."
6. Notes for the Implementer — explicit "No fallbacks" section
replaces the implicit-fallback language. STOP-and-notify-user for
Case 2 deleted (A0.5 handles it inline).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,18 +17,21 @@
|
||||
## Scope contract
|
||||
|
||||
**In scope (Phase A):**
|
||||
- Investigate `forward_only` cost model
|
||||
- Investigate `forward_only` cost model (Task A0)
|
||||
- If investigation reveals `forward_only` doesn't support incremental state advance, **refactor it to do so** (Task A0.5). Kernel changes acceptable — greenfields.
|
||||
- Remove `decision_stride` field (greenfields atomic) per spec §3.3 + §8
|
||||
- Remove stride gate from `BacktestHarness::run`
|
||||
- Minimal anti-hyperactivity smoothing (conviction-EMA in controller — small subset of spec §4.2 that ships now to keep Gate 1 measurable)
|
||||
- Wiener-α conviction-EMA smoothing — a load-bearing component of continuous control, not a hedge. Without smoothing, event-rate trading is incoherent (alpha jitters → target oscillates → spread bleed). Spec §4.2's EMA formula ships in Phase A.
|
||||
- Cluster smoke validation against Gate 1 acceptance criteria
|
||||
|
||||
**Out of scope (deferred to Phase B/C/D plans):**
|
||||
- Full multi-horizon conviction formula (spec §4.4 — only the EMA smoothing of the existing scalar conviction is in Phase A)
|
||||
- Conviction-degradation exit (spec §4.3)
|
||||
- Adaptive envelope/threshold/vol-target (spec §5)
|
||||
- Online weight adaptation (spec §6)
|
||||
- `open_trade_state` 24→64 byte expansion (spec §7)
|
||||
**Out of scope (deferred to Phase B):**
|
||||
- Full multi-horizon conviction *formula* — spec §4.4's per-horizon ISV-weighted aggregation. Phase A uses the existing scalar max-conviction-across-horizons as the EMA input; Phase B replaces the scalar with the proper multi-horizon weighted aggregation.
|
||||
- Conviction-degradation composite exit (spec §4.3)
|
||||
- `open_trade_state` 24→64 byte expansion (spec §7) — Phase B introduces the trajectory fields needed by §4.3 exit logic
|
||||
- Adaptive envelope/threshold/vol-target (spec §5) — Phase C
|
||||
- Online weight adaptation (spec §6) — Phase D
|
||||
|
||||
**Distinction**: Phase A ships the *continuous control loop* with proper smoothing on the existing scalar conviction. Phase B ships the *multi-horizon signal-driven policy* that the spec describes — that's a different code path that consumes the smoothed conviction differently. The split is by code-path responsibility, not by "shipping less to be safe."
|
||||
|
||||
---
|
||||
|
||||
@@ -97,10 +100,10 @@ Create `docs/superpowers/memos/2026-05-20-crt-a-forward-cost-investigation.md` w
|
||||
- Which case (1/2/3) applies
|
||||
- The relevant files and key functions
|
||||
- Estimated cost ratio
|
||||
- Recommended Phase A implementation path:
|
||||
- **If Case 1:** simple — Phase A just removes the stride gate. Cost target ≤ 2× should hold.
|
||||
- **If Case 2:** Phase A needs `forward_only_incremental` first (advance trunk state by 1 step using cached prior state). This becomes Task A1.5 added to this plan.
|
||||
- **If Case 3:** Phase A needs to relax cost target OR add state caching. Recommend approach.
|
||||
- The required work to make Phase A feasible at ≤ 2× wall-time:
|
||||
- **Case 1** (stateful, incremental): no extra work. Proceed to Task A1.
|
||||
- **Case 2** (stateless K-window): Task A0.5 fires — refactor `forward_only` to maintain persistent SSM state, expose `forward_step` that advances state by 1 event. Kernel changes acceptable.
|
||||
- **Case 3** (stateful with periodic reset): Task A0.5 fires — remove or extend the reset interval to support continuous operation. Document the new state model.
|
||||
|
||||
- [ ] **Step 5: Commit the memo**
|
||||
|
||||
@@ -109,7 +112,103 @@ git add docs/superpowers/memos/2026-05-20-crt-a-forward-cost-investigation.md
|
||||
git commit -m "memo(crt-a): forward pass cost investigation — chose [Case 1/2/3]"
|
||||
```
|
||||
|
||||
**Stop condition:** If the memo recommends adding `forward_only_incremental` (Case 2), pause and notify the user — they should approve the scope expansion before proceeding. If Case 1 or Case 3-with-trivial-mitigation, proceed to Task A1.
|
||||
The next task fires based on outcome: Case 1 → skip to A1 (A0.5 is a no-op); Case 2 or 3 → execute A0.5 in full.
|
||||
|
||||
---
|
||||
|
||||
### Task A0.5: Refactor `forward_only` for incremental state advance (fires if A0 finds Case 2 or 3)
|
||||
|
||||
This task is pre-planned, not a fallback. If Task A0's memo concludes Case 1, A0.5 is a no-op (proceed to A1). If Case 2 or 3, A0.5 ships the refactor.
|
||||
|
||||
**Files (filled in based on A0 memo):**
|
||||
- Modify: `crates/ml-perception-trainer/src/lib.rs` (or wherever `PerceptionTrainer` lives) — add `forward_step` method that takes the prior SSM state and advances by 1 snapshot
|
||||
- Modify: trunk forward kernels (`crates/ml-alpha/cuda/*.cu` for Mamba2/Cfc) — add per-event step kernel if missing
|
||||
- Modify: `crates/ml-backtesting/src/harness.rs` — replace `forward_only(&window)` call with `forward_step(&snapshot, prev_state)`
|
||||
- Modify: relevant test fixtures and golden-state checks
|
||||
|
||||
- [ ] **Step 1: Write a failing test that asserts `forward_step` produces bit-identical output to `forward_only` of the equivalent window**
|
||||
|
||||
The test should run a 100-event sequence two ways:
|
||||
- Way A: call `forward_only` once on the full 100-event window
|
||||
- Way B: call `forward_step` 100 times, threading state
|
||||
|
||||
Assert: way A's last position == way B's final output, bit-identical (per `pearl_temporal_encoder_must_train` style golden-state check).
|
||||
|
||||
Add to `crates/ml-perception-trainer/tests/incremental_forward.rs` (create file).
|
||||
|
||||
```bash
|
||||
SQLX_OFFLINE=true cargo test -p ml-perception-trainer --test incremental_forward 2>&1 | tail -10
|
||||
```
|
||||
|
||||
Expected: FAIL (`forward_step` doesn't exist yet).
|
||||
|
||||
- [ ] **Step 2: Add persistent SSM state to `PerceptionTrainer`**
|
||||
|
||||
Add fields to hold per-backtest SSM state across calls (Mamba2 state is per-layer × per-channel). Allocate matching the trunk's hidden dim.
|
||||
|
||||
- [ ] **Step 3: Implement `forward_step`**
|
||||
|
||||
```rust
|
||||
pub fn forward_step(
|
||||
&mut self,
|
||||
snapshot: &Mbp10RawInput,
|
||||
backtest_idx: usize,
|
||||
) -> Result<[f32; N_HORIZONS]> {
|
||||
// Advance the persistent SSM state by 1 event for this backtest.
|
||||
// Returns the alpha probabilities for the new state.
|
||||
// Uses the same kernels as forward_only but reads/writes the
|
||||
// persistent state slot instead of recomputing from a window.
|
||||
}
|
||||
```
|
||||
|
||||
If the trunk kernels currently process a K-window in one launch, refactor to a per-step kernel (block-per-backtest, one thread sequentially advancing through the layers' SSM state). Reference Mamba2 step-wise inference patterns.
|
||||
|
||||
- [ ] **Step 4: Run the test from Step 1, confirm bit-identical**
|
||||
|
||||
```bash
|
||||
SQLX_OFFLINE=true cargo test -p ml-perception-trainer --test incremental_forward 2>&1 | tail -10
|
||||
```
|
||||
|
||||
Expected: PASS. If not bit-identical, the per-step kernel has a state-management bug — fix before proceeding.
|
||||
|
||||
- [ ] **Step 5: Update harness to use `forward_step`**
|
||||
|
||||
In `crates/ml-backtesting/src/harness.rs:244`: replace `self.trainer.forward_only(&window)` with `self.trainer.forward_step(&raw, 0)` (since `n_parallel=1` in the smoke; for batched runs the per-backtest indexing applies).
|
||||
|
||||
Remove the `snapshot_window` buffer if no longer needed (the SSM state IS the window memory).
|
||||
|
||||
- [ ] **Step 6: Run smoke tests + existing test suite**
|
||||
|
||||
```bash
|
||||
SQLX_OFFLINE=true cargo test -p ml-backtesting --test stop_controller -- --ignored --nocapture 2>&1 | tail -10
|
||||
SQLX_OFFLINE=true cargo test -p ml-perception-trainer 2>&1 | tail -10
|
||||
```
|
||||
|
||||
Expected: all pass.
|
||||
|
||||
- [ ] **Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "$(cat <<'EOF'
|
||||
arch(crt-a): forward_step incremental state advance — enables event-rate forward
|
||||
|
||||
Per Task A0 cost investigation memo: forward_only was [Case 2/3] —
|
||||
[reason]. Refactored PerceptionTrainer to maintain persistent SSM
|
||||
state per backtest and expose forward_step(snapshot, backtest_idx)
|
||||
that advances state by 1 event. Bit-identical to forward_only of the
|
||||
equivalent window per the new incremental_forward golden test.
|
||||
|
||||
Harness updated to call forward_step every event instead of
|
||||
forward_only at stride boundaries.
|
||||
|
||||
Per-event cost now O(state-dim) rather than O(K-window × state-dim).
|
||||
This is the structural change Phase A's ≤ 2× wall-time target needs.
|
||||
|
||||
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -221,16 +320,29 @@ EOF
|
||||
|
||||
---
|
||||
|
||||
### Task A2: Add conviction-EMA anti-hyperactivity smoothing (minimal Layer B subset)
|
||||
### Task A2: Wiener-α conviction-EMA smoothing in `decision_policy`
|
||||
|
||||
This task ships a SMALL part of spec §4.2 to keep Phase A behaviorally sensible. Without smoothing, removing the stride gate likely produces hyperactive target oscillation as alpha jiggles event-to-event. The full multi-horizon conviction formula is Phase B — this task implements ONLY the scalar conviction EMA on whatever the controller currently uses (typically max conviction across horizons).
|
||||
This task ships the Wiener-α EMA from spec §4.2 applied to scalar `max_conviction_across_horizons`. The EMA is a **load-bearing component** of continuous control — without it, event-rate trading is structurally incoherent (alpha jitters event-to-event → target oscillates → spread bleed). The full multi-horizon conviction *aggregation* (spec §4.4) is Phase B because it requires per-horizon ISV state plumbing in the kernel; the *smoothing operator itself* (Wiener-α EMA with floor) is identical regardless of what scalar conviction feeds it.
|
||||
|
||||
**Files:**
|
||||
- Modify: `crates/ml-backtesting/cuda/decision_policy.cu` (`decision_policy_default` and/or `decision_policy_program`)
|
||||
- Modify: `crates/ml-backtesting/src/sim/mod.rs` (add `conviction_ema_d: CudaSlice<f32>` field, alloc, thread into decision launches)
|
||||
- Modify: `crates/ml-backtesting/tests/stop_controller.rs` (add test)
|
||||
|
||||
- [ ] **Step 1: Write failing test for the EMA smoothing**
|
||||
- [ ] **Step 1: Audit `LobSimCuda` public API for required test helpers**
|
||||
|
||||
Required helpers for the test in Step 2:
|
||||
- `broadcast_alpha(&[f32; N_HORIZONS]) -> Result<()>` — already exists per harness.rs:261
|
||||
- `step_decision_with_latency(ts_ns, &sim_config) -> Result<()>` — already exists per harness.rs:262
|
||||
- `read_market_target(b: usize) -> Result<(i32, i32)>` — **must exist for this test**. If missing, add it (it's a thin wrapper over `memcpy_dtoh` on `market_targets_d`). Per [feedback_no_quickfixes](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/feedback_no_quickfixes.md): write the helper properly.
|
||||
|
||||
```bash
|
||||
grep -n "pub fn read_market_target\|pub fn broadcast_alpha\|pub fn step_decision_with_latency" crates/ml-backtesting/src/sim/mod.rs
|
||||
```
|
||||
|
||||
For each missing helper, add it in `crates/ml-backtesting/src/sim/mod.rs` following the pattern of existing `read_*` accessors. Commit-included with this task; no separate task. Greenfields — if the API needs an accessor for testing, the accessor lives on the public API permanently.
|
||||
|
||||
- [ ] **Step 2: Write failing test for the EMA smoothing**
|
||||
|
||||
Append to `crates/ml-backtesting/tests/stop_controller.rs`:
|
||||
|
||||
@@ -238,51 +350,51 @@ Append to `crates/ml-backtesting/tests/stop_controller.rs`:
|
||||
#[test]
|
||||
#[ignore = "requires CUDA"]
|
||||
fn conviction_ema_smooths_micro_oscillations() -> Result<()> {
|
||||
use ml_backtesting::sim::test_helpers::minimal_batched_sim_config;
|
||||
let dev = match MlDevice::cuda(0) {
|
||||
Ok(d) => d,
|
||||
Err(e) => { eprintln!("skipping: cuda unavailable ({e})"); return Ok(()); }
|
||||
};
|
||||
let mut sim = LobSimCuda::new(1, &dev)?;
|
||||
sim.upload_price_range(&[1000.0], &[20000.0])?;
|
||||
let sim_config = minimal_batched_sim_config(1); // helper added in Step 1 if missing
|
||||
|
||||
// Drive 10 alternating high/low convictions. Without EMA, target lots
|
||||
// would oscillate. With EMA (Wiener-α floor = 0.4), target should
|
||||
// damp toward the mean of the two.
|
||||
let alphas_high = [0.8_f32, 0.8, 0.8, 0.8]; // strongly bullish all horizons
|
||||
let alphas_low = [0.55_f32, 0.55, 0.55, 0.55]; // weakly bullish
|
||||
let alphas_high: [f32; N_HORIZONS] = [0.8; N_HORIZONS]; // strongly bullish all horizons
|
||||
let alphas_low: [f32; N_HORIZONS] = [0.55; N_HORIZONS]; // weakly bullish
|
||||
|
||||
let mut prev_target: Option<i32> = None;
|
||||
let mut prev_target_signed: Option<i32> = None;
|
||||
let mut flips = 0;
|
||||
|
||||
for i in 0..10 {
|
||||
let probs = if i % 2 == 0 { alphas_high } else { alphas_low };
|
||||
sim.broadcast_alpha(&probs)?;
|
||||
sim.step_decision_with_latency(1_000_000_000u64 * (i + 1) as u64, &/*sim_config*/test_sim_config())?;
|
||||
let target = sim.read_market_target(0)?;
|
||||
if let Some(p) = prev_target {
|
||||
if (target > 0) != (p > 0) && target != 0 && p != 0 { flips += 1; }
|
||||
sim.step_decision_with_latency(1_000_000_000u64 * (i + 1) as u64, &sim_config)?;
|
||||
let (side, size) = sim.read_market_target(0)?;
|
||||
let target_signed = if side == 0 { size } else if side == 1 { -size } else { 0 };
|
||||
if let Some(p) = prev_target_signed {
|
||||
if (target_signed > 0) != (p > 0) && target_signed != 0 && p != 0 {
|
||||
flips += 1;
|
||||
}
|
||||
}
|
||||
prev_target = Some(target);
|
||||
prev_target_signed = Some(target_signed);
|
||||
}
|
||||
// With Wiener-α floor 0.4, EMA on alternating high/low produces a
|
||||
// smooth trajectory — flip count should be 0 or 1, NOT 10.
|
||||
assert!(flips <= 2, "conviction EMA must smooth oscillations: flips={}", flips);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test_sim_config() -> BatchedSimConfig {
|
||||
// Minimal config for the test. Take from existing helpers if present.
|
||||
todo!("use existing test config helper if available; otherwise hand-build")
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** If existing test helpers like `read_market_target` and config builders aren't present in `LobSimCuda`'s public API, **omit this unit test and rely on the cluster smoke at Task A4 as the validation gate**. Don't invent helpers — that's scope creep.
|
||||
If `minimal_batched_sim_config` helper doesn't exist in a `test_helpers` module, add it in `crates/ml-backtesting/src/sim/mod.rs` under `#[cfg(test)] pub mod test_helpers { ... }` (or expose unconditionally if the existing convention does — match what the codebase already does).
|
||||
|
||||
```bash
|
||||
SQLX_OFFLINE=true cargo test -p ml-backtesting --test stop_controller conviction_ema_smooths_micro_oscillations -- --ignored --nocapture 2>&1 | tail -10
|
||||
```
|
||||
|
||||
Expected (if test exists): FAIL with "conviction EMA must smooth oscillations".
|
||||
Expected: FAIL with "conviction EMA must smooth oscillations".
|
||||
|
||||
- [ ] **Step 2: Add `conviction_ema_d` device slot in `LobSimCuda`**
|
||||
|
||||
@@ -599,63 +711,29 @@ Confirm clean state. Phase A complete.
|
||||
|
||||
---
|
||||
|
||||
### Task A5: Hyperactivity mitigation (conditional — only if Gate 1 reveals churn)
|
||||
|
||||
This task fires ONLY if Step 8 detects hyperactivity (trade count balloon, e.g., > 2× baseline, despite Sharpe staying within ±15%).
|
||||
|
||||
**Files:**
|
||||
- Modify: `crates/ml-backtesting/cuda/decision_policy.cu` (tighten EMA α floor OR add hysteresis on target deltas)
|
||||
|
||||
- [ ] **Step 1: Quantify hyperactivity**
|
||||
|
||||
Pull the trade CSV. Compare:
|
||||
- Mean trade hold time (should be similar to baseline — small or matches max_hold setting)
|
||||
- Trade count distribution (per-hour, per-day)
|
||||
- Fees paid (proportional to round-trip count)
|
||||
|
||||
- [ ] **Step 2: Choose mitigation**
|
||||
|
||||
Two options:
|
||||
|
||||
**Option A** (preferred if minor): raise the Wiener-α floor from 0.4 to 0.6 in §4.2's `alpha_active = fmaxf(alpha_raw, 0.6f);`. Damps further. Lower responsiveness.
|
||||
|
||||
**Option B** (stronger): add target-delta hysteresis in `seed_inflight_limits_batched`. Don't seed a new order unless `|new_target − effective_position| ≥ delta_floor` where delta_floor is e.g. 0.3 lots (rounded). Skips micro-rebalances.
|
||||
|
||||
- [ ] **Step 3: Apply mitigation, re-test, re-validate Gate 1**
|
||||
|
||||
Follow A4 steps with the chosen mitigation. If Gate 1 passes after mitigation, document the chosen value as a tuned constant in the spec amendment (acknowledge as tuned, not derived — pearl_adaptive_not_tuned says "fixes are signal-driven not tuned constants" so any tuned floor should be a temporary stopgap with a follow-up to make it ISV-derived).
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
If mitigation chosen:
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "fix(crt-a): tighten conviction-EMA floor 0.4→0.6 — mitigates hyperactivity seen in [smoke]"
|
||||
```
|
||||
|
||||
If mitigation NOT needed (hyperactivity wasn't a real problem), no commit — leave task A5 as documentation that it was considered and ruled out.
|
||||
|
||||
---
|
||||
|
||||
## Notes for the Implementer
|
||||
|
||||
- **TDD discipline.** Each task starts with a failing test where possible (Tasks A2, A5 explicitly do); Tasks A0 and A1 are refactor/research and don't fit the failing-test mold. Per [feedback_no_quickfixes](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/feedback_no_quickfixes.md) — every issue gets a proper fix; tests where a test makes sense.
|
||||
- **TDD discipline.** Tasks A0.5 and A2 start with failing tests. A0 is read-only research. A1 is refactor (existing tests stay green). A3/A4 are verification.
|
||||
|
||||
- **Each task is one commit.** No mid-task commits.
|
||||
|
||||
- **Greenfields atomic refactor (Task A1).** Every `decision_stride` consumer migrates in one commit per [feedback_no_partial_refactor](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/feedback_no_partial_refactor.md). Don't leave a "compat" branch around.
|
||||
|
||||
- **No fallbacks.** Greenfields means we resolve properly:
|
||||
- Missing test helpers → add them to the public API (Task A2 Step 1).
|
||||
- Forward pass is stateless → refactor it to be stateful (Task A0.5).
|
||||
- Kernel changes needed → make them. Spec §3.3 already accepts kernel-signature changes.
|
||||
|
||||
- **Pearl conformance:**
|
||||
- Task A2 uses [pearl_wiener_optimal_adaptive_alpha](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/pearl_wiener_optimal_adaptive_alpha.md) and [pearl_wiener_alpha_floor_for_nonstationary](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/pearl_wiener_alpha_floor_for_nonstationary.md).
|
||||
- Task A2 uses [pearl_first_observation_bootstrap](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/pearl_first_observation_bootstrap.md) for EMA init.
|
||||
- Task A1 follows [feedback_no_legacy_aliases](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/feedback_no_legacy_aliases.md) — no compat shim.
|
||||
- Task A4 follows [feedback_push_before_deploy](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/feedback_push_before_deploy.md).
|
||||
- Task A0.5 reference golden-state pattern from [pearl_temporal_encoder_must_train](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/pearl_temporal_encoder_must_train.md) for bit-identical incremental-vs-window test.
|
||||
|
||||
- **Local GPU is RTX 3050 Ti 4GB** ([user_dev_environment](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/user_dev_environment.md)) — may not be able to run the full smoke locally; cluster smoke at Task A4 is the real validation.
|
||||
- **Local GPU is RTX 3050 Ti 4GB** ([user_dev_environment](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/user_dev_environment.md)) — may not be able to run the full smoke locally; cluster smoke at Task A4 is the real validation. This is a hardware constraint, not a fallback.
|
||||
|
||||
- **If Task A0 returns Case 2 (`forward_only` is stateless K-window per call):** STOP and notify the user. This expands Phase A scope significantly (need `forward_only_incremental` first). Don't proceed without explicit approval.
|
||||
|
||||
- **If Task A4 Gate 1 fails:** apply [feedback_stop_on_anomaly](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/feedback_stop_on_anomaly.md) — terminate, diagnose, fix, re-run. Use SP20/SP21-style per-event instrumentation if needed. Do NOT advance to Phase B with a red Gate 1.
|
||||
- **If Task A4 Gate 1 fails:** apply [feedback_stop_on_anomaly](../../../../home/jgrusewski/.claude/projects/-home-jgrusewski-Work-foxhunt/memory/feedback_stop_on_anomaly.md) — terminate, diagnose, fix root cause, re-run. Use SP20/SP21-style per-event instrumentation if needed. Do NOT advance to Phase B with a red Gate 1. Root-cause investigation is not a fallback — it's the correct response to a failed validation.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user