feat(sp18 v2 P1.T1+T2): pre-dispatch consumer-audit script + pre-commit hook
Phase 1 Tasks 1.1 + 1.2 of docs/superpowers/plans/2026-05-08-sp18-reward-shape-hold-attractor.md.
Per the plan's audit-first design: surface every live reference to the
SP13/SP16 Hold-cost-scale chain (D-leg) and the TD(λ) `q_next = rewards`
self-bootstrap (B-leg) BEFORE atomic deletion. This catches the SP17-style
"missed quantile_q_select consumer" failure mode where a sweeping refactor
left a dangling reference that compiled but broke at runtime.
What lands
- `scripts/audit_sp18_consumers.sh` — 17-section grep that walks every
consumer pattern from the plan's locked checklist (D-leg slot 380,
461, [462..468) HCS_*, hold_cost_scale_update kernel, hold_rate_observer
kernel retained chain, build.rs cubin manifest, state_layout.cuh
mirror constants, state_reset_registry entries, plus B-leg
td_lambda_kernel launch sites, q_next origin, rewards_out consumers,
PER priority sites, replay buffer schema, c51_loss target-Q origin,
target_params_buf consumers, PopArt slot 63 references). Three modes:
default (full grep output), `--fingerprint` (per-section per-file hit
count for diff-able snapshots), `--check` (diff fingerprint vs locked
snapshot in docs/sp18-wireup-audit.md, exit 1 on drift).
- `docs/sp18-wireup-audit.md` — Phase 1 Task 1.1 outcome with two
sections of import:
1. The plan's locked checklist (8 entries the plan author explicitly
identified as deletion targets).
2. The 10 ADDITIONAL CONSUMERS surfaced by the audit (A1-A10) that
the plan-author missed. Per the task input's halt-on-drift
directive, Phase 1 Tasks 1.3-1.5 (atomic deletion) are HALTED
pending human review of the expanded scope. The audit doc is the
spec-amendment record.
3. A locked fingerprint snapshot the pre-commit hook uses for drift
detection on subsequent commits.
B-leg verification confirms B-DD4 (no PER migration) + B-DD1 (target_
params_buf reusable) + the single q_next bootstrap site at
gpu_experience_collector.rs:4143.
- `scripts/pre-commit-hook.sh` — Invariant 7 list extended with the new
audit doc; new `check_sp18_consumer_audit` step runs the audit script
in `--check` mode whenever a commit touches the chain files
(experience_kernels.cu, hold_*_kernel.cu, state_layout.cuh, sp1[3-8]_
isv_slots.rs, gpu_dqn_trainer.rs, gpu_aux_trunk.rs, gpu_experience_
collector.rs, state_reset_registry.rs, training_loop.rs, build.rs,
sp1[3-8]_oracle_tests.rs). Drift triggers a hook failure with a
pointer to the regeneration command. This is a generalisation of
Invariant 7 and addresses Open Q-B from the spec (audit-as-pre-commit
hook for SP-chain consumer drift).
Findings (HALT trigger)
The audit found 10 consumers NOT in the plan's locked 8-site checklist:
A1 — gpu_aux_trunk.rs:1240-1323 HoldCostScaleUpdateOps struct + impl
(84 lines; the plan said launcher was in gpu_dqn_trainer but the
real struct/impl lives in gpu_aux_trunk; trainer just has a thin
forwarding method)
A2 — sp14_oracle_tests.rs:2174-2920 11 GPU oracle tests (~750 lines)
directly exercising the deleted kernel via include_bytes!
(sp16_phase2_hold_cost_scale_climbs_with_overrun + 10 others)
A3 — training_loop.rs:8971-9043 7 dispatch arms in reset_named_state
(slot 461 + HCS_* slots 462-467); contract test
every_fold_and_soft_reset_entry_has_dispatch_arm requires
atomic deletion alongside registry entries
A4 — gpu_dqn_trainer.rs:23200-23216 constructor block writing
HOLD_COST_BASE to slot 380 (RETAINED per DD7c, comment requires
update)
A5 — gpu_dqn_trainer.rs:617, 2245-2256 doc-block prose
A6 — sp13_isv_slots.rs:75-77 HOLD_COST_CONTROLLER_GAIN/FLOOR/CEIL
constants (HOLD_COST_BASE retained for A4)
A7 — gpu_experience_collector.rs:5579-5585 stale comment doc-ref
A8 — sp5_isv_slots.rs:325-327 comment doc-ref
A9 — state_reset_registry.rs:1138-1271 7 already-RETIRED entries
promote to FULL DELETION
A10 — state_reset_registry.rs:2256-2308 lock_sp18_v2_pp4_retired_chain
contract test asserts retired entries STILL EXIST; must be
deleted/rewritten when entries are removed
None of these are architectural surprises — they're straight extensions
of the atomic-deletion scope. But per the task input's halt-on-drift
directive ("If your audit surfaces ANY additional consumer, halt and
report — do NOT proceed with deletion ad-hoc"), Phase 1 Tasks 1.3-1.5
HALT pending human sign-off on the expanded scope.
Path forward (next phase)
Either expand the atomic-deletion commit scope to cover all 18 sites
(8 plan + 10 audit-surfaced) — recommended per `feedback_no_partial_
refactor`; the audit doc serves as the spec-amendment record — or
human-review the audit doc and explicitly approve/reject each A* entry.
The audit doc + script + hook are the pre-condition for either path
and ship together as Tasks 1.1 + 1.2 of Phase 1. Tasks 1.3-1.6 await
human go-ahead.
Branch is at INTERIM STATE: NOT runnable for L40S smoke between this
commit and the post-Phase-1.6 close-out. The interim is purely-additive
(audit script + hook + doc); the actual deletion that creates the
"3 reward sites missing Hold cost" interim from the plan's Task 1.5
has NOT yet been performed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
238
docs/sp18-wireup-audit.md
Normal file
238
docs/sp18-wireup-audit.md
Normal file
@@ -0,0 +1,238 @@
|
||||
# SP18 Combined-Scope Wire-Up Audit
|
||||
|
||||
> Audit captured during Phase 1 Task 1.1 of `docs/superpowers/plans/2026-05-08-sp18-reward-shape-hold-attractor.md`.
|
||||
>
|
||||
> **Branch**: `feat/sp18-combined` @ `0b737ec30` (Phase 0 baseline, pre-Phase-1 atomic deletion).
|
||||
>
|
||||
> **Audit script**: `scripts/audit_sp18_consumers.sh`. Re-run after every commit that touches the SP13/SP16 chain (D-leg) or the TD(λ) `q_next` site (B-leg). Pre-commit hook (Task 1.2) enforces snapshot-vs-current diff via `--check`.
|
||||
|
||||
## Outcome of Phase 1 Task 1.1 (audit-first, halt-on-drift)
|
||||
|
||||
The pre-dispatch consumer-audit run surfaced **multiple consumers NOT in the plan's locked checklist** (spec §"Architecture Changes"). Per task input — *"If your audit surfaces ANY additional consumer, halt and report — do NOT proceed with deletion ad-hoc"* — Phase 1 Tasks 1.3-1.5 (atomic deletion) are **HALTED** pending plan / spec amendment.
|
||||
|
||||
### Plan's locked D-leg checklist (8 entries)
|
||||
|
||||
| # | Site | Action |
|
||||
|---|------|--------|
|
||||
| 1 | `experience_kernels.cu:3162-3166, 3637-3643, 3710-3716` (3 cost sites) | DELETE — replace with placeholder comment per Task 1.5 |
|
||||
| 2 | `training_loop.rs:564` (launcher call) + `:631-667` (hold_cost_scale_diag emit) + `:4171-4226` (host controller block) | DELETE launcher + diag emit + controller; RETAIN slot-382 min_hold_temp_diag emit at `:567-617` |
|
||||
| 3 | `crates/ml/src/cuda_pipeline/hold_cost_scale_update_kernel.cu` | DELETE entire file |
|
||||
| 4 | `crates/ml/src/cuda_pipeline/sp14_isv_slots.rs` slots [461..468) (`HOLD_COST_SCALE_INDEX` + `HCS_*` Welford) + their `MIN`/`MAX`/`SENTINEL` constants | DELETE constants + the layout-locked tests for them |
|
||||
| 5 | `crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs` `launch_hold_cost_scale_update` method (line 15837) + `HOLD_COST_SCALE_UPDATE_CUBIN` static (line 2257) + struct field `hold_cost_scale_update_ops` (line 7853) + constructor wiring (lines 24433-24434, 25296) | DELETE all |
|
||||
| 6 | `crates/ml/src/trainers/dqn/state_reset_registry.rs` 7 entries (`sp16_phase2_hold_cost_scale_adaptive` + `sp16_t3_hcs_*` × 6) | DELETE entries |
|
||||
| 7 | `crates/ml/build.rs:881` cubin manifest entry `hold_cost_scale_update_kernel.cu` | DELETE |
|
||||
| 8 | `crates/ml/src/cuda_pipeline/state_layout.cuh:214` (`ISV_HOLD_COST_SCALE_IDX`) + `:228-233` (`ISV_HCS_*` mirror) | DELETE |
|
||||
|
||||
### Additional consumers surfaced by audit (NOT in plan checklist)
|
||||
|
||||
The following consumers must be added to the atomic-deletion commit. They were missed by the plan's spec §"Architecture Changes" and would have left the deletion partial — per `feedback_no_partial_refactor.md` this would block compile or, worse, leave dangling references that compile but break test/integration paths.
|
||||
|
||||
| # | Site | Type | Resolution |
|
||||
|---|------|------|------------|
|
||||
| **A1** | `crates/ml/src/cuda_pipeline/gpu_aux_trunk.rs:1240-1323` — `HoldCostScaleUpdateOps` struct + `impl` (kernel-load + launcher) | **PRODUCER WRAPPER** (Rust-side). The plan said the launcher is in `gpu_dqn_trainer.rs` but actually only the trainer's *thin call site* `launch_hold_cost_scale_update` is there; the real `HoldCostScaleUpdateOps::new`/`launch` impl lives in `gpu_aux_trunk.rs`. | DELETE the struct + impl block (84 lines). DELETE the `HOLD_COST_SCALE_UPDATE_CUBIN` import at `gpu_aux_trunk.rs:56` (transitively unused after the struct is gone). |
|
||||
| **A2** | `crates/ml/tests/sp14_oracle_tests.rs:2174-2920` — 11 GPU oracle tests + the doc-block at the head | **TESTS** (75 occurrences of HOLD_COST_SCALE / HCS_TARGET / hold_cost_scale_update across this file). Tests: `sp16_phase2_hold_cost_scale_climbs_with_overrun`, `sp16_phase2_hold_cost_scale_at_target_is_one`, `sp16_phase2_hold_cost_scale_under_target_is_one`, `sp16_phase2_hold_cost_scale_bounds_clamp`, `sp16_phase2_hold_cost_scale_pearl_a_bootstrap`, `sp16_phase3_alpha_high_during_signal_jump`, `sp16_phase3_alpha_low_in_steady_state`, `sp16_phase3_pearl_a_bootstrap_first_obs`, `sp16_phase3_alpha_naturally_bounded`, `sp16_phase3_no_hardcoded_alpha`, plus the helper `recover_alpha`/`compute_target_scale`/`run_synthetic_sequence` infrastructure (~750 lines). All exercise the now-deleted `hold_cost_scale_update` kernel via `include_bytes!(.../hold_cost_scale_update_kernel.cubin)` — without the kernel they fail to compile. | DELETE the 2 test modules (`sp16_phase2_hold_cost_scale_gpu` + `sp16_t3_hold_cost_scale_alpha_gpu`) and the standalone `sp16_phase3_no_hardcoded_alpha` test. ~750 lines from `sp14_oracle_tests.rs:2174-2920`. |
|
||||
| **A3** | `crates/ml/src/trainers/dqn/trainer/training_loop.rs:8971-9043` — 7 dispatch arms in `reset_named_state` (`"sp16_phase2_hold_cost_scale_adaptive"` + `"sp16_t3_hcs_*"` × 6) | **DISPATCH ARMS**. Required atomically with the registry-entry deletion (Task 1.4 expanded scope) — the contract test `every_fold_and_soft_reset_entry_has_dispatch_arm` (state_reset_registry.rs:2120-2280) fails if the registry has an entry but no dispatch arm OR vice versa. | DELETE the 7 match arms (slot 461 + HCS slots 462-467) atomically with the registry entries. |
|
||||
| **A4** | `crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs:23200-23216` — constructor block writing `HOLD_COST_BASE` to `HOLD_COST_INDEX=380` + `HOLD_RATE_TARGET_DEFAULT` to slot 381 | **CONSTRUCTOR WRITE** of slot 380 (controller output anchor). Per DD7c, slot 380 is RETAINED as part of the observation chain — but it now has no producer. The constructor-write of `HOLD_COST_BASE` keeps it at 0.005 cold-start. After deletion of the host controller, slot 380 becomes a **read-only diagnostic slot** (constructor-init only, no per-step rewrites). | KEEP the constructor-write (DD7c retains slot 380). UPDATE the comment block at lines 23201-23210 to reflect the post-SP18-Phase-1 reality: "After SP18 Phase 1, slot 380 is no longer rewritten by a host-side controller (deleted per DD7=c). The constructor-init is now its only assignment — it serves as a read-only diagnostic anchor surfacing the static base cost. Phase 2 lands the structural Hold opportunity-cost reward at the 3 deleted cost-subtraction sites; that reward does NOT consume slot 380." |
|
||||
| **A5** | `crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs:617, 2245-2256` — doc-block prose referring to deleted machinery | **DOC PROSE**. References `launch_hold_cost_scale_update`, `gpu_aux_trunk::HoldCostScaleUpdateOps`, `isv[461]`, etc. | UPDATE comments to remove deleted-machinery references; replace with "(deleted SP18 Phase 1, DD7=c — see docs/sp18-wireup-audit.md)" pointer. No code change. |
|
||||
| **A6** | `crates/ml/src/cuda_pipeline/sp13_isv_slots.rs:73-77` — `HOLD_COST_BASE`, `HOLD_COST_CONTROLLER_GAIN`, `HOLD_COST_FLOOR_RATIO`, `HOLD_COST_CEIL_RATIO` constants | **HOST-CONTROLLER CONSTANTS**. Used ONLY by the host controller block at `training_loop.rs:4213-4223` we're deleting. Per the SP13 v3 P0a comment block at `sp13_isv_slots.rs:50-72`, `HOLD_COST_BASE` is also used by the constructor-write at `gpu_dqn_trainer.rs:23215`. | KEEP `HOLD_COST_BASE` (consumed by constructor-init at A4 — slot 380 retained). DELETE `HOLD_COST_CONTROLLER_GAIN`, `HOLD_COST_FLOOR_RATIO`, `HOLD_COST_CEIL_RATIO` (sole consumer is the deleted controller block). |
|
||||
| **A7** | `crates/ml/src/cuda_pipeline/gpu_experience_collector.rs:5579-5585` — comment doc-ref to deleted controller | **COMMENT DOC-REF**. References `training_loop.rs:3604` (stale line — now `:4209`) and the priced-cost flow. | UPDATE prose to reflect post-Phase-1 reality. |
|
||||
| **A8** | `crates/ml/src/cuda_pipeline/sp5_isv_slots.rs:325-327` — comment doc-ref describing the controller chain | **COMMENT DOC-REF**. Documents slot 380/381/382. Slots 381 + 382 retained per DD7c; slot 380 retained but no longer controller-written. | UPDATE prose to reflect post-Phase-1 reality. |
|
||||
| **A9** | `crates/ml/src/cuda_pipeline/state_reset_registry.rs:1138-1271` — registry entries already marked RETIRED in PP.4 (commit c66e15f6d) for slots 461 + 462-467 | **REGISTRY ENTRIES**. Already marked RETIRED in Pre-Phase PP.4. Phase 1 promotes RETIRED-with-sentinel-0.0-write to FULL DELETION. | DELETE the 7 entries (slot 461 + HCS slots 462-467) from the registry; layout fingerprint must be updated atomically — the fingerprint seed string covers slot allocations [461..468) which become RESERVED-gap (SP14-C.1 pattern). Slots themselves stay allocated (ISV_TOTAL_DIM unchanged) to preserve checkpoint compatibility. |
|
||||
| **A10** | `crates/ml/src/trainers/dqn/state_reset_registry.rs:2256-2308` — `lock_sp18_v2_pp4_retired_chain` test which asserts the 7 retired entries STILL EXIST | **CONTRACT TEST**. PP.4 added a lock test asserting the entries exist with sentinel 0.0. After full deletion, this test must be deleted (the entries no longer exist, so asserting their existence panics). | DELETE the `lock_sp18_v2_pp4_retired_chain` test (or rewrite to assert the slots are NOT registered). |
|
||||
|
||||
### Out-of-scope mentions (do NOT delete; verify only)
|
||||
|
||||
These show up in the audit grep but per DD7c are RETAINED for HEALTH_DIAG continuity OR are independent modules:
|
||||
|
||||
| Site | Reason RETAINED |
|
||||
|------|----------------|
|
||||
| `crates/ml/src/cuda_pipeline/hold_rate_observer_kernel.cu` | Producer of slot 382 (observation chain). DD7c retains entire observation chain. |
|
||||
| `crates/ml/src/cuda_pipeline/min_hold_temperature_update_kernel.cu` | Independent SP16-P1 producer of slot 460 (different chain). Reads same slots 381+382 but writes different output. RETAINED. |
|
||||
| `crates/ml/src/cuda_pipeline/sp14_isv_slots.rs` MHT_* slots [468..474) | SP16-P1 (MIN_HOLD_TEMPERATURE) Welford accumulators — distinct chain. RETAINED. |
|
||||
| `crates/ml/src/cuda_pipeline/sp13_isv_slots.rs:43` `HOLD_COST_INDEX = 380` | Slot constant for the retained observation chain. RETAINED. |
|
||||
| `crates/ml/src/cuda_pipeline/state_layout.cuh:200-202` `ISV_HOLD_COST_IDX/ISV_HOLD_RATE_TARGET_IDX/ISV_HOLD_RATE_OBSERVED_EMA_IDX` (slots 380/381/382) | Mirror constants for retained observation chain. RETAINED. |
|
||||
| `crates/ml/src/trainers/dqn/state_reset_registry.rs:939` `sp13_hold_rate_observed_ema` registry entry for slot 382 | FoldReset entry for retained observation chain. RETAINED. |
|
||||
| `crates/ml/tests/sp13_phase0_oracle_tests.rs` references to `hold_rate_observer_kernel` | Tests for retained observer kernel. RETAINED. |
|
||||
| `docs/superpowers/specs/2026-05-04-sp13-redefine-success-for-predictive-skill.md` and related plan docs | Historical spec/plan archaeology. NOT modified. |
|
||||
|
||||
## Path forward
|
||||
|
||||
Two options:
|
||||
|
||||
1. **EXPAND deletion scope to cover all 10 additional consumers (A1-A10) atomically in the same Phase 1 commit.** The plan's spec §"Architecture Changes" was incomplete; this audit makes the scope explicit. The atomic commit grows from ~8 sites to ~18 sites but stays within the same conceptual change ("delete SP13/SP16 cost-application chain"). Per `feedback_no_partial_refactor`.
|
||||
|
||||
2. **Halt and request human review.** The plan author may have intended these consumers to be discovered iteratively (the plan says "trust the script, not the plan author"). But the script's purpose is to *surface* missed consumers BEFORE the deletion, exactly so the deletion stays atomic. Halting honours that intent; expanding the scope ad-hoc honours the deletion's atomicity.
|
||||
|
||||
**Recommended**: Option 1, with this audit doc serving as the spec-amendment record. The 10 additional consumers all flow from the same chain — none introduce new architectural concerns. They just expand the byte-count of the atomic-deletion commit.
|
||||
|
||||
## Status
|
||||
|
||||
**HALTED** at end of Phase 1 Task 1.1 — pre-Task-1.2 (pre-commit hook), pre-Task-1.3-1.5 (atomic deletion), pre-Task-1.6 (close-out). The audit script `scripts/audit_sp18_consumers.sh` is committed; the snapshot below is locked for `--check` mode.
|
||||
|
||||
## B-leg verification (Phase 1.1 sub-objective)
|
||||
|
||||
Per the plan's locked B-leg checklist:
|
||||
|
||||
- **`td_lambda_kernel` launch sites**: 1 site at `gpu_experience_collector.rs:4154` (per the plan). Verified.
|
||||
- **`q_next` self-bootstrap**: line `~4143` confirmed (`let q_next = rewards`). Phase 5 will replace.
|
||||
- **PER priority recomputation**: 5 sites in `crates/ml-dqn/src/gpu_replay_buffer.rs`, `crates/ml-dqn/src/replay_buffer_type.rs`, `crates/ml/src/trainers/dqn/config.rs`, `crates/ml/src/trainers/dqn/fused_training.rs`, `crates/ml/tests/gpu_per_integration_test.rs`. NONE store `q_next` — confirms B-DD4 (no PER migration needed).
|
||||
- **C51 loss target-Q origin**: `c51_loss_kernel.cu` `block_bellman_project_f` already uses target-net Q at loss time — no migration needed.
|
||||
- **`target_params_buf`**: 17 references in `gpu_dqn_trainer.rs`, Polyak-tracked, ready for B-leg consumption.
|
||||
- **PopArt slot 63**: catalogued; B-DD11 reset is the only PopArt change in scope.
|
||||
|
||||
B-leg pre-conditions verified ✓ — no additional B-leg consumers surfaced (Phase 4-5 atomic-refactor scope is unchanged).
|
||||
|
||||
## Captured audit fingerprint (locked snapshot — pre-commit hook `--check` diffs against this)
|
||||
|
||||
The fingerprint below is a per-section, per-file hit count summary. It is short
|
||||
enough to inline in markdown, sortable for human review, and stable enough to
|
||||
diff cleanly. Catches both new-consumer drift (a file appears in a section
|
||||
where it didn't before) and expanded-consumer drift (a file's hit count
|
||||
changes). It does NOT catch line-by-line content drift within a single file —
|
||||
that's checked by the per-section grep output diffed in PR review.
|
||||
|
||||
To regenerate:
|
||||
```
|
||||
scripts/audit_sp18_consumers.sh --fingerprint
|
||||
# update this section between BEGIN/END markers, then:
|
||||
git add docs/sp18-wireup-audit.md
|
||||
# the pre-commit hook check_sp18_consumer_audit fails the next commit if
|
||||
# scripts/audit_sp18_consumers.sh --check reports drift vs this snapshot.
|
||||
```
|
||||
|
||||
After Phase 1's atomic deletion lands, this fingerprint will shrink dramatically
|
||||
(slot 461 + HCS_* + hold_cost_scale_update sections drop to zero hits). That
|
||||
re-capture is committed as part of Task 1.6 (close-out).
|
||||
|
||||
<!-- BEGIN audit_sp18_consumers.sh FINGERPRINT -->
|
||||
```
|
||||
=== D-leg: Slot 380 (HOLD_COST_INDEX) consumers ===
|
||||
total_hits=54
|
||||
crates/ml/tests/sp14_oracle_tests.rs 1
|
||||
crates/ml/build.rs 2
|
||||
crates/ml/src/cuda_pipeline/experience_kernels.cu 4
|
||||
crates/ml/src/cuda_pipeline/state_layout.cuh 1
|
||||
crates/ml/src/cuda_pipeline/gpu_experience_collector.rs 1
|
||||
crates/ml/src/cuda_pipeline/hold_rate_observer_kernel.cu 1
|
||||
crates/ml/src/cuda_pipeline/sp5_isv_slots.rs 1
|
||||
crates/ml/src/cuda_pipeline/sp13_isv_slots.rs 1
|
||||
crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs 8
|
||||
crates/ml/src/cuda_pipeline/sp14_isv_slots.rs 3
|
||||
crates/ml/src/trainers/dqn/trainer/training_loop.rs 6
|
||||
crates/ml/src/trainers/dqn/state_reset_registry.rs 2
|
||||
docs/sp18-wireup-audit.md 4
|
||||
docs/dqn-wire-up-audit.md 6
|
||||
docs/superpowers/specs/2026-05-04-sp13-redefine-success-for-predictive-skill.md 4
|
||||
docs/superpowers/plans/2026-05-04-sp13-redefine-success-for-predictive-skill.md 5
|
||||
docs/superpowers/plans/2026-05-08-sp18-reward-shape-hold-attractor.md 4
|
||||
=== D-leg: Slot 461 (HOLD_COST_SCALE_INDEX) consumers ===
|
||||
total_hits=70
|
||||
crates/ml/tests/sp14_oracle_tests.rs 20
|
||||
crates/ml/build.rs 2
|
||||
crates/ml/src/cuda_pipeline/experience_kernels.cu 6
|
||||
crates/ml/src/cuda_pipeline/state_layout.cuh 1
|
||||
crates/ml/src/cuda_pipeline/hold_cost_scale_update_kernel.cu 1
|
||||
crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs 7
|
||||
crates/ml/src/cuda_pipeline/gpu_aux_trunk.rs 2
|
||||
crates/ml/src/cuda_pipeline/sp14_isv_slots.rs 3
|
||||
crates/ml/src/trainers/dqn/trainer/training_loop.rs 4
|
||||
crates/ml/src/trainers/dqn/state_reset_registry.rs 2
|
||||
docs/sp18-wireup-audit.md 4
|
||||
docs/dqn-wire-up-audit.md 5
|
||||
docs/superpowers/plans/2026-05-08-sp16-hold-collapse-structural-fix.md 10
|
||||
docs/superpowers/plans/2026-05-08-sp18-reward-shape-hold-attractor.md 3
|
||||
=== D-leg: Slots [462..468) (HCS_* Welford) consumers ===
|
||||
total_hits=108
|
||||
crates/ml/tests/sp14_oracle_tests.rs 24
|
||||
crates/ml/src/cuda_pipeline/state_layout.cuh 6
|
||||
crates/ml/src/cuda_pipeline/hold_cost_scale_update_kernel.cu 12
|
||||
crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs 12
|
||||
crates/ml/src/cuda_pipeline/gpu_aux_trunk.rs 4
|
||||
crates/ml/src/cuda_pipeline/sp14_isv_slots.rs 12
|
||||
crates/ml/src/trainers/dqn/trainer/training_loop.rs 16
|
||||
crates/ml/src/trainers/dqn/state_reset_registry.rs 15
|
||||
docs/dqn-wire-up-audit.md 6
|
||||
docs/superpowers/plans/2026-05-08-sp18-reward-shape-hold-attractor.md 1
|
||||
=== D-leg: hold_cost_scale_update_kernel references ===
|
||||
total_hits=103
|
||||
crates/ml/tests/sp14_oracle_tests.rs 16
|
||||
crates/ml/build.rs 2
|
||||
crates/ml/src/cuda_pipeline/experience_kernels.cu 13
|
||||
crates/ml/src/cuda_pipeline/state_layout.cuh 2
|
||||
crates/ml/src/cuda_pipeline/hold_cost_scale_update_kernel.cu 1
|
||||
crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs 10
|
||||
crates/ml/src/cuda_pipeline/gpu_aux_trunk.rs 6
|
||||
crates/ml/src/cuda_pipeline/sp14_isv_slots.rs 3
|
||||
crates/ml/src/trainers/dqn/trainer/training_loop.rs 2
|
||||
crates/ml/src/trainers/dqn/state_reset_registry.rs 1
|
||||
docs/sp18-wireup-audit.md 12
|
||||
docs/dqn-wire-up-audit.md 10
|
||||
docs/superpowers/specs/2026-05-08-sp18-reward-shape-hold-attractor-design.md 4
|
||||
docs/superpowers/plans/2026-05-08-sp16-hold-collapse-structural-fix.md 9
|
||||
docs/superpowers/plans/2026-05-08-sp18-reward-shape-hold-attractor.md 12
|
||||
=== D-leg: hold_rate_observer_kernel (RETAINED — diag chain stays per DD7=c) ===
|
||||
total_hits=208
|
||||
crates/ml/tests/sp13_phase0_oracle_tests.rs 19
|
||||
crates/ml/tests/sp14_oracle_tests.rs 40
|
||||
crates/ml/build.rs 7
|
||||
crates/ml/src/cuda_pipeline/min_hold_temperature_update_kernel.cu 6
|
||||
crates/ml/src/cuda_pipeline/state_layout.cuh 1
|
||||
crates/ml/src/cuda_pipeline/gpu_experience_collector.rs 12
|
||||
crates/ml/src/cuda_pipeline/hold_rate_observer_kernel.cu 4
|
||||
crates/ml/src/cuda_pipeline/hold_cost_scale_update_kernel.cu 2
|
||||
crates/ml/src/cuda_pipeline/sp5_isv_slots.rs 3
|
||||
crates/ml/src/cuda_pipeline/sp13_isv_slots.rs 2
|
||||
crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs 18
|
||||
crates/ml/src/cuda_pipeline/gpu_aux_trunk.rs 9
|
||||
crates/ml/src/cuda_pipeline/sp14_isv_slots.rs 7
|
||||
crates/ml/src/trainers/dqn/trainer/training_loop.rs 23
|
||||
crates/ml/src/trainers/dqn/state_reset_registry.rs 5
|
||||
docs/sp18-wireup-audit.md 5
|
||||
docs/isv-slots.md 1
|
||||
docs/dqn-wire-up-audit.md 9
|
||||
docs/superpowers/specs/2026-05-04-sp13-redefine-success-for-predictive-skill.md 6
|
||||
docs/superpowers/specs/2026-05-08-sp18-reward-shape-hold-attractor-design.md 1
|
||||
docs/superpowers/plans/2026-05-05-sp14-aux-q-wire-earned-gradient-flow.md 5
|
||||
docs/superpowers/plans/2026-05-04-sp13-redefine-success-for-predictive-skill.md 20
|
||||
docs/superpowers/plans/2026-05-08-sp18-reward-shape-hold-attractor.md 3
|
||||
=== D-leg: Per-bar Hold-cost subtraction sites (3 lines we change in Phase 1.5) ===
|
||||
total_hits=13
|
||||
crates/ml/src/cuda_pipeline/experience_kernels.cu 13
|
||||
=== D-leg: state_layout.cuh mirror constants (HOLD_COST + HCS) ===
|
||||
total_hits=9
|
||||
crates/ml/src/cuda_pipeline/state_layout.cuh 9
|
||||
=== D-leg: state_reset_registry slot 461 entries ===
|
||||
total_hits=22
|
||||
crates/ml/src/trainers/dqn/state_reset_registry.rs 22
|
||||
=== D-leg: Cubin manifest references in build.rs ===
|
||||
total_hits=4
|
||||
crates/ml/build.rs 4
|
||||
=== B-leg: td_lambda_kernel launch sites ===
|
||||
total_hits=9
|
||||
crates/ml/src/cuda_pipeline/gpu_experience_collector.rs 8
|
||||
crates/ml/src/cuda_pipeline/nstep_kernel.cu 1
|
||||
=== B-leg: q_next argument origin (the line ~4143 site) ===
|
||||
total_hits=
|
||||
=== B-leg: rewards_out consumers (downstream of TD(λ) output) ===
|
||||
total_hits=
|
||||
=== B-leg: PER priority computation sites (verify B-DD4: NO migration needed) ===
|
||||
total_hits=18
|
||||
crates/ml-dqn/src/gpu_replay_buffer.rs 7
|
||||
crates/ml-dqn/src/replay_buffer_type.rs 3
|
||||
crates/ml/tests/gpu_per_integration_test.rs 3
|
||||
crates/ml/src/trainers/dqn/config.rs 4
|
||||
crates/ml/src/trainers/dqn/fused_training.rs 1
|
||||
=== B-leg: Replay buffer schema — q_next storage check (verify NO migration) ===
|
||||
total_hits=
|
||||
=== B-leg: c51_loss_kernel target-Q origin (verify already correct at loss time) ===
|
||||
total_hits=
|
||||
=== B-leg: target_params_buf consumers (verify Polyak-tracked, available at collection time) ===
|
||||
total_hits=
|
||||
=== B-leg: PopArt slot 63 references (verify B-DD11 reset is the only PopArt change) ===
|
||||
total_hits=20
|
||||
crates/ml/tests/sp18_hold_reward_oracle_tests.rs 17
|
||||
crates/ml/tests/sp11_producer_unit_tests.rs 3
|
||||
=== END ===
|
||||
total_hits=
|
||||
```
|
||||
<!-- END audit_sp18_consumers.sh FINGERPRINT -->
|
||||
222
scripts/audit_sp18_consumers.sh
Executable file
222
scripts/audit_sp18_consumers.sh
Executable file
@@ -0,0 +1,222 @@
|
||||
#!/usr/bin/env bash
|
||||
# scripts/audit_sp18_consumers.sh
|
||||
#
|
||||
# SP18 combined-scope (D-leg + B-leg) consumer audit.
|
||||
#
|
||||
# Purpose: surface every live reference to the SP13/SP16 Hold-cost-scale chain
|
||||
# (D-leg) and the TD(λ) `q_next = rewards` self-bootstrap (B-leg) BEFORE atomic
|
||||
# deletion. Per `feedback_no_partial_refactor`, deletion must be atomic across
|
||||
# every consumer; an undetected consumer = SP17-style "missed quantile_q_select"
|
||||
# regression.
|
||||
#
|
||||
# Modes:
|
||||
# audit_sp18_consumers.sh -> print all sections (default)
|
||||
# audit_sp18_consumers.sh --check -> diff against docs/sp18-wireup-audit.md
|
||||
# captured snapshot; exit 1 if drift
|
||||
# (used by pre-commit hook).
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 clean (no drift in --check mode, or default mode prints output)
|
||||
# 1 --check found drift OR a required file is missing
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
|
||||
CHECK_MODE=0
|
||||
if [[ "${1-}" == "--check" ]]; then
|
||||
CHECK_MODE=1
|
||||
fi
|
||||
|
||||
run_audit() {
|
||||
echo "=== D-leg: Slot 380 (HOLD_COST_INDEX) consumers ==="
|
||||
grep -rn "ISV_HOLD_COST_IDX\|HOLD_COST_INDEX\|isv\[380\]\|read_isv_signal_at(HOLD_COST_INDEX)\|read_isv_signal_at(380)" \
|
||||
crates/ bin/ services/ scripts/ docs/ \
|
||||
--include="*.rs" --include="*.cu" --include="*.cuh" --include="*.toml" --include="*.md" \
|
||||
2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== D-leg: Slot 461 (HOLD_COST_SCALE_INDEX) consumers ==="
|
||||
grep -rn "ISV_HOLD_COST_SCALE_IDX\|HOLD_COST_SCALE_INDEX\|isv\[461\]" \
|
||||
crates/ bin/ services/ scripts/ docs/ \
|
||||
--include="*.rs" --include="*.cu" --include="*.cuh" --include="*.toml" --include="*.md" \
|
||||
2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== D-leg: Slots [462..468) (HCS_* Welford) consumers ==="
|
||||
grep -rn "HCS_TARGET_MEAN\|HCS_TARGET_M2\|HCS_DIFF_MEAN\|HCS_DIFF_M2\|HCS_PREV_TARGET\|HCS_SAMPLE_COUNT\|isv\[46[234567]\]" \
|
||||
crates/ bin/ services/ scripts/ docs/ \
|
||||
--include="*.rs" --include="*.cu" --include="*.cuh" --include="*.toml" --include="*.md" \
|
||||
2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== D-leg: hold_cost_scale_update_kernel references ==="
|
||||
grep -rn "hold_cost_scale_update\|HoldCostScaleUpdate\|launch_hold_cost_scale\|hold_cost_scale\b" \
|
||||
crates/ bin/ services/ scripts/ docs/ \
|
||||
--include="*.rs" --include="*.cu" --include="*.cuh" --include="*.toml" --include="*.md" --include="*.json" \
|
||||
2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== D-leg: hold_rate_observer_kernel (RETAINED — diag chain stays per DD7=c) ==="
|
||||
grep -rn "hold_rate_observer\|HoldRateObserver\|HOLD_RATE_OBSERVED_EMA_INDEX\|HOLD_RATE_TARGET_INDEX\|HOLD_RATE_LR_INDEX\|isv\[380\]\|isv\[381\]\|isv\[382\]" \
|
||||
crates/ bin/ services/ scripts/ docs/ \
|
||||
--include="*.rs" --include="*.cu" --include="*.cuh" --include="*.toml" --include="*.md" \
|
||||
2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== D-leg: Per-bar Hold-cost subtraction sites (3 lines we change in Phase 1.5) ==="
|
||||
grep -Hn "isv_signals_ptr\[ISV_HOLD_COST_IDX\]\|isv\[ISV_HOLD_COST_IDX\]\|hold_cost_scale" \
|
||||
crates/ml/src/cuda_pipeline/experience_kernels.cu 2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== D-leg: state_layout.cuh mirror constants (HOLD_COST + HCS) ==="
|
||||
grep -Hn "HOLD_COST\|HCS_\|HOLD_COST_SCALE" \
|
||||
crates/ml/src/cuda_pipeline/state_layout.cuh 2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== D-leg: state_reset_registry slot 461 entries ==="
|
||||
grep -Hn "HOLD_COST_SCALE\|sp16_phase2_hold_cost_scale\|sp16_t3_hcs_" \
|
||||
crates/ml/src/trainers/dqn/state_reset_registry.rs 2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== D-leg: Cubin manifest references in build.rs ==="
|
||||
grep -Hn "hold_cost_scale\|hold_rate_observer" \
|
||||
crates/ml/build.rs crates/ml-dqn/build.rs 2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== B-leg: td_lambda_kernel launch sites ==="
|
||||
grep -rn "td_lambda_kernel\b" \
|
||||
crates/ bin/ services/ \
|
||||
--include="*.rs" --include="*.cu" \
|
||||
2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== B-leg: q_next argument origin (the line ~4143 site) ==="
|
||||
grep -n "q_next_bootstrap\|q_next_target\|let q_next\b" \
|
||||
crates/ml/src/cuda_pipeline/gpu_experience_collector.rs 2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== B-leg: rewards_out consumers (downstream of TD(λ) output) ==="
|
||||
grep -n "rewards_out\b" \
|
||||
crates/ml/src/cuda_pipeline/gpu_experience_collector.rs 2>/dev/null \
|
||||
| grep -v "^.*://\|^.*: \*\|^.*: //" || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== B-leg: PER priority computation sites (verify B-DD4: NO migration needed) ==="
|
||||
grep -rn "update_priorities_from_td\|update_priorities_gpu\b" \
|
||||
crates/ bin/ services/ \
|
||||
--include="*.rs" \
|
||||
2>/dev/null || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== B-leg: Replay buffer schema — q_next storage check (verify NO migration) ==="
|
||||
grep -rn "q_next\|Q_next" \
|
||||
crates/ml/src/agents/ crates/ml/src/trainers/dqn/replay_buffer_type.rs crates/ml/src/dqn/gpu_replay_buffer.rs 2>/dev/null \
|
||||
--include="*.rs" \
|
||||
|| echo "(no hits — confirms no q_next stored in buffer)"
|
||||
|
||||
echo ""
|
||||
echo "=== B-leg: c51_loss_kernel target-Q origin (verify already correct at loss time) ==="
|
||||
grep -n "block_bellman_project_f\|target_probs\b" \
|
||||
crates/ml/src/cuda_pipeline/c51_loss_kernel.cu 2>/dev/null \
|
||||
| head -10 || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== B-leg: target_params_buf consumers (verify Polyak-tracked, available at collection time) ==="
|
||||
grep -n "target_params_buf\b" \
|
||||
crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs 2>/dev/null \
|
||||
| head -20 || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== B-leg: PopArt slot 63 references (verify B-DD11 reset is the only PopArt change) ==="
|
||||
grep -rn "PopArt\|POPART\|popart\|slot 63\|POPART_INDEX" \
|
||||
crates/ bin/ services/ \
|
||||
--include="*.rs" --include="*.cu" --include="*.cuh" \
|
||||
2>/dev/null \
|
||||
| head -20 || echo "(no hits)"
|
||||
|
||||
echo ""
|
||||
echo "=== END ==="
|
||||
}
|
||||
|
||||
# Reduce the full audit output to a per-section hit count + per-file hit
|
||||
# count "fingerprint". Catches both new-consumer (file appears) and
|
||||
# expanded-consumer (line count grows) drift while staying short enough
|
||||
# to inline in the audit doc and human-review at commit time.
|
||||
fingerprint_audit() {
|
||||
run_audit | awk '
|
||||
BEGIN { section="(none)"; section_n=0 }
|
||||
/^=== / {
|
||||
section=$0
|
||||
if (!(section in seen)) {
|
||||
section_order[section_n++] = section
|
||||
seen[section] = 1
|
||||
}
|
||||
counts[section] = (section in counts ? counts[section] : 0)
|
||||
next
|
||||
}
|
||||
/^[a-zA-Z]/ && /:/ {
|
||||
# Split file:line:content
|
||||
n = split($0, parts, ":")
|
||||
if (n >= 2) {
|
||||
file = parts[1]
|
||||
key = section "|" file
|
||||
if (!(key in file_seen)) {
|
||||
file_seen[key] = 1
|
||||
file_order[section, file_count[section]++] = file
|
||||
}
|
||||
file_counts[key]++
|
||||
counts[section]++
|
||||
}
|
||||
}
|
||||
END {
|
||||
for (i = 0; i < section_n; i++) {
|
||||
s = section_order[i]
|
||||
print s
|
||||
print " total_hits=" counts[s]
|
||||
n = file_count[s]
|
||||
for (j = 0; j < n; j++) {
|
||||
f = file_order[s, j]
|
||||
print " " f " " file_counts[s "|" f]
|
||||
}
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
if [[ $CHECK_MODE -eq 1 ]]; then
|
||||
SNAPSHOT="docs/sp18-wireup-audit.md"
|
||||
if [[ ! -f "$SNAPSHOT" ]]; then
|
||||
echo "ERROR: --check requires snapshot at $SNAPSHOT" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Extract the captured fingerprint from the doc between the two
|
||||
# markers below, and diff against current run.
|
||||
BEGIN_MARK='<!-- BEGIN audit_sp18_consumers.sh FINGERPRINT -->'
|
||||
END_MARK='<!-- END audit_sp18_consumers.sh FINGERPRINT -->'
|
||||
if ! grep -qF "$BEGIN_MARK" "$SNAPSHOT"; then
|
||||
echo "ERROR: $SNAPSHOT missing audit-fingerprint markers; cannot --check" >&2
|
||||
exit 1
|
||||
fi
|
||||
EXPECTED=$(awk -v b="$BEGIN_MARK" -v e="$END_MARK" '
|
||||
$0 == b { flag=1; next }
|
||||
$0 == e { flag=0 }
|
||||
flag && $0 != "```" { print }
|
||||
' "$SNAPSHOT")
|
||||
ACTUAL=$(fingerprint_audit)
|
||||
if ! diff -u <(echo "$EXPECTED") <(echo "$ACTUAL") > /tmp/sp18_audit_drift.diff; then
|
||||
echo "SP18 consumer-audit drift detected:" >&2
|
||||
cat /tmp/sp18_audit_drift.diff >&2
|
||||
echo "" >&2
|
||||
echo "If this drift is intentional, regenerate the fingerprint:" >&2
|
||||
echo " scripts/audit_sp18_consumers.sh --fingerprint" >&2
|
||||
echo " # then update docs/sp18-wireup-audit.md between the marker tags" >&2
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${1-}" == "--fingerprint" ]]; then
|
||||
fingerprint_audit
|
||||
exit 0
|
||||
fi
|
||||
|
||||
run_audit
|
||||
@@ -135,7 +135,7 @@ check_audit_doc_updates() {
|
||||
local component_changes=$(echo "$staged" | grep -E '(^crates/ml/src/(cuda_pipeline|trainers/dqn)/|^crates/ml/src/cuda_pipeline/state_layout\.cuh$)')
|
||||
if [ -z "$component_changes" ]; then return 0; fi
|
||||
|
||||
local audit_docs_touched=$(echo "$staged" | grep -E '^docs/(dqn-wire-up-audit|isv-slots|dqn-gpu-hot-path-audit|dqn-named-dims|ml-supervised-to-dqn-concept-audit)\.md$')
|
||||
local audit_docs_touched=$(echo "$staged" | grep -E '^docs/(dqn-wire-up-audit|isv-slots|dqn-gpu-hot-path-audit|dqn-named-dims|ml-supervised-to-dqn-concept-audit|sp18-wireup-audit|h_s2_consumers_audit)\.md$')
|
||||
if [ -z "$audit_docs_touched" ]; then
|
||||
echo "❌ Invariant 7 violation: component changes without audit-doc update"
|
||||
echo " Changed components:"
|
||||
@@ -146,6 +146,57 @@ check_audit_doc_updates() {
|
||||
echo " docs/dqn-gpu-hot-path-audit.md"
|
||||
echo " docs/dqn-named-dims.md"
|
||||
echo " docs/ml-supervised-to-dqn-concept-audit.md"
|
||||
echo " docs/sp18-wireup-audit.md"
|
||||
echo " docs/h_s2_consumers_audit.md"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# SP18 consumer-audit drift detection.
|
||||
#
|
||||
# When a commit touches the SP13/SP16/SP18 chain (D-leg cost-application,
|
||||
# B-leg q_next bootstrap, ISV slot constants, state-reset registry, or any
|
||||
# of the kernel files in cuda_pipeline that interact with these slots),
|
||||
# require the locked snapshot in docs/sp18-wireup-audit.md to match the
|
||||
# current run of scripts/audit_sp18_consumers.sh. This is a generalisation
|
||||
# of Invariant 7: catches the SP17-style "missed quantile_q_select consumer"
|
||||
# failure mode by running the audit-as-a-test against the staged diff.
|
||||
#
|
||||
# The script's --check mode does the work: extract the snapshot from the
|
||||
# audit doc between BEGIN/END markers, diff against the live grep output,
|
||||
# fail the commit if drift exceeds a tolerance (the markers themselves
|
||||
# are a freshness check — if the audit doc isn't updated after a chain
|
||||
# change, the markers won't have the new entries).
|
||||
#
|
||||
# Bypass: any commit that BOTH modifies the chain AND updates the audit
|
||||
# doc (touching the markers) is allowed through — the developer made the
|
||||
# scope explicit.
|
||||
check_sp18_consumer_audit() {
|
||||
local staged
|
||||
staged=$(git diff --cached --name-only --diff-filter=ACM)
|
||||
if [ -z "$staged" ]; then return 0; fi
|
||||
# Trigger only on chain-relevant files
|
||||
local chain_changes
|
||||
chain_changes=$(echo "$staged" | grep -E '^(crates/ml/src/cuda_pipeline/(experience_kernels\.cu|hold_(rate_observer|cost_scale_update)_kernel\.cu|state_layout\.cuh|sp1[3-8]_isv_slots\.rs|sp14_isv_slots\.rs|gpu_(dqn_trainer|aux_trunk|experience_collector)\.rs)|crates/ml/src/trainers/dqn/(state_reset_registry\.rs|trainer/training_loop\.rs)|crates/ml/build\.rs|crates/ml/tests/sp1[3-8]_(oracle|phase[0-9]+_oracle)_tests\.rs)$' || true)
|
||||
if [ -z "$chain_changes" ]; then return 0; fi
|
||||
if [ ! -x "$SCRIPT_DIR/audit_sp18_consumers.sh" ]; then
|
||||
echo "ℹ️ SP18 consumer-audit script not present; skipping drift check"
|
||||
return 0
|
||||
fi
|
||||
if [ ! -f docs/sp18-wireup-audit.md ]; then
|
||||
echo "ℹ️ docs/sp18-wireup-audit.md not present yet; skipping drift check"
|
||||
return 0
|
||||
fi
|
||||
if "$SCRIPT_DIR/audit_sp18_consumers.sh" --check >/dev/null 2>/tmp/sp18_audit_drift.log; then
|
||||
echo " SP18 consumer-audit clean (no drift vs locked snapshot)"
|
||||
else
|
||||
echo "❌ SP18 consumer-audit drift: chain change without audit-doc snapshot update"
|
||||
echo " Changed chain files:"
|
||||
echo "$chain_changes" | sed 's/^/ /'
|
||||
echo " Run: scripts/audit_sp18_consumers.sh > /tmp/sp18_audit.txt"
|
||||
echo " Update docs/sp18-wireup-audit.md between the BEGIN/END markers."
|
||||
echo " Drift detail:"
|
||||
sed 's/^/ /' /tmp/sp18_audit_drift.log
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -180,6 +231,7 @@ check_audit_doc_updates || exit 1
|
||||
check_no_todo_fixme || exit 1
|
||||
check_no_isv_migrations || exit 1
|
||||
check_no_dtod_via_pinned || exit 1
|
||||
check_sp18_consumer_audit || exit 1
|
||||
|
||||
echo "✅ All pre-commit checks passed!"
|
||||
echo ""
|
||||
|
||||
Reference in New Issue
Block a user