Skip to content

refactor(linking): move fixed-anchor transformations to Rust - #663

Closed
seonghobae wants to merge 1 commit into
mainfrom
refactor/linking-rust-fixed-anchor-662
Closed

refactor(linking): move fixed-anchor transformations to Rust#663
seonghobae wants to merge 1 commit into
mainfrom
refactor/linking-rust-fixed-anchor-662

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Production numerical-ownership gap

Advances #662. Protected main a7be9eb8ca0b807364173f8471fc300e3cf9350f still computes fixed-anchor scale/shift coefficients and transformed theta/alpha/b directly in Python/NumPy inside link_fixed_item_parameters(). Those values determine score-scale comparability, so this is production psychometric linking arithmetic and must have one Rust numerical owner.

Intentional fail-first boundary

Exact test-only head: 78c08f6898c1f24332e95bc614b346d121b2b7ca, directly based on current protected main.

tests/test_linking_fixed_anchor_rust_ownership.py installs an unmistakable compiled-core sentinel for link_fixed_item_parameters and requires the public Python API to obtain linked theta/alpha/b plus scale/shift evidence from that Rust result. Current protected-main production code never consults the compiled core in this function, so the intended RED is the zero-call/sentinel mismatch after normal package setup and import. Setup/import/fixture/changelog failure is not valid RED.

Minimum GREEN after exact RED proof

  1. Move the current fixed-anchor transformation equations into mlsirm-core; reuse existing linking primitives if and only if the estimand is exactly equivalent.
  2. Expose one thin PyO3 binding. Python performs bounded validation, immutable marshalling, construction of MLSIRMParams, and evidence transport only. Missing compiled capability fails closed; no ordinary Python numerical fallback remains.
  3. Preserve current simple-structure semantics before any scientific redesign: unique valid anchors, factor mapping, per-dimension anchors, no-anchor dimensions, positive slopes, unchanged latent-space xi/zeta/tau, and existing affine parameter transformations.
  4. Add direct Rust↔Python parity/property tests for ordinary/multidimensional/extreme/malformed cases and caller immutability, plus realistic known-affine-transformation recovery using coefficient and linked-parameter bias/MAE/RMSE. Correlation alone is insufficient.
  5. Keep CPU f64 as reference and benchmark before any GPU work; this per-link workload is expected to be small.
  6. Add complete rustdoc/docstrings, APA 7 doctoring/equation traceability grounded in the established linking literature, an authoritative changelog fragment, exact changed-production statement/branch coverage, then one unchanged final head with full applicable Python/Rust/PyO3/package/GPU-existing/fuzz/Security/SAST/current-head review evidence.
  7. Canonical Architecture/TRD/ADR/UML/ERD/traceability remains owned by docs: establish canonical product and architecture baseline #604/docs: close canonical documentation fitness gaps without parallel authority #621. Do not create a parallel documentation authority.

Primary scientific basis already verified for this slice includes Stocking and Lord (1983), Applied Psychological Measurement, https://doi.org/10.1177/014662168300700208, and Kolen and Brennan (2014), Test Equating, Scaling, and Linking, https://doi.org/10.1007/978-1-4939-0317-7.

Keep Draft until RED→GREEN history and all exact-head gates are complete.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8dbb0f79-b855-474d-be2f-5a12f7a3973d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Exact bounded GREEN implementation handoff for issue #662 / Draft #663. Final pre-write guard is mandatory: immediately refetch #663, protected main, current comments/reviews, and every target blob; proceed only if source head is still 78c08f6898c1f24332e95bc614b346d121b2b7ca, live protected main is still a7be9eb8ca0b807364173f8471fc300e3cf9350f, and no other writer targets the fixed-anchor linking/PyO3/Rust paths. Abort rather than race if any identity or writer state moved. CodeRabbit is review-only.

The intended production-boundary RED is now proven. Exact CI run 31403108331 checked out synthetic merge 9236e748a4028b263d3a1d606b6514c347e11bd1. Setup, locked dependencies, editable Rust/PyO3 build, and Rust-primary backend verification all succeeded. Rust workspace, PyO3, package/build/reinstall/release acceptance, GPU-smoke, fuzz, Security Scan 31403108456, and SAST 31403108252 are GREEN. Python job 93502726990 collected the full suite and completed 1 failed, 2948 passed, 2 skipped. The sole failure is tests/test_linking_fixed_anchor_rust_ownership.py::test_fixed_anchor_linking_delegates_transformation_to_rust: the sentinel compiled-core entrypoint receives zero calls (len(calls) == 0), proving link_fixed_item_parameters() still owns the transformation in Python. The _log_sigmoid RuntimeWarning is existing #583/#564 evidence and is out of scope.

Implement the minimum GREEN only:

  1. Move the current fixed-anchor scale/shift and linked theta/alpha/b transformation arithmetic into mlsirm-core, reusing an existing Rust linking primitive only if its estimand and conventions are exactly equivalent. CPU f64 remains the reference.
  2. Expose one thin PyO3 entrypoint registered as _core.link_fixed_item_parameters. Python may validate bounded shapes/IDs, marshal immutable inputs, construct MLSIRMParams, and transport evidence; it must not independently recompute the production transformation. Missing/incompatible compiled capability must fail closed with a stable non-reflective package error.
  3. Preserve current scientific/public semantics exactly before any redesign: unique valid anchor indices, factor mapping, per-dimension anchors, dimensions with no anchors, positive finite slope handling, existing affine coefficient/sign convention, unchanged xi/zeta/tau, public return shape/types, and caller-array immutability.
  4. Add direct Rust↔public-Python parity/property tests for ordinary, multidimensional, no-anchor-dimension, extreme-but-finite, duplicate/out-of-range/malformed anchor and incompatible-factor cases. Add a deterministic known-affine-transformation recovery fixture reporting scale/shift and linked-parameter bias/MAE/RMSE after the appropriate scale convention; correlation alone is not acceptance.
  5. Benchmark this per-link workload before considering GPU; do not add GPU unless measured batched benefit justifies a separately parity-verified path. Do not widen into another linking/equating method.
  6. Add complete rustdoc/public docstrings and authoritative doctoring/equation traceability. Preserve the primary basis already recorded for this slice, including Stocking & Lord (1983) and Kolen & Brennan (2014), in APA 7 form. Add one authoritative changelog fragment only after product GREEN, then render/check managed CHANGELOG.md with the repository renderer.
  7. Require exact changed-production statement/branch coverage and focused then full Python/Rust/PyO3/package/reinstall/GPU-existing/fuzz/Security/SAST validation on one unchanged final head. Keep Draft; final current-head independent review, zero valid unresolved findings, Ready/merge handling return to the maintainer loop.
  8. Do not touch canonical PRD/TRD/Architecture/ADR/UML/ERD docs: establish canonical product and architecture baseline #604/docs: close canonical documentation fitness gaps without parallel authority #621, dependencies/workflows, package version/release, hosted persistence, provider credentials, reviewer authority, or unrelated numerical paths.

After one coherent GREEN completion, stop source writes to this branch and leave exact-head gate/review/merge decisions to the maintainer loop.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Fresh current-main reconciliation + GREEN handoff for Draft #663. The prior handoff was explicitly bound to old protected main a7be9eb8... and therefore self-invalidated as main advanced. Immediately refetch #663, live main, comments/reviews and target blobs; proceed only if source head remains 78c08f6898c1f24332e95bc614b346d121b2b7ca and live main is compatible with current 56967deceafeb7ecd0ff08a98f196282a6ec81a3. Abort if another writer appears or either ref moves.

Fresh compare is diverged, ahead 1 / behind 151, merge base a7be9eb8ca0b807364173f8471fc300e3cf9350f; the only unique branch path is the fail-first ownership regression tests/test_linking_fixed_anchor_rust_ownership.py. Reconcile protected main non-destructively before production implementation; do not replay predecessor-main changes as branch-owned work. Preserve the already-proven RED history as historical evidence only.

Then implement the minimum issue #662 GREEN: Rust-owned fixed-anchor scale/shift plus theta/alpha/b transformation, thin _core.link_fixed_item_parameters PyO3 marshalling, no ordinary Python production recomputation/fallback, exact current linking semantics, direct Rust↔public parity and known-affine recovery using bias/MAE/RMSE, complete docs/rustdoc, authoritative changelog/doctoring, and full same-head gates. Keep CPU-f64; no GPU without benchmark justification. Do not change other linking methods, workflows/dependencies/release/version, or canonical #604 docs. Keep Draft until current-head gates/review are complete.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Fresh current-main GREEN handoff for issue #662 / Draft #663. Immediately before any write, refetch #663 head, protected main, comments/reviews and all target blobs. Proceed only if source is still 78c08f6898c1f24332e95bc614b346d121b2b7ca, protected main is exactly 56967deceafeb7ecd0ff08a98f196282a6ec81a3, and no competing writer targets the fixed-anchor linking/Rust/PyO3 paths. The earlier handoff bound to a7be9eb... is stale and must not write.

Reconcile protected main non-destructively first, preserving all newer accepted backend/security/public-contract behavior. Then complete only the already-proven GREEN: move current fixed-anchor scale/shift plus linked theta/alpha/b transformation arithmetic into mlsirm-core; expose thin _core.link_fixed_item_parameters; keep Python to bounded validation, immutable marshalling, MLSIRMParams construction and evidence transport; fail closed if the compiled capability is unavailable; preserve existing anchor/factor/sign/xi/zeta/tau/public-shape semantics. Add direct Rust↔Python parity/property tests and known-affine scale/shift + linked-parameter bias/MAE/RMSE recovery; keep CPU f64 reference and do not add GPU without separate benchmark evidence. Complete rustdoc/docstrings, APA 7 equation traceability, changelog, changed coverage and one unchanged-head full Python/Rust/PyO3/package/GPU-existing/fuzz/Security/SAST cycle. Keep Draft for current-head independent review/governance; do not touch canonical #604/#621 docs, dependencies/workflows/version/release or unrelated linking methods. Stop if head/main/writer state moves.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Fresh current-main reconciliation + GREEN handoff for Draft #663 after protected-main movement. Immediately refetch source head, live main, comments/reviews and target blobs; proceed only if #663 is still 78c08f6898c1f24332e95bc614b346d121b2b7ca, live main is still compatible with d2301dccb7d39a794d08cc96ea8c858b9ff49125, and no other writer targets this branch/linking paths. Abort if any identity moves.

Fresh compare is diverged, ahead 1 / behind 155, merge base a7be9eb8ca0b807364173f8471fc300e3cf9350f; the sole unique branch path remains the fail-first ownership regression tests/test_linking_fixed_anchor_rust_ownership.py. Reconcile current protected main non-destructively first and preserve all accepted newer linking/backend/security/package behavior. The earlier RED remains historical evidence only after reconciliation; rerun it on the new integrated head before production mutation if the merge context can affect the boundary.

Then implement the minimum #662 GREEN only: Rust-owned fixed-anchor scale/shift and linked theta/alpha/b transformation, thin _core.link_fixed_item_parameters PyO3 marshalling, Python bounded validation/immutability/result construction only, fail closed if compiled capability is absent. Preserve current simple-structure/no-anchor-dimension/positive-slope/factor-map and xi/zeta/tau semantics. Add direct Rust↔Python parity and known-affine recovery with coefficient/parameter bias/MAE/RMSE; correlation alone is not acceptance. Keep CPU-f64, benchmark before any GPU. Add rustdoc/docstrings, APA 7 equation traceability/changelog, exact changed coverage and full same-head gates. Do not widen to other linking methods, workflows/dependencies/version/release or canonical #604/#621 docs. Keep Draft until current-head review/gates are complete.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Reacquire the bounded source-writer lease for Draft #663 / issue #662 only if a final refetch still shows source head 78c08f6898c1f24332e95bc614b346d121b2b7ca and protected main 9b7335466c1d61349228d33e7b1e58d279f984c4; abort without writing if either ref moved or another current writer targets the fixed-anchor linking/PyO3/Rust paths. The predecessor handoff 5242426768 was explicitly bound to protected main a7be9eb8ca0b807364173f8471fc300e3cf9350f, instructed itself to abort on movement, has no reaction/receipt and produced no source movement. Treat it as stale predecessor evidence.

Fresh compare is diverged: this branch has exactly one unique fail-first test path and is 186 protected-main commits behind, merge base a7be9eb8ca0b807364173f8471fc300e3cf9350f. Reconcile current main non-destructively before implementation; preserve every accepted-main linking/API/numerical contract and the fail-first evidence rather than transplanting stale main behavior wholesale.

The valid RED from CI 31403108331 reached the production boundary with exactly one failure after normal Rust/PyO3 setup: _core.link_fixed_item_parameters receives zero calls, proving public fixed-anchor scale/shift and linked theta/alpha/b transformation remain Python-owned. Implement only the minimum GREEN:

  1. Revalidate the current protected-main link_fixed_item_parameters() estimand and sign/scale convention after reconciliation. Move that exact result-affecting affine scale/shift and theta/alpha/b transformation arithmetic into mlsirm-core; reuse a Rust linking primitive only if equivalence is proved.
  2. Expose one thin _core.link_fixed_item_parameters PyO3 boundary. Python may validate bounded shapes/anchor/factor IDs, marshal immutable inputs, construct MLSIRMParams and transport evidence only. Missing/incompatible core must fail closed.
  3. Preserve unique valid anchors, per-dimension factor mapping, no-anchor dimensions, positive finite slope semantics, xi/zeta/tau, public return shapes/types, caller immutability and any newer accepted-main linking safeguards.
  4. Add direct Rust↔public parity/property tests for ordinary/multidimensional/no-anchor/extreme finite/malformed/duplicate/out-of-range/incompatible-factor cases and known-affine recovery reporting scale/shift plus linked-parameter bias/MAE/RMSE under the proper scale convention. Correlation alone is insufficient.
  5. Keep CPU f64; profile before any GPU addition. This slice is fixed-anchor linking only.
  6. Preserve primary equation/source traceability to Stocking & Lord (1983) and Kolen & Brennan (2014) in APA 7 form, with stable links/summaries where allowed. Add changelog only after GREEN; run focused linking/recovery tests, full Python 3.12/3.14, Rust/PyO3/package/reinstall/GPU-existing/fuzz/Security/SAST, changelog check and git diff --check on one unchanged head.

Do not widen into another linking/equating method, dependencies/workflows/version/release, hosted persistence or canonical #604/#621 docs. Keep Draft; exact-head review/Ready/merge returns to the maintainer loop.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Fresh replacement implementation lease for issue #662 / Draft #663 after protected-main movement invalidated the prior exact-base handoff. Immediately before writing refetch source head, live protected main, comments/reviews and every fixed-anchor linking/PyO3/Rust target blob; proceed only while source remains 78c08f6898c1f24332e95bc614b346d121b2b7ca, live main remains compatible with 3bc1222bf9552bb74f98cf34c89eba0b8d29c0dc, and no other writer targets those paths. Fresh compare is diverged ahead 1 / behind 193 with exactly one unique fail-first test file. Reconcile protected main non-destructively first and preserve exact RED CI 31403108331 as predecessor proof.

Implement only the fixed-anchor Rust ownership slice: move current scale/shift and linked theta/alpha/b transformation arithmetic into mlsirm-core, expose thin _core.link_fixed_item_parameters, and leave Python with bounded validation/marshalling/MLSIRMParams construction/evidence transport only. Missing/incompatible capability must fail closed; no ordinary Python production recomputation. Preserve exact anchor/factor semantics, dimensions with no anchors, positive finite slope convention, affine sign/scale convention, unchanged xi/zeta/tau, return types and caller immutability.

Add direct Rust↔public parity plus deterministic known-affine recovery with coefficient/linked-parameter bias/MAE/RMSE, full malformed/duplicate/out-of-range/factor cases, primary APA 7 equation/source links (Stocking & Lord; Kolen & Brennan), rustdoc/docstrings and authoritative changelog after GREEN. CPU-f64 remains reference; benchmark before GPU. Then run one unchanged final head through Python 3.12/3.14, Rust/PyO3/package/GPU-existing/fuzz/Security/SAST/coverage/current-head review. Do not widen into other linking methods, canonical #604 docs, dependencies/workflows/version/release/hosted state. Stop on any source/base/lease movement.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Fresh current-main clean-lineage reconciliation/replacement lease for Draft #663 / issue #662. Immediately before any write refetch exact source head 78c08f6898c1f24332e95bc614b346d121b2b7ca, live protected main 7b57f77747b9a9bd911660c76b1be0ca0dc2d145, comments/reviews/threads and exact fixed-anchor linking / Rust / PyO3 target blobs; abort if either ref moves or another writer targets those paths. Every prior handoff is stale because it was bound to predecessor protected heads.

Fresh compare is diverged, ahead 1 / behind 197 from merge base a7be9eb8ca0b807364173f8471fc300e3cf9350f; the only unique path is tests/test_linking_fixed_anchor_rust_ownership.py. Preserve exact RED evidence from CI 31403108331: full installed Python reached the production boundary and completed 1 failed, 2948 passed, 2 skipped, with the sole failure proving _core.link_fixed_item_parameters receives zero calls while all Rust/PyO3/package/GPU/fuzz/Security/SAST gates were green.

Because this is a one-test branch almost 200 protected-main commits behind, prefer exactly one clean-lineage replacement from current protected main over conflict-heavy ancestry repair: carry the same fail-first ownership test and exact RED lineage into the replacement PR, make that replacement the sole #662 implementation authority, then close #663 with precise supersession lineage. Never leave both branches active.

Implement only the bounded fixed-anchor linking ownership slice:

  1. Move current fixed-anchor scale/shift and linked theta/alpha/b transformation arithmetic into mlsirm-core, reusing existing Rust linking functions only if the estimand/sign/scale conventions are exactly equivalent.
  2. Expose a thin PyO3 _core.link_fixed_item_parameters boundary. Python validates bounded shapes/IDs, marshals immutable inputs, constructs MLSIRMParams and transports evidence only. Missing/incompatible compiled capability fails closed with stable non-reflective package error; no Python production transformation fallback.
  3. Preserve current unique anchor validation, factor mapping, per-dimension anchors, no-anchor-dimension behavior, positive finite slope convention, affine coefficient/sign convention, unchanged xi/zeta/tau, return shapes/types and input immutability unless a separately reviewed scientific defect is established test-first.
  4. Add direct Rust↔public parity/property tests for ordinary/multidimensional/no-anchor/extreme finite/malformed/duplicate/out-of-range/incompatible-factor cases plus deterministic known-affine recovery with scale/shift and linked-parameter bias/MAE/RMSE under the declared convention; correlation alone is insufficient.
  5. CPU f64 remains reference; benchmark this small per-link workload before any GPU work.
  6. Add complete rustdoc/docstrings, APA 7 equation/source traceability (including Stocking & Lord 1983 and Kolen & Brennan 2014 where applicable), authoritative changelog only after GREEN, exact changed-production 100% statement/branch coverage, then full Python 3.12/3.14, Rust/PyO3, package/reinstall, existing GPU/fuzz, Security/SAST and current-head review gates on one unchanged final head.
  7. Do not widen into other linking/equating methods, dependencies/workflows/version/release, hosted persistence, provider credentials or canonical docs: establish canonical product and architecture baseline #604/docs: close canonical documentation fitness gaps without parallel authority #621 documentation.

Stop writing immediately if source/base/lease state moves.

Copy link
Copy Markdown
Contributor Author

Superseded by clean-lineage Draft #737. Fresh evidence on protected main 7b57f77747b9a9bd911660c76b1be0ca0dc2d145 showed #663 was 197 protected-main commits behind and contained exactly one unique path, tests/test_linking_fixed_anchor_rust_ownership.py. That fail-first contract has been preserved unchanged on #737 at head 3cefab9decf304a93bb2286969079925208fa004, directly based on current protected main. No checks, reviews, or approvals transfer from #663. Issue #662 remains open and #737 is now the sole implementation authority for this fixed-anchor Rust-ownership slice.

@seonghobae seonghobae closed this Aug 11, 2026
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