diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index b364318e..1a9d6980 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -71,6 +71,8 @@ boundaries above remain the target modular MSA architecture. | `location_membership` | location is not entity identity and not a language channel | | `validation_core` | RMSE, bias, coverage, graph, Monte Carlo, and exact-head claim-promotion metrics | | `tepp_api` | versioned DTO, schema, and export contracts | +| `episode_membership` | event-time episode membership containment gate | +| `location_membership` | location is not entity identity and not a language channel | | `prompt_source` | prompt boilerplate is not unique latent content and not stopword deletion | | `corpus_background` | corpus-background wording is not unique latent content and not stopword deletion | | `modality_source` | non-lexical modality is not unique latent content and not stopword deletion | diff --git a/CHANGELOG.md b/CHANGELOG.md index f375d95f..bf603f7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,9 @@ All notable changes to TEPP are documented here. The format follows Keep a Chang - `psychometric_core` posterior-aware structural input gates: construct classification, refusal of raw-proportion Pearson/OLS, explicit ALR-versus-ILR geometry boundaries, CPU `f64` OLS recovery, posterior-draw loading point-estimate averaging without Rubin uncertainty claims, invariance-gated latent-mean comparison, and causal-heuristic refusal (ADR 0005 first production slice; no new migration). ### Added +- `episode_membership` identity gate: a document's episode membership cannot + start before or end after the episode event-time interval; recovered + containment flags are compared with known truth (ADR 0003). - `tepp_simulation` cutoff eligibility: delayed-reporting documents are excluded when `available_time` exceeds the knowledge cutoff, with recovered eligible counts matching known truth. - `topic_measurement` bounded deterministic CPU `f64` TRSL-TM reference estimator: canonical CSR/CSC inputs, cutoff-safe documents, standardized event time, weighted multiple memberships, prevalence covariates, explicit predecessor/successor regularization, multi-seed generalized EM, diagonal Laplace uncertainty, and fitted topic-lineage counts with known-truth RMSE plus exact line/branch coverage (ADR 0012; no persistence or accelerated-backend claim). - `topic_measurement` logistic-normal additive log-ratio and sequential Egozcue isometric log-ratio coordinates: fail-closed simplex validation, max-shifted stable ALR/ILR inverses with true-parameter RMSE, pairwise CLR Aitchison distance recovered by ILR Euclidean isometry for valid composition pairs, and refusal of TF-IDF/BM25/keyword scores as inferential topic coordinates (ADR 0012 first production slice; no new migration). diff --git a/Cargo.lock b/Cargo.lock index 7bbfc51b..4a370781 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,9 +168,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cc" -version = "1.4.2" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "shlex", @@ -381,7 +381,7 @@ checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -396,9 +396,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "either" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" dependencies = [ "serde", ] @@ -470,9 +470,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" [[package]] name = "foldhash" @@ -672,9 +672,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", @@ -686,9 +686,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -699,9 +699,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -713,16 +713,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -733,15 +734,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -879,21 +880,21 @@ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libredox" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2026a5056764a10b2bf5d56488cba40da507f5493a6a429340e2004d9ed085fa" +checksum = "28d0a00925a9f930d679b6789b721e3a7f9ed110f41b86d2497caa780c3a070a" dependencies = [ "bitflags 2.13.1", "libc", "plain", - "redox_syscall 0.9.2", + "redox_syscall 0.9.3", ] [[package]] name = "litemap" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "location_membership" @@ -910,9 +911,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "longitudinal_core" @@ -1102,9 +1103,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ "zerovec", ] @@ -1206,9 +1207,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c93da5bb2c5d4e6c0ef7abeead62c89169a0a4882bfb83ac892f2423aea2fe" +checksum = "d678d17679829e73d371e96880897e98fee2ded7acc0a50bdf8af2affa4b2fe5" dependencies = [ "bitflags 2.13.1", ] @@ -1276,9 +1277,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.14" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "ring", "rustls-pki-types", @@ -1331,7 +1332,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -1572,9 +1573,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" dependencies = [ "proc-macro2", "quote", @@ -1647,14 +1648,14 @@ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] name = "tinystr" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", @@ -2109,9 +2110,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "writeable" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] name = "yoke" @@ -2185,9 +2186,9 @@ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", "yoke", @@ -2196,9 +2197,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -2207,13 +2208,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.4", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b36593bc..c9bf316b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ members = [ "crates/interpretation_gateway", "crates/model_selection", "crates/checkpoint_authority", + "crates/episode_membership", "crates/compute_backend", "crates/episode_membership", "crates/membership_target", @@ -107,6 +108,7 @@ default-members = [ "crates/interpretation_gateway", "crates/model_selection", "crates/checkpoint_authority", + "crates/episode_membership", "crates/compute_backend", "crates/episode_membership", "crates/membership_target", diff --git a/README.md b/README.md index c0110375..b9240a92 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,29 @@ evidence, six-clock temporal values, event mentions/instances, relations, membership, persistence, splits, simulation, validation, API DTOs, and the predicted-versus-observed promotion gate. This branch establishes the Rust workspace, quality-gate foundation, and the -longitudinal within/between decomposition capability. The eleven bounded crates +longitudinal within/between decomposition capability. The workspace bounded crates compile independently. `longitudinal_core` exposes within/between decomposition and component RMSE APIs; the remaining crates expose no placeholder production APIs, and domain behavior for them begins in Task 2 with immutable evidence identifiers and source records. +This branch establishes the Task 1 Rust workspace and quality-gate foundation. +The workspace bounded crates compile independently but intentionally expose no +The workspace bounded crates compile independently; Task 1 includes the +The twelve bounded crates compile independently but intentionally expose no +The eleven bounded crates compile independently; Task 1 includes the +implemented `encrypted_mapping` crate with AES-256-GCM sealing and +purpose-bound opening, while the remaining domain behavior begins in Task 2 +with immutable evidence identifiers and source records. +The workspace bounded crates compile independently. `derived_sensitivity` inherits +source Restricted/Internal classes onto topic, factor, and relation artifacts +and fails closed on unknown kinds; derivation and blanket PII masking are not +declassification. Other crates still begin domain behavior in Task 2 with +immutable evidence identifiers and source records. +The workspace bounded crates compile independently but intentionally expose no + +The eleven bounded crates compile independently but intentionally expose no +placeholder production APIs. Domain behavior begins in Task 2 with immutable +evidence identifiers and source records. This branch establishes the Rust workspace and quality-gate foundation. The bounded crates compile independently. Domain crates expose only validated production APIs; placeholder surfaces are prohibited. @@ -78,6 +96,12 @@ crates/operational_log crates/outcome_order crates/payload_bound crates/persistence_postgres +crates/corpus_split +crates/tepp_simulation +crates/validation_core +crates/tepp_api +crates/episode_membership +crates/location_membership crates/prediction_contradiction crates/prompt_source crates/provider_receipt diff --git a/crates/episode_membership/src/window.rs b/crates/episode_membership/src/window.rs index afe8798b..fd5fa0cc 100644 --- a/crates/episode_membership/src/window.rs +++ b/crates/episode_membership/src/window.rs @@ -72,6 +72,12 @@ pub fn identity_recovery_rate( if truth.is_empty() || truth.len() != decided.len() { return Err(EpisodeMembershipError::InvalidEpisodePayload); } + let matches = truth + .iter() + .zip(decided) + .filter(|(truth_flag, decided_flag)| truth_flag == decided_flag) + .count(); + Ok(matches as f64 / truth.len() as f64) let matches = count_matching_decisions(truth.iter().copied().zip(decided.iter().copied())); Ok(recovery_rate_from_tally(matches, truth.len())) } diff --git a/crates/episode_membership/tests/episode_membership_contract.rs b/crates/episode_membership/tests/episode_membership_contract.rs index 336e3a8c..29b9c7c6 100644 --- a/crates/episode_membership/tests/episode_membership_contract.rs +++ b/crates/episode_membership/tests/episode_membership_contract.rs @@ -27,21 +27,28 @@ fn membership_cannot_escape_the_episode_interval() { #[test] fn recovered_containment_matches_known_truth_better_than_accepting_every_membership() { - let truth = [true, false, false]; - let recovered = [true, false, false]; - let collapsed = [true, true, true]; + let cases = [ + (10, 20, 10, 18, true), + (30, 40, 32, 40, true), + (50, 60, 50, 60, true), + (70, 80, 69, 75, false), + (90, 100, 95, 101, false), + (110, 120, 112, 118, true), + ]; + let mut truth = Vec::with_capacity(cases.len()); + let mut recovered = Vec::with_capacity(cases.len()); + for (episode_start, episode_end, member_start, member_end, expected) in cases { + let episode = EventWindow::new(episode_start, episode_end).expect("episode"); + let membership = EventWindow::new(member_start, member_end).expect("membership"); + assert!(episode.start() <= episode.end()); + truth.push(expected); + recovered.push(refuse_membership_outside_episode(membership, episode).is_ok()); + } + let collapsed = vec![true; truth.len()]; let recovered_rate = identity_recovery_rate(&truth, &recovered).expect("recovered"); let collapsed_rate = identity_recovery_rate(&truth, &collapsed).expect("collapsed"); - let expected = { - let mut matches = 0_u32; - for (truth_flag, decided_flag) in truth.iter().zip(recovered.iter()) { - if truth_flag == decided_flag { - matches += 1; - } - } - f64::from(matches) / f64::from(u32::try_from(truth.len()).expect("len")) - }; - assert!((recovered_rate - expected).abs() < f64::EPSILON); + assert!((recovered_rate - 1.0).abs() < f64::EPSILON); + assert!((collapsed_rate - (2.0 / 3.0)).abs() < f64::EPSILON); assert!(recovered_rate > collapsed_rate); } diff --git a/docs/TRACEABILITY.md b/docs/TRACEABILITY.md index 04d1c97f..5bd27112 100644 --- a/docs/TRACEABILITY.md +++ b/docs/TRACEABILITY.md @@ -29,6 +29,9 @@ The full APA 7th standards/literature register remains `docs/research/standards- | forward-only transition subgraph | PRD; ADR 0002/0003 | `relation_graph` on protected main; `outcome_order` IPO event-time order on the active PR | partial | | forward-only transition subgraph | PRD; ADR 0002/0003 | `relation_graph` on protected main; `summarizes_edge` summary-versus-source identity on the active PR | partial | | forward-only transition subgraph | PRD; ADR 0002/0003 | `relation_graph` on protected main; `copy_identity` copy-versus-source identity on the active PR | partial | +| event ontology/evidence mentions | PRD; ADR 0003 | `event_core` mention/instance separation on protected main; `persistence_postgres` mention SQL implemented-main refuses mention-as-instance; event-instance SQL (#39 implemented-main) refuses inverted windows; full intelligence stack remaining | partial | +| time-varying cross-classified multiple membership | PRD; ADR 0003 | `membership_core` network on protected main; `location_membership` location-versus-entity/language identity on the active PR; multilevel estimators remaining | partial | +| episode-time membership containment | ADR 0003 | `episode_membership` refuses membership windows outside the episode event-time interval on the active PR | active-PR | | time-varying cross-classified multiple membership | PRD; ADR 0003 | `membership_core` network on protected main; `inferred_status` inferred-versus-observed identity on the active PR; multilevel estimators remaining | partial | | time-varying cross-classified multiple membership | PRD; ADR 0003 | `membership_core` network on protected main; `episode_membership` containment on the active PR; multilevel estimators remaining | partial | | time-varying cross-classified multiple membership | PRD; ADR 0003 | `membership_core` network on protected main; `location_membership` location-versus-entity/language identity on the active PR; multilevel estimators remaining | partial | diff --git a/docs/adr/0003-relational-event-multiple-membership.md b/docs/adr/0003-relational-event-multiple-membership.md index 9293ae5b..0ebe4906 100644 --- a/docs/adr/0003-relational-event-multiple-membership.md +++ b/docs/adr/0003-relational-event-multiple-membership.md @@ -1,6 +1,7 @@ # ADR 0003 — Relational event ontology and time-varying multiple membership **Decision status:** Accepted +**Implementation maturity:** partial — membership network and event mention/instance separation are implemented-main; episode membership containment, typed forward-only relation behavior, status gates, and cross-classified/multiple-membership refusal are active in this increment; full multilevel/MMMC estimators and remaining persistence remain accepted-target. **Implementation maturity:** partial — membership networks, event mention/instance separation, and the protected-main forward-transition foundation are implemented-main; `support_edge`, `outcome_order`, `retrospective_edge`, `inferred_status`, `copy_identity`, `summarizes_edge`, `subevent_containment`, `location_membership`, `episode_membership`, and typed target kinds are covered by this active consolidation PR; full multilevel/MMMC estimators and remaining persistence remain accepted-target. **Date:** 2026-08-05 **Implementation maturity:** partial — membership network, event mention/instance separation, inferred/evidential/retrospective status gates, summary/source identity separation, template-copy/source identity separation, typed forward-only relation graph, strict input-process-outcome ordering, nested ICC refusal, and subevent parent-window containment are implemented-main; full multilevel/MMMC estimators and remaining persistence remain accepted-target. @@ -19,6 +20,10 @@ TEPP represents document, passage, event, entity, revision, translation, evidenc Authors, departments, organizations, customers, partners, competitors, projects, opportunity pools, templates, languages, locations, and episodes form cross-classified, time-varying, multiple-membership assignments. Memberships carry explicit weights where scientifically justified and governed validity intervals. Customer/partner/competitor are role assignments, not immutable entity classes. +An episode assignment is accepted only when its event-time window is contained by +the episode window. Equal boundaries are valid, while inverted windows and +windows that escape either boundary fail closed. + Observed relation evidence, inferred relations, and promoted transition edges remain distinct. Relation absence is not silently interpreted as evidence of no relationship. This ADR names a **relational event ontology** and time-varying membership structure. It does not adopt, and TEPP does not implement, a statistical relational-event-model (REM) estimator family. Multilevel/non-independence measurement follows Fox and Glas (2001) and the clustered-observation discipline in the *Standards for Educational and Psychological Testing* (American Educational Research Association et al., 2014). Production multilevel IRT/ESEM/DSEM estimators remain accepted-target under ADR 0005. diff --git a/docs/adr/0012-temporal-relational-shared-latent-topic-measurement.md b/docs/adr/0012-temporal-relational-shared-latent-topic-measurement.md index 6f3fb9a6..de41bde4 100644 --- a/docs/adr/0012-temporal-relational-shared-latent-topic-measurement.md +++ b/docs/adr/0012-temporal-relational-shared-latent-topic-measurement.md @@ -1,6 +1,7 @@ # ADR 0012 — Temporal Relational Shared-Latent Topic Measurement **Decision status:** Accepted +**Implementation maturity:** partial — bounded identity, recovery, temporal lineage, network geometry, model-selection, preprocessing, method-effect, and modality gates are implemented across the foundation crates; the TRSL-TM estimator, global topic identity, method effects, and backend interchange remain accepted-target. **Implementation maturity:** partial — logistic-normal ALR/ILR coordinates, lexical-weight refusal, statistical/Pareto candidate-`K` gates, stable active/dormant/reactivated topic identity, and the bounded CPU `f64` reference estimator are implemented on the active product branch; `corpus_background`, `topic_lineage`, `network_analysis`, `model_selection`, `stopword_deletion`, `style_source`, `copied_text`, and `modality_source` implement bounded identity and recovery gates implemented-main; method effects, calibrated posterior acceptance, accelerated backends, and backend interchange remain accepted-target until implemented and protected-main integrated **Implementation maturity:** partial — `corpus_background`, `topic_lineage`, `network_analysis`, `model_selection`, `stopword_deletion`, `style_source`, `copied_text`, and `modality_source` implement bounded identity and recovery gates; the TRSL-TM estimator, method effects, global topic identity, and backend interchange remain accepted-target. **Date:** 2026-08-12 diff --git a/docs/adr/README.md b/docs/adr/README.md index 1a742559..e659bf32 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -29,6 +29,42 @@ Read [`ADR_POLICY.md`](ADR_POLICY.md) first. **Decision status and implementatio | [0021](0021-lineageweave-project-history-boundary.md) | LineageWeave project-history service boundary | Accepted | active-PR | Credential-free bounded project-history API preserves LineageWeave authorization ownership. | | [0022](0022-deterministic-analysis-run-execution.md) | Deterministic cutoff-safe analysis-run execution | Accepted | active-PR | Closes the first executable product path from accepted run to digest-bound terminal result without claiming estimator authority. | | [0001](0001-rust-first-modular-msa.md) | Rust-first numerical core and CPU `f64` reference | Accepted | partial | ADR 0011 owns cross-service/MSA authority; 0001 retains numerical/backend authority. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | partial | Typed clocks/intervals are implemented-main via `temporal_core`; input-process-outcome event-time order is `outcome_order` on the active PR. Remaining clock-identity and split enforcement stay accepted-target. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Weighted time-varying membership network/roles and the forward-transition graph are implemented-main; IPO event-time order is `outcome_order` on the active PR; full multilevel estimators and persistence remain accepted-target. ADR 0016 owns event-intelligence tasks. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | active-PR | `episode_membership` refuses episode membership windows outside the episode event-time interval; full multilevel estimators remain accepted-target. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | partial | Typed clocks/intervals are implemented-main via `temporal_core`; retrospective-reporting identity is `retrospective_edge` on the active PR. Later graph/split enforcement remains target work. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Weighted time-varying membership network/roles are implemented-main (PR #12); retrospective-reporting identity is `retrospective_edge` on the active PR; full multilevel estimators and persistence remain accepted-target. ADR 0016 owns event-intelligence tasks. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | Unmerged PR #8 is the canonical Task 3 replacement implementing typed clocks/intervals against the current protected-main lineage; conflicted PR #5 is superseded lineage. Later graph/split enforcement remains target work. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Weighted time-varying membership network/roles are implemented-main (PR #12); copy-versus-source identity is `copy_identity` on the active PR; full multilevel estimators and persistence remain accepted-target. ADR 0016 owns event-intelligence tasks. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Weighted time-varying membership network/roles are implemented-main (PR #12); summary-versus-source identity is `summarizes_edge` on the active PR; full multilevel estimators and persistence remain accepted-target. ADR 0016 owns event-intelligence tasks. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Weighted time-varying membership network/roles are implemented-main (PR #12); inferred-versus-observed identity is `inferred_status` on the active PR; full multilevel estimators and persistence remain accepted-target. ADR 0016 owns event-intelligence tasks. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | Evidential-vs-transition gate in `support_edge` on the active PR; remaining graph/split enforcement stays accepted-target. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Evidential-vs-transition identity in `support_edge` on the active PR; membership network/roles remain implemented-main; full multilevel estimators and persistence remain accepted-target. ADR 0016 owns event-intelligence tasks. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | System-clock identity in `system_clock` on the active PR; remaining graph/split enforcement stays accepted-target. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | Event-clock identity in `event_clock` on the active PR; remaining graph/split enforcement stays accepted-target. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | Assertion-clock identity in `assertion_clock` on the active PR; remaining graph/split enforcement stays accepted-target. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | Knowledge-cutoff identity is `cutoff_clock` on the active PR; typed clocks/intervals remain implemented-main via `temporal_core`. Later graph/split enforcement remains target work. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | Availability-clock identity in `available_clock` on the active PR; remaining graph/split enforcement stays accepted-target. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | Typed clocks/intervals are implemented-main; `document_clocks` refuses omitted assertion/document time on the active PR. Later graph/split enforcement remains target work. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | Provenance-vs-transition gate in `citation_edge` on the active PR; remaining graph/split enforcement stays accepted-target. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Weighted time-varying membership network/roles are active-PR (PR #12); full multilevel estimators, graph ontology, and persistence remain accepted-target. ADR 0016 owns event-intelligence tasks. | +| [0004](0004-shared-multilingual-latent-space.md) | One shared multilingual latent space with explicit invariance status | Accepted | accepted-target | ADR 0020 owns the first span-grounded unit-identity slice; ADR 0012 owns the topic estimator. | +| [0004](0004-shared-multilingual-latent-space.md) | One shared multilingual latent space with explicit invariance status | Accepted | accepted-target | Prompt-versus-unique-content identity is `prompt_source` on the active PR; ADR 0012 owns the full topic-estimator contract. | +| [0004](0004-shared-multilingual-latent-space.md) | One shared multilingual latent space with explicit invariance status | Accepted | accepted-target | Corpus-background-versus-unique-content identity is `corpus_background` on the active PR; ADR 0012 owns the full topic-estimator contract. | +| [0004](0004-shared-multilingual-latent-space.md) | One shared multilingual latent space with explicit invariance status | Accepted | accepted-target | Modality-versus-unique-content identity is `modality_source` on the active PR; ADR 0012 owns the full topic-estimator contract. | +| [0004](0004-shared-multilingual-latent-space.md) | One shared multilingual latent space with explicit invariance status | Accepted | accepted-target | Copied-versus-unique-content identity is `copied_text` on the active PR; ADR 0012 owns the full topic-estimator contract. | +| [0004](0004-shared-multilingual-latent-space.md) | One shared multilingual latent space with explicit invariance status | Accepted | accepted-target | Style-versus-unique-content identity is `style_source` on the active PR; ADR 0012 owns the full topic-estimator contract. | +| [0004](0004-shared-multilingual-latent-space.md) | One shared multilingual latent space with explicit invariance status | Accepted | partial | Default stopword-deletion refusal is `stopword_deletion` on the active PR; ADR 0012 owns the full topic-estimator/backend/global-topic contract. | +| [0005](0005-posterior-esem-dsem.md) | Posterior-aware ESEM/DSEM and valid compositional coordinates | Accepted | accepted-target | Downstream psychometric authority; upstream topic/network model is clarified by ADR 0012. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | partial | Typed clocks/intervals (merged PR #8) and Allen/path-consistency (merged PR #9) are implemented-main; superseded PRs #5/#6 are historical lineage only. Downstream estimator and remaining persistence-policy uses stay with their owning ADRs. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Membership network/roles and forward-only relation graph are implemented-main; multilevel estimators remain accepted-target. This is an ontology/membership contract, not a statistical REM paper. ADR 0016 owns event-intelligence tasks. | +| [0001](0001-rust-first-modular-msa.md) | Rust-first numerical core and CPU `f64` reference | Accepted | partial | Workspace foundation is implemented-main; checkpoint-versus-estimator authority is `checkpoint_authority` on the active PR. ADR 0011 owns cross-service/MSA authority; 0001 retains numerical/backend authority. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | active-PR | Unmerged PR #8 is the canonical Task 3 replacement implementing typed clocks/intervals against the current protected-main lineage; conflicted PR #5 is superseded lineage. Later graph/split enforcement remains target work. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | active-PR | Subevent parent-window containment in `subevent_containment` on the active PR; multilevel estimators remain accepted-target. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Membership network/roles and Kish ESS are implemented-main; this increment adds nested ICC with fail-closed cross-classified/multiple-membership refusal. Full multilevel/MMMC estimators, graph ontology, and remaining persistence stay accepted-target. ADR 0016 owns event-intelligence tasks. | +| [0004](0004-shared-multilingual-latent-space.md) | One shared multilingual latent space with explicit invariance status | Accepted | accepted-target | ADR 0012 owns the full topic-estimator/backend/global-topic contract. | +| [0005](0005-posterior-esem-dsem.md) | Posterior-aware ESEM/DSEM and valid compositional coordinates | Accepted | active-PR | CPU `f64` ESEM/DSEM fit in `psychometric_fit` on the active PR; `psychometric_core` input gates remain #49; invariance/multilevel remain accepted-target. | +| [0005](0005-posterior-esem-dsem.md) | Posterior-aware ESEM/DSEM and valid compositional coordinates | Accepted | active-PR | Within/between decomposition in `longitudinal_core` on the active PR; remaining ESEM/DSEM fit remains accepted-target. ADR 0012 owns the upstream topic/network contract. | | [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical leakage prevention | Accepted | partial | Typed clocks/intervals (merged PR #8), Allen/path-consistency (merged PR #9), the clock-identity/revision-order/document-completeness gates (`system_clock`, `event_clock`, `assertion_clock`, `cutoff_clock`, `available_clock`, `document_clocks`, `revision_order`), and the provenance/ordering gates (`citation_edge`, `support_edge`, `retrospective_edge`) are implemented-main; superseded PRs #5/#6 are historical lineage only; remaining graph/split enforcement stays accepted-target. | | [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Membership network/roles, Kish ESS, nested ICC, subevent parent-window containment (`subevent_containment`), the forward-only relation graph, evidential-vs-transition identity (`support_edge`), inferred-versus-observed identity (`inferred_status`), retrospective-reporting identity (`retrospective_edge`), summary-versus-source identity (`summarizes_edge`), copy-versus-source identity (`copy_identity`), location-versus-entity/language identity (`location_membership`), and IPO event-time order (`outcome_order`) are implemented-main; typed target-kind identity in `membership_target` is on PR #131; full multilevel estimators and persistence remain accepted-target. ADR 0016 owns event-intelligence tasks. | | [0004](0004-shared-multilingual-latent-space.md) | One shared multilingual latent space with explicit invariance status | Accepted | accepted-target | ADR 0012 owns the full topic-estimator/backend/global-topic contract. | diff --git a/docs/validation/temporal-event-foundation.md b/docs/validation/temporal-event-foundation.md index 449dce44..74da29c2 100644 --- a/docs/validation/temporal-event-foundation.md +++ b/docs/validation/temporal-event-foundation.md @@ -23,6 +23,7 @@ This report tracks exact-head scientific and engineering evidence required befor | TDT link precision/recall | `event_core` | active-PR | this PR | computed precision/recall + RMSE vs always-link | ADR 0016; `docs/research/event-link-detection-calibration.md` | | First-story FAR/miss | `event_core` | active-PR | this PR | computed FAR/miss + RMSE vs always-first | ADR 0016; `docs/research/first-story-detection-calibration.md` | | Multiple membership | `membership_core` | partial | nested ICC + non-nested refusal | unit + ESS + nested ICC recovery | Task 7 / PR #12 + #25 + this increment | +| Episode membership containment | `episode_membership` | active-PR | event-time window containment | boundary, inversion, and recovery contracts | ADR 0003 / PR #146 | | TDT tracking stability | `event_core` | active-PR | this PR | pair P/R + switch rate + RMSE vs always-one-track | ADR 0016; `docs/research/event-tracking-calibration.md` | | CHRONOS schema-slot accuracy | `event_core` | active-PR | this PR | computed slot P/R + RMSE vs always-fill | ADR 0016; `docs/research/chronos-schema-slot-calibration.md` | | TDT story segmentation | `event_core` | active-PR | this PR | computed `WindowDiff`/`Pk` + RMSE vs always-cut | ADR 0016; `docs/research/tdt-story-segmentation.md` | diff --git a/scripts/check_workspace_contract.py b/scripts/check_workspace_contract.py index 764bec93..5542ace9 100644 --- a/scripts/check_workspace_contract.py +++ b/scripts/check_workspace_contract.py @@ -62,6 +62,7 @@ "interpretation_gateway", "model_selection", "checkpoint_authority", + "episode_membership", "compute_backend", "episode_membership", "membership_target", diff --git a/tests/quality/test_check_docstrings.py b/tests/quality/test_check_docstrings.py index b990da9a..750f0e35 100644 --- a/tests/quality/test_check_docstrings.py +++ b/tests/quality/test_check_docstrings.py @@ -35,13 +35,13 @@ def test_live_repository_is_documented(self) -> None: len(contract.EXPECTED_CRATES), "workspace crate inventory must not contain duplicate entries", ) + self.assertEqual(len(crate_roots), len(contract.EXPECTED_CRATES)) expected_crate_roots = { REPOSITORY_ROOT / path / "src" / "lib.rs" for path in contract.expected_member_paths() } self.assertEqual(set(crate_roots), expected_crate_roots) self.assertEqual(len(crate_roots), len(contract.EXPECTED_CRATES)) - self.assertEqual(len(crate_roots), len(contract.EXPECTED_CRATES)) self.assertTrue(set(crate_roots).issubset(sources)) self.assertGreaterEqual(len(sources), len(crate_roots)) self.assertEqual(docstrings.validate_repository(REPOSITORY_ROOT), [])