Skip to content

feat(selection): add governed factor-retention evidence contract - #617

Closed
seonghobae wants to merge 11 commits into
mainfrom
feat/factor-retention-evidence-contract
Closed

seonghobae wants to merge 11 commits into
mainfrom
feat/factor-retention-evidence-contract

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Buyer-visible gap

Issue #608 separates factor retention from structural measurement-model selection. Protected main already exposes Rust-backed parallel analysis, Velicer MAP and relation-safe model-comparison primitives, but it lacked one governed factor-retention evidence/result contract that can conservatively represent agreement, disagreement and insufficient evidence without declaring a universal method winner.

Test-first implementation

This branch began with an intentional runtime RED proving that fast_mlsirm.factor_retention did not exist, then added the bounded provider-neutral contract/orchestration layer. Numerical factor-retention arithmetic remains outside Python ownership.

The implemented contract:

  • records distinct factor-retention method identities rather than collapsing them into one algorithm;
  • supports parallel analysis, Velicer MAP, likelihood/information-criterion, bootstrap-LR, predictive and explicitly supported external evidence as distinct inputs;
  • validates bounded positive candidate counts and rejects duplicate method evidence rather than double-counting it;
  • returns conservative consensus, disagreement, or insufficient_evidence status with a candidate range instead of forcing one retained count when supported methods disagree;
  • computes no eigenvalues, likelihoods, LR statistics, information criteria, bootstrap statistics or other psychometric arithmetic in Python; and
  • does not select bifactor, higher-order, testlet, two-tier, faceted or latent-space structure. Structural selection remains a separate Implement factor-retention and structural measurement-model selection workflow #608 stage.

Canonical PRD/TRD/Architecture/ADR/UML authority remains #604; this feature PR must not create a competing architecture baseline.

Exact-current evidence

Freshly revalidated state:

  • protected main: 8db4bf358b0a469915d6c5e336054f4a4f9c6b46;
  • exact Draft head: 89fa2e8d542c50ded20bb28e27b6f418e96e01f0;
  • factor-retention contract tests pass on the exact head;
  • exact-head CI run 31325541500 reaches the full Python suite with the feature GREEN and fails only tests/test_changelog_fragment_contract.py::test_repository_changelog_is_rendered_from_current_fragments because docs/changelog.d/608-factor-retention-evidence-contract.md has not yet been rendered into managed CHANGELOG.md;
  • exact-head Security Scan and SAST Semgrep are successful;
  • a bounded exact-current source-writer handoff already exists for deterministic changelog synchronization and focused verification. Do not race or duplicate it while head/main remain unchanged.

Scientific boundary

Factor retention is evidence about dimensionality count, not proof of a particular structural model, scoreability, construct validity, fairness or consequential-decision readiness. Method agreement is informative but is not a universal optimality guarantee; disagreement remains a first-class governed outcome.

Remaining Draft gate

Keep Draft. Render/check the authoritative changelog without changing the feature contract, then require one unchanged exact head with full relevant CI/Security/SAST, current-head automated review, zero valid unresolved findings and the repository's actual approval/branch-protection policy. If source head or protected main moves, discard predecessor acceptance evidence and refetch.

Advances #608.

@coderabbitai

coderabbitai Bot commented Aug 9, 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: 33889624-9087-4efd-9040-8582b07149a3

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

Take a bounded writer lease only if a final refetch still shows Draft head 89fa2e8d542c50ded20bb28e27b6f418e96e01f0 over protected main 8db4bf358b0a469915d6c5e336054f4a4f9c6b46; abort without writing if either moved or another source writer appears.

The original test-only head already produced the intended production-boundary RED (fast_mlsirm.factor_retention absent; Python CI: 1 failed, 2926 passed, 2 skipped). The current head contains the minimal governance implementation, bounded candidate validation, streaming duplicate-method rejection regression/fix, method doctoring, and changelog fragment. Do not redo or weaken that RED.

Complete only deterministic GREEN/acceptance cleanup for issue #608's factor-retention contract slice:

  1. Run pytest -q tests/test_factor_retention_contract.py and fix only genuine failures in python/fast_mlsirm/factor_retention.py or that test. Preserve: no numerical psychometric arithmetic in Python; closed method identities; positive bounded candidate counts; duplicate methods rejected before iterable over-read; zero/one method => insufficient evidence; multi-method agreement => consensus; disagreement => conservative range with no forced retained count; no structural-model selection.
  2. Run focused statement/branch coverage for the new module and add only meaningful missing tests until owned production statement/branch coverage is 100%; keep complete public docstrings. Do not add unreachable branches merely for coverage.
  3. Run formatting/lint and git diff --check; remove unrelated churn.
  4. Run python scripts/render_changelog_fragments.py --update CHANGELOG.md then --check CHANGELOG.md, preserving all protected-main managed notes and the docs/changelog.d/608-factor-retention-evidence-contract.md fragment exactly through the repository renderer.
  5. Rerun the focused test and relevant changelog contract. Commit one bounded GREEN/renderer cleanup if changes are required.

Keep Draft. Do not create another PR, change dependencies/workflows/version/release, modify canonical architecture PR #604, add NumPy/statistical kernels, mark Ready, approve, merge, or expand into structural model selection. Stop after exact-head deterministic evidence.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

The prior exact-head handoff on this Draft has produced no receipt/reaction and no source movement for more than an hour, so treat it as inactive. Reacquire a bounded writer lease only if a final refetch still shows head 89fa2e8d542c50ded20bb28e27b6f418e96e01f0, protected main 8db4bf358b0a469915d6c5e336054f4a4f9c6b46, and the current CHANGELOG.md blob 6f558dce1350178d0ea6272d86d798125e24ddcc; abort without writing if any identity moved or another current-head source writer appears.

Current RCA is deterministic and narrow: exact-head Python CI fails only because docs/changelog.d/608-factor-retention-evidence-contract.md has not been rendered into the managed CHANGELOG.md; factor-retention implementation/tests are otherwise the intended bounded slice. Execute only:

  1. python scripts/render_changelog_fragments.py --update CHANGELOG.md;
  2. python scripts/render_changelog_fragments.py --check CHANGELOG.md;
  3. pytest -q tests/test_factor_retention_contract.py tests/test_changelog_fragment_contract.py and git diff --check;
  4. commit only the mechanical renderer delta if those checks are GREEN.

Do not alter factor-retention semantics, dependencies, workflows, version/release, canonical architecture PR #604, PR Ready/merge state, or any other branch. If the renderer produces any non-mechanical change outside its authoritative marker block, stop without committing.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Take a bounded writer lease only if a final refetch still shows Draft head 01615e83fd206cd102ad9b195e853e5307790773 over protected main a6b7ecc680b73a277714a795143c7a27125022c3; abort without writing if either moved or another source writer appears.

The branch has already been non-destructively reconciled with current protected main as a two-parent merge commit while preserving exactly the four factor-retention paths. The factor-retention implementation and focused tests were already GREEN on the predecessor; do not change numerical/decision semantics or canonical architecture PR #604.

Complete only deterministic release-note cleanup on this exact head:

  1. Run python scripts/render_changelog_fragments.py --update CHANGELOG.md and then python scripts/render_changelog_fragments.py --check CHANGELOG.md so the existing current-main #616 note and docs/changelog.d/608-factor-retention-evidence-contract.md are both preserved by the repository renderer.
  2. Run pytest -q tests/test_factor_retention_contract.py tests/test_changelog_fragment_contract.py plus formatting/git diff --check as needed.
  3. If and only if those checks require it, commit the renderer-produced CHANGELOG.md and no unrelated source changes.

Keep Draft. Do not create another PR, alter dependencies/workflows/version/release, change the factor-retention contract, mark Ready, approve, merge, or expand into structural model selection. Stop after exact-head deterministic evidence.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Take a bounded writer lease on PR #617 only if a final refetch still shows exact head 01615e83fd206cd102ad9b195e853e5307790773 and protected main f43a466b1441b27bd2ac4a71be8aa3e4f08c8e8f; abort without writing if either moved or another source writer is active. The earlier handoff bound to 89fa2e8... / 8db4bf3... is predecessor evidence and no longer authorizes a write.

Current exact-head Security/SAST are green and CI reaches the complete product suite; the known deterministic integration defect is managed changelog parity, while protected main has since advanced through #618.

Execute only this bounded cleanup:

  1. reconcile protected main non-destructively, preserving accepted-main behavior and only feat(selection): add governed factor-retention evidence contract #617's factor-retention implementation/tests/doctoring/fragment;
  2. run python scripts/render_changelog_fragments.py --update, then --check;
  3. run pytest -q tests/test_factor_retention_contract.py tests/test_changelog_fragment_contract.py and git diff --check;
  4. push only if those checks are green and the exact branch lease still holds.

Keep Draft. Do not alter factor-retention semantics, add psychometric arithmetic in Python, enter structural-model selection, modify dependencies/workflows/version/release, or touch canonical architecture PR #604.

seonghobae commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Superseded bookkeeping note: an earlier exact-current writer handoff already covers head 01615e83fd206cd102ad9b195e853e5307790773 over protected main f43a466b1441b27bd2ac4a71be8aa3e4f08c8e8f. This duplicate request is withdrawn; do not create an additional writer from this comment.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Take a bounded writer lease only if a final refetch still shows Draft head 01615e83fd206cd102ad9b195e853e5307790773 and protected main f43a466b1441b27bd2ac4a71be8aa3e4f08c8e8f; abort without writing if either moved or another current-head source writer appears. The earlier handoff bound to 89fa2e8d... / 8db4bf35... is stale.

Exact-current evidence is narrow: Security Scan 31334692758 and SAST 31334692749 succeeded; Rust, package/reinstall/release acceptance, GPU-smoke and fuzz jobs in CI 31334692776 succeeded; the Python job ran the complete suite with 2943 passed, 2 skipped and only tests/test_changelog_fragment_contract.py::test_repository_changelog_is_rendered_from_current_fragments failed. The factor-retention contract tests are GREEN. Do not change the feature semantics.

Reconcile current protected main non-destructively, preserving #618 and all accepted-main behavior plus only this PR's four unique paths (python/fast_mlsirm/factor_retention.py, its test, doctoring, and fragment). Then run python scripts/render_changelog_fragments.py --update CHANGELOG.md followed by --check CHANGELOG.md, focused factor-retention and changelog tests, formatting/lint, and git diff --check. Commit only the minimum integration/changelog cleanup. Keep Draft and do not mark Ready, approve, merge, alter numerical ownership, expand into structural model selection, touch canonical architecture PR #604, change dependencies/workflows/version/release, or create another PR. Stop if exact head/base moves during the write.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Take a bounded writer lease only if a final refetch still shows Draft head 6a0a75f2aa638b81c12f82e89bec37afe36d48d1 and protected main f43a466b1441b27bd2ac4a71be8aa3e4f08c8e8f; abort if either moved or another current-head source writer appears. This head is now a non-destructive two-parent reconciliation of the four unique factor-retention paths over current protected main; every predecessor-head handoff is stale.

Do not change factor-retention semantics. Run the focused contract first, then synchronize only managed release notes with python scripts/render_changelog_fragments.py --update CHANGELOG.md and --check CHANGELOG.md, run the changelog contract, formatting/lint and git diff --check, and commit the minimum renderer result if GREEN. Keep Draft. Do not change numerical ownership, model-selection semantics, dependencies/workflows/version/release, canonical docs #604, Ready/approval/merge state, or create another PR. Stop if exact head/base moves during the write.

Copy link
Copy Markdown
Contributor Author

@jules address

Fallback bounded writer handoff for exact Draft head 6a0a75f2aa638b81c12f82e89bec37afe36d48d1 over protected main f43a466b1441b27bd2ac4a71be8aa3e4f08c8e8f. The prior exact-head OpenCode handoff has shown no receipt/reaction and no source movement for more than two hours; treat it as inactive, but perform a final head/base/comment refetch before writing and abort if another writer has appeared or either ref moved.

Do not change factor-retention semantics. Exact-head CI has one deterministic failure only: managed CHANGELOG.md is stale relative to docs/changelog.d/608-factor-retention-evidence-contract.md; the factor-retention contract itself, Rust/PyO3, package/reinstall, GPU, fuzz, Security Scan and SAST evidence are green. Run the focused factor-retention tests, then only python scripts/render_changelog_fragments.py --update CHANGELOG.md and --check CHANGELOG.md, the changelog contract, formatting/lint as applicable, and git diff --check. Commit only the generated CHANGELOG.md synchronization if all focused verification is green. Keep Draft. Do not alter source/tests/dependencies/workflows/version/release/canonical docs #604, mark Ready, approve, merge, close #608, or open another PR. Stop writing if exact head/base changes.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Superseding bounded handoff after protected main advanced through #630. Fresh identities immediately before dispatch: Draft #617 head 6a0a75f2aa638b81c12f82e89bec37afe36d48d1; live protected main dccd1f281ec95216b3fcfd682d872c3ace74c68b. Every earlier writer handoff was bound to an older base and required abort on base movement; treat it as predecessor evidence. Refetch head/base/comments before writing and abort if either ref moves or another current-head writer appears.

Reconcile current main non-destructively while preserving only #617's factor-retention implementation/test/doctoring/fragment plus all accepted-main behavior, including the CodeQL analyze 4.37.6 pin. Do not change factor-retention semantics or numerical ownership. Run the focused factor-retention contract, render/check managed CHANGELOG.md, run the changelog contract, formatting/lint and git diff --check, and commit only the minimum verified reconciliation/changelog result. Keep Draft; do not change model-selection scope, dependencies/workflows/version/release, canonical docs #604, Ready/approval/merge state, or create another PR. Stop branch writes after one coherent verified update; fresh exact-head CI/Security/SAST/review returns to the maintainer loop.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Superseding factor-retention cleanup handoff after both CodeQL dependency PRs merged. Fresh identities: Draft #617 exact head 6a0a75f2aa638b81c12f82e89bec37afe36d48d1; protected main a7be9eb8ca0b807364173f8471fc300e3cf9350f; compare = diverged, ahead 11 / behind 2, with the net feature limited to factor-retention implementation/tests/doctoring/changelog fragment. Older handoffs were bound to prior source/base identities and required abort on movement. Refetch head/main/comments before writing and abort if either moves or another current-head writer appears.

Preserve the already-proven RED and current governed factor-retention semantics: Python is validation/orchestration only, closed method identities, bounded positive counts, streaming duplicate rejection, zero/one method insufficient, agreement consensus, disagreement conservative range/no forced winner, no structural-model selection. Reconcile protected main non-destructively, preserving both CodeQL init/analyze 4.37.6 pins. Then do only deterministic GREEN/acceptance cleanup: run focused factor-retention tests and owned statement/branch coverage/docstrings; format/lint/diff-check; render/check managed CHANGELOG from authoritative fragments; commit the minimum reconciliation/renderer correction if GREEN.

Keep Draft. No dependencies/workflows/version/release, NumPy/statistical kernels, structural model-selection expansion, canonical docs #604, Ready/approval/merge changes. Stop source writes after one coherent verified update; fresh exact-head full CI/Security/SAST/review returns to the maintainer loop.

Copy link
Copy Markdown
Contributor Author

@jules address

Fallback sole branch writer for exact Draft #617 head 6a0a75f2aa638b81c12f82e89bec37afe36d48d1 over live protected main a7be9eb8ca0b807364173f8471fc300e3cf9350f. Fresh compare is still diverged, ahead 11 / behind 2, merge base f43a466b1441b27bd2ac4a71be8aa3e4f08c8e8f, and the net branch paths remain only factor-retention implementation/tests/doctoring/changelog fragment. The latest exact-base OpenCode handoff 5235697373 has no receipt/reaction and has produced no source movement for more than six hours; treat it as inactive for this bounded fallback. Immediately refetch head/main/comments before writing and abort if either ref moves or any other current writer appears.

Preserve the already-proven fail-first history and existing governed factor-retention semantics. Reconcile the two accepted CodeQL 4.37.6 protected-main commits non-destructively; do not ours/theirs or force-push. Then run focused tests/test_factor_retention_contract.py, exact owned statement/branch coverage and docstring checks, formatting/lint and git diff --check; render managed CHANGELOG.md only through python scripts/render_changelog_fragments.py --update CHANGELOG.md, prove --check, and rerun the changelog contract. Commit one coherent minimal reconciliation/renderer update only if GREEN.

Keep Draft and stop source writes after that coherent update. Do not change factor-retention semantics, add numerical Python kernels, expand into structural-model selection, alter dependencies/workflows/version/release, touch canonical docs #604, mark Ready/approve/merge/close #608, or create another PR. Fresh exact-head CI/Security/SAST/review belongs to the maintainer loop.

Copy link
Copy Markdown
Contributor Author

Superseded by a clean-lineage replacement from exact protected main a7be9eb8ca0b807364173f8471fc300e3cf9350f. The latest #617 writer handoff (5234666131) has no reaction/receipt, and exact source head 6a0a75f2aa638b81c12f82e89bec37afe36d48d1 has remained stationary while protected main advanced materially. I reconstructed the replacement branch replacement/factor-retention-main-20260811 from the exact four surviving #617 paths only: python/fast_mlsirm/factor_retention.py, its contract test, scientific doctoring, and authoritative changelog fragment. Fresh compare proves ahead 4 / behind 0 with merge base exactly current protected main and exactly those four files. No predecessor checks/reviews transfer. Closing this stale lineage prevents a second writer authority; the replacement must recreate all exact-head CI/Security/SAST/review evidence.

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