Skip to content

scientific(validation): reject negative-zero recovery policy to preserve canonical profile identity #628

Description

@seonghobae

Finding

#627 correctly moved scientific recovery promotion from request-time scalars to a versioned ScientificRecoveryProfileV1 whose SHA-256 is the durable design/acceptance identity. Fresh review found one remaining canonicalization defect: the predecessor constructor accepted se_multiplier = -0.0 because its validation rejected only non-finite values or values < 0.0, and IEEE 754 negative zero compares equal to positive zero.

Promotion semantics are identical for +0.0 and -0.0, but ScientificRecoveryProfileV1::sha256() hashes raw f64::to_bits() representations. The same zero-uncertainty scientific policy could therefore acquire two different profile SHA-256 identities, fragmenting provenance/audit evidence without changing any scientific decision.

This is a represented-policy canonicalization defect, not a tolerance or threshold issue.

RED → causal repair

  • source-level deterministic RED a727e85f790469a01b00bb3abc1eeb4efdb68646 extends scientific_recovery_profile_provenance.rs: canonical +0.0 must remain valid and preserve the positive-zero bits; otherwise identical -0.0 must return ValidationError::InvalidConfiguration. Workflows had not materialized before the immediate repair, so no hosted failing RED receipt is claimed.
  • causal production repair 3c1a68370fded2f927941a9d0ae9722ddd5572db rejects only sign-negative zero with (se_multiplier == 0.0 && se_multiplier.is_sign_negative()); finite positive multipliers and canonical +0.0 are unchanged. RMSE/MCSE arithmetic, practical target, DGP/seed/estimand/state-composition identities, failure policy, and digest domain remain unchanged.
  • CHANGELOG/current exact head ccc9f45e94638695ae40831ceba03ceb5b1fb308 records why the accepted profile space needs one canonical zero representation.

Current exact-head gate

#488 is Draft/open/mergeable at exact ccc9f45e94638695ae40831ceba03ceb5b1fb308 on protected main@a243f18da4a4ca8a8d068c39922537f1f8ed6ad0. Fresh workflows for this head are live and non-terminal:

  • Documentation Quality 35499663284 pending;
  • Rust Foundation CI 35499663300 queued;
  • Security Scan 35499663286 queued;
  • SAST Semgrep 35499663271 queued;
  • CodeQL PR 35499663292 queued;
  • Bias SE Exact-Proof Budget 35499663283 queued.

Combined status currently includes CodeRabbit success, but qualifying independent current-head APPROVED review is absent. Do not transfer predecessor receipts, blind-rerun, wake-commit, merge, or release while this generation is live.

Boundaries / remaining gap

Keep #623 practical-target semantics, #624 exact conservative-bound semantics, #625 independent-replication grouping, #626 planned-denominator refusal, and #627 versioned profile provenance intact. No normalization, tolerance, mutable sibling source, LLM decision, or second scientific arithmetic path is introduced.

#627/#628 establish canonical profile content identity only. They do not prove the profile was persisted/approved before simulation execution began. Pre-execution registration/approval chronology remains the next Validation Evidence / integration gap and must be proven from owner evidence rather than caller timestamps.

Keep this issue open through exact-head Rust/coverage/security/CodeQL/proof-budget, qualifying independent review, normal prerequisite/protected-main integration, and code-current TRACEABILITY/product-gap authority. Source repair alone is not completion.

Refs #488 #623 #624 #625 #626 #627 #492.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions