Repository navigation
Description
Scientific/domain finding
MembershipWeight on #605 currently accepts finite [0,1], including +0.0 and -0.0. That is inconsistent with the canonical active-membership meaning and with TEPP's existing persistence boundary: MembershipAssignmentRecord::validate already rejects membership_weight <= 0.0, and migration 0006_typed_membership_assignment has CHECK (membership_weight > 0).
A zero-share edge therefore has no affiliation mass but can still enter MembershipNetwork, contribute an active group/role edge, alter classify_membership_design, and affect nested-ICC applicability. This is structural contamination, not an estimator tolerance question.
Required RED
On #605 or its verified successor:
MembershipWeight::new(+0.0)andMembershipWeight::new(-0.0)must returnInvalidMembershipWeight;- transparent serde must reject zero as well;
- the minimum positive binary64 subnormal (
f64::from_bits(1)) remains valid so the repair does not invent an epsilon threshold; 1.0remains valid and existing finite>1, negative, NaN, and infinity refusals remain intact.
Repair boundary
Change the owner VO domain from [0,1] to (0,1]. Do not clamp, renormalize, use a tolerance, or reinterpret zero as missing data. #612 exact dyadic share-budget arithmetic remains separate and may still represent arithmetic zero internally; persisted/public MembershipWeight must remain strictly positive.
Persistence follow-up
Zero is already refused by both the Rust persistence record validator and PostgreSQL 0006. A separate persistence-owner gap remains for the upper bound: MembershipAssignmentRecord::validate and the database currently accept weights above one even though membership_core rejects them. Repair that through the active persistence lineage without rewriting historical migration 0006 or colliding with #287's reserved 0008_analysis_run_persistence migration.
Acceptance
- public RED before production repair;
- minimal
(0,1]owner fix with unit/serde edge coverage; - exact-head Rust/rustdoc/test/coverage/security/CodeQL/Semgrep evidence and qualifying independent review before feat(membership): add owner-issued single-membership admission #605 lands;
- keep this issue open through protected-main landing; source repair on a mutable Draft is not completion.
Activity
seonghobae commentedon Sep 19, 2026
Source lineage is now concrete on #605. Public RED
3ee43cca54594eaba1c49324dd6fb55a3c00f49crejects+0.0/-0.0through both constructor and transparent serde while preservingf64::from_bits(1)as the smallest valid positive share. Causal repair064d5e3e285c604a431f8b87ee504a1d1ad887f0changesMembershipWeightto finite(0,1]and documents why zero-share active edges are structurally invalid. #605 is still Draft; exact-head Rust Foundation/Security/CodeQL are queued and Semgrep is pending, with no qualifying current-head approval. Keep #613 open through protected-main landing and downstream acceptance.