fix(a2k): reject out-of-range fraction-decrease scales #89

Merged
core-labs merged 2 commits from fix/a2k-fraction-decrease-scale-range into main 2026-07-20 04:42:10 +00:00
Owner

Summary

Close a fail-closed inconsistency on Gate A2k fraction-decrease: obligation assessment refused scales outside 0 < scale < 1 (scale_out_of_range), but geometric VersorBinding admission accepted any positive finite scale. Contract resolution fell back to the geometric path when obligation was non-runnable, so inputs like “decrease to 5/4 of …” could still reach resolve_promotable_fraction_decrease() and emit a negative decrease answer.

Root cause

  • assess_fraction_decrease required 0 < scale < 1
  • _versor_binding_from_scale_value / _fraction_decrease_scale_binding only required finite scale > 0 (algebraic dilation precondition)
  • _resolve_fraction_decrease_contract fell back to assess_geometric_proposals when obligation was non-runnable

Fix

  • Add shared predicate _is_valid_fraction_decrease_scale — finite 0 < k < 1
  • Use it in obligation assessment (scale_out_of_range)
  • Use it in _fraction_decrease_scale_binding so no VersorBinding is emitted for out-of-range scales
  • Leave pure dilation construction (k > 0) intact for algebraic use; organ domain is stricter

Non-effects

  • No serving flags, packs, morphology, language, runtime, or backend changes
  • No PR #87 sealed fixture or score changes (still 2 correct / 0 wrong / 6 refused)
  • Valid 3/4 / 2/3 paths unchanged

Verification

[Verification]: Smoke suite passed locally (~131s, 176 passed)

Also:

  • pytest tests/test_problem_frame_contracts.py tests/test_relational_operator_ablation.py tests/test_math_candidate_graph_sprint8_r6_affine_lift.py tests/test_construction_affordances.py tests/test_contract_residuals.py163 passed
  • Relational operator ablation report: baseline/operator/depth/metadata_only = 2 correct, 0 wrong, 6 refused; passed: true
  • Live repro: resolve_promotable_fraction_decrease("…5/4…") is None; valid 3/4 still answers ~21

PR checklist

  • Capability protected: fail-closed fraction-decrease scale domain on all admission paths
  • Invariant: geometric admission cannot grant permission obligation denies; dilation payloads still versor_condition < 1e-6 when admitted
  • Lane: smoke + focused contract/organ/ablation tests
  • Avoided: no hidden normalization, no clipping into range, no stochastic fallback, no unreviewed mutation
  • Trust boundary: user problem text still grounded via existing frame builder; only refusal tightened

Rollback

Revert the two commits on this branch; no data/migration side effects.

## Summary Close a fail-closed inconsistency on Gate A2k fraction-decrease: obligation assessment refused scales outside `0 < scale < 1` (`scale_out_of_range`), but geometric VersorBinding admission accepted any positive finite scale. Contract resolution fell back to the geometric path when obligation was non-runnable, so inputs like “decrease to 5/4 of …” could still reach `resolve_promotable_fraction_decrease()` and emit a **negative** decrease answer. ## Root cause - `assess_fraction_decrease` required `0 < scale < 1` - `_versor_binding_from_scale_value` / `_fraction_decrease_scale_binding` only required finite `scale > 0` (algebraic dilation precondition) - `_resolve_fraction_decrease_contract` fell back to `assess_geometric_proposals` when obligation was non-runnable ## Fix - Add shared predicate `_is_valid_fraction_decrease_scale` — finite `0 < k < 1` - Use it in obligation assessment (`scale_out_of_range`) - Use it in `_fraction_decrease_scale_binding` so no VersorBinding is emitted for out-of-range scales - Leave pure dilation construction (`k > 0`) intact for algebraic use; organ domain is stricter ## Non-effects - No serving flags, packs, morphology, language, runtime, or backend changes - No PR #87 sealed fixture or score changes (still 2 correct / 0 wrong / 6 refused) - Valid `3/4` / `2/3` paths unchanged ## Verification ```text [Verification]: Smoke suite passed locally (~131s, 176 passed) ``` Also: - `pytest tests/test_problem_frame_contracts.py tests/test_relational_operator_ablation.py tests/test_math_candidate_graph_sprint8_r6_affine_lift.py tests/test_construction_affordances.py tests/test_contract_residuals.py` → **163 passed** - Relational operator ablation report: baseline/operator/depth/metadata_only = **2 correct, 0 wrong, 6 refused**; `passed: true` - Live repro: `resolve_promotable_fraction_decrease("…5/4…") is None`; valid `3/4` still answers ~21 ## PR checklist - **Capability protected:** fail-closed fraction-decrease scale domain on all admission paths - **Invariant:** geometric admission cannot grant permission obligation denies; dilation payloads still `versor_condition < 1e-6` when admitted - **Lane:** smoke + focused contract/organ/ablation tests - **Avoided:** no hidden normalization, no clipping into range, no stochastic fallback, no unreviewed mutation - **Trust boundary:** user problem text still grounded via existing frame builder; only refusal tightened ## Rollback Revert the two commits on this branch; no data/migration side effects.
core-labs added 2 commits 2026-07-20 04:35:36 +00:00
Obligation assessment required 0 < scale < 1 (scale_out_of_range) while
_versor_binding_from_scale_value admitted any positive finite scale, so
resolve_promotable_fraction_decrease could still bind and return a
negative decrease for inputs like 5/4.

Add _is_valid_fraction_decrease_scale as the single semantic-domain
predicate and enforce it in both assess_fraction_decrease and
_fraction_decrease_scale_binding so geometric VersorBinding cannot
grant permission the obligation layer denies.
Regression coverage for the audit repro (5/4), zero/one/gt-one geometric
no-bypass, injected Fraction domain mutations, promotable resolver
refusal, and flip the PR #87 preexisting gap pin to require operator
refuse alongside baseline.
core-labs force-pushed fix/a2k-fraction-decrease-scale-range from 41f309eb92 to ac4c3e04ad 2026-07-20 04:40:43 +00:00 Compare
core-labs merged commit 4b9dbe7236 into main 2026-07-20 04:42:10 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: core-labs/core#89
No description provided.