Skip to content

feat(format): lbfgs-kernel-v1 6-gate PARTIAL discharge#1400

Open
noahgift wants to merge 1 commit into
mainfrom
feat/lb-001-006-partial-discharge
Open

feat(format): lbfgs-kernel-v1 6-gate PARTIAL discharge#1400
noahgift wants to merge 1 commit into
mainfrom
feat/lb-001-006-partial-discharge

Conversation

@noahgift
Copy link
Copy Markdown
Contributor

@noahgift noahgift commented May 2, 2026

Summary

  • Binds FALSIFY-LB-001..006 from lbfgs-kernel-v1 at PARTIAL_ALGORITHM_LEVEL via 6 verdict functions + reference dot-product.
  • 24 unit tests including 4-bucket history-bound sweep.
  • Algorithm-level coverage advances by 6 gates; runtime ship % unchanged.

Gates bound

Gate ID Rule
LB-001 g^T * direction < 0 (descent) for non-zero gradient
LB-002 y^T * s > 0 for every accepted (s, y) pair
LB-003 history length ≤ m
LB-004 f(x_{k+1}) < f(x_k) strictly
LB-005 SIMD vs scalar within 8 ULP
LB-006 empty history → direction == -g (bit-exact steepest)

Five Whys

See commit message — captures bit-exact for LB-006, 8 ULP rationale for LB-005, and fail-on-zero-grad for LB-001.

Test plan

  • cargo test -p aprender-core --lib lb_001_006 — 24 passed
  • PMAT pre-commit gates green
  • CI green

🤖 Generated with Claude Code

Binds FALSIFY-LB-001..006 from lbfgs-kernel-v1 at PARTIAL_ALGORITHM_LEVEL
via 6 verdict functions plus a reference dot-product helper.

- LB-001: g^T * direction < 0 strictly (descent direction)
- LB-002: y^T * s > 0 for every accepted (s, y) pair
- LB-003: history length ≤ m (eviction works)
- LB-004: f(x_{k+1}) < f(x_k) (objective strictly decreases)
- LB-005: SIMD vs scalar within 8 ULP
- LB-006: empty history → direction == -g (steepest descent)

## Five Whys

1. Why does lbfgs-kernel-v1 list 6 falsification IDs without
   algorithm-level discharge? PMAT lints flagged FALSIFY-LB-001..006
   as unbound at PARTIAL_ALGORITHM_LEVEL.
2. Why does that block ship? Coverage % cannot move while peripheral
   second-order optimization invariants are unbound.
3. Why bit-exact (`to_bits()`) for LB-006 (empty history → -g)?
   The contract specifies "direction = -g" — pure negation, not a
   computation. Float-tolerant compare would let "almost -g" slip
   past, masking the regression class "initial scaling applied a
   factor of 1.0001 instead of 1.0."
4. Why 8 ULP budget for LB-005 (vs e.g. 4)? L-BFGS two-loop
   recursion accumulates over `m=5..20` (s, y) pair dot products.
   Each dot product over a 1000-dim parameter vector adds ~1000
   floats; the round-off accumulates to ~7 ULPs in the worst case.
   8 ULP gives 1 ULP of slack while still catching real divergence.
5. Why fail-on-zero-grad for LB-001 (vs vacuous Pass)? A
   zero-gradient input means we're at the optimum — the gate
   doesn't apply, but returning Fail forces the call site to gate
   on `||g|| > eps` first. Vacuous Pass would let "we forgot to
   check the convergence condition" pollute coverage with
   dead-code paths.

Adds 24 unit tests including a 4-bucket history-bound sweep and a
strict-vs-equal objective-decrease check. Realistic-healthy walks
the canonical L-BFGS step on a quadratic; pre-fix walks 6
simultaneous regressions across the entire kernel surface.

No runtime % shift; algorithm-level coverage advances by 6 gates.
@noahgift noahgift force-pushed the feat/lb-001-006-partial-discharge branch from 7ddf16a to 6f5d8b1 Compare May 11, 2026 15:15
@noahgift noahgift enabled auto-merge (squash) May 11, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant