docs: lock buyer-facing auto backend to fail-closed Rust - #945
docs: lock buyer-facing auto backend to fail-closed Rust#945cursor[bot] wants to merge 9 commits into
Conversation
Keep the Claude runtime-contract TOML, and stop README, commercial readiness, PRD, TRD, and ADR-0002 from advertising a silent NumPy fallback for backend=auto. Purchasers should install the compiled Rust core or pass explicit backend=numpy for parity testing. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Verdict: REQUEST_CHANGES (posted as COMMENT; GitHub rejects REQUEST_CHANGES on cursor[bot] PRs)
The Install rewrite, CLAUDE.md TOML contract, commercial Supported Product Surface, and the PRD/TRD/ADR-0002 auto sentences match shipped resolve_backend("auto"). Prefer this PR over #833. Do not merge #833 in parallel.
This branch does not close the buyer-facing defect it claims to close. A purchaser can still be told that auto falls back to NumPy — in the same README this PR edited, in fast-mlsirm fit --help, in the public FitConfig comments, and in commercial Operational Notes. The new tests lock exact phrases and stay green through all of that. They never import resolve_backend.
Shipped policy on this head:
python/fast_mlsirm/backend.py:auto→"rust"whenfast_mlsirm._coreimports; otherwiseRuntimeError("compiled Rust core is required for automatic backend resolution"). Explicitnumpynever inspects the core.FitConfig.backenddefault is"auto".- CLI
--backenddefault isauto. - Behavioral lock already exists in
tests/test_backend.py.
No security, formula, estimator, or dependency issues.
Blocking leftovers (same defect class)
README.mdCLI section (lines 378–381) — Install now says fail-closed; the later CLI examples still sayfit --backend auto“falls back to NumPy otherwise.” Buyer confusion in the primary install doc.python/fast_mlsirm/cli.py--help— still saysdefault: auto = Rust core when available, numpy reference fallback. That is the purchaser-visible contract forfast-mlsirm fit.python/fast_mlsirm/config.pyFitConfig.backendcomment — still says"auto"“transparently falls back to the pure-numpy reference implementation otherwise.”docs/commercial_readiness.mdOperational Notes — still says “Installed wheels can use the NumPy backend by default,” which contradicts the new Supported Product Surface and README (“installed wheels ship the compiled core”).tests/test_claude_runtime_contract.py— phrase locks, not a shipped-policy bind._STALE_AUTO_NUMPY_FALLBACKis the old Install sentence only. It does not catch “falls back to NumPy otherwise”, CLI help,FitConfigcomments, or commercial Operational Notes.test_claude_machine_runtime_contract_matches_shipped_policynever importsresolve_backend.
Residual product gap (not introduced here)
Auto fail-closed errors do not tell the next action. Doctoring correctly wants a stable, non-reflective error, but a purchaser is not told to install a wheel/_core or pass backend="numpy" / --backend numpy.
Next action
A successor on this run’s branch will lock the leftover README/CLI/FitConfig/commercial surfaces, bind the contract tests to resolve_backend, and add a stable next-action suffix on the auto fail-closed error. Treat that successor as the landing vehicle. Reviewer seonghobae is already requested. Do not self-approve.
Sent by Cursor Automation: Fix Issues
| assert _STALE_AUTO_NUMPY_FALLBACK not in normalized | ||
| assert _STALE_PARITY_AND_FALLBACK not in normalized | ||
| assert "fails closed when that extension is unavailable" in normalized | ||
| assert "Automatic resolution never silently selects NumPy" in normalized |
There was a problem hiding this comment.
This README lock only forbids the old Install sentence. The same file still says fit --backend auto “falls back to NumPy otherwise” around lines 378–381. A purchaser who follows the CLI examples gets the opposite of shipped resolve_backend("auto"). Scan that later CLI section (or the whole README) for the leftover claim.
| project = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8")) | ||
| guidance = (ROOT / "CLAUDE.md").read_text(encoding="utf-8") | ||
|
|
||
| assert _runtime_contract(guidance) == { |
There was a problem hiding this comment.
test_claude_machine_runtime_contract_matches_shipped_policy compares CLAUDE.md TOML to hardcoded rust_required / reference_parity_only. It never imports resolve_backend. The executable fail-closed bind already lives in tests/test_backend.py; this lock should call or document that shipped function so a docs-only rewrite cannot drift from runtime policy.
|
|
||
| assert _STALE_NUMPY_DEFAULT not in readiness | ||
| assert "Rust/PyO3 backend as the default `auto` runtime path" in readiness | ||
| assert "Explicit NumPy reference backend for parity testing only" in readiness |
There was a problem hiding this comment.
This assertion locks the Supported Product Surface rewrite and misses Operational Notes: “Installed wheels can use the NumPy backend by default.” That leftover still tells a sales reviewer the opposite of “installed wheels ship the compiled core.” Include that sentence in the stale-claim scan.
| `backend="numpy"` to force the pure-Python reference (used for parity testing). | ||
| The default runtime backend is `"auto"`. It uses the compiled Rust core | ||
| (`fast_mlsirm._core`) and fails closed when that extension is unavailable. | ||
| Automatic resolution never silently selects NumPy. Source and editable installs |
There was a problem hiding this comment.
Install copy is now correct. The CLI section later in this same file still says fit --backend auto uses Rust when available and falls back to NumPy otherwise. Until that paragraph is rewritten, this PR does not close the buyer-facing #621 defect.
| - Rust/PyO3 backend as the default `auto` runtime path through | ||
| `fast_mlsirm._core`. `auto` fails closed when the compiled core is | ||
| unavailable. | ||
| - Explicit NumPy reference backend for parity testing only. |
There was a problem hiding this comment.
Supported Product Surface is now correct. Operational Notes still say installed wheels can use NumPy by default. A sales reviewer who reads past the surface list still gets the old ownership story.
|
Superseded by #946 after a fresh exact-head comparison. #946 is a strict descendant of this head ( |
…faces (#951) * test(docs): pin Claude runtime support contract * docs: align Claude guidance with fail-closed runtime * test(docs): normalize Markdown wrapping in runtime contract * test(docs): reject marginal fallback claim * revert: keep runtime guidance lane scoped * test(docs): require machine-readable runtime contract * docs: publish machine-readable runtime contract * test(config): expose integer callback trust gap * fix(config): reject caller-controlled integer coercion * test(config): cover bounded integer trust controls * docs(changelog): record config integer boundary hardening * docs(doctoring): record config integer trust boundary * fix(config): validate simulation and fit controls at construction Strix VULN-0001 failed the current head because MLS2PLMConfig and FitConfig could be constructed with values that bypass memory-safety bounds until a later explicit validate() call. Run the existing validators from __post_init__ so invalid objects cannot exist, and keep validate() public and idempotent. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(config): store trusted integers and harden seed controls Write admitted NumPy integers back as built-in ints so n_items and seed + restart cannot wrap, and reject untrusted seed/verbose values before construction returns. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * docs: lock buyer-facing auto backend to fail-closed Rust Keep the Claude runtime-contract TOML, and stop README, commercial readiness, PRD, TRD, and ADR-0002 from advertising a silent NumPy fallback for backend=auto. Purchasers should install the compiled Rust core or pass explicit backend=numpy for parity testing. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix: lock leftover auto-backend surfaces to fail-closed Rust Close the buyer-facing leftovers that #945 missed: README CLI examples, fit --help, FitConfig comments, commercial Operational Notes, and the auto fail-closed error now name the next action. Contract tests bind to resolve_backend and scan those surfaces. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * test: tolerate wrapped fit --help and reference/parity wording The auto-unavailable message uses "reference/parity" as policy language, not a filesystem path. fit --help wraps the next-action clause, so the lock now compares whitespace-normalized help text. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix: lock leftover demo and acceptance auto surfaces to Rust Buyer demo copy, README layout, sales --check-import help, and release-acceptance still treated Rust as optional or accepted NumPy as an automatic fit outcome. Fail those surfaces closed and lock them. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * test(sales): expose automatic backend authority gap * test(sales): defer backend authority to owning PR * test(backend): cover unloadable Rust core * fix(backend): fail closed before untrusted controls and loader errors * test(backend): enforce callback-safe controls * docs(backend): record loader and control hardening * docs(backend): unify loader and selector trust boundary * test(config): align resource-limit regressions with constructor validation * test(config): keep bifactor objective fixture valid * fix(test): match auto-fit Rust authority error text The merge with main kept the pre-helper regex from #865 after _require_auto_fit_resolved_to_rust started raising "fit auto backend must resolve to rust". Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(diagnostics): trust fold counts before budget products dimensionality_diagnostics still multiplied untrusted NumPy k_folds and added untrusted seed offsets, so uint8(32)*32 wrapped past the fit-budget cap and uint8(250)+6 wrapped to 0. Store built-in ints the same way seed/verbose already do. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * test(config): use raw regex literals in compatibility checks * fix(diagnostics): trust fit-diagnostic integer controls fit_diagnostics still coerced parameter_count with int() and left m2_q_* untrusted, so a hostile __index__ object could execute during AIC/BIC arithmetic. Marshal those controls through _trusted_integer the same way seed/verbose already do. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * test(backend): document import failure fixture * test(backend): lock reference guidance contract * fix(adr): preserve accepted backend decision * fix(docs): distinguish CLI and Python reference paths * fix(cli): point NumPy parity users to --reference * test(runtime): align fail-closed reference contract --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> Co-authored-by: opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>


Scope
Keep the executable Claude runtime-contract from #833, and close the remaining buyer-facing #621 defect: README and commercial-readiness still told a purchaser that
backend="auto"transparently falls back to NumPy, which is the opposite of shippedresolve_backend("auto")behavior.This branch includes the #833 CLAUDE.md TOML contract and extends the lock to customer-facing install/sales copy plus the PRD/TRD/ADR-0002 summaries that still called automatic resolution a transparent fallback.
Prefer this PR over #833. Do not merge #833 in parallel.
What a purchaser should do
fast_mlsirm._core.FitConfig(backend="auto")for production; it fails closed if the Rust core is missing.backend="numpy"only when you want the explicit reference/parity path.Machine-readable contract (unchanged)
Verification
Focused contract tests in
tests/test_claude_runtime_contract.pypassed locally (7 tests), including README, commercial-readiness, PRD, TRD, and ADR-0002 stale-claim locks. No runtime, formula, estimator, or dependency changes.Advances #621.