diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index e6dafbcc2..7fc31b14b 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -2,227 +2,179 @@ ## Product definition -TEPP is a Temporal Event Psychometrics Platform. It measures multilingual semantic evidence, links documents and event mentions through typed temporal relations, estimates shared latent topic and higher-order psychometric structures, and renders the resulting evidence, uncertainty, trajectories, and networks. +TEPP is the Temporal Event Psychometrics Platform. It measures multilingual documentary evidence as fallible observations of semantic, event, and psychological structure while preserving temporal eligibility, relation provenance, multilevel/multiple-membership structure, uncertainty, and scientific claim boundaries. + +The approved product target is defined in [`docs/product/prd-v0.4-approved.md`](docs/product/prd-v0.4-approved.md). Strategic DDD ownership is defined in [`docs/architecture/domain-context-map.md`](docs/architecture/domain-context-map.md). Cross-repository psychometric/dependence ownership is governed by ADR 0011 and [`docs/architecture/temporal-dependence-composition.md`](docs/architecture/temporal-dependence-composition.md). ```mermaid flowchart LR - A[Immutable documents and metadata] --> B[Evidence ingestion] - B --> C[Temporal and event normalization] - C --> D[Multilingual semantic units] - D --> E[Shared-latent temporal topic measurement] - C --> F[Typed document-event-entity graph] - E --> G[Posterior topic coordinates] - F --> G - G --> H[Longitudinal ESEM and DSEM] - G --> I[Topic and event networks] - H --> J[Evidence-grounded interpretation] - I --> J - J --> K[Accessible visual analytics and exports] + E[Evidence & Semantic Measurement] --> T[Temporal Event Knowledge] + E --> M[Topic Measurement] + T --> M + T --> L[Longitudinal Modeling] + M --> L + M --> A[Analysis Run] + L --> A + A --> V[Validation Evidence] + V --> P[Claim Promotion] + A --> R[Projection / Read Models] + P --> R + R --> I[Evidence-grounded Interpretation] ``` -## Bounded services and Rust crates - -| Boundary | Primary responsibility | -|---|---| -| `evidence_ingestion` | immutable source bytes, hashes, layout, exact spans, metadata, provenance | -| `temporal_core` | instants, intervals, uncertain dates, partial orders, bitemporal availability and leakage gates | -| `event_ontology` | event mentions, event instances, roles, subevents, products, factors, places, and evidence links | -| `relation_graph` | typed document, segment, event, entity, revision, translation, evidence, and transition edges | -| `membership_model` | time-varying cross-classified and multiple-membership assignments | -| `semantic_preprocessor` | Unicode, segmentation, morphology, dependency phrases, LLM span contracts, validation | -| `concept_dictionary` | versioned multilingual concept alignment and unknown-concept review | -| `topic_measurement` | shared-latent temporal/relational topic estimation and uncertainty | -| `compute_backend` | CPU `f64`, fixed-pool multithreading, CUDA/WGPU, sparse streaming, VRAM budgeting | -| `model_selection` | fitted candidate-K scoring from the CPU reference, predictive fit, coherence, exclusivity, stability, alignment, fairness, blinded LLM review | -| `psychometric_core` | posterior-plausible-value ESEM, longitudinal invariance, DSEM, continuous-time paths | -| `event_intelligence` | TDT segmentation/link/detection/first-story/tracking and CHRONOS schema reasoning | -| `network_analysis` | log-ratio topic correlation, conditional networks, uncertainty, Leiden consensus clusters | -| `interpretation_gateway` | evidence-bounded LLM interpretation, independent verification, routing and ablations | -| `artifact_service` | model registry, manifests, JSON-LD, GraphML, Arrow/Parquet, tables, SVG/PDF exports | -| `visual_analytics` | bitemporal lens, event graph, topic river, drift, ESEM/DSEM builder, invariance and leakage audit | - -Every boundary must be independently usable and expose versioned contracts for integration with organization repositories, `naruon`, and `contextual-orchestrator`. - -The `analysis_engine` vertical slice is intentionally separate from `tepp_api`: -the API owns wire contracts while the engine owns deterministic execution. It -does not replace the future topic or psychometric estimators and does not read -another service's application tables. - -## Implemented foundation topology - -Task 1 materializes the first storage-independent workspace boundaries. The -crate names are stable implementation identifiers, while the broader service -boundaries above remain the target modular MSA architecture. - -| Rust crate | Initial responsibility | -|---|---| -| `evidence_core` | immutable evidence domain primitives | -| `semantic_core` | span-grounded semantic units; language is not identity | -| `location_membership` | location is not entity identity and not a language channel | -| `temporal_core` | typed clocks, intervals, and temporal reasoning | -| `event_core` | event instances, span-grounded `EventMention` (the only constructible mention type), roles, provenance, and CHRONOS occurrence-prediction calibration | -| `relation_graph` | typed relations and forward-transition validation | -| `membership_core` | time-varying cross-classified multiple membership, Kish ESS, nested ICC with non-nested refusal | -| `role_contradiction` | customer and competitor cannot occupy the same group | -| `relation_absence` | unobserved relation pairs are not evidence of no relationship | -| `persistence_postgres` | PostgreSQL repositories and migrations | -| `corpus_split` | cutoff-safe, relation-aware partitioning | -| `tepp_simulation` | known-truth temporal/event data generation | -| `validation_core` | RMSE, bias, coverage, graph, Monte Carlo, and exact-head claim-promotion metrics | -| `tepp_api` | versioned DTO, schema, terminal-result, and export contracts | -| `analysis_engine` | bounded cutoff-safe temporal evidence readiness execution and digest-bound terminal artifacts | -| `episode_membership` | event-time episode membership containment gate | -| `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 | -| `copied_text` | copied-text residue is not unique latent content and not stopword deletion | -| `style_source` | house-voice style residue is not unique latent content and not stopword deletion | -| `stopword_deletion` | default stopword deletion is not a valid method for repeated report language | -| `copy_identity` | a template copy is not the source document and not a state transition | -| `intake_authorization` | untrusted intake fails closed without a grant; bounds are not authorization | -| `summarizes_edge` | a summary is not a state transition and not the source document | -| `outcome_order` | input-process-outcome edges cannot move backward in event time | -| `retrospective_edge` | retrospective reporting cannot become a transition or a translation | -| `payload_bound` | untrusted documents, records, checkpoints, and LLM outputs fail closed without identity, provenance, size, and depth | -| `inferred_status` | inferred relations cannot be promoted to observed evidence or transitions | -| `support_edge` | support, contradiction, summary, and outcome_of edges are not state transitions | -| `system_clock` | system time cannot be replaced by event, assertion, document, available, or cutoff time | -| `event_clock` | event time cannot be replaced by assertion, system, document, or available time | -| `assertion_clock` | assertion time cannot be replaced by event, system, document, or available time | -| `cutoff_clock` | knowledge cutoff cannot be replaced by event, system, or availability time | -| `available_clock` | availability time cannot be replaced by event or system time | -| `document_clocks` | document rows must carry assertion time and document time | -| `revision_order` | later document revisions must have later system time | -| `encrypted_mapping` | purpose-bound in-memory AES-256-GCM identity mappings; no plaintext persistence or KMS integration | -| `citation_edge` | citation, revision, translation, and retrospective edges are not state transitions | -| `psychometric_fit` | CPU `f64` ESEM loading recovery and event-time DSEM lag gates | -| `subevent_containment` | subevent event-time intervals must stay inside the parent | -| `prediction_contradiction` | Allen promotion gate: `before`/`after` stay contradictory; `meets`/`met_by` stay unsupported; coverage is required before unmatched predicted mass may be authorized for promotion | -| `provider_receipt` | provider-disclosure field-code receipts; source text and identity are not disclosable | -| `operational_log` | operational logs; `try_record` is the only recording API; source text and source identity are not loggable; `persistence_postgres` `audit_event` inserts call the same gate | -| `service_tls` | production TLS bind gates and rustls server config | -| `derived_sensitivity` | derived topic/factor/relation outputs inherit source sensitivity | -| `longitudinal_core` | active-PR: within/between decomposition; refuse between-as-within; component RMSE | -| `topic_lineage` | global topic identity across active/dormant/reactivated states | -| `network_analysis` | compositional cluster-pair gates; raw simplex is not Euclidean | -| `interpretation_gateway` | evidence-bounded LLM interpretations; not estimators or observed facts | -| `orchestrator_live` | loopback interpretation HTTP/1.1 listener | -| `model_selection` | fitted candidate-`K` scoring from the CPU `f64` reference plus statistical/Pareto gates; LLM votes are not numerical authority | -| `checkpoint_authority` | a model checkpoint is not the CPU `f64` estimator | -| `compute_backend` | VRAM-budgeted streamed planning, executable OOM retry plans, and a compensated CPU `f64` reference | -| `episode_membership` | episode membership cannot escape the episode event-time interval | -| `membership_target` | language, episode, template, department, and opportunity-pool targets cannot collapse into entity or project | -| `topic_measurement` | logistic-normal ALR/ILR coordinates and the CPU `f64` TRSL-TM reference estimator | -| `analysis_engine` | bounded cutoff-safe temporal evidence readiness execution and digest-bound terminal artifacts | -| `psychometric_core` | posterior-aware structural input gates, CWC within/between OLS plus the contextual effect, event-time log-rate, unequal-interval discrete-lag remapping, constant-predictor discrete effect, time-varying-predictor discrete effect (Eq. 14), exact scalar discrete process noise (Driver et al., 2017, Eq. 3), lagged latent covariance and unconditional latent variance (Driver et al., 2017, Eq. 3–4), stationary within-subject variance (Driver et al., 2017, Eq. 4 as `Δt → ∞`; `asymDIFFUSION`), trait-plus-state variance (Driver et al., 2017, §4.3 `TRAITVAR`; not process noise), observed-indicator variance and lagged observed covariance (Driver et al., 2017, Eq. 5; Table 2 `MANIFESTVAR` is `Θ`, not `Var(y)`; `MANIFESTTRAITVAR` is not `MANIFESTVAR`; `Θ` does not enter lagged observed covariance; observed-indicator mean is `τ + λ μ`; `MANIFESTMEANS` is not `E(y)`; `CINT` is not `MANIFESTMEANS`; discrete latent mean is `exp(a Δt) μ_0 + (exp(a Δt) − 1)/a κ`; `T0MEANS` is not `μ_t`; `CINT` is not the discrete increment; evolved observed mean is `τ + λ μ_t`; `τ + λ μ_0` is not `E(y_t)`; contemporaneous `TDPREDEFFECT` impulse is `m x`, not `CINT`, not `TIPREDEFFECT`, and not Voelkle Eq. 14; Eq. 5 of that contemporaneous impulse is `τ + λ(μ_t + m x)`, and `τ + λ μ_t` is not that observed mean; time-independent `TIPREDEFFECT` increment is `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, not `M x`, not Voelkle Eq. 14, and not the coefficient `B`; Eq. 5 of that increment is `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that observed mean; `τ + λ(μ_t + e^{a(t−u)} m x)` is not that observed mean when `u ≠ t`; within-interval `TDPREDEFFECT` carry is `e^{A(t−u)} M x` for `t0 < u < t`, not the contemporaneous Dirac, not `CINT`, not `TIPREDEFFECT`, and not Voelkle Eq. 14; Eq. 5 of that carry is `τ + λ(μ_t + e^{a(t−u)} m x)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that carried observed mean when `u ≠ t`; first-occasion `T0TIPREDEFFECT` shift is `t0_b z` and Eq. 3 first-summand carry is `e^{A Δt} t0_b z` (`T0TIPREDEFFECT` is not `TIPREDEFFECT` `B`; `t0_b z` is not `A^{-1}[e^{A Δt} − I] B z`; `e^{A Δt} t0_b z` is not `t0_b z`; Eq. 5 of that carry is `τ + λ(μ_t + e^{a Δt} t0_b z)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not that observed mean), first-occasion `T0TDPREDEFFECT` shift is `t0_m x0` and Eq. 3 first-summand carry is `e^{A Δt} t0_m x0` (`T0TDPREDEFFECT` is not `TDPREDEFFECT` `M`; `t0_m x0` is not `M x`; `e^{A Δt} t0_m x0` is not `t0_m x0`; `e^{A Δt} t0_m x0` is not `e^{A(t−u)} M x` for `t0 < u < t`; `t0_m x0` is not `t0_b z`; an impulse at `u ≤ t0` that used `M` is already in `η(t0)` as `TDPREDEFFECT`, not as `T0TDPREDEFFECT`; Eq. 5 of that carry is `τ + λ(μ_t + e^{a Δt} t0_m x0)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not that observed mean; `τ + λ(μ_t + e^{a Δt} t0_b z)` is not that observed mean; §7.2 level-change `CINT` is `κ = −a m x` with `a < 0` so `−κ / a = m x` (`−a m x` is not the dissipating Dirac, not a free `CINT`, not `TIPREDEFFECT`, and not the extra near-zero-drift latent process also named in §7.2; Eq. 3 of that setting is `(1 − e^{a Δt}) m x`, which is not `m x`, not `κ`, and not `TIPREDEFFECT`; §7.2 extra-process contribution is `a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)` (`ε = a` is `a_{ηξ} x Δt e^{a Δt}`; identification `TDPREDEFFECT` on the extra process is 1; printed extra `DRIFT` is `−0.000001`; not `κ = −a m x`, not `(1 − e^{a Δt}) m x`, and not the dissipating Dirac `m x`; `ε ≥ 0` fails closed; Eq. 5 of that contribution is `τ + λ(μ_t + a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)`; the extra process has `LAMBDA` 0 and is not an observed indicator; `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that observed mean; the contribution is not `E(y_t)`; the evolved-plus-contribution latent mean is not `E(y_t)`; after-t0 extra-process `TDPREDEFFECT` is `a_{ηξ} x (e^{ε(t−u)} − e^{a(t−u)}) / (ε − a)` for `t0 < u < t` while `μ_t` uses `Δt`; Eq. 5 of that after-t0 contribution is `τ + λ(μ_t + a_{ηξ} x (e^{ε(t−u)} − e^{a(t−u)}) / (ε − a)`; the first-occasion extra-process observed mean is not that observed mean when `u ≠ t0`; `e^{a(t−u)} m x` is a Dirac on the original process, not this `DRIFT` drive; §7.2 `asymTIPREDEFFECT` is `-B z / a` for `a < 0` (`-B z / a` is not the coefficient `B`, not `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, and not `M x`; §7.2 `addedTIPREDVAR` is `(B / a)² v`, not `TRAITVAR`, not `asymDIFFUSION`, and not `-B z / a`; Table 2 `asymCINT` is `-κ / a` for `a < 0` and is not `κ`, not `A^{-1}[e^{A Δt} − I] κ`, not `T0MEANS`, and not `-B z / a`; p. 16 stationary `T0MEANS` is `-κ / a + −B z / a` and is not free `T0MEANS`, not `asymCINT` alone, not `asymTIPREDEFFECT` alone, and not the finite-interval discrete latent mean; Eq. 5 of that constrained mean is `τ + λ(−κ / a + −B z / a)`; `τ + λ μ_0` is not that observed mean; `τ + λ(−κ / a)` is not that observed mean when `B z ≠ 0`; `τ + λ μ_t` is not that observed mean; `MANIFESTMEANS` is not `E(y_0)`; the constrained latent mean is not `E(y_0)`; stationary `T0VAR` is `trait + −q / (2 a) + (B / a)² v` (not free `T0VAR`, not `asymDIFFUSION` alone, not `TRAITVAR` alone, not `addedTIPREDVAR` alone, and not the finite-interval discrete latent variance. Eq. 5 of that constrained variance is `λ²(trait + −q / (2 a) + (B / a)² v) + θ + ψ` (JSS PDF re-opened 2026-08-22T03:20Z; form the stationary latent variance first, then `λ² p + θ + ψ`; `λ² p_0` is not that observed variance; `λ²(−q / (2 a)) + θ` is not that observed variance when `TRAITVAR` or `addedTIPREDVAR` is nonzero; `MANIFESTVAR` is not `Var(y_0)`; the constrained latent variance is not `Var(y_0)`); lagged stationary `T0VAR` is `trait + e^{a Δt}(−q / (2 a)) + (B / a)² v` (trait and `addedTIPREDVAR` do not decay; contemporaneous `T0VAR` is not that lagged map; decaying the constrained total as if it were all state is not that lagged map; Eq. 5 of that lagged covariance is `λ²(trait + e^{a Δt}(−q / (2 a)) + (B / a)² v) + ψ`; `Θ` does not enter; contemporaneous `Var(y_0)` is not that lagged observed covariance; the lagged latent covariance is not that observed covariance); later-occasion stationary `T0VAR` is `trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v` (trait and `addedTIPREDVAR` do not enter `Q_Δt`; under stationarity that composition equals contemporaneous `T0VAR`; evolving the constrained total as if it were all state is not that later map; the lagged covariance omits `Q_Δt`; `Q_Δt` is not that later map; Eq. 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v) + θ + ψ`; lagged observed covariance omits `Q_Δt` and `θ`; `MANIFESTVAR` is not `Var(y_t)`; the later-occasion latent variance is not `Var(y_t)`))), irregular already-centered residual lag, Rubin `T` on OLS loadings, and strong-gated latent means (two-observation residual variance is identically `0` and caps at strong/scalar; Putnick & Bornstein, 2016) | -| `validation_core` | RMSE, bias, coverage, graph, and Monte Carlo metrics | -| `tepp_api` | versioned DTO, schema, and export contracts | -| `psychometric_core` | posterior-aware structural input gates, CWC within/between OLS plus the contextual effect, event-time log-rate, unequal-interval discrete-lag remapping, constant-predictor discrete effect, time-varying-predictor discrete effect (Eq. 14), exact scalar discrete process noise (Driver et al., 2017, Eq. 3), lagged latent covariance and unconditional latent variance (Driver et al., 2017, Eq. 3–4), stationary within-subject variance (Driver et al., 2017, Eq. 4 as `Δt → ∞`; `asymDIFFUSION`), trait-plus-state variance (Driver et al., 2017, §4.3 `TRAITVAR`; not process noise), observed-indicator variance and lagged observed covariance (Driver et al., 2017, Eq. 5; Table 2 `MANIFESTVAR` is `Θ`, not `Var(y)`; `MANIFESTTRAITVAR` is not `MANIFESTVAR`; `Θ` does not enter lagged observed covariance; observed-indicator mean is `τ + λ μ`; `MANIFESTMEANS` is not `E(y)`; `CINT` is not `MANIFESTMEANS`; discrete latent mean is `exp(a Δt) μ_0 + (exp(a Δt) − 1)/a κ`; `T0MEANS` is not `μ_t`; `CINT` is not the discrete increment; evolved observed mean is `τ + λ μ_t`; `τ + λ μ_0` is not `E(y_t)`; contemporaneous `TDPREDEFFECT` impulse is `m x`, not `CINT`, not `TIPREDEFFECT`, and not Voelkle Eq. 14; Eq. 5 of that contemporaneous impulse is `τ + λ(μ_t + m x)`, and `τ + λ μ_t` is not that observed mean; time-independent `TIPREDEFFECT` increment is `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, not `M x`, not Voelkle Eq. 14, and not the coefficient `B`; Eq. 5 of that increment is `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that observed mean; `τ + λ(μ_t + e^{a(t−u)} m x)` is not that observed mean when `u ≠ t`; within-interval `TDPREDEFFECT` carry is `e^{A(t−u)} M x` for `t0 < u < t`, not the contemporaneous Dirac, not `CINT`, not `TIPREDEFFECT`, and not Voelkle Eq. 14; Eq. 5 of that carry is `τ + λ(μ_t + e^{a(t−u)} m x)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that carried observed mean when `u ≠ t`; first-occasion `T0TIPREDEFFECT` shift is `t0_b z` and Eq. 3 first-summand carry is `e^{A Δt} t0_b z` (`T0TIPREDEFFECT` is not `TIPREDEFFECT` `B`; `t0_b z` is not `A^{-1}[e^{A Δt} − I] B z`; `e^{A Δt} t0_b z` is not `t0_b z`; Eq. 5 of that carry is `τ + λ(μ_t + e^{a Δt} t0_b z)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not that observed mean), first-occasion `T0TDPREDEFFECT` shift is `t0_m x0` and Eq. 3 first-summand carry is `e^{A Δt} t0_m x0` (`T0TDPREDEFFECT` is not `TDPREDEFFECT` `M`; `t0_m x0` is not `M x`; `e^{A Δt} t0_m x0` is not `t0_m x0`; `e^{A Δt} t0_m x0` is not `e^{A(t−u)} M x` for `t0 < u < t`; `t0_m x0` is not `t0_b z`; an impulse at `u ≤ t0` that used `M` is already in `η(t0)` as `TDPREDEFFECT`, not as `T0TDPREDEFFECT`; Eq. 5 of that carry is `τ + λ(μ_t + e^{a Δt} t0_m x0)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not that observed mean; `τ + λ(μ_t + e^{a Δt} t0_b z)` is not that observed mean; §7.2 level-change `CINT` is `κ = −a m x` with `a < 0` so `−κ / a = m x` (`−a m x` is not the dissipating Dirac, not a free `CINT`, not `TIPREDEFFECT`, and not the extra near-zero-drift latent process also named in §7.2; Eq. 3 of that setting is `(1 − e^{a Δt}) m x`, which is not `m x`, not `κ`, and not `TIPREDEFFECT`; §7.2 extra-process contribution is `a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)` (`ε = a` is `a_{ηξ} x Δt e^{a Δt}`; identification `TDPREDEFFECT` on the extra process is 1; printed extra `DRIFT` is `−0.000001`; not `κ = −a m x`, not `(1 − e^{a Δt}) m x`, and not the dissipating Dirac `m x`; `ε ≥ 0` fails closed; Eq. 5 of that contribution is `τ + λ(μ_t + a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)`; the extra process has `LAMBDA` 0 and is not an observed indicator; `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that observed mean; the contribution is not `E(y_t)`; the evolved-plus-contribution latent mean is not `E(y_t)`; after-t0 extra-process `TDPREDEFFECT` is `a_{ηξ} x (e^{ε(t−u)} − e^{a(t−u)}) / (ε − a)` for `t0 < u < t` while `μ_t` uses `Δt`; Eq. 5 of that after-t0 contribution is `τ + λ(μ_t + a_{ηξ} x (e^{ε(t−u)} − e^{a(t−u)}) / (ε − a)`; the first-occasion extra-process observed mean is not that observed mean when `u ≠ t0`; `e^{a(t−u)} m x` is a Dirac on the original process, not this `DRIFT` drive; §7.2 `asymTIPREDEFFECT` is `-B z / a` for `a < 0` (`-B z / a` is not the coefficient `B`, not `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, and not `M x`; §7.2 `addedTIPREDVAR` is `(B / a)² v`, not `TRAITVAR`, not `asymDIFFUSION`, and not `-B z / a`; Table 2 `asymCINT` is `-κ / a` for `a < 0` and is not `κ`, not `A^{-1}[e^{A Δt} − I] κ`, not `T0MEANS`, and not `-B z / a`; p. 16 stationary `T0MEANS` is `-κ / a + −B z / a` and is not free `T0MEANS`, not `asymCINT` alone, not `asymTIPREDEFFECT` alone, and not the finite-interval discrete latent mean; Eq. 5 of that constrained mean is `τ + λ(−κ / a + −B z / a)`; `τ + λ μ_0` is not that observed mean; `τ + λ(−κ / a)` is not that observed mean when `B z ≠ 0`; `τ + λ μ_t` is not that observed mean; `MANIFESTMEANS` is not `E(y_0)`; the constrained latent mean is not `E(y_0)`; stationary `T0VAR` is `trait + −q / (2 a) + (B / a)² v` (not free `T0VAR`, not `asymDIFFUSION` alone, not `TRAITVAR` alone, not `addedTIPREDVAR` alone, and not the finite-interval discrete latent variance. Eq. 5 of that constrained variance is `λ²(trait + −q / (2 a) + (B / a)² v) + θ + ψ` (JSS PDF re-opened 2026-08-22T03:20Z; form the stationary latent variance first, then `λ² p + θ + ψ`; `λ² p_0` is not that observed variance; `λ²(−q / (2 a)) + θ` is not that observed variance when `TRAITVAR` or `addedTIPREDVAR` is nonzero; `MANIFESTVAR` is not `Var(y_0)`; the constrained latent variance is not `Var(y_0)`); lagged stationary `T0VAR` is `trait + e^{a Δt}(−q / (2 a)) + (B / a)² v` (trait and `addedTIPREDVAR` do not decay; contemporaneous `T0VAR` is not that lagged map; decaying the constrained total as if it were all state is not that lagged map; Eq. 5 of that lagged covariance is `λ²(trait + e^{a Δt}(−q / (2 a)) + (B / a)² v) + ψ`; `Θ` does not enter; contemporaneous `Var(y_0)` is not that lagged observed covariance; the lagged latent covariance is not that observed covariance); later-occasion stationary `T0VAR` is `trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v` (trait and `addedTIPREDVAR` do not enter `Q_Δt`; under stationarity that composition equals contemporaneous `T0VAR`; evolving the constrained total as if it were all state is not that later map; the lagged covariance omits `Q_Δt`; `Q_Δt` is not that later map; Eq. 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v) + θ + ψ`; lagged observed covariance omits `Q_Δt` and `θ`; `MANIFESTVAR` is not `Var(y_t)`; the later-occasion latent variance is not `Var(y_t)`); predetermined later-occasion `T0VAR` is `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v` (free `T0VAR` `p_0` is not that later map; setting `p_0 = −q / (2 a)` recovers the stationary later-occasion map; stationary later variance uses `−q / (2 a)` in place of `p_0` and is not that later map when `p_0` is free; evolving `trait + p_0 + (B / a)² v` as if it were all state is not that later map; Eq. 5 of that predetermined later-occasion variance is `λ²(trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v) + θ + ψ`; `MANIFESTVAR` is not `Var(y_t)`; the predetermined later-occasion latent variance is not `Var(y_t)`; stationary later observed variance is not that observed variance when `p_0` is free); predetermined lagged `T0VAR` is `trait + e^{a Δt} p_0 + (B / a)² v` (free `T0VAR` `p_0` is not that lagged map; setting `p_0 = −q / (2 a)` recovers the stationary lagged map; stationary lagged covariance uses `−q / (2 a)` in place of `p_0` and is not that lagged map when `p_0` is free; evolving `trait + p_0 + (B / a)² v` as if it were all state is not that lagged map; later-occasion variance includes `Q_Δt` and is not that lagged map; Eq. 5 of that predetermined lagged covariance is `λ²(trait + e^{a Δt} p_0 + (B / a)² v) + ψ`; `MANIFESTVAR` does not enter; the predetermined lagged latent covariance is not that observed covariance; predetermined later observed variance includes `Q_Δt` and `θ` and is not that lagged observed covariance; stationary lagged observed covariance is not that observed covariance when `p_0` is free; the predetermined first-occasion variance of §4.3 predetermined `T0VAR` is `trait + p_0 + (B / a)² v`; free `p_0` is not that map; stationary first-occasion variance uses `−q / (2 a)` in place of `p_0` and is not that map when `p_0` is free; lagged covariance decays the state and is not that map; later-occasion variance includes `Q_Δt` and is not that map; Eq. 5 of that predetermined first-occasion variance is `λ²(trait + p_0 + (B / a)² v) + θ + ψ`; `MANIFESTVAR` is not that first-occasion observed variance; the predetermined first-occasion latent variance is not that observed variance; stationary first-occasion observed variance is not that observed variance when `p_0` is free; predetermined later observed variance includes `Q_Δt` and is not that first-occasion observed variance; later-start lagged covariance of predetermined `T0VAR` is `trait + e^{a s}(e^{2 a u} p_0 + Q_u) + (B / a)² v` (Driver et al., 2017, §4.3 `startoffset`; Eq. 4; JSS PDF re-opened 2026-08-23T10:27Z; first-occasion lagged omits `e^{a s} Q_u`; later-occasion variance does not lag; stationary lagged uses `−q / (2 a)`; decaying the later total is not that map; Eq. 5 of that later-start lagged covariance is `λ²` of it plus `ψ`; `Θ` does not enter; first-occasion lagged observed omits `e^{a s} Q_u`; later observed variance includes `Q_u` and `θ`; later-start later-occasion variance of predetermined `T0VAR` is `trait + e^{2 a s}(e^{2 a u} p_0 + Q_u) + Q_s + (B / a)² v` (Driver et al., 2017, §4.3 `startoffset`; Eq. 3–4 Chapman–Kolmogorov `Q_{u+s} = e^{2 a s} Q_u + Q_s`; JSS PDF re-opened 2026-08-23T11:05Z; later-occasion variance at `u` omits `Q_s`; later-start lagged covariance omits `Q_s`; stationary later uses `−q / (2 a)`; evolving the later total as if it were all state is not that map; ignoring `startoffset` omits `e^{2 a s} Q_u`; Eq. 5 of that later-start later-occasion variance is `λ²` of it plus `θ + ψ`; `MANIFESTVAR` is not that observed variance; p. 16 `discreteDRIFTstd` is `e^{a Δt}` after strictly positive `asymDIFFUSION` `-q / (2 a)` (footnote 4; unstandardised `e^{a Δt}` is defined for growing `a ≥ 0` and for zero diffusion and is not `discreteDRIFTstd`; the §7.1 trait-plus-state autocorrelation uses `TRAITVAR` and is not `discreteDRIFTstd`; `TRAITVAR` is not the standardisation variance; p. 16 `discreteDIFFUSIONstd` is `Q_Δt / (−q / (2 a))` after strictly positive `asymDIFFUSION` `-q / (2 a)` (footnote 4; unstandardised `Q_Δt` is defined for growing `a ≥ 0` and for zero diffusion and is not `discreteDIFFUSIONstd`; the continuous standardisation `−2 a` is not `discreteDIFFUSIONstd`; `Q_Δt / (trait + p + added)` uses `TRAITVAR` and is not `discreteDIFFUSIONstd`; `TRAITVAR` is not the standardisation variance; p. 16 `DIFFUSIONstd` is `q / (−q / (2 a)) = −2 a` after strictly positive `asymDIFFUSION` `-q / (2 a)` (Driver et al., 2017, p. 16; Eq. 4; footnote 4; JSS PDF re-opened 2026-08-23T13:20Z; unstandardised `q` is defined for growing `a ≥ 0` and for zero diffusion and is not `DIFFUSIONstd`; the discrete standardisation `Q_Δt / (−q / (2 a))` depends on `Δt` and is not `DIFFUSIONstd`; `q / (trait + p + added)` uses `TRAITVAR` and is not `DIFFUSIONstd`; `TRAITVAR` is not the standardisation variance; p. 16 `DRIFTstd` is the continuous auto-effect after strictly positive `asymDIFFUSION` `-q / (2 a)` (Driver et al., 2017, p. 16; Eq. 1; footnote 4; JSS PDF re-opened 2026-08-23T13:28Z); unstandardised `a` is defined for growing `a ≥ 0` and for zero diffusion and is not `DRIFTstd`; the discrete standardisation `e^{a Δt}` depends on the event interval and is not `DRIFTstd`; `a p / (trait + p + added)` uses `TRAITVAR` and is not `DRIFTstd`; `TRAITVAR` is not the standardisation variance); p. 16 `asymTIPREDEFFECTstd` is `(-B / a) · √v / √(-q / (2 a))` after strictly positive `asymDIFFUSION` `-q / (2 a)` and strictly positive predictor variance `v` (Driver et al., 2017, p. 16; §7.2; footnote 4; JSS PDF re-opened 2026-08-23T14:25Z; unstandardised `-B / a` is defined for a zero coefficient and for zero predictor variance and is not `asymTIPREDEFFECTstd`; the finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not `asymTIPREDEFFECTstd`; `(-B / a) · √v / √(trait + p + added)` uses `TRAITVAR` and is not `asymTIPREDEFFECTstd`; `TRAITVAR` is not the standardisation variance); p. 16 `TIPREDEFFECTstd` is `B · √v / √(-q / (2 a))` after strictly positive `asymDIFFUSION` `-q / (2 a)` and strictly positive predictor variance `v` (Driver et al., 2017, p. 16; §7.2; footnote 4; JSS PDF re-opened 2026-08-23T16:21Z; unstandardised `B` is defined for a zero coefficient and for zero predictor variance and is not `TIPREDEFFECTstd`; the asymptotic standardisation `(-B / a) · √v / √p` is the total change and is not `TIPREDEFFECTstd`; the finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not `TIPREDEFFECTstd`; `B · √v / √(trait + p + added)` uses `TRAITVAR` and is not `TIPREDEFFECTstd`; `TRAITVAR` is not the standardisation variance); Table 3 `T0TIPREDEFFECTstd` is `t0_b · √v / √p_0` after strictly positive free `T0VAR` `p_0` and strictly positive predictor variance `v` (Driver et al., 2017, Table 3, p. 13; p. 16; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T17:20Z; the affected variance is free `T0VAR`, not `asymDIFFUSION`; unstandardised `t0_b` is defined for a zero coefficient and for zero predictor variance and is not `T0TIPREDEFFECTstd`; `TIPREDEFFECTstd` `B · √v / √(-q / (2 a))` is the continuous coefficient and is not `T0TIPREDEFFECTstd`; `asymTIPREDEFFECTstd` `(-B / a) · √v / √p` is the total change and is not `T0TIPREDEFFECTstd`; `t0_b · √v / √(trait + p_0 + added)` uses `TRAITVAR` and is not `T0TIPREDEFFECTstd`; `TRAITVAR` is not the standardisation variance); 2017-era `addedT0TIPREDVAR` is `t0_b² v` (Driver et al., 2017, Table 3, p. 13; p. 16; §7.2; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T18:20Z; `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`; form `t0_b` first, then square, then multiply by `v`; a zero coefficient or zero predictor variance is exactly zero; free `T0TIPREDEFFECT` does not require `a < 0`; `(B / a)² v` is `addedTIPREDVAR` and is not this first-occasion map; `t0_b · √v / √p_0` is `T0TIPREDEFFECTstd` and is not this variance; free `T0VAR` is not this extra TI variance; `TRAITVAR` is not this extra TI variance; Equation 5 of 2017-era `addedT0TIPREDVAR` is `λ² t0_b² v` (Driver et al., 2017, Eq. 5, p. 5; Table 3, p. 13; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T19:10Z; form `t0_b² v` first, then `(λ extra) λ` with `θ = 0`; a zero loading or zero extra is exactly zero; `t0_b² v` is the latent extra, not the observed extra; `λ² p_0 + θ` is first-occasion observed variance, not this extra; `λ² (B / a)² v` is Eq. 5 of `addedTIPREDVAR`, not this first-occasion observed extra; `MANIFESTVAR` `θ` is not this extra; Equation 5 of §7.2 `addedTIPREDVAR` is `λ² (B / a)² v`; form `(B / a)² v` first, then `(λ extra) λ` with `θ = 0`; a zero loading or zero extra is exactly zero; lasting asymptotic extra requires `a < 0`; `(B / a)² v` is the latent extra, not the observed extra; `λ² t0_b² v` is first-occasion extra observed TI variance, not this extra; `λ² p + θ` is stationary observed variance, not this extra; `MANIFESTVAR` `θ` is not this extra; p. 16 `TDPREDEFFECTstd` is `m · √v / √(-q / (2 a))` after strictly positive `asymDIFFUSION` and strictly positive time-dependent predictor variance; unstandardised `M` is not `TDPREDEFFECTstd`; `TIPREDEFFECTstd` is not `TDPREDEFFECTstd` even when `M = B`; intercept-style `A^{-1}[e^{A Δt} − I] M · √v / √p` is not `TDPREDEFFECTstd`; `m · √v / √(trait + p + added)` uses `TRAITVAR` and is not `TDPREDEFFECTstd`; Table 3 / p. 16 `T0TDPREDEFFECTstd` is `t0_m · √v / √p_0` after strictly positive free `T0VAR` and strictly positive TD predictor variance; unstandardised `t0_m` is not `T0TDPREDEFFECTstd`; `TDPREDEFFECTstd` uses `asymDIFFUSION` and is not `T0TDPREDEFFECTstd`; `T0TIPREDEFFECTstd` is not `T0TDPREDEFFECTstd` even when `t0_m = t0_b`; `t0_m · √v / √(trait + p_0 + added)` uses `TRAITVAR` and is not `T0TDPREDEFFECTstd`; free `T0VAR` does not require `a < 0`; p. 16 `T0VARstd` is `p_0 / p_0 = 1` after strictly positive free `T0VAR` (`solve(sqrt(diag(T0VAR))) %&% T0VAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; default ridge is 0); unstandardised `T0VAR` is not `T0VARstd`; `T0TDPREDEFFECTstd` is not `T0VARstd`; `addedT0TIPREDVAR` is not `T0VARstd`; p. 16 `TRAITVARstd` is `trait / trait = 1` after strictly positive `TRAITVAR` (`solve(sqrt(diag(TRAITVAR))) %&% TRAITVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; no ridge addend); unstandardised `TRAITVAR` is not `TRAITVARstd`; `T0VARstd` is not `TRAITVARstd` even when both equal 1; `addedT0TIPREDVAR` is not `TRAITVARstd`; p. 16 `MANIFESTTRAITVARstd` is `ψ / ψ = 1` after strictly positive `MANIFESTTRAITVAR` (`solve(sqrt(diag(MANIFESTTRAITVAR))) %&% MANIFESTTRAITVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0); unstandardised `MANIFESTTRAITVAR` is not `MANIFESTTRAITVARstd`; `TRAITVARstd` is not `MANIFESTTRAITVARstd` even when both equal 1; `MANIFESTVAR` is not `MANIFESTTRAITVARstd`; p. 16 `MANIFESTVARstd` is `θ / θ = 1` after strictly positive `MANIFESTVAR` (`solve(sqrt(diag(MANIFESTVAR))) %&% MANIFESTVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0; 2017-era `dimnames` assignment to `latentNames` is a source bug); unstandardised `MANIFESTVAR` is not `MANIFESTVARstd`; `MANIFESTTRAITVARstd` is not `MANIFESTVARstd` even when both equal 1; Equation 5 `Var(y)` is not `MANIFESTVARstd`; p. 16 `TIPREDVARstd` is `v / v = 1` after strictly positive `TIPREDVAR` (`solve(sqrt(diag(TIPREDVAR))) %&% TIPREDVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0; `dimnames` are `TIpredNames`); unstandardised `TIPREDVAR` is not `TIPREDVARstd`; `MANIFESTVARstd` is not `TIPREDVARstd` even when both equal 1; §7.2 `addedTIPREDVAR` is not `TIPREDVARstd`; p. 16 `asymDIFFUSIONstd` is `p / p = 1` after strictly positive `asymDIFFUSION` (`solve(sqrt(diag(asymDIFFUSION))) %&% asymDIFFUSION`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0; `dimnames` are `latentNames`); unstandardised `asymDIFFUSION` is not `asymDIFFUSIONstd`; `TIPREDVARstd` is not `asymDIFFUSIONstd` even when both equal 1; `DIFFUSIONstd` `−2 a` is not `asymDIFFUSIONstd`; p. 16 `discreteCINTstd` is `A^{-1}[e^{A Δt} − I] κ / √p` after strictly positive `asymDIFFUSION`; unstandardised `discreteCINT` is not `discreteCINTstd`; `κ / √p` is not `discreteCINTstd`; `(-κ / a) / √p` is not `discreteCINTstd`; `asymCINTstd` is `(-κ / a) / √p` after strictly positive `asymDIFFUSION`; unstandardised `asymCINT` is not `asymCINTstd`; `κ / √p` is not `asymCINTstd`; `discreteCINTstd` is not `asymCINTstd`; `T0MEANSstd` is `μ_0 / √p_0` after strictly positive free `T0VAR`; unstandardised `T0MEANS` is not `T0MEANSstd`; `T0VARstd` is not `T0MEANSstd`; `μ_0 / √asymDIFFUSION` is not `T0MEANSstd`; `MANIFESTMEANSstd` is `τ / √θ` after strictly positive `MANIFESTVAR`; unstandardised `MANIFESTMEANS` is not `MANIFESTMEANSstd`; `MANIFESTVARstd` is not `MANIFESTMEANSstd`; `τ / √(λ² Var(η) + θ)` is not `MANIFESTMEANSstd`; p. 16 `CINTstd` is `κ / √p` after strictly positive `asymDIFFUSION`; unstandardised `CINT` is not `CINTstd`; `asymCINTstd` is not `CINTstd`; `discreteCINTstd` is not `CINTstd`; `κ / √(trait + p + added)` is not `CINTstd`;))))), irregular already-centered residual lag, Rubin `T` on OLS loadings, and strong-gated latent means (two-observation residual variance is identically `0` and caps at strong/scalar; Putnick & Bornstein, 2016) | -| `psychometric_core` | posterior-aware structural input gates, CWC within/between OLS plus the contextual effect, event-time log-rate, unequal-interval discrete-lag remapping, constant-predictor discrete effect, time-varying-predictor discrete effect (Eq. 14), exact scalar discrete process noise (Driver et al., 2017, Eq. 3), lagged latent covariance and unconditional latent variance (Driver et al., 2017, Eq. 3–4), stationary within-subject variance (Driver et al., 2017, Eq. 4 as `Δt → ∞`; `asymDIFFUSION`), trait-plus-state variance (Driver et al., 2017, §4.3 `TRAITVAR`; not process noise), observed-indicator variance and lagged observed covariance (Driver et al., 2017, Eq. 5; Table 2 `MANIFESTVAR` is `Θ`, not `Var(y)`; `MANIFESTTRAITVAR` is not `MANIFESTVAR`; `Θ` does not enter lagged observed covariance; observed-indicator mean is `τ + λ μ`; `MANIFESTMEANS` is not `E(y)`; `CINT` is not `MANIFESTMEANS`; discrete latent mean is `exp(a Δt) μ_0 + (exp(a Δt) − 1)/a κ`; `T0MEANS` is not `μ_t`; `CINT` is not the discrete increment; evolved observed mean is `τ + λ μ_t`; `τ + λ μ_0` is not `E(y_t)`; contemporaneous `TDPREDEFFECT` impulse is `m x`, not `CINT`, not `TIPREDEFFECT`, and not Voelkle Eq. 14; Eq. 5 of that contemporaneous impulse is `τ + λ(μ_t + m x)`, and `τ + λ μ_t` is not that observed mean; time-independent `TIPREDEFFECT` increment is `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, not `M x`, not Voelkle Eq. 14, and not the coefficient `B`; Eq. 5 of that increment is `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that observed mean; `τ + λ(μ_t + e^{a(t−u)} m x)` is not that observed mean when `u ≠ t`; within-interval `TDPREDEFFECT` carry is `e^{A(t−u)} M x` for `t0 < u < t`, not the contemporaneous Dirac, not `CINT`, not `TIPREDEFFECT`, and not Voelkle Eq. 14; Eq. 5 of that carry is `τ + λ(μ_t + e^{a(t−u)} m x)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that carried observed mean when `u ≠ t`; first-occasion `T0TIPREDEFFECT` shift is `t0_b z` and Eq. 3 first-summand carry is `e^{A Δt} t0_b z` (`T0TIPREDEFFECT` is not `TIPREDEFFECT` `B`; `t0_b z` is not `A^{-1}[e^{A Δt} − I] B z`; `e^{A Δt} t0_b z` is not `t0_b z`; Eq. 5 of that carry is `τ + λ(μ_t + e^{a Δt} t0_b z)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not that observed mean), first-occasion `T0TDPREDEFFECT` shift is `t0_m x0` and Eq. 3 first-summand carry is `e^{A Δt} t0_m x0` (`T0TDPREDEFFECT` is not `TDPREDEFFECT` `M`; `t0_m x0` is not `M x`; `e^{A Δt} t0_m x0` is not `t0_m x0`; `e^{A Δt} t0_m x0` is not `e^{A(t−u)} M x` for `t0 < u < t`; `t0_m x0` is not `t0_b z`; an impulse at `u ≤ t0` that used `M` is already in `η(t0)` as `TDPREDEFFECT`, not as `T0TDPREDEFFECT`; Eq. 5 of that carry is `τ + λ(μ_t + e^{a Δt} t0_m x0)`, and `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not that observed mean; `τ + λ(μ_t + e^{a Δt} t0_b z)` is not that observed mean; §7.2 level-change `CINT` is `κ = −a m x` with `a < 0` so `−κ / a = m x` (`−a m x` is not the dissipating Dirac, not a free `CINT`, not `TIPREDEFFECT`, and not the extra near-zero-drift latent process also named in §7.2; Eq. 3 of that setting is `(1 − e^{a Δt}) m x`, which is not `m x`, not `κ`, and not `TIPREDEFFECT`; §7.2 extra-process contribution is `a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)` (`ε = a` is `a_{ηξ} x Δt e^{a Δt}`; identification `TDPREDEFFECT` on the extra process is 1; printed extra `DRIFT` is `−0.000001`; not `κ = −a m x`, not `(1 − e^{a Δt}) m x`, and not the dissipating Dirac `m x`; `ε ≥ 0` fails closed; Eq. 5 of that contribution is `τ + λ(μ_t + a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)`; the extra process has `LAMBDA` 0 and is not an observed indicator; `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that observed mean; the contribution is not `E(y_t)`; the evolved-plus-contribution latent mean is not `E(y_t)`; after-t0 extra-process `TDPREDEFFECT` is `a_{ηξ} x (e^{ε(t−u)} − e^{a(t−u)}) / (ε − a)` for `t0 < u < t` while `μ_t` uses `Δt`; Eq. 5 of that after-t0 contribution is `τ + λ(μ_t + a_{ηξ} x (e^{ε(t−u)} − e^{a(t−u)}) / (ε − a)`; the first-occasion extra-process observed mean is not that observed mean when `u ≠ t0`; `e^{a(t−u)} m x` is a Dirac on the original process, not this `DRIFT` drive; §7.2 `asymTIPREDEFFECT` is `-B z / a` for `a < 0` (`-B z / a` is not the coefficient `B`, not `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, and not `M x`; §7.2 `addedTIPREDVAR` is `(B / a)² v`, not `TRAITVAR`, not `asymDIFFUSION`, and not `-B z / a`; Table 2 `asymCINT` is `-κ / a` for `a < 0` and is not `κ`, not `A^{-1}[e^{A Δt} − I] κ`, not `T0MEANS`, and not `-B z / a`; p. 16 stationary `T0MEANS` is `-κ / a + −B z / a` and is not free `T0MEANS`, not `asymCINT` alone, not `asymTIPREDEFFECT` alone, and not the finite-interval discrete latent mean; Eq. 5 of that constrained mean is `τ + λ(−κ / a + −B z / a)`; `τ + λ μ_0` is not that observed mean; `τ + λ(−κ / a)` is not that observed mean when `B z ≠ 0`; `τ + λ μ_t` is not that observed mean; `MANIFESTMEANS` is not `E(y_0)`; the constrained latent mean is not `E(y_0)`; stationary `T0VAR` is `trait + −q / (2 a) + (B / a)² v` (not free `T0VAR`, not `asymDIFFUSION` alone, not `TRAITVAR` alone, not `addedTIPREDVAR` alone, and not the finite-interval discrete latent variance. Eq. 5 of that constrained variance is `λ²(trait + −q / (2 a) + (B / a)² v) + θ + ψ` (JSS PDF re-opened 2026-08-22T03:20Z; form the stationary latent variance first, then `λ² p + θ + ψ`; `λ² p_0` is not that observed variance; `λ²(−q / (2 a)) + θ` is not that observed variance when `TRAITVAR` or `addedTIPREDVAR` is nonzero; `MANIFESTVAR` is not `Var(y_0)`; the constrained latent variance is not `Var(y_0)`); lagged stationary `T0VAR` is `trait + e^{a Δt}(−q / (2 a)) + (B / a)² v` (trait and `addedTIPREDVAR` do not decay; contemporaneous `T0VAR` is not that lagged map; decaying the constrained total as if it were all state is not that lagged map; Eq. 5 of that lagged covariance is `λ²(trait + e^{a Δt}(−q / (2 a)) + (B / a)² v) + ψ`; `Θ` does not enter; contemporaneous `Var(y_0)` is not that lagged observed covariance; the lagged latent covariance is not that observed covariance); later-occasion stationary `T0VAR` is `trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v` (trait and `addedTIPREDVAR` do not enter `Q_Δt`; under stationarity that composition equals contemporaneous `T0VAR`; evolving the constrained total as if it were all state is not that later map; the lagged covariance omits `Q_Δt`; `Q_Δt` is not that later map; Eq. 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v) + θ + ψ`; lagged observed covariance omits `Q_Δt` and `θ`; `MANIFESTVAR` is not `Var(y_t)`; the later-occasion latent variance is not `Var(y_t)`); predetermined later-occasion `T0VAR` is `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v` (free `T0VAR` `p_0` is not that later map; setting `p_0 = −q / (2 a)` recovers the stationary later-occasion map; stationary later variance uses `−q / (2 a)` in place of `p_0` and is not that later map when `p_0` is free; evolving `trait + p_0 + (B / a)² v` as if it were all state is not that later map; Eq. 5 of that predetermined later-occasion variance is `λ²(trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v) + θ + ψ`; `MANIFESTVAR` is not `Var(y_t)`; the predetermined later-occasion latent variance is not `Var(y_t)`; stationary later observed variance is not that observed variance when `p_0` is free); predetermined lagged `T0VAR` is `trait + e^{a Δt} p_0 + (B / a)² v` (free `T0VAR` `p_0` is not that lagged map; setting `p_0 = −q / (2 a)` recovers the stationary lagged map; stationary lagged covariance uses `−q / (2 a)` in place of `p_0` and is not that lagged map when `p_0` is free; evolving `trait + p_0 + (B / a)² v` as if it were all state is not that lagged map; later-occasion variance includes `Q_Δt` and is not that lagged map; Eq. 5 of that predetermined lagged covariance is `λ²(trait + e^{a Δt} p_0 + (B / a)² v) + ψ`; `MANIFESTVAR` does not enter; the predetermined lagged latent covariance is not that observed covariance; predetermined later observed variance includes `Q_Δt` and `θ` and is not that lagged observed covariance; stationary lagged observed covariance is not that observed covariance when `p_0` is free; the predetermined first-occasion variance of §4.3 predetermined `T0VAR` is `trait + p_0 + (B / a)² v`; free `p_0` is not that map; stationary first-occasion variance uses `−q / (2 a)` in place of `p_0` and is not that map when `p_0` is free; lagged covariance decays the state and is not that map; later-occasion variance includes `Q_Δt` and is not that map; Eq. 5 of that predetermined first-occasion variance is `λ²(trait + p_0 + (B / a)² v) + θ + ψ`; `MANIFESTVAR` is not that first-occasion observed variance; the predetermined first-occasion latent variance is not that observed variance; stationary first-occasion observed variance is not that observed variance when `p_0` is free; predetermined later observed variance includes `Q_Δt` and is not that first-occasion observed variance; later-start lagged covariance of predetermined `T0VAR` is `trait + e^{a s}(e^{2 a u} p_0 + Q_u) + (B / a)² v` (Driver et al., 2017, §4.3 `startoffset`; Eq. 4; JSS PDF re-opened 2026-08-23T10:27Z; first-occasion lagged omits `e^{a s} Q_u`; later-occasion variance does not lag; stationary lagged uses `−q / (2 a)`; decaying the later total is not that map; Eq. 5 of that later-start lagged covariance is `λ²` of it plus `ψ`; `Θ` does not enter; first-occasion lagged observed omits `e^{a s} Q_u`; later observed variance includes `Q_u` and `θ`; later-start later-occasion variance of predetermined `T0VAR` is `trait + e^{2 a s}(e^{2 a u} p_0 + Q_u) + Q_s + (B / a)² v` (Driver et al., 2017, §4.3 `startoffset`; Eq. 3–4 Chapman–Kolmogorov `Q_{u+s} = e^{2 a s} Q_u + Q_s`; JSS PDF re-opened 2026-08-23T11:05Z; later-occasion variance at `u` omits `Q_s`; later-start lagged covariance omits `Q_s`; stationary later uses `−q / (2 a)`; evolving the later total as if it were all state is not that map; ignoring `startoffset` omits `e^{2 a s} Q_u`; Eq. 5 of that later-start later-occasion variance is `λ²` of it plus `θ + ψ`; `MANIFESTVAR` is not that observed variance; p. 16 `discreteDRIFTstd` is `e^{a Δt}` after strictly positive `asymDIFFUSION` `-q / (2 a)` (footnote 4; unstandardised `e^{a Δt}` is defined for growing `a ≥ 0` and for zero diffusion and is not `discreteDRIFTstd`; the §7.1 trait-plus-state autocorrelation uses `TRAITVAR` and is not `discreteDRIFTstd`; `TRAITVAR` is not the standardisation variance; p. 16 `discreteDIFFUSIONstd` is `Q_Δt / (−q / (2 a))` after strictly positive `asymDIFFUSION` `-q / (2 a)` (footnote 4; unstandardised `Q_Δt` is defined for growing `a ≥ 0` and for zero diffusion and is not `discreteDIFFUSIONstd`; the continuous standardisation `−2 a` is not `discreteDIFFUSIONstd`; `Q_Δt / (trait + p + added)` uses `TRAITVAR` and is not `discreteDIFFUSIONstd`; `TRAITVAR` is not the standardisation variance; p. 16 `DIFFUSIONstd` is `q / (−q / (2 a)) = −2 a` after strictly positive `asymDIFFUSION` `-q / (2 a)` (Driver et al., 2017, p. 16; Eq. 4; footnote 4; JSS PDF re-opened 2026-08-23T13:20Z; unstandardised `q` is defined for growing `a ≥ 0` and for zero diffusion and is not `DIFFUSIONstd`; the discrete standardisation `Q_Δt / (−q / (2 a))` depends on `Δt` and is not `DIFFUSIONstd`; `q / (trait + p + added)` uses `TRAITVAR` and is not `DIFFUSIONstd`; `TRAITVAR` is not the standardisation variance; p. 16 `DRIFTstd` is the continuous auto-effect after strictly positive `asymDIFFUSION` `-q / (2 a)` (Driver et al., 2017, p. 16; Eq. 1; footnote 4; JSS PDF re-opened 2026-08-23T13:28Z); unstandardised `a` is defined for growing `a ≥ 0` and for zero diffusion and is not `DRIFTstd`; the discrete standardisation `e^{a Δt}` depends on the event interval and is not `DRIFTstd`; `a p / (trait + p + added)` uses `TRAITVAR` and is not `DRIFTstd`; `TRAITVAR` is not the standardisation variance); p. 16 `asymTIPREDEFFECTstd` is `(-B / a) · √v / √(-q / (2 a))` after strictly positive `asymDIFFUSION` `-q / (2 a)` and strictly positive predictor variance `v` (Driver et al., 2017, p. 16; §7.2; footnote 4; JSS PDF re-opened 2026-08-23T14:25Z; unstandardised `-B / a` is defined for a zero coefficient and for zero predictor variance and is not `asymTIPREDEFFECTstd`; the finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not `asymTIPREDEFFECTstd`; `(-B / a) · √v / √(trait + p + added)` uses `TRAITVAR` and is not `asymTIPREDEFFECTstd`; `TRAITVAR` is not the standardisation variance); p. 16 `TIPREDEFFECTstd` is `B · √v / √(-q / (2 a))` after strictly positive `asymDIFFUSION` `-q / (2 a)` and strictly positive predictor variance `v` (Driver et al., 2017, p. 16; §7.2; footnote 4; JSS PDF re-opened 2026-08-23T16:21Z; unstandardised `B` is defined for a zero coefficient and for zero predictor variance and is not `TIPREDEFFECTstd`; the asymptotic standardisation `(-B / a) · √v / √p` is the total change and is not `TIPREDEFFECTstd`; the finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not `TIPREDEFFECTstd`; `B · √v / √(trait + p + added)` uses `TRAITVAR` and is not `TIPREDEFFECTstd`; `TRAITVAR` is not the standardisation variance); Table 3 `T0TIPREDEFFECTstd` is `t0_b · √v / √p_0` after strictly positive free `T0VAR` `p_0` and strictly positive predictor variance `v` (Driver et al., 2017, Table 3, p. 13; p. 16; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T17:20Z; the affected variance is free `T0VAR`, not `asymDIFFUSION`; unstandardised `t0_b` is defined for a zero coefficient and for zero predictor variance and is not `T0TIPREDEFFECTstd`; `TIPREDEFFECTstd` `B · √v / √(-q / (2 a))` is the continuous coefficient and is not `T0TIPREDEFFECTstd`; `asymTIPREDEFFECTstd` `(-B / a) · √v / √p` is the total change and is not `T0TIPREDEFFECTstd`; `t0_b · √v / √(trait + p_0 + added)` uses `TRAITVAR` and is not `T0TIPREDEFFECTstd`; `TRAITVAR` is not the standardisation variance); 2017-era `addedT0TIPREDVAR` is `t0_b² v` (Driver et al., 2017, Table 3, p. 13; p. 16; §7.2; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T18:20Z; `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`; form `t0_b` first, then square, then multiply by `v`; a zero coefficient or zero predictor variance is exactly zero; free `T0TIPREDEFFECT` does not require `a < 0`; `(B / a)² v` is `addedTIPREDVAR` and is not this first-occasion map; `t0_b · √v / √p_0` is `T0TIPREDEFFECTstd` and is not this variance; free `T0VAR` is not this extra TI variance; `TRAITVAR` is not this extra TI variance; Equation 5 of 2017-era `addedT0TIPREDVAR` is `λ² t0_b² v` (Driver et al., 2017, Eq. 5, p. 5; Table 3, p. 13; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T19:10Z; form `t0_b² v` first, then `(λ extra) λ` with `θ = 0`; a zero loading or zero extra is exactly zero; `t0_b² v` is the latent extra, not the observed extra; `λ² p_0 + θ` is first-occasion observed variance, not this extra; `λ² (B / a)² v` is Eq. 5 of `addedTIPREDVAR`, not this first-occasion observed extra; `MANIFESTVAR` `θ` is not this extra; Equation 5 of §7.2 `addedTIPREDVAR` is `λ² (B / a)² v`; form `(B / a)² v` first, then `(λ extra) λ` with `θ = 0`; a zero loading or zero extra is exactly zero; lasting asymptotic extra requires `a < 0`; `(B / a)² v` is the latent extra, not the observed extra; `λ² t0_b² v` is first-occasion extra observed TI variance, not this extra; `λ² p + θ` is stationary observed variance, not this extra; `MANIFESTVAR` `θ` is not this extra; p. 16 `TDPREDEFFECTstd` is `m · √v / √(-q / (2 a))` after strictly positive `asymDIFFUSION` and strictly positive time-dependent predictor variance; unstandardised `M` is not `TDPREDEFFECTstd`; `TIPREDEFFECTstd` is not `TDPREDEFFECTstd` even when `M = B`; intercept-style `A^{-1}[e^{A Δt} − I] M · √v / √p` is not `TDPREDEFFECTstd`; `m · √v / √(trait + p + added)` uses `TRAITVAR` and is not `TDPREDEFFECTstd`; Table 3 / p. 16 `T0TDPREDEFFECTstd` is `t0_m · √v / √p_0` after strictly positive free `T0VAR` and strictly positive TD predictor variance; unstandardised `t0_m` is not `T0TDPREDEFFECTstd`; `TDPREDEFFECTstd` uses `asymDIFFUSION` and is not `T0TDPREDEFFECTstd`; `T0TIPREDEFFECTstd` is not `T0TDPREDEFFECTstd` even when `t0_m = t0_b`; `t0_m · √v / √(trait + p_0 + added)` uses `TRAITVAR` and is not `T0TDPREDEFFECTstd`; free `T0VAR` does not require `a < 0`; p. 16 `T0VARstd` is `p_0 / p_0 = 1` after strictly positive free `T0VAR` (`solve(sqrt(diag(T0VAR))) %&% T0VAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; default ridge is 0); unstandardised `T0VAR` is not `T0VARstd`; `T0TDPREDEFFECTstd` is not `T0VARstd`; `addedT0TIPREDVAR` is not `T0VARstd`; p. 16 `TRAITVARstd` is `trait / trait = 1` after strictly positive `TRAITVAR` (`solve(sqrt(diag(TRAITVAR))) %&% TRAITVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; no ridge addend); unstandardised `TRAITVAR` is not `TRAITVARstd`; `T0VARstd` is not `TRAITVARstd` even when both equal 1; `addedT0TIPREDVAR` is not `TRAITVARstd`; p. 16 `MANIFESTTRAITVARstd` is `ψ / ψ = 1` after strictly positive `MANIFESTTRAITVAR` (`solve(sqrt(diag(MANIFESTTRAITVAR))) %&% MANIFESTTRAITVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0); unstandardised `MANIFESTTRAITVAR` is not `MANIFESTTRAITVARstd`; `TRAITVARstd` is not `MANIFESTTRAITVARstd` even when both equal 1; `MANIFESTVAR` is not `MANIFESTTRAITVARstd`; p. 16 `MANIFESTVARstd` is `θ / θ = 1` after strictly positive `MANIFESTVAR` (`solve(sqrt(diag(MANIFESTVAR))) %&% MANIFESTVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0; 2017-era `dimnames` assignment to `latentNames` is a source bug); unstandardised `MANIFESTVAR` is not `MANIFESTVARstd`; `MANIFESTTRAITVARstd` is not `MANIFESTVARstd` even when both equal 1; Equation 5 `Var(y)` is not `MANIFESTVARstd`; p. 16 `TIPREDVARstd` is `v / v = 1` after strictly positive `TIPREDVAR` (`solve(sqrt(diag(TIPREDVAR))) %&% TIPREDVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0; `dimnames` are `TIpredNames`); unstandardised `TIPREDVAR` is not `TIPREDVARstd`; `MANIFESTVARstd` is not `TIPREDVARstd` even when both equal 1; §7.2 `addedTIPREDVAR` is not `TIPREDVARstd`; p. 16 `asymDIFFUSIONstd` is `p / p = 1` after strictly positive `asymDIFFUSION` (`solve(sqrt(diag(asymDIFFUSION))) %&% asymDIFFUSION`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0; `dimnames` are `latentNames`); unstandardised `asymDIFFUSION` is not `asymDIFFUSIONstd`; `TIPREDVARstd` is not `asymDIFFUSIONstd` even when both equal 1; `DIFFUSIONstd` `−2 a` is not `asymDIFFUSIONstd`; p. 16 `discreteCINTstd` is `A^{-1}[e^{A Δt} − I] κ / √p` after strictly positive `asymDIFFUSION`; unstandardised `discreteCINT` is not `discreteCINTstd`; `κ / √p` is not `discreteCINTstd`; `(-κ / a) / √p` is not `discreteCINTstd`; `asymCINTstd` is `(-κ / a) / √p` after strictly positive `asymDIFFUSION`; unstandardised `asymCINT` is not `asymCINTstd`; `κ / √p` is not `asymCINTstd`; `discreteCINTstd` is not `asymCINTstd`; `T0MEANSstd` is `μ_0 / √p_0` after strictly positive free `T0VAR`; unstandardised `T0MEANS` is not `T0MEANSstd`; `T0VARstd` is not `T0MEANSstd`; `μ_0 / √asymDIFFUSION` is not `T0MEANSstd`;))))), irregular already-centered residual lag, Rubin `T` on OLS loadings, and strong-gated latent means (two-observation residual variance is identically `0` and caps at strong/scalar; Putnick & Bornstein, 2016) | - - -Foundation crates expose only tested contracts. Empty façades are not public -APIs. - -No crate exposes placeholder production behavior in Task 1. This prevents an -empty façade from becoming a de facto public API before its invariants and tests -exist. - -## Immutable evidence boundary - -Task 2 begins the executable `evidence_core` boundary. Stable RFC 9562 `UUIDv7` -identities are independent from canonical `SHA-256` content digests. Source -bytes and UTF-8 document text are copied into immutable owned storage, bounded -before allocation, and verified without exposing mutable fields. - -A source span records an owning document, a half-open UTF-8 byte range, the -matching half-open Unicode-scalar range, and optional page/layout geometry. It -fails closed for empty or reversed ranges, byte or scalar overflow, -mid-code-point boundaries, coordinate disagreement, cross-document use, -nonfinite geometry, nonpositive dimensions, and rectangles outside the page. -Scalar coordinates are evidence locations rather than grapheme, word, or -sentence boundaries; language-tailored segmentation remains a later module. - -The boundary now exposes a strict JSON wire version `1` without exposing private -Rust fields. Artifacts, documents, spans, and nested page locations are serialized -through explicit DTOs with unknown-field rejection. Reconstruction parses and -revalidates RFC 9562 identifiers, canonical digests, content limits, exact text -coordinates, document ownership, and page geometry. Artifact bytes and document -text are rehashed during reconstruction, and digest substitution fails closed. -Malformed JSON, unsupported versions, invalid byte values, and unknown nested -fields produce stable content-redacting errors. - -Persistence, JSON Schema publication, JSON-LD, GraphML, source acquisition -metadata, signatures, and W3C PROV remain outward adapters or later contracts. -They must depend inward on these validated domain values rather than defining -them. - -## Quality architecture - -The workspace centralizes package metadata and Rust/Clippy lints. Every member -inherits `unsafe_code = "forbid"`, `missing_docs = "deny"`, and warning denial. -Repository contract scripts independently verify the approved crate set, -workspace inheritance, action SHA pinning, absence of LLM credentials from -ordinary CI, and complete Rust documentation. - -Stable Rust 1.98.0 is the compile, lint, test, and line-coverage reference. -Branch coverage runs in a pinned nightly lane because LLVM branch coverage -remains unstable in Rust. `cargo-nextest` runs tests without retries, while -doctests remain a separate `cargo test --doc` gate. `cargo-deny` enforces -advisory, license, ban, and source policy. Failed Rust coverage gates print the -exact missing source locations from the same instrumented run without weakening -the 100% contract. - -## Temporal invariants - -TEPP stores event/valid time, assertion time, document time, system time, available time, and knowledge cutoff independently. A historical analysis may include a document only when: +## Strategic bounded contexts + +Cargo crates are implementation units. A crate, API route, clock type, refusal rule, equation, or ADR number is not automatically a bounded context. + +| Bounded context | Domain responsibility | Aggregate / authority | Current implementation nucleus | +| --- | --- | --- | --- | +| Evidence & Semantic Measurement | immutable source evidence, exact spans, multilingual semantic units, concept alignment, method/source-effect admission | `EvidenceCorpus`, `SemanticUnitSet`, `ConceptDictionaryRevision` | `evidence_core`, `semantic_core`; rule-fragment crates are fold candidates | +| Temporal Event Knowledge | six-clock semantics, temporal intervals/partial order, event ontology, typed transition/provenance relations, time-varying memberships | `EventEpisode`, `TemporalRelationSet`, `MembershipAssignmentSet` | `temporal_core`, `event_core`, `relation_graph`, `membership_core`; clock/edge crates are fold candidates | +| Topic Measurement | shared-latent temporal/relational topic estimation, topic identity, uncertainty, model-selection evidence | `TopicModelRun`, `TopicLineage` | `topic_measurement`, `topic_lineage`, `model_selection`, `network_analysis` | +| Longitudinal Modeling | TEPP-owned temporal composition of psychometric models: irregular time, longitudinal invariance/drift, time-varying covariates/random effects/membership, temporal state evolution and alignment | `TemporalModelSpecification`, `TemporalModelRun` | `longitudinal_core`; legacy temporal fragments in `psychometric_core` are staged migration/fold candidates | +| Analysis Run | cutoff-safe lifecycle, idempotency, application orchestration, durable terminal binding; no scientific formula ownership | `AnalysisRun` | `analysis_engine` application modules | +| Scientific Validation | method-specific recovery, RMSE/bias/coverage, convergence, invariance, graph/parity evidence | `ValidationStudy` | `validation_core`, `tepp_simulation` | +| Scientific Claim Promotion | preregistered decision over complete validation evidence; separate from evidence generation and transport success | `ClaimPromotionDecision` | ADR 0014 policy; implementation remains incomplete | +| Projection | typed buyer/consumer read models and exports without changing scientific authority | projection-specific read models | `tepp_api`, artifact/export adapters | + +Supporting contexts are Interpretation, Persistence & Recovery, and Runtime Security & Operations. Compute execution, serialization, hashing, transport framing, and accelerator adapters are generic infrastructure and do not define scientific truth. + +## Canonical cross-repository ownership + +ADR 0011 defines the service boundary. + +- `ContextualWisdomLab/fast-mlsirm` owns reusable static/generalized-mixed/dependence-aware psychometric model specification and reusable numerical kernels, including reusable LSIRM, MLSIRM, and DLSJM computation. +- TEPP owns temporal/event composition around a released/versioned upstream candidate: event-or-valid time, assertion time, document time, system time, available time, knowledge cutoff, leakage prevention, irregular intervals, time-varying membership/covariates, longitudinal invariance/drift, state evolution, temporal map alignment, event ontology/graph, and temporal recovery. +- `ContextualWisdomLab/contextual-orchestrator` owns all LLM provider execution, routing/fallback, verifier/adjudicator execution, credentials, and model-call provenance. TEPP never calls a model provider directly. +- Naruon, LineageWeave, Context Graph, and EA Core are external bounded contexts. Integration uses released/versioned contracts and explicit anti-corruption layers; no cross-service SQL is permitted. + +When reusable static computation exists in TEPP but belongs to fast-mlsirm, migration is `owner contract -> parity/recovery -> TEPP ACL -> duplicate removal`. A second TEPP production source is not retained for convenience. An open upstream PR head is not a released production dependency. + +## Six-clock temporal contract + +TEPP has exactly six temporal roles: + +1. **event or valid time** — when an event occurs or a state holds; an instant and a validity interval are representations of this same role; +2. **assertion time** — when a claim is stated; +3. **document time** — document creation/publication/revision/reporting period; +4. **system time** — when TEPP records or observes the fact; +5. **available time** — when the evidence could actually be used; +6. **knowledge cutoff** — maximum available time admitted to an analysis. + +A historical run enforces: \[ \operatorname{available\_time}(d) \leq \operatorname{knowledge\_cutoff}. \] -When availability is an interval, every possible instant in that interval must satisfy the inequality. Unknown or open-ended availability that can extend past the cutoff fails closed; event time and document time cannot substitute for availability. +Event instants and valid-time intervals do not create separate seventh/eighth clocks. Unknown/open availability that could exceed cutoff fails closed. -Forward transition edges require a temporally valid partial order. Retrospective, revision, translation, citation, support, and contradiction relations retain their direction and provenance but do not create reverse state transitions. +Forward transition and input-process-outcome relations obey temporal order. Citation, revision, translation, summary, support, contradiction, and retrospective reporting may point backward but never become reverse state transitions. -## Measurement invariants +## Generalized mixed and membership contract -All languages share global topic identities and latent document coordinates. Language-specific lexical emissions, morphology, script, and content deviations are modeled rather than forced to be identical. Validated, calibrated, provisional, and unresolved language profiles are reported separately. +A person, document, segment, item, or occasion may be cross-classified and may have multiple simultaneous memberships. These are different operators: -Repeated report vocabulary is modeled through corpus-background, template, section, style, copied-text, prompt, modality, and substantive-topic sources. It is not silently removed by stopword lists, TF-IDF, or BM25. +- **cross-classification** describes non-nested classification dimensions; +- **multiple membership** permits one observation to belong to several units in a dimension with explicit weights. -Topic proportions are compositional (Aitchison, 1982). ESEM and network analysis consume logistic-normal latent coordinates or orthonormal log-ratio coordinates, with posterior uncertainty propagated through plausible values or a joint model (Asparouhov & Muthén, 2009; Asparouhov et al., 2018; Marsh et al., 2014). The product topic-estimator contract is TRSL-TM (ADR 0012); an STM-style logistic-normal family is the reference, not a shipped-backend claim (Blei & Lafferty, 2006; Roberts et al., 2014, 2019). TDT/CHRONOS event intelligence remains an accepted-target boundary (Allan, 2002; Anagnostopoulos et al., 2013). +Membership weights are time-valid and auditable. They are observed/normalized or model-estimated according to the declared formulation; equal weights are never invented as a fallback. Known hierarchy, testlets, item families, raters, methods, and justified covariates are represented before residual latent-space dependence is introduced. -## Compute architecture +## Dependence-aware temporal composition -The CPU `f64` implementation is the numerical reference. Rayon-style fixed worker pools and thread-local sufficient statistics minimize context switching and oversubscription. GPU work is streamed; temporary responsibilities are never retained for the full corpus. The VRAM controller estimates peak allocation, reserves a safety margin, autotunes micro-batches, records telemetry, reduces batches after OOM, and falls back to CPU safely. +TEPP consumes the complete released upstream candidate identity rather than switching on names such as `rasch`, `mirt`, `ggum`, `lsirm`, or `dlsjm`. -## Persistence +- Rasch remains distinct from generic 1PL. +- 2PLM through formulation-qualified 5PLM preserve parameter meaning. +- confirmatory/exploratory MIRT preserve factor/loading semantics; +- dominance and ideal-point/GGUM response processes remain distinct from dependence and temporal operators; +- LSIRM/MLSIRM residual person-item geometry remains distinct from known design structure; +- DLSJM preserves separate local-item and local-person dependence spaces. -PostgreSQL is the reference relational store. Database objects use two-or-more-word `snake_case` names, including `document_record`, `temporal_interval`, `event_instance`, `event_mention`, `document_relation`, `segment_relation`, `entity_role_assignment`, `model_run`, `topic_definition`, `topic_correlation`, `topic_cluster`, `factor_solution`, `validation_metric`, and `audit_event`. `audit_event` inserts call `operational_log::try_record` before SQL is rendered so source text and source identity cannot enter the row. +Every temporal candidate is `supported`, `research_candidate`, or `unsupported`. Auto-expansion never means auto-activation. `supported` requires the exact combined formulation, temporal state equation, identification/alignment, canonical estimator, primary citations, required data support, and passing known-truth recovery. Primary dependence-family evidence and extension limits are maintained in [`docs/research/temporal-dependence-models.md`](docs/research/temporal-dependence-models.md). -## Security and trust boundaries +## Longitudinal numerical boundary + +Generic temporal standardization belongs in `longitudinal_core`, not in an indefinitely expanding technical `psychometric_core` module. Model-specific static covariance/likelihood primitives migrate to fast-mlsirm when they are reusable static psychometric computation. + +A lagged correlation is defined only from a valid lagged covariance and **both** marginal variances: + +\[ +\rho_{t,t+\Delta} = +\frac{\operatorname{Cov}(Y_t,Y_{t+\Delta})} +{\sqrt{\operatorname{Var}(Y_t)\operatorname{Var}(Y_{t+\Delta})}}. +\] + +A covariance divided only by the initial variance is not generally an autocorrelation under nonstationary marginals. The repaired Longitudinal Modeling contract therefore requires both marginals and checks the covariance bound. Detailed Driver/Oud/Voelkle equation evidence stays in [`docs/research/multilevel-event-time-recovery.md`](docs/research/multilevel-event-time-recovery.md), not in this architecture table. + +## Analysis Run application boundary + +`analysis_engine` orchestrates accepted domain capabilities. `tepp_api` is a transport/projection adapter. HTTP routes, CLI verbs, export operations, project-history operations, and individual refusal helpers do not establish new bounded contexts or scientific authority. + +Target application layout is capability-oriented rather than a flat one-file-per-rule list: + +```text +analysis_engine/src/ + runs/ + evidence_measurement/ + topic_measurement/ + longitudinal_modeling/ + event_intelligence/ + validation/ +``` + +Transport-only behavior stays in `tepp_api`. Persistence adapters implement domain/application repositories; domain code does not import PostgreSQL, HTTP, CLI, or provider-specific DTOs. + +## Current implementation topology and migration + +Protected main contains useful domain primitives alongside many historical one-rule/one-clock crates and a large `psychometric_core`. Those implementation paths are not target ownership. -Documents and LLM outputs are untrusted. Exact spans, JSON Schema, size/depth limits, Unicode validity, prompt-injection isolation, provider allowlists, no-tool execution, tenant isolation, immutable audit events, dependency pinning, SBOM, provenance, and reproducible releases are mandatory. LLM live tests use `NVIDIA_NIM_API_KEY`; `COPILOT_GITHUB_TOKEN` is forbidden. +The delivery recovery folds fragments into the owning contexts while preserving unique tests, research, review evidence, and public compatibility where required. Representative folds are: -## References +| Current fragments | Owning context | +| --- | --- | +| `system_clock`, `event_clock`, `assertion_clock`, `cutoff_clock`, `available_clock`, `document_clocks`, `revision_order` | Temporal Event Knowledge | +| `summarizes_edge`, `retrospective_edge`, `support_edge`, `citation_edge`, `outcome_order`, `subevent_containment`, `prediction_contradiction`, `relation_absence`, `role_contradiction` | Temporal Event Knowledge | +| `location_membership`, `episode_membership`, `membership_target` | Temporal Event Knowledge | +| `prompt_source`, `style_source`, `modality_source`, `copied_text`, `copy_identity`, `corpus_background`, `stopword_deletion`, `payload_bound`, `derived_sensitivity` | Evidence & Semantic Measurement | +| event-time correlation standardization | Longitudinal Modeling / `longitudinal_core` | +| reusable static/generalized-mixed/dependence psychometric kernels in TEPP | fast-mlsirm owner path after parity/recovery | +| flat Analysis Run route/refusal modules | capability-oriented Analysis Run modules | -The full APA 7th register is [`docs/research/standards-and-literature.md`](docs/research/standards-and-literature.md). Method claims on this page use: +A repository-wide rename across a large active PR fleet is not used as a shortcut. Path repair is staged through coherent landing vehicles, but legacy paths are not canonical merely because migration is staged. -Aitchison, J. (1982). The statistical analysis of compositional data. *Journal of the Royal Statistical Society: Series B, 44*(2), 139–177. https://doi.org/10.1111/j.2517-6161.1982.tb01195.x +## Scientific validation and claim promotion -Allan, J. (Ed.). (2002). *Topic detection and tracking: Event-based information organization*. Kluwer Academic Publishers. +Validation Evidence and Scientific Claim Promotion are separate authorities. -Anagnostopoulos, E., Batsakis, S., & Petrakis, E. G. M. (2013). CHRONOS: A reasoning engine for qualitative temporal information in OWL. *Procedia Computer Science, 22*, 70–77. https://doi.org/10.1016/j.procs.2013.09.082 +A validation artifact may contain known-truth parameter recovery, RMSE, bias, interval coverage, convergence, invariance, graph recovery, temporal ordering, CPU/GPU parity, and Monte Carlo uncertainty. It does not itself grant a global `scientific_acceptance=true` flag. -Asparouhov, T., Hamaker, E. L., & Muthén, B. (2018). Dynamic structural equation models. *Structural Equation Modeling, 25*(3), 359–388. https://doi.org/10.1080/10705511.2017.1406803 +Claim promotion applies a preregistered method-specific evidence contract. Scale-invariant self-referential gates such as comparing an error magnitude with an uncertainty estimate computed from the same residual vector cannot substitute for a scientifically meaningful acceptance bound. LLM judgments and transport success cannot satisfy numerical evidence requirements. -Asparouhov, T., & Muthén, B. (2009). Exploratory structural equation modeling. *Structural Equation Modeling, 16*(3), 397–438. https://doi.org/10.1080/10705510903008204 +## Compute architecture + +All TEPP-owned production mathematical/statistical arithmetic is Rust-first. Deterministic CPU `f64` is the scientific numerical reference. Parallel CPU execution uses bounded/fixed worker pools and deterministic reduction where required. GPU/MLX/OpenCL/CUDA paths must demonstrate parity against the CPU reference and bounded memory/OOM fallback behavior before they are scientific evidence. + +A compute receipt proves that a named backend executed a named operation; it does not prove estimator validity. + +## Persistence + +PostgreSQL is the reference relational store. Domain persistence is normalized, tenant/time/provenance aware, and uses descriptive multiword `snake_case` objects. Bitemporal/interval constraints, immutable evidence/provenance, explicit idempotency/UPSERT behavior, and measured hot-partition behavior are required where applicable. + +`persistence_postgres` is an adapter. Other contexts do not query its tables directly, and external CWL services never read/write TEPP application tables. + +## Security and trust boundaries -Blei, D. M., & Lafferty, J. D. (2006). Dynamic topic models. In *Proceedings of the 23rd International Conference on Machine Learning* (pp. 113–120). ACM. https://doi.org/10.1145/1143844.1143859 +Documents, external metadata, serialized payloads, model artifacts, and LLM output are untrusted until their owning boundary validates identity, provenance, size/depth, authorization, and scientific semantics. Source text and secrets are not copied into ordinary operational telemetry. Service/provider credentials are scoped to their owner and cannot be repurposed as review/release authority. -Marsh, H. W., Morin, A. J. S., Parker, P. D., & Kaur, G. (2014). Exploratory structural equation modeling: An integration of the best features of exploratory and confirmatory factor analysis. *Annual Review of Clinical Psychology, 10*, 85–110. https://doi.org/10.1146/annurev-clinpsy-032813-153700 +## Documentation and research authority -Roberts, M. E., Stewart, B. M., Tingley, D., Lucas, C., Leder-Luis, J., Gadarian, S. K., Albertson, B., & Rand, D. G. (2014). Structural topic models for open-ended survey responses. *American Journal of Political Science, 58*(4), 1064–1082. https://doi.org/10.1111/ajps.12103 +- product target: [`docs/product/prd-v0.4-approved.md`](docs/product/prd-v0.4-approved.md) +- DDD context map: [`docs/architecture/domain-context-map.md`](docs/architecture/domain-context-map.md) +- service/dependence boundary: ADR 0011 and [`docs/architecture/temporal-dependence-composition.md`](docs/architecture/temporal-dependence-composition.md) +- general standards/literature: [`docs/research/standards-and-literature.md`](docs/research/standards-and-literature.md) +- LSIRM/MLSIRM/DLSJM evidence: [`docs/research/temporal-dependence-models.md`](docs/research/temporal-dependence-models.md) +- longitudinal/ctsem equation evidence: [`docs/research/multilevel-event-time-recovery.md`](docs/research/multilevel-event-time-recovery.md) +- scientific promotion: ADR 0014 and [`docs/TRACEABILITY.md`](docs/TRACEABILITY.md) -Roberts, M. E., Stewart, B. M., & Tingley, D. (2019). stm: An R package for structural topic models. *Journal of Statistical Software, 91*(2), 1–40. https://doi.org/10.18637/jss.v091.i02 +Detailed equation-by-equation recovery evidence belongs in `docs/research/` and executable tests, not duplicated into architecture responsibility tables. \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b495291a..38057006b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,451 +1,36 @@ # Changelog -All notable changes to TEPP are documented here. The format follows Keep a Changelog and semantic versioning once the first implementation release is cut. +All notable TEPP changes are recorded here. The current file is intentionally concise and product/release oriented; detailed pre-normalization scientific and micro-PR lineage is preserved byte-for-byte in [`docs/archive/CHANGELOG-pre-queue-normalization-2026-09-01.md`](docs/archive/CHANGELOG-pre-queue-normalization-2026-09-01.md). -## [0.2.0] - 2026-08-25 - -### Fixed - -- `network_analysis` posterior edge estimation landed with heuristic and fail-open defects that this release repairs before any consumer depends on it: a non-finite correlation now fails to the neutral p-value instead of masquerading as `|r| = 1`; negative-effect edges are excluded from the whole consensus perturbation pipeline rather than leaking into the union partition; the hardcoded 0.1 edge-drop probability became an explicit validated `edge_drop_probability` parameter; pseudo-p-values were replaced by exact two-sided Fisher z-transform p-values (Fisher, 1921) driving Benjamini–Hochberg admission (Benjamini & Hochberg, 1995) with percentile-bootstrap intervals (Efron, 1979); and 27 uncovered branch outcomes gained exact red-to-green cases. The workspace version is aligned to 0.2.0 across every crate manifest. - -### Added - -- **TDT/CHRONOS durable result contract**: canonical typed JSON and deterministic GraphML now export the actual bounded Allen reasoner result, observed/derived status, and conservative accepted-assertion support; canonical payload digest and `tdt_chronos_interval_consistency_v1` type bind the immutable bytes into ADR 0013's append-only `model_artifact` chain. -- **Analysis engine**: deterministic end-to-end analysis-run execution with cutoff-safe eligibility, immutable evidence binding, and reproducibility manifests (`analysis_engine` crate). -- **Restore Driver p.16 `MANIFESTVARstd`**: `recover_standardised_manifest_variance` maps `θ / θ = 1` with strictly positive `MANIFESTVAR`, refusing unstandardised manifest-variance, `MANIFESTTRAITVARstd`, and Equation 5 `Var(y)` substitutions (`psychometric_core`). -- **Posterior network estimator**: cross-draw Pearson correlations in ILR space, jackknife SE and CI, Benjamini–Hochberg FDR edge admission, nonparametric bootstrap stability, greedy modularity consensus clustering (`network_analysis` crate). -- **Topic measurement reference estimator**: bounded deterministic CPU `f64` TRSL-TM fitting with ALR/ILR coordinates, Aitchison distance, and lexical-inferential-weight refusal gates (`topic_measurement` crate). -- **Psychometric core**: Driver et al. (2017) SDE discrete-time recovery suite including drift, diffusion, T0VAR, TIPRED/TDPRED effects, standardised parameters, trait/state variance decomposition, and observed-indicator mapping — 18 K lines of production Rust with true-parameter RMSE tests. -- **Temporal six-clock architecture**: system, event, assertion, document, availability, and knowledge-cutoff clocks with forward-only transition enforcement and revision ordering (`temporal_core` + dedicated clock crates). -- **Membership and relation boundaries**: episode membership, role contradiction, relation absence detection, support-edge refusal, inferred-status gate, payload bounds, outcome ordering, summarises-edge identity, copy identity, citation/support non-transition, retrospective reporting, intake authorization, provider receipt, encrypted identity mapping, derived sensitivity inheritance, and purpose-bound PII governance. -- **Interpretation gateway**: loopback HTTP listener serving contextual-orchestrator interpretation POSTs with evidence-bound LLM claims and numerical-authority refusal. -- **Compute backend**: VRAM budget types with CPU `f64` fallback policy. -- **Persistence**: bitemporal PostgreSQL store with live sqlx integration, concurrent-write SQLSTATE classification, entity/project fail-closed SQL, audit-event inspection through try_record, and retention lifecycle. -- **Validation**: exact-head claim promotion gates, corpus-split leakage-audit manifests, documentation quality validation, and scientific claim boundary contracts. - -### Changed - -- Consolidated 99 open pull requests into protected main through batch integration vehicle (#215), hourly scheduler independent merges, and individual rebase-admin passes. -- Workspace grew from 10 to 57 crates covering evidence, semantic, temporal, event, relation, membership, persistence, simulation, validation, API, topic measurement, psychometric, network, interpretation, compute, and analysis-engine boundaries. -- All database objects use two-or-more-word `snake_case`; third normal form enforced; hot-partition readiness tracked as a separate acceptance gate. - -### Security - -- Purpose-bound authorization grants; blanket PII masking refused in favour of selective disclosure. -- Identity mappings sealed with HMAC; re-identification exports restricted to explicit purpose grants. -- Tenant roles bound to system-time lifetimes; privileged-access decisions replayed without source identity. -- Provider field codes recorded without source text; sensitivity inherited onto derived artifacts. +TEPP currently has **no GitHub release**. A source-version heading or historical changelog entry is not release evidence; protected-main state, exact-head gates, reproducible provenance/SBOM, scientific recovery, and required released integration contracts govern release claims. ## [Unreleased] -- Removed the repository-local hourly PR-maintenance caller now covered by the central required scheduler, retired stale workflow registrations, narrowed documentation triggers, keyed PR concurrency by fixed workflow name, repository, and pull-request number without cancelling non-PR runs, and combined line/branch coverage on one sequential runner while preserving both 100% gates and diagnostics. - -- `event_core` adds bounded Allen interval-consistency classification, atomic path-consistency closure, contradiction/resource refusals, and an explicit dependency-error fallback without claiming unrestricted global satisfiability. - -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `MANIFESTTRAITVAR`; §7.1, p. 19; p. 16 `MANIFESTTRAITVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-27T14:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised manifest-trait variance on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map (register items 83–84). Table 2 names `MANIFESTTRAITVAR` `Ψ_τ` the additional time-invariant variance-covariance on the measurement level and sets it `NULL` when there is no manifest trait. Equation 5 writes `Γ ~ N(τ, Ψ)` and names that covariance the manifest traits. Section 7.1 names manifest traits stable individual differences in indicator levels, distinct from process-level `TRAITVAR` `φ_ξ`. Page 16 prints standardised matrices with the suffix `std` when appropriate. The printed example on p. 16 is `discreteDRIFTstd`, not `MANIFESTTRAITVARstd`. Footnote 4 standardises using only the relevant variance, not the total. The relevant variance for that named indicator-level correlation is `MANIFESTTRAITVAR`, not process-level `TRAITVAR` and not residual `MANIFESTVAR` `θ`. The 2017-era source forms `MANIFESTTRAITVARstd` only when `MANIFESTTRAITVAR != 0`, as `solve(sqrt(diag(MANIFESTTRAITVAR) + ridging)) %&% MANIFESTTRAITVAR` when `verbose = TRUE`. OpenMx `%&%` is `t(A) %*% B %*% A`. Unlike `TRAITVARstd`, that formation adds `diag(c(ridging), n.manifest)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `ψ / ψ = 1` after strictly positive `MANIFESTTRAITVAR`. Form strictly positive `ψ` first, then `1 / √ψ`, then `(1 / √ψ) ψ (1 / √ψ)`. Unstandardised `MANIFESTTRAITVAR` is defined for a zero trait; standardised `MANIFESTTRAITVAR` is not. Zero `MANIFESTTRAITVAR` skips forming `MANIFESTTRAITVARstd` in the 2017-era source and fails closed here. Indicator-level trait variance is an event-time structural quantity, so a non-event clock fails closed. `MANIFESTTRAITVAR` does not require stable `a < 0`. Distinct positive `ψ` recover the same 1. `trait / trait = 1` is `TRAITVARstd` and recovers the same number and remains a distinct named quantity. `θ` is `MANIFESTVAR` and is measurement error, not this correlation. Meredith (1993) remains unread (web search 2026-08-27T14:20Z: Springer/Cambridge Core paywalled; Unpaywall historically `is_oa: false`; Springer `content/pdf` is an HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms (DOI `10.1007/bf02294457`). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. - -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `TRAITVAR`; §7.1, pp. 18–19; p. 16 `TRAITVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T17:45Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised trait variance on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map (register items 81–82). Table 2 names `TRAITVAR` `φ_ξ` the latent trait variance/covariance and sets it `NULL` when there is no trait. Section 7.1 names traits the stable between-subject differences (unit-level unobserved heterogeneity). Page 16 prints standardised matrices with the suffix `std` when appropriate. The printed example on p. 16 is `discreteDRIFTstd`, not `TRAITVARstd`. Footnote 4 standardises using only the relevant variance, not the total. The relevant variance for that named between-subject correlation is `TRAITVAR`, not free first-occasion `T0VAR` and not process-dynamics `asymDIFFUSION`. The 2017-era source forms `TRAITVARstd` only when `TRAITVAR != 0`, as `solve(sqrt(diag(TRAITVAR))) %&% TRAITVAR` when `verbose = TRUE`. OpenMx `%&%` is `t(A) %*% B %*% A`. Unlike `T0VARstd`, that formation uses `diag(diag(TRAITVAR))` and does not add `diag(c(ridging))`. The ridge is a `T0VAR` numerical hack and is not this exact map. The scalar correlation is `trait / trait = 1` after strictly positive `TRAITVAR`. Form strictly positive `trait` first, then `1 / √trait`, then `(1 / √trait) trait (1 / √trait)`. Unstandardised `TRAITVAR` is defined for a zero trait; standardised `TRAITVAR` is not. Zero `TRAITVAR` skips forming `TRAITVARstd` in the 2017-era source and fails closed here. Between-subject variance is an event-time structural quantity, so a non-event clock fails closed. `TRAITVAR` does not require stable `a < 0`. Distinct positive `trait` recover the same 1. `p_0 / p_0 = 1` is `T0VARstd` and recovers the same number and remains a distinct named quantity. `t0_b² v` is `addedT0TIPREDVAR` and is extra first-occasion TI variance, not this correlation. Meredith (1993) remains unread (Unpaywall 2026-08-26T17:20Z: `is_oa: false`; OpenAlex closed; Springer `content/pdf` is an HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms (DOI `10.1007/bf02294457`; Unpaywall `is_oa: false`). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymDIFFUSIONstd`; footnote 4; Eq. 4, p. 5; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T17:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic within-subject variance on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map (register items 89–90). Page 16 prints standardised matrices with the suffix `std` when appropriate, and names `asymDIFFUSION` the total within-subject variance as `Δt → ∞`. The printed example on p. 16 is `discreteDRIFTstd`, not `asymDIFFUSIONstd`. Footnote 4 standardises using only the relevant variance, not the total. The relevant variance for that named process-dynamics correlation is within-subject `asymDIFFUSION` `p = −q / (2 a)`, not free first-occasion `T0VAR`. The 2017-era source forms `asymDIFFUSIONstd` as `solve(sqrt(diag(asymDIFFUSION))) %&% asymDIFFUSION` when `verbose = TRUE`. OpenMx `%&%` is `t(A) %*% B %*% A`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `p / p = 1` after strictly positive `p`. Form strictly positive `p` first, then `1 / √p`, then `(1 / √p) p (1 / √p)`. Unstandardised `p` is defined for a zero process; standardised `asymDIFFUSION` is not. Zero `q` has no positive SD and fails closed. Lasting `p` requires stable `a < 0`. A non-event clock fails closed. Distinct positive `p` recover the same 1. `p_0 / p_0 = 1` is `T0VARstd` and recovers the same number and remains a distinct named quantity. `q / p = −2 a` is `DIFFUSIONstd` and is not this correlation. `v / v = 1` is `TIPREDVARstd` and recovers the same number and remains a distinct named quantity. Meredith (1993) remains unread (Unpaywall 2026-08-26T17:20Z: `is_oa: false`; OpenAlex closed; Springer `content/pdf` is an HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms (DOI `10.1007/bf02294457`; Unpaywall `is_oa: false`). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `T0VARstd`; Table 2, p. 12; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T07:17Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised initial latent variance on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map (register items 79–80). Page 16 prints standardised matrices with the suffix `std` when appropriate. The printed example on p. 16 is `discreteDRIFTstd`, not `T0VARstd`. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `T0VAR` the latent process initial variance/covariance. The first-occasion relevant variance is free `T0VAR` `p_0`, not process-dynamics `asymDIFFUSION` `-q / (2 a)`. The 2017-era source forms `T0VARstd` as `solve(sqrt(diag(T0VAR))) %&% T0VAR` when `verbose = TRUE`. OpenMx `%&%` is `t(A) %*% B %*% A`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `p_0 / p_0 = 1` after strictly positive `p_0`. Form strictly positive `p_0` first, then `1 / √p_0`, then `(1 / √p_0) p_0 (1 / √p_0)`. A zero first-occasion variance has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. Distinct positive `p_0` recover the same 1. `μ_0 / √p_0` is `T0MEANSstd` and recovers the same number when `μ_0 = √p_0` and remains a distinct named quantity. `p / p = 1` is `asymDIFFUSIONstd` and recovers the same number and remains a distinct named quantity. Meredith (1993) remains unread (Unpaywall 2026-08-26T07:17Z: `is_oa: false`; OpenAlex closed; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms (DOI `10.1007/bf02294457`; Unpaywall `is_oa: false`). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymCINTstd`; Eq. 3, p. 4; Table 2, p. 12; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T00:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic continuous intercept on current main after consolidation dropped the pre-consolidation `(-κ / a) / √p` slice. Page 16 prints standardised matrices with the suffix `std` when appropriate, and asymptotic values as `Δt → ∞`. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `κ` `CINT`. The relevant variance for that process intercept is within-subject `asymDIFFUSION` `p = −q / (2 a)`. The 2017-era source forms unstandardised `asymCINT` whenever `verbose = TRUE` as `-solve(DRIFT) %*% CINT` and does not form an `asymCINTstd` matrix. Form strictly positive `p` first, then the asymptotic intercept, then divide by `√p`. A zero intercept is exactly zero after that positive SD. Zero `q` has no positive process SD and fails closed. Lasting `p` requires stable `a < 0`. A non-event clock fails closed. `κ / √p` is `CINTstd` and is not this total-change map. `A^{-1}[e^{A Δt} − I] κ / √p` is `discreteCINTstd` and depends on the event interval. Meredith (1993) remains unread (Unpaywall 2026-08-25T18:22Z: `is_oa: false`; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991) remains unread on the same terms. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `T0MEANSstd`; Table 2, p. 12; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T04:09Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised initial latent mean on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `T0MEANS` the `n.latent × 1` matrix of latent process means at the first time point `T0` and names `T0VAR` the latent process initial variance/covariance. The first-occasion relevant variance is free `T0VAR` `p_0`, not process-dynamics `asymDIFFUSION` `-q / (2 a)`. The 2017-era source forms unstandardised `T0MEANS` and does not form a `T0MEANSstd` matrix; the scalar map is `μ_0 / √p_0` after strictly positive `p_0`. A zero mean is exactly zero. Zero `p_0` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0MEANS` does not require stable `a < 0`. `p_0 / p_0 = 1` recovers the same number when `μ_0 = √p_0` and remains a distinct named quantity. `μ_0 / √asymDIFFUSION` uses process-dynamics variance and is not this first-occasion map. Meredith (1993) remains unread (Unpaywall 2026-08-26T00:22Z: `is_oa: false`; OpenAlex closed; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `MANIFESTMEANSstd`; Table 2, p. 12; footnote 4; Eq. 5, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-25T11:32Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised manifest mean on current main after `0ce16e8` restored the pre-consolidation unstandardised slice. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `MANIFESTMEANS` `τ` the `n.manifest × 1` matrix of manifest means and `MANIFESTVAR` `Θ` the residual covariance of the indicators. The relevant variance for that named measurement intercept is residual `θ`, not total observed `Var(y) = λ² Var(η) + θ`. The 2017-era source forms unstandardised `MANIFESTMEANS` and does not form a `MANIFESTMEANSstd` matrix; the scalar map is `τ / √θ` after strictly positive `θ`. A zero mean is exactly zero. Zero `θ` has no positive SD and fails closed. A non-event clock fails closed. `MANIFESTMEANS` does not require stable `a < 0`. `θ / θ = 1` recovers the same number when `τ = √θ` and remains a distinct named quantity. `τ / √(λ² Var(η) + θ)` uses total observed variance and is not this residual map. Meredith (1993) remains unread (Unpaywall 2026-08-25T11:32Z: `is_oa: false`, 0 locations; OpenAlex closed; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-25T11:32Z: `is_oa: false`, 0 locations). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `CINTstd`; Eq. 1, p. 4; Table 2, p. 12; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-25T11:43Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous intercept on current main after consolidation dropped the pre-consolidation `κ / √p` slice. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `κ` `CINT`. The relevant variance for that process intercept is within-subject `asymDIFFUSION` `p = −q / (2 a)`, not total `trait + p + added`. Form strictly positive `p` first, then `κ / √p`. A zero intercept is exactly zero after that positive SD. Zero `q` has no positive process SD and fails closed. Lasting `p` requires stable `a < 0`. A non-event clock fails closed. `(-κ / a) / √p` is `asymCINTstd` and is not this continuous intercept. `A^{-1}[e^{A Δt} − I] κ / √p` is `discreteCINTstd` and depends on the event interval. `κ / √(trait + p + added)` uses the total and is not this residual map. `TRAITVAR` is not the standardisation variance. Meredith (1993) remains unread (Unpaywall 2026-08-25T11:43Z: `is_oa: false`; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991) remains unread on the same terms. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- Operator-gap register refreshed against protected main `c482ccea` (#239): workspace version 0.2.0, 57 crates, queue at seven open PRs with exact-head SHAs, issues #156/#168/#175 closed, GAP-009 advanced to estimator-core-plus-repairs with Leiden consensus remaining, GAP-001/GAP-012/GAP-017 closed on protected main, and a new Post-#239 state note recording both the estimator repairs and the non-release status of the version bump. Supersedes #236 whose base predated #239. -- `event_core` `EventMention` is the only constructible mention type and must be span-grounded: it cites one exact `SourceSpan`, document identity, six-clock evidence, extractor/model version, and proposed/reviewed status, and the surface is the document substring at that span. Exact-extent precision/recall recover known ACE extents with occupancy RMSE 0 versus whole-document RMSE 1; reviewed status and TDT/CHRONOS detections still cannot promote an instance. Interval consistency, persistence, and exports remain later #170 work. -- Restored protected-main gate integrity after the consolidation merges: hourly-scheduler prompt-contract tests now assert the gap-baseline-derived task contract (Gap ID naming, no invented weights) instead of stale increment-specific tokens, the operator-gap register inventory matches the live 33-PR queue, `evidence_core::image_unit` non-image/empty-subtype refusals and `load_union_branch_totals` valid-record accumulation have exact coverage, and the README crate fence plus duplicate registry entries stay deduped. -- Branch-coverage diagnostics on the post-consolidation head exposed two uncovered outcomes in `evidence_core::image_unit` (`is_image_media_type_token` non-image prefix and empty-subtype refusals), one uncovered authored line (the strip-prefix refusal), and lost valid-record coverage for `load_union_branch_totals`; exact red-to-green cases now cover the non-image/empty-subtype data URIs and per-coordinate True/False accumulation. -- Repaired post-consolidation merge fallout that left protected `main` red: restored the lost `return True` in the `check_coverage.py` match-guard branch, removed the shadowed duplicate `load_union_branch_totals` and `_is_multiline_match_guard` definitions plus duplicate workspace-crate entries (`episode_membership`, `analysis_engine`) from the contract tuple and Cargo member arrays, split two union-fused four-tuples back into `(variant, message)` pairs in the `event_core` error table, repaired the fused `identity_recovery_rate` body in `episode_membership::window`, deduplicated the checked-arithmetic eligible-count block in `analysis_engine`, fixed four-argument `unit()` test call sites, rebalanced the README crate-list fence around all 54 unique crates, and deduplicated the `location_membership`/`validation_core`/`tepp_api` architecture-table rows. Also documents private `PLAUSIBLE_IMAGE_MEDIA_TYPES` so `cargo doc -D warnings` passes. -- Branch coverage JSON now unique-folds `files[].branches` True/False counts across instantiations. Nightly totals on #49 head `1e3e2eb` reported `event_time.rs` 505/506 while every unique site had both arms taken (253 sites × 2 instantiations). Summary-only reports without branch arrays still fail closed on totals. The 100% contract is unique production arms, matching the LCOV authored-line gate. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` maps overflowing `expm1(a Δt)` / `expm1(2 a Δt)` in `recover_discrete_constant_predictor_effect` and `recover_discrete_process_noise` through the log-space rewrite without a redundant `if !argument.is_finite()` after overflow. Local crate llvm-cov on #49 head `559e7b399473ee90ba3234677dd9ef7f05f7fd2e` was 509/510: the same LLVM `exp`/`expm1` finite-argument proof as L768/L5040. Existing rewrite (`a = 800` / `a = 400`) and overflow (`a = 1e308`) tests remain the contract. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` maps overflowing `e^{a Δt}` / `e^{a(t−u)}` through the log-space rewrite without redundant `if !argument.is_finite()` after `exp` overflow on lagged covariance, T0 TI/TD carry, and impulse carry. Nightly branch coverage on #49 head `7e669babcc54408dd8407bbac56be0f304fa99e5` was 1713/1714: LLVM counted `event_time.rs` L5040 True and treated the finite-argument overflow False as uncovered after proving `exp` of a finite argument is finite, which binary64 overflow falsifies. `fit_scalar_log_rate` now also skips a zero earlier residual and a negative lag while still recovering from a valid pair. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` maps overflowing `e^{2 a Δt}` in `recover_discrete_latent_variance` through the log-space rewrite `(ln p + 2 a Δt).exp()` without a redundant `if !2 a Δt.is_finite()` after `exp` overflow. Nightly branch coverage on #49 head `e301e9706c0bd671ccad533063fb624cc568d0b3` was 1715/1716: LLVM counted `event_time.rs` L768 True and treated the finite-argument overflow False as uncovered after proving `exp` of a finite argument is finite, which binary64 overflow falsifies. Existing rewrite (`p = 1e-308`, `a = 400`, `Δt = 1`) and overflow (`a = 1e308`) tests remain the contract. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` executes the later `|| !log_rate.is_finite()` operand on `recover_discrete_time_independent_predictor_effect` from both the lib tests and the multilevel integration crate. Nightly branch coverage on #49 head `90b08bbe82cbe7776365a6c04df38857dfe5e53c` was 1714/1716: both True arms at `event_time.rs` L2480 were unhit because fail-closed tests supplied a non-finite `TIPREDEFFECT` or predictor before `a`. Direct `a = NaN` now takes those arms. `LagClock::as_str` is called through `black_box` so the outlined instantiation is not const-folded away. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` evaluates the Driver, Oud, and Voelkle (2017, §7.2) extra-process lag as `e^{ε Δt}` even when `ε Δt` underflows to `0` (`exp(0) = 1`). Nightly branch coverage on #49 head `22b8e68813ad59a9a91689bacfa4cf033dfad158` was 1718/1720: LLVM deleted `if extra_argument == 0.0` / `original_argument == 0.0` True after proving `ε < 0` and `Δt > 0` imply a nonzero product, which binary64 underflow falsifies. The public map now uses `exp` directly; `original_log_rate == 0` remains the Brownian `e^{0} = 1` path. Recovery tests assert the §7.2 identity `a_{ηξ} x e^{a Δt}(e^{(ε−a)Δt} − 1)/(ε − a)` on `(-min_subnormal) * 1e-320`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `MANIFESTMEANSstd`; Table 2, p. 12; footnote 4; Eq. 5, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-25T05:04Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised manifest mean. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `MANIFESTMEANS` `τ` the `n.manifest × 1` matrix of manifest means. Table 2 names `MANIFESTVAR` `Θ` the residual covariance of the indicators. The relevant variance for that named measurement intercept is residual `MANIFESTVAR` `θ`, not total observed `Var(y) = λ² Var(η) + θ`, matching `MANIFESTVARstd`. The 2017-era `summary.ctsemFit.R` forms unstandardised `MANIFESTMEANS` as `mxEval(MANIFESTMEANS, mxobj, compute=TRUE)`. That source does not form a `MANIFESTMEANSstd` matrix; the scalar map here is the footnote 4 standardisation of that named intercept: `τ / √θ`. Form strictly positive `θ` first, then divide `τ` by `√θ`. A zero mean is exactly zero. Unstandardised `MANIFESTMEANS` is defined for a zero residual; standardised `MANIFESTMEANS` is not. Zero `θ` has no positive SD and fails closed. Manifest means are an event-time measurement quantity, so a non-event clock fails closed. `MANIFESTMEANS` does not require stable `a < 0`. `MANIFESTVARstd` `θ / θ = 1` recovers the same number when `τ = √θ` and remains a distinct named quantity. `τ / √(λ² Var(η) + θ)` uses total observed variance and is not this residual map. The 2017-era source assigns `dimnames(MANIFESTMEANS)` to `list(manifestNames, manifestNames)` on an `n.manifest × 1` matrix; that assignment is a source bug and is not this map. `T0MEANSstd` `μ_0 / √p_0` recovers the same number when `τ = μ_0` and `θ = p_0` and remains a distinct named quantity. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-25T05:04Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-25T05:04Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `T0MEANSstd`; Table 2, p. 12; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-24T22:30Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised initial latent mean. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `T0MEANS` the latent process means at the first time point `T0`. The first-occasion relevant variance is free `T0VAR` `p_0`, not process-dynamics `asymDIFFUSION` `-q / (2 a)`, matching Table 3 `T0TIPREDEFFECTstd`. The 2017-era `summary.ctsemFit.R` forms unstandardised `T0MEANS` as `OpenMx::mxEval(T0MEANS, mxobj, compute=TRUE)`. That source does not form a `T0MEANSstd` matrix; the scalar map here is the footnote 4 standardisation of that named first-occasion mean: `μ_0 / √p_0`. Form strictly positive `p_0` first, then divide `μ_0` by `√p_0`. A zero mean is exactly zero. Unstandardised `T0MEANS` is defined for a zero first-occasion variance; standardised `T0MEANS` is not. Zero `p_0` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0MEANS` does not require stable `a < 0`. `T0VARstd` `p_0 / p_0 = 1` recovers the same number when `μ_0 = √p_0` and remains a distinct named quantity. `μ_0 / √asymDIFFUSION` uses process-dynamics variance and is not this first-occasion map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymCINTstd`; Eq. 3, p. 4; footnote 4; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-24T09:05Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic continuous intercept. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. `CINT` is the process intercept of individual, or average individual, dynamics, so that relevant variance is within-subject `asymDIFFUSION` `p = −q / (2 a)`. The 2017-era `summary.ctsemFit.R` forms `asymCINT` whenever `verbose = TRUE`, as `-solve(DRIFT) %*% CINT`. That source does not form an `asymCINTstd` matrix; the scalar map here is the footnote 4 standardisation of that named asymptotic intercept: `(-κ / a) / √p`. Form strictly positive `p` first, then the asymptotic intercept, then divide by `√p`. A zero intercept is exactly zero. Unstandardised `asymCINT` is defined for a zero process; standardised `asymCINT` is not. Zero `q` has no positive process SD and fails closed. Lasting `asymDIFFUSION` requires stable `a < 0`. A non-event clock fails closed. `κ / √p` is the continuous intercept standardisation and is not this total-change map. `A^{-1}[e^{A Δt} − I] κ / √p` depends on the event interval and is not this `Δt → ∞` map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, not `CINTstd`, not `discreteCINTstd`, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `discreteCINTstd`; Eq. 3, p. 4; footnote 4; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-24T05:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised discrete continuous intercept. Page 16 prints discrete-time transformations for a chosen event interval and, when appropriate, standardised matrices with the suffix `std`. Footnote 4 standardises using only the relevant variance, not the total. `CINT` is the process intercept of individual, or average individual, dynamics, so that relevant variance is within-subject `asymDIFFUSION` `p = −q / (2 a)`. The 2017-era `summary.ctsemFit.R` forms `discreteCINT` whenever `verbose = TRUE`, as `solve(DRIFT) %*% (discreteDRIFT − I) %*% CINT`. That source does not form a `discreteCINTstd` matrix; the scalar map here is the footnote 4 standardisation of that named discrete intercept: `A^{-1}[e^{A Δt} − I] κ / √p`. Form strictly positive `p` first, then the discrete intercept, then divide by `√p`. A zero intercept is exactly zero. Unstandardised `discreteCINT` is defined for growing `a ≥ 0` and for zero diffusion; standardised `discreteCINT` is not. Zero `q` has no positive process SD and fails closed. Lasting `asymDIFFUSION` requires stable `a < 0`. A non-event clock fails closed. A non-positive event interval fails closed. `κ / √p` does not depend on `Δt` and is not this finite-interval map. `(-κ / a) / √p` is the standardised asymptotic intercept and is not this map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, not `CINTstd`, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymDIFFUSIONstd`; footnote 4; Eq. 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T23:02Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic within-subject variance. Page 16 names `asymDIFFUSION` the total within-subject variance as `Δt → ∞` and prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. The 2017-era `summary.ctsemFit.R` forms `asymDIFFUSIONstd` whenever `verbose = TRUE`, as `solve(sqrt(diag(asymDIFFUSION) + ridging)) %&% asymDIFFUSION`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. That formation adds `diag(c(ridging), n.latent)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The 2017-era source assigns `dimnames(asymDIFFUSIONstd)` to `latentNames`; that assignment matches the `n.latent × n.latent` matrix and is this map. The scalar correlation is `p / p = 1` after strictly positive Lyapunov `p = −q / (2 a)`. Form strictly positive `p` first, then `1 / √p`, then `(1 / √p) p (1 / √p)`. Unstandardised `asymDIFFUSION` is defined for a zero process; standardised `asymDIFFUSION` is not. Zero `q` makes `solve(sqrt(0))` fail in the 2017-era source and fails closed here. That source does not skip forming `asymDIFFUSIONstd` when `p = 0`. Within-subject variance is an event-time structural quantity, so a non-event clock fails closed. Lasting `asymDIFFUSION` requires stable `a < 0`. Distinct positive `p` recover the same 1. `TIPREDVARstd` `v / v = 1` recovers the same number and remains a distinct named quantity. `DIFFUSIONstd` `q / p = −2 a` is the continuous-diffusion ratio, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `TIPREDVAR`; p. 16 `TIPREDVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:53Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised time-independent predictor variance. Table 2 names `TIPREDVAR` the variance/covariance of time-independent predictors. Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `TIPREDVARstd` whenever `verbose = TRUE` and `n.TIpred > 0`, as `solve(sqrt(diag(TIPREDVAR) + ridging)) %&% TIPREDVAR`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. Unlike `TRAITVARstd`, that formation adds `diag(c(ridging), n.TIpred)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The 2017-era source assigns `dimnames(TIPREDVARstd)` to `TIpredNames`; that assignment matches the `n.TIpred × n.TIpred` matrix and is this map. The scalar correlation is `v / v = 1` after strictly positive `TIPREDVAR`. Form strictly positive `v` first, then `1 / √v`, then `(1 / √v) v (1 / √v)`. Unstandardised `TIPREDVAR` is defined for a zero predictor; standardised `TIPREDVAR` is not. Zero `v` makes `solve(sqrt(0))` fail in the 2017-era source and fails closed here. Unlike `TRAITVAR` / `MANIFESTTRAITVAR`, that source does not skip forming `TIPREDVARstd` when `v = 0`. Predictor variance is an event-time structural quantity, so a non-event clock fails closed. `TIPREDVAR` does not require stable `a < 0`. Distinct positive `v` recover the same 1. `MANIFESTVARstd` `θ / θ = 1` recovers the same number and remains a distinct named quantity. Section 7.2 `addedTIPREDVAR` `(B / a)² v` is extra process variance, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers Equation 5 of the scalar analog of Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 2, p. 12 `TDPREDVAR` / `T0TDPREDCOV`; Table 3, p. 13 `T0TIPREDEFFECT`; p. 16; §7.2, pp. 20–21; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:26Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) extra first-occasion time-dependent predictor variance. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The 2017-era `summary.ctsemFit.R` forms the latent extra `addedT0TIPREDVAR` as `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`. That file comments out `TDPREDVAR` and does not form `addedT0TDPREDVAR`. The scalar analog of that quadratic form using the stack's first-occasion TD coefficient `t0_m` and Table 2 `TDPREDVAR` `v` is `t0_m² v`. Equation 5 of that analog extra, with `θ = 0` and `ψ = 0`, is `λ² t0_m² v`. Form the analog extra first, then `(λ extra) λ`. Do not form `λ²` first. A zero loading or zero extra is exactly zero. `v < 0` fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `t0_m` does not require stable `a < 0`. `t0_m² v` is the latent extra, not this observed extra. `λ² p_0 + θ` is first-occasion observed variance, not this extra. `λ² t0_b² v` is Eq. 5 of `addedT0TIPREDVAR` and is not this extra even when `t0_m = t0_b`. `MANIFESTVAR` `θ` is measurement error, not this extra. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:26Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:26Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `MANIFESTVAR`; Eq. 5, p. 5; p. 16 `MANIFESTVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:40Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised measurement-error variance. Table 2 names `MANIFESTVAR` `Θ` the residual covariance of the indicators. Equation 5 writes `ζ ~ N(0, Θ)`. Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `MANIFESTVARstd` whenever `verbose = TRUE`, as `solve(sqrt(diag(MANIFESTVAR) + ridging)) %&% MANIFESTVAR`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. Unlike `TRAITVARstd`, that formation adds `diag(c(ridging), n.manifest)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The 2017-era source assigns `dimnames(MANIFESTVARstd)` to `latentNames`; the matrix is `n.manifest × n.manifest`. That assignment is a source bug and is not this exact map. The scalar correlation is `θ / θ = 1` after strictly positive `MANIFESTVAR`. Form strictly positive `θ` first, then `1 / √θ`, then `(1 / √θ) θ (1 / √θ)`. Unstandardised `MANIFESTVAR` is defined for a zero residual; standardised `MANIFESTVAR` is not. Zero `θ` makes `solve(sqrt(0))` fail in the 2017-era source and fails closed here. Unlike `TRAITVAR` / `MANIFESTTRAITVAR`, that source does not skip forming `MANIFESTVARstd` when `θ = 0`. Measurement-error variance is an event-time structural quantity, so a non-event clock fails closed. `MANIFESTVAR` does not require stable `a < 0`. Distinct positive `θ` recover the same 1. `MANIFESTTRAITVARstd` `ψ / ψ = 1` recovers the same number and remains a distinct named quantity. Equation 5 `λ² Var(η) + θ` is `Var(y)`, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `MANIFESTTRAITVAR`; §7.1, p. 19; p. 16 `MANIFESTTRAITVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:28Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised manifest-trait variance. Table 2 names `MANIFESTTRAITVAR` `Ψ_τ` the additional time-invariant variance-covariance on the measurement level and sets it `NULL` when there is no manifest trait. Section 7.1 names manifest traits stable individual differences in indicator levels, distinct from process-level `TRAITVAR` `φ_ξ`. Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `MANIFESTTRAITVARstd` only when `MANIFESTTRAITVAR != 0`, as `solve(sqrt(diag(MANIFESTTRAITVAR) + ridging)) %&% MANIFESTTRAITVAR` when `verbose = TRUE`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. Unlike `TRAITVARstd`, that formation adds `diag(c(ridging), n.manifest)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `ψ / ψ = 1` after strictly positive `MANIFESTTRAITVAR`. Form strictly positive `ψ` first, then `1 / √ψ`, then `(1 / √ψ) ψ (1 / √ψ)`. Unstandardised `MANIFESTTRAITVAR` is defined for a zero trait; standardised `MANIFESTTRAITVAR` is not. Zero `MANIFESTTRAITVAR` skips forming `MANIFESTTRAITVARstd` in the 2017-era source and fails closed here. Indicator-level trait variance is an event-time structural quantity, so a non-event clock fails closed. `MANIFESTTRAITVAR` does not require stable `a < 0`. Distinct positive `ψ` recover the same 1. `TRAITVARstd` `trait / trait = 1` recovers the same number and remains a distinct named quantity. `MANIFESTVAR` `θ` is measurement error, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the scalar analog of Driver, Oud, and Voelkle (2017, Table 2, p. 12 `TDPREDVAR` / `T0TDPREDCOV`; Table 3, p. 13 `T0TIPREDEFFECT`; p. 16; §7.2, pp. 20–21; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) extra first-occasion time-dependent predictor variance. The 2017-era `summary.ctsemFit.R` forms `addedT0TIPREDVAR` as `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`. That file comments out `TDPREDVAR` and does not form `addedT0TDPREDVAR`. Table 2 names `T0TDPREDCOV` the covariance between latents at `T0` and time-dependent predictors, not this extra variance. Table 3 names `T0TIPREDEFFECT`, not a TD first-occasion effect matrix. The scalar analog of that quadratic form using the stack's first-occasion TD coefficient `t0_m` and Table 2 `TDPREDVAR` `v` is `t0_m² v`. Form `t0_m` first, then square, then multiply by `v`. A zero coefficient or zero predictor variance is exactly zero. `v < 0` fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `t0_m` does not require stable `a < 0`. `t0_b² v` is `addedT0TIPREDVAR` and is not this extra even when `t0_m = t0_b`. `t0_m · √v / √p_0` is `T0TDPREDEFFECTstd` and is not this variance. `T0TDPREDCOV` is the covariance, not `t0_m² v`. Free `T0VAR` `p_0` is the first-occasion state, not the extra TD variance. `TRAITVAR` is a zero-drift latent process, not `t0_m² v`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T21:34Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T21:34Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `TRAITVAR`; §7.1, pp. 18–19; p. 16 `TRAITVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:21Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised trait variance. Table 2 names `TRAITVAR` `φ_ξ` the latent trait variance/covariance and sets it `NULL` when there is no trait. Section 7.1 names traits the stable between-subject differences (unit-level unobserved heterogeneity). Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `TRAITVARstd` only when `TRAITVAR != 0`, as `solve(sqrt(diag(TRAITVAR))) %&% TRAITVAR` when `verbose = TRUE`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. Unlike `T0VARstd`, that formation uses `diag(diag(TRAITVAR))` and does not add `diag(c(ridging))`. The ridge is a `T0VAR` numerical hack and is not this exact map. The scalar correlation is `trait / trait = 1` after strictly positive `TRAITVAR`. Form strictly positive `trait` first, then `1 / √trait`, then `(1 / √trait) trait (1 / √trait)`. Unstandardised `TRAITVAR` is defined for a zero trait; standardised `TRAITVAR` is not. Zero `TRAITVAR` skips forming `TRAITVARstd` in the 2017-era source and fails closed here. Between-subject variance is an event-time structural quantity, so a non-event clock fails closed. `TRAITVAR` does not require stable `a < 0`. Distinct positive `trait` recover the same 1. `T0VARstd` `p_0 / p_0 = 1` recovers the same number and remains a distinct named quantity. `addedT0TIPREDVAR` `t0_b² v` is extra first-occasion TI variance, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13 `T0TDPREDEFFECTstd`; Table 2, p. 12 `TDPREDVAR`; p. 16; footnote 4; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T18:17Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised first-occasion time-dependent predictor effect. Table 3 names `T0TDPREDEFFECT` the effect of time-dependent predictors on latents at `T0`. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is time-dependent predictor variance `TDPREDVAR` `v_x`, not `TIPREDVAR`. The affected variance is free first-occasion `T0VAR` `p_0`, not within-subject `asymDIFFUSION` `-q / (2 a)`, because Table 3 is the first occasion, not the process dynamics. Form strictly positive `p_0` first, then strictly positive `v_x`, then `t0_m · √v_x / √p_0`. Unstandardised `t0_m` is defined for a zero coefficient and for zero predictor variance; standardised `T0TDPREDEFFECT` is not. Zero `p_0` or zero `v_x` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. Same numbers as `T0TIPREDEFFECTstd` yield the same product; Table 3 names a different matrix. The continuous standardisation `B · √v / √(-q / (2 a))` uses `asymDIFFUSION` and is not this first-occasion map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `t0_m · √v_x / √(trait + p_0 + added)` uses the total, not free `T0VAR`, and is not `T0TDPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T18:17Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T18:17Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16; §7.2, pp. 20–21; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T21:22Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised extra time-independent predictor variance `addedTIPREDVARstd`. Page 16 prints standardised matrices with the suffix `std` when appropriate. After `addedTIPREDVAR` as `asymTIPREDEFFECT %*% TIPREDVAR %*% t(asymTIPREDEFFECT)`, the 2017-era `summary.ctsemFit.R` forms `addedTIPREDVARstd = solve(sqrt(diag(addedTIPREDVAR))) %&% addedTIPREDVAR`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `extra / extra = 1` after strictly positive extra. Form `addedTIPREDVAR` first, then the ratio. A zero extra has no positive extra SD and fails closed. Unstandardised `(B / a)² v` is defined for a zero coefficient and for zero predictor variance; standardised `addedTIPREDVAR` is not. `λ² (B / a)² v` is Eq. 5 of the extra, not this correlation. `t0_b² v` is `addedT0TIPREDVAR`, not this asymptotic extra correlation. `TRAITVAR` is not the standardisation variance. The printed 2-latent `addedTIPREDVAR` 2.838 is not this scalar 1. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T21:22Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T21:22Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `TDPREDEFFECTstd`; Table 2, p. 12; Eq. 3, p. 5; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T21:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous time-dependent predictor effect. Page 16 prints continuous-time parameters and, when appropriate, standardised matrices with the suffix `std`. Table 2 names `M` `TDPREDEFFECT`. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is time-dependent predictor variance `v`. The affected variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because the process dynamics are individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then strictly positive `v`, then `m · √v / √(-q / (2 a))`. Unstandardised `M` is defined for a zero coefficient and for zero predictor variance; standardised `TDPREDEFFECT` is not. Zero `asymDIFFUSION` or zero `v` has no positive SD and fails closed. `TIPREDEFFECTstd` `B · √v / √p` is a different named matrix even when `M = B` and the predictor variances match. The finite-interval intercept-style standardisation `A^{-1}[e^{A Δt} − I] M · √v / √p` depends on the event interval and is not this continuous Dirac coefficient. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `m · √v / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `TDPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Predecessor `event_time.rs` asymptotic-std `process_sd == 0` / `predictor_sd == 0` gates after already-checked `within == 0` and `v == 0` were unreachable; this slice drops them so stacked line/branch coverage can close. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T21:10Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T21:10Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `CINTstd`; Eq. 1, p. 4; Table 2, p. 12; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T17:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous intercept. Page 16 prints continuous-time parameters and, when appropriate, standardised matrices with the suffix `std`. Table 2 names `κ` `CINT`. Footnote 4: standardisations use only the relevant variance, not the total. `CINT` is the process intercept of individual, or average individual, dynamics, so that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`. Form strictly positive `asymDIFFUSION` first, then `κ / √(-q / (2 a))`. Unstandardised `κ` is defined for growing `a ≥ 0` and for zero diffusion; standardised `CINT` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. The asymptotic standardisation `(-κ / a) / √p` is the total change, not this continuous intercept. The finite-interval standardisation `A^{-1}[e^{A Δt} − I] κ / √p` depends on the event interval and is not this continuous map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `κ / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `CINTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `TIPREDEFFECTstd`; §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; footnote 4; JSS PDF re-opened 2026-08-23T16:21Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous time-independent predictor effect. Page 16 prints continuous-time parameters and, when appropriate, standardised matrices with the suffix `std`. Table 2 names `B` `TIPREDEFFECT`. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is predictor variance `TIPREDVAR` `v`. The affected variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because the process dynamics are individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then strictly positive `v`, then `B · √v / √(-q / (2 a))`. Unstandardised `B` is defined for a zero coefficient and for zero predictor variance; standardised `TIPREDEFFECT` is not. Zero `asymDIFFUSION` or zero `v` has no positive SD and fails closed. The asymptotic standardisation `(-B / a) · √v / √p` is the total change, not this continuous coefficient. The finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not this continuous map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `B · √v / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `TIPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymTIPREDEFFECTstd`; §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; footnote 4; JSS PDF re-opened 2026-08-23T14:25Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic time-independent predictor effect. Page 16 prints continuous-time parameters and, when appropriate, standardised matrices with the suffix `std`. Section 7.2 names `asymTIPREDEFFECT` the expected total change in process means given a unit increase on a time-independent predictor. The scalar map is `-B / a` for stable `a < 0`. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is predictor variance `TIPREDVAR` `v`. The affected variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because the process dynamics are individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then strictly positive `v`, then the unit asymptotic effect, then `(-B / a) · √v / √(-q / (2 a))`. Unstandardised `-B / a` is defined for a zero coefficient and for zero predictor variance; standardised `asymTIPREDEFFECT` is not. Zero `asymDIFFUSION` or zero `v` has no positive SD and fails closed. The finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not this `Δt → ∞` map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `(-B / a) · √v / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `asymTIPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `DRIFTstd`; Eq. 1, p. 4; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T13:28Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous `DRIFT`. Page 16 prints continuous-time parameters (e.g., `DRIFT`) and, when appropriate, standardised matrices with the suffix `std`. Footnote 4: standardisations use only the relevant variance, not the total. For `DRIFT` that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because `DRIFT` is intended to represent individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first. In the scalar stationary case the within-subject SD ratio is 1, so the standardised auto-effect equals the unstandardised log-rate numerically; those remain distinct named quantities. Unstandardised `a` is defined for growing `a ≥ 0` and for zero diffusion; standardised `DRIFT` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. The discrete standardisation `e^{a Δt}` depends on the event interval and is not the continuous map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `a p / (trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `DRIFTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `DIFFUSIONstd`; Eq. 4, p. 5; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T13:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous `DIFFUSION`. Page 16 prints continuous-time parameters (e.g., `DRIFT`, `DIFFUSION`) and, when appropriate, standardised matrices with the suffix `std`. Footnote 4: standardisations use only the relevant variance, not the total. Process noise is within-subject stochastic input, so that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`, the same footnote 4 variance used for `DRIFT`. Form strictly positive `asymDIFFUSION` first, then `q / (−q / (2 a))`. In the scalar stationary case that ratio equals `-2 a` and does not depend on `q` once `q > 0`. Unstandardised `q` is defined for growing `a ≥ 0` and for zero diffusion; standardised `DIFFUSION` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. The discrete standardisation `Q_Δt / (−q / (2 a)) = 1 − exp(2 a Δt)` depends on the event interval and is not the continuous map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `q / (trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `DIFFUSIONstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `discreteDIFFUSIONstd`; Eq. 3–4, pp. 4–5; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T13:06Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised discrete `DIFFUSION`. Page 16 prints discrete-time transformations for a chosen event interval (`discreteDRIFT`, `discreteDIFFUSION`) and, when appropriate, standardised matrices with the suffix `std`. Footnote 4: standardisations use only the relevant variance, not the total. Process noise is within-subject stochastic input, so that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`, the same footnote 4 variance used for `DRIFT`. Form strictly positive `asymDIFFUSION` first, then `Q_Δt` from Equation 4, then `Q_Δt / (−q / (2 a))`. In the scalar stationary case that ratio equals `1 − exp(2 a Δt)`. Unstandardised `Q_Δt` is defined for growing `a ≥ 0` and for zero diffusion; standardised `DIFFUSION` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. The continuous standardisation `q / (−q / (2 a)) = −2 a` is not the discrete map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `Q_Δt / (trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `discreteDIFFUSIONstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:06Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:06Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `discreteDRIFTstd`; Eq. 3, p. 5; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T11:40Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised discrete `DRIFT`. Page 16 prints `discreteDRIFT` as `expm(DRIFT Δt)` and, when appropriate, `discreteDRIFTstd`. Footnote 4: standardisations use only the relevant variance, not the total. For `DRIFT` that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because `DRIFT` is intended to represent individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then `φ = exp(a Δt)`. In the scalar stationary case the within-subject SD ratio is 1, so the standardised auto-effect equals the unstandardised discrete lag numerically; those remain distinct named quantities. Unstandardised `e^{a Δt}` is defined for growing `a ≥ 0` and for zero diffusion; standardised `DRIFT` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. Section 7.1 warns that omitting trait variance confounds between- and within-person information. The trait-plus-state autocorrelation `(trait + e^{a Δt} p + added) / (trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `discreteDRIFTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T11:40Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T11:40Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 5, p. 5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T10:03Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar first-occasion variance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Between-subject `TRAITVAR` and `addedTIPREDVAR` are inherently stationary. The first-occasion composition is `trait + p_0 + (B / a)² v`. Form the free first-occasion state variance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary first-occasion map. Stationary first-occasion variance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Free `T0VAR` `p_0` is not this map. The lagged map `trait + e^{a Δt} p_0 + (B / a)² v` decays the state and is not this map. The later-occasion map `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v` includes `Q_Δt` and is not this map. As `Δt → 0+` those maps approach this composition. A zero trait, a zero initial variance, and a zero TI contribution is exactly zero. A zero initial variance and a zero TI contribution is exactly the trait. Trait-only variance does not require a stable drift. `a ≥ 0` cannot hold a finite TI extra variance when that contribution is nonzero and fails closed. Equation 5 of that first-occasion variance is `λ²(trait + p_0 + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not that first-occasion observed variance. The predetermined first-occasion latent variance is not the predetermined first-occasion observed variance. Stationary first-occasion observed variance is not that observed variance when `p_0` is free. Predetermined later observed variance includes `Q_Δt` and is not that first-occasion observed variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T10:03Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T10:03Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T20:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar lagged covariance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Equation 3 writes `η(t) = exp(A Δt) η(t0) + …`. Equation 4 writes `cov(η_t, η_{t-1}) = A_Δt cov(η_{t-1})`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not decay with `e^{a Δt}`. The lagged composition is `trait + e^{a Δt} p_0 + (B / a)² v`. Form the lagged free first-occasion covariance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary lagged map. Stationary lagged covariance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state (`e^{a Δt}` of that total) is not this map. Free `T0VAR` `p_0` is not this map. The later-occasion map `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v` includes `Q_Δt` and is not this map. As `Δt → ∞` with stable `a < 0` the state term vanishes. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. A zero-diffusion carry with `a ≥ 0` is `e^{a Δt} p_0` and is kept. Trait-only variance does not require a stable drift. The interval must be event time and strictly positive. Equation 5 of that lagged covariance is `λ²(trait + e^{a Δt} p_0 + (B / a)² v) + ψ`. Independent `ε_t` does not enter. `MANIFESTVAR` is not that lagged observed covariance. The predetermined lagged latent covariance is not the predetermined lagged observed covariance. Predetermined later observed variance includes `Q_Δt` and `θ` and is not that lagged observed covariance. Stationary lagged observed covariance is not that observed covariance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T20:20Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T20:20Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T20:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-occasion variance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. The process gradually transitions from the variances of the initial parameters toward those of the parameters when the model is stationary. Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes that the integral exhibits covariance `Q_Δt`. The law of total variance on the within-subject state is `e^{2 a Δt} p_0 + Q_Δt`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not enter that process-noise integral. The later-occasion composition is `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v`. Form the evolved free first-occasion variance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary later-occasion map. Stationary later-occasion variance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state (`e^{2 a Δt}` of that total plus `Q_Δt`) is not this map. Free `T0VAR` `p_0` is not this map. As `Δt → ∞` with stable `a < 0` the carried `p_0` vanishes and `Q_Δt` approaches `−q / (2 a)`, so the composition approaches contemporaneous stationary `T0VAR`. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. Nonzero diffusion with `a ≥ 0` is a growing process and is kept. The interval must be event time and strictly positive. Equation 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not that later-occasion observed variance. The predetermined later-occasion latent variance is not the predetermined later-occasion observed variance. Stationary later-occasion observed variance is not that observed variance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T20:20Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T20:20Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 finite-interval standardised `TIPREDEFFECT`; §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; footnote 4; JSS PDF re-opened 2026-08-24T01:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised finite-interval time-independent predictor effect. Page 16 prints discrete-time transformations for a chosen event interval and, when appropriate, standardised matrices with the suffix `std`. Equation 3 maps a finite event interval as `A^{-1}[e^{A Δt} − I] B`. Table 2 names `B` `TIPREDEFFECT`. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is predictor variance `TIPREDVAR` `v`. The affected variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because the process dynamics are individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then strictly positive `v`, then the unit discrete increment, then `A^{-1}[e^{A Δt} − I] B · √v / √(-q / (2 a))`. Unstandardised `A^{-1}[e^{A Δt} − I] B` is defined for a zero coefficient and for zero predictor variance; standardised finite-interval `TIPREDEFFECT` is not. Zero `asymDIFFUSION` or zero `v` has no positive SD and fails closed. Page 16 `asymTIPREDEFFECTstd` `(-B / a) · √v / √p` is the `Δt → ∞` map and is not this finite interval. A later event interval yields a different standardised increment. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `A^{-1}[e^{A Δt} − I] B · √v / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not the finite-interval map when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T01:20Z: `is_oa: false`; Springer `content/pdf` is HTML 200; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T01:20Z: `is_oa: false`; Springer `content/pdf` is HTML 200; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `T0VAR`; p. 16 `T0VARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:06Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised first-occasion latent variance. Table 2 names `T0VAR` the latent process initial variance/covariance. Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `T0VARstd` as `solve(sqrt(diag(T0VAR))) %&% T0VAR` when `verbose = TRUE`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `p_0 / p_0 = 1` after strictly positive free `T0VAR`. Form strictly positive `p_0` first, then `1 / √p_0`, then `(1 / √p_0) p_0 (1 / √p_0)`. Unstandardised `T0VAR` is defined for a zero first-occasion variance; standardised `T0VAR` is not. Zero `p_0` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. Distinct positive `p_0` recover the same 1. `T0TDPREDEFFECTstd` `t0_m · √v / √p_0` depends on `p_0` and is not this correlation. `addedT0TIPREDVAR` `t0_b² v` is extra TI variance, not this correlation. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:06Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:06Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13 `T0TDPREDEFFECTstd`; Table 2, p. 12; p. 16; footnote 4; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T21:34Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised first-occasion time-dependent predictor effect. Table 3 names `T0TDPREDEFFECT` the effect of time-dependent predictors on latents at `T0`. Table 2 names `M` `TDPREDEFFECT` and names `T0TDPREDCOV` the first-occasion covariance, not this coefficient. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is time-dependent predictor variance `v`, not `TIPREDVAR`. The affected variance is free first-occasion `T0VAR` `p_0`, not within-subject `asymDIFFUSION` `-q / (2 a)`, because Table 3 is the first occasion, not the process dynamics. Form strictly positive `p_0` first, then strictly positive `v`, then `t0_m · √v / √p_0`. Unstandardised `t0_m` is defined for a zero coefficient and for zero predictor variance; standardised `T0TDPREDEFFECT` is not. Zero `p_0` or zero `v` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. The continuous standardisation `m · √v / √(-q / (2 a))` uses `asymDIFFUSION` and is not this first-occasion map. `T0TIPREDEFFECTstd` `t0_b · √v / √p_0` is a different named matrix even when `t0_m = t0_b` and the predictor variances match. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `t0_m · √v / √(trait + p_0 + added)` uses the total, not free `T0VAR`, and is not `T0TDPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T21:34Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T21:34Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 2, p. 12; §7.2, pp. 20–21; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T19:23Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar extra observed-indicator time-independent predictor variance of §7.2 `addedTIPREDVAR`. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The 2017-era `summary.ctsemFit.R` forms the latent extra `addedTIPREDVAR` as `asymTIPREDEFFECT %*% TIPREDVAR %*% t(asymTIPREDEFFECT)`. The scalar latent extra is `(B / a)² v`. Equation 5 of that extra, with `θ = 0` and `ψ = 0`, is `λ² (B / a)² v`. Form `addedTIPREDVAR` first, then `(λ extra) λ`. Do not form `λ²` first. A zero loading or zero extra is exactly zero. `v < 0` fails closed. A non-event clock fails closed. `a ≥ 0` cannot hold a finite process-mean change when the extra is nonzero and fails closed. `(B / a)² v` is the latent extra, not this observed extra. `λ² t0_b² v` is Eq. 5 of `addedT0TIPREDVAR`, not this asymptotic observed extra. `λ² p + θ` is stationary observed variance, not this extra. `MANIFESTVAR` `θ` is measurement error, not this extra. `Ψ` is intercept variance and is not extra TI. The printed 2-latent `addedTIPREDVAR` 2.838 is not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T19:10Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T19:10Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 3, p. 13 `T0TIPREDEFFECT`; Table 2, p. 12; p. 16; §7.2, pp. 20–21; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T19:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar extra observed-indicator time-independent predictor variance of 2017-era `addedT0TIPREDVAR`. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The 2017-era `summary.ctsemFit.R` forms the latent extra `addedT0TIPREDVAR` as `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`. The scalar latent extra is `t0_b² v`. Equation 5 of that extra, with `θ = 0` and `ψ = 0`, is `λ² t0_b² v`. Form `addedT0TIPREDVAR` first, then `(λ extra) λ`. Do not form `λ²` first. A zero loading or zero extra is exactly zero. `v < 0` fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0TIPREDEFFECT` does not require stable `a < 0`. `t0_b² v` is the latent extra, not this observed extra. `λ² p_0 + θ` is first-occasion observed variance, not this extra. `λ² (B / a)² v` is Eq. 5 of `addedTIPREDVAR`, not this first-occasion observed extra. `MANIFESTVAR` `θ` is measurement error, not this extra. `Ψ` is intercept variance and is not extra TI. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T19:10Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T19:10Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13 `T0TIPREDEFFECT`; p. 16; §7.2, pp. 20–21; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T18:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar first-occasion extra time-independent predictor variance `addedT0TIPREDVAR`. Table 3 names `T0TIPREDEFFECT` the effect of time-independent predictors on latents at `T0`. Page 16 prints extra summary matrices when `verbose = TRUE`. The 2017-era `summary.ctsemFit.R` forms `addedT0TIPREDVAR` as `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`. Section 7.2 names `addedTIPREDVAR` the stable between-subject variance accounted for by time-independent predictors at the process asymptote, `(B / a)² v`. The first-occasion analogue uses free `T0TIPREDEFFECT`, not `-B / a`. The scalar map is `t0_b² v`. Form `t0_b` first, then square, then multiply by `v`. A zero coefficient or zero predictor variance is exactly zero. `v < 0` fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0TIPREDEFFECT` does not require stable `a < 0`. `(B / a)² v` is `addedTIPREDVAR` and is not this first-occasion map. `t0_b · √v / √p_0` is `T0TIPREDEFFECTstd` and is not this variance. Free `T0VAR` `p_0` is the first-occasion state, not the extra TI variance. `TRAITVAR` is a zero-drift latent process, not `t0_b² v`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T18:20Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T18:20Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13 `T0TIPREDEFFECTstd`; p. 16; footnote 4; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T17:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised first-occasion time-independent predictor effect. Table 3 names `T0TIPREDEFFECT` the effect of time-independent predictors on latents at `T0`. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is predictor variance `TIPREDVAR` `v`. The affected variance is free first-occasion `T0VAR` `p_0`, not within-subject `asymDIFFUSION` `-q / (2 a)`, because Table 3 is the first occasion, not the process dynamics. Form strictly positive `p_0` first, then strictly positive `v`, then `t0_b · √v / √p_0`. Unstandardised `t0_b` is defined for a zero coefficient and for zero predictor variance; standardised `T0TIPREDEFFECT` is not. Zero `p_0` or zero `v` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. The continuous standardisation `B · √v / √(-q / (2 a))` uses `asymDIFFUSION` and is not this first-occasion map. The asymptotic standardisation `(-B / a) · √v / √p` is the total change, not this first-occasion coefficient. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `t0_b · √v / √(trait + p_0 + added)` uses the total, not free `T0VAR`, and is not `T0TIPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T17:20Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T17:20Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T11:05Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-start later-occasion variance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Section 4.3 notes that the process gradually transitions from the initial variances toward the stationary variances, and that the initial time point need not reflect the first measurement occasion (`startoffset`). Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes that the integral exhibits covariance `Q_Δt`. After a later start `u` the within-subject state variance is `e^{2 a u} p_0 + Q_u`. Evolving that later start over `s` is `e^{2 a s}(e^{2 a u} p_0 + Q_u) + Q_s`. Chapman–Kolmogorov writes `Q_{u+s} = e^{2 a s} Q_u + Q_s`, so the later-occasion map over `u + s` is the same composition. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not enter `Q_s`. The later-start later-occasion composition is `trait + e^{2 a s}(e^{2 a u} p_0 + Q_u) + Q_s + (B / a)² v`. Form the later-start within-subject variance first, then evolve that state, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary later-occasion map. Stationary later-occasion variance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Later-occasion variance at `u` omits `Q_s` and is not this map when `s > 0`. Later-start lagged covariance is `e^{a s}` of the later state and omits `Q_s`; it is not this map. Evolving the later total as if it were all state (`e^{2 a s}` of `trait + e^{2 a u} p_0 + Q_u + (B / a)² v` plus `Q_s`) is not this map. Later-occasion variance over the lag interval alone ignores `startoffset` and omits `e^{2 a s} Q_u`; it is not this map when `u > 0`. As `u → 0+` the composition approaches later-occasion variance over `s`. As `s → 0+` the composition approaches later-occasion variance at `u`. As `s → ∞` with stable `a < 0` the carried later state vanishes and `Q_s` approaches `−q / (2 a)`, so the composition approaches contemporaneous stationary `T0VAR`. A zero trait, a zero initial variance, a zero diffusion, and a zero TI contribution is exactly zero. A zero initial variance, a zero diffusion, and a zero TI contribution is exactly the trait. Trait-only variance does not require a stable drift. `a ≥ 0` cannot hold a finite TI extra variance when that contribution is nonzero and fails closed. Nonzero diffusion with `a ≥ 0` is a growing process and is kept. Both intervals must be event time and strictly positive. Equation 5 of that later-start later-occasion variance is `λ²(trait + e^{2 a s}(e^{2 a u} p_0 + Q_u) + Q_s + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not that later-start later-occasion observed variance. The later-start later-occasion latent variance is not the later-start later-occasion observed variance. Predetermined later observed variance at `u` omits `Q_s` and is not that observed variance when `s > 0`. Later-start lagged observed covariance omits `Q_s` and `θ` and is not that observed variance. Stationary later-occasion observed variance is not that observed variance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T11:05Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T11:05Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T10:27Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-start lagged covariance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Section 4.3 notes that the process gradually transitions from the initial variances toward the stationary variances, and that the initial time point need not reflect the first measurement occasion (`startoffset`). Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes `cov(η_t, η_{t-1}) = A_Δt cov(η_{t-1})`. After a later start `u` the within-subject state variance is `e^{2 a u} p_0 + Q_u`. Lagging that later start over `s` is `e^{a s}(e^{2 a u} p_0 + Q_u)`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not decay with `e^{a s}`. The lagged composition is `trait + e^{a s}(e^{2 a u} p_0 + Q_u) + (B / a)² v`. Form the later-start within-subject variance first, then lag that state, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary lagged map. Stationary lagged covariance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. First-occasion lagged covariance `trait + e^{a s} p_0 + (B / a)² v` omits `e^{a s} Q_u` and is not this map when `u > 0`. Later-occasion variance includes `Q_u` without lagging that later state and is not this map. Evolving the later total as if it were all state (`e^{a s}` of `trait + e^{2 a u} p_0 + Q_u + (B / a)² v`) is not this map. As `u → 0+` the composition approaches first-occasion lagged covariance. As `s → 0+` the composition approaches later-occasion variance at `u`. As `s → ∞` with stable `a < 0` the state term vanishes. A zero trait, a zero initial variance, a zero diffusion, and a zero TI contribution is exactly zero. A zero initial variance, a zero diffusion, and a zero TI contribution is exactly the trait. Trait-only variance does not require a stable drift. `a ≥ 0` cannot hold a finite TI extra variance when that contribution is nonzero and fails closed. Nonzero diffusion with `a ≥ 0` is a growing process and is kept. Both intervals must be event time and strictly positive. Equation 5 of that later-start lagged covariance is `λ²(trait + e^{a s}(e^{2 a u} p_0 + Q_u) + (B / a)² v) + ψ`. Independent `ε_t` does not enter. `MANIFESTVAR` is not that later-start lagged observed covariance. The later-start lagged latent covariance is not the later-start lagged observed covariance. First-occasion lagged observed covariance omits `e^{a s} Q_u` and is not that observed covariance when `u > 0`. Predetermined later observed variance includes `Q_u` and `θ` and is not that later-start lagged observed covariance. Stationary lagged observed covariance is not that observed covariance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T10:27Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T10:27Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T09:04Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar lagged covariance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Equation 3 writes `η(t) = exp(A Δt) η(t0) + …`. Equation 4 writes `cov(η_t, η_{t-1}) = A_Δt cov(η_{t-1})`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not decay with `e^{a Δt}`. The lagged composition is `trait + e^{a Δt} p_0 + (B / a)² v`. Form the lagged free first-occasion covariance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary lagged map. Stationary lagged covariance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state (`e^{a Δt}` of that total) is not this map. Free `T0VAR` `p_0` is not this map. The later-occasion map `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v` includes `Q_Δt` and is not this map. As `Δt → ∞` with stable `a < 0` the state term vanishes. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. A zero-diffusion carry with `a ≥ 0` is `e^{a Δt} p_0` and is kept. Trait-only variance does not require a stable drift. The interval must be event time and strictly positive. Equation 5 of that lagged covariance is `λ²(trait + e^{a Δt} p_0 + (B / a)² v) + ψ`. Independent `ε_t` does not enter. `MANIFESTVAR` is not that lagged observed covariance. The predetermined lagged latent covariance is not the predetermined lagged observed covariance. Predetermined later observed variance includes `Q_Δt` and `θ` and is not that lagged observed covariance. Stationary lagged observed covariance is not that observed covariance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T09:04Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T09:04Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T05:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-occasion variance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. The process gradually transitions from the variances of the initial parameters toward those of the parameters when the model is stationary. Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes that the integral exhibits covariance `Q_Δt`. The law of total variance on the within-subject state is `e^{2 a Δt} p_0 + Q_Δt`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not enter that process-noise integral. The later-occasion composition is `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v`. Form the evolved free first-occasion variance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary later-occasion map. Stationary later-occasion variance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state (`e^{2 a Δt}` of that total plus `Q_Δt`) is not this map. Free `T0VAR` `p_0` is not this map. As `Δt → ∞` with stable `a < 0` the carried `p_0` vanishes and `Q_Δt` approaches `−q / (2 a)`, so the composition approaches contemporaneous stationary `T0VAR`. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. Nonzero diffusion with `a ≥ 0` is a growing process and is kept. The interval must be event time and strictly positive. Equation 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not that later-occasion observed variance. The predetermined later-occasion latent variance is not the predetermined later-occasion observed variance. Stationary later-occasion observed variance is not that observed variance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T05:12Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T05:12Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- Branch coverage JSON now unique-folds `files[].branches` True/False counts across instantiations. Nightly totals on #49 head `1e3e2eb` reported `event_time.rs` 505/506 while every unique site had both arms taken (253 sites × 2 instantiations). Summary-only reports without branch arrays still fail closed on totals. The 100% contract is unique production arms, matching the LCOV authored-line gate. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` maps overflowing `expm1(a Δt)` / `expm1(2 a Δt)` in `recover_discrete_constant_predictor_effect` and `recover_discrete_process_noise` through the log-space rewrite without a redundant `if !argument.is_finite()` after overflow. Local crate llvm-cov on #49 head `559e7b399473ee90ba3234677dd9ef7f05f7fd2e` was 509/510: the same LLVM `exp`/`expm1` finite-argument proof as L768/L5040. Existing rewrite (`a = 800` / `a = 400`) and overflow (`a = 1e308`) tests remain the contract. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` maps overflowing `e^{a Δt}` / `e^{a(t−u)}` through the log-space rewrite without redundant `if !argument.is_finite()` after `exp` overflow on lagged covariance, T0 TI/TD carry, and impulse carry. Nightly branch coverage on #49 head `7e669babcc54408dd8407bbac56be0f304fa99e5` was 1713/1714: LLVM counted `event_time.rs` L5040 True and treated the finite-argument overflow False as uncovered after proving `exp` of a finite argument is finite, which binary64 overflow falsifies. `fit_scalar_log_rate` now also skips a zero earlier residual and a negative lag while still recovering from a valid pair. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` maps overflowing `e^{2 a Δt}` in `recover_discrete_latent_variance` through the log-space rewrite `(ln p + 2 a Δt).exp()` without a redundant `if !2 a Δt.is_finite()` after `exp` overflow. Nightly branch coverage on #49 head `e301e9706c0bd671ccad533063fb624cc568d0b3` was 1715/1716: LLVM counted `event_time.rs` L768 True and treated the finite-argument overflow False as uncovered after proving `exp` of a finite argument is finite, which binary64 overflow falsifies. Existing rewrite (`p = 1e-308`, `a = 400`, `Δt = 1`) and overflow (`a = 1e308`) tests remain the contract. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` executes the later `|| !log_rate.is_finite()` operand on `recover_discrete_time_independent_predictor_effect` from both the lib tests and the multilevel integration crate. Nightly branch coverage on #49 head `90b08bbe82cbe7776365a6c04df38857dfe5e53c` was 1714/1716: both True arms at `event_time.rs` L2480 were unhit because fail-closed tests supplied a non-finite `TIPREDEFFECT` or predictor before `a`. Direct `a = NaN` now takes those arms. `LagClock::as_str` is called through `black_box` so the outlined instantiation is not const-folded away. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` evaluates the Driver, Oud, and Voelkle (2017, §7.2) extra-process lag as `e^{ε Δt}` even when `ε Δt` underflows to `0` (`exp(0) = 1`). Nightly branch coverage on #49 head `22b8e68813ad59a9a91689bacfa4cf033dfad158` was 1718/1720: LLVM deleted `if extra_argument == 0.0` / `original_argument == 0.0` True after proving `ε < 0` and `Δt > 0` imply a nonzero product, which binary64 underflow falsifies. The public map now uses `exp` directly; `original_log_rate == 0` remains the Brownian `e^{0} = 1` path. Recovery tests assert the §7.2 identity `a_{ηξ} x e^{a Δt}(e^{(ε−a)Δt} − 1)/(ε − a)` on `(-min_subnormal) * 1e-320`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` integration tests now execute the Driver, Oud, and Voelkle (2017, Eq. 3 first-summand carry) overflow rewrite of Table 3 `T0TIPREDEFFECT` / `T0TDPREDEFFECT` (`sign(t0_b z) exp(ln|t0_b z| + a Δt)` and the same form for `t0_m x0`). Nightly branch coverage on #49 head `d634f5849ed8e9f75af1b43c2e59d8e7d6301b45` was 1718/1720: the two missing records were the unused non-`cfg(test)` instantiations of `if !drift_interval.is_finite()` at the T0 TI and T0 TD carry overflow rewrites (`event_time.rs` L4245 and L4628). Lib tests already covered both sides; integration tests now take overflowing `a Δt` (`1e308 * 2`) and finite-`a Δt` overflowed `exp` (`710`) on those public maps. Meredith (1993) remains unread (Unpaywall 2026-08-22T23:12Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T23:12Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-22T23:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-occasion variance of §4.3 stationary `T0VAR`. Section 4.3 constrains first-occasion variance according to the model-predicted variances across all time points. Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes that the integral exhibits covariance `Q_Δt`. The law of total variance on the within-subject state is `e^{2 a Δt}(−q / (2 a)) + Q_Δt`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not enter that process-noise integral. The later-occasion composition is `trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v`. Form the evolved within-subject variance first, then include the trait, then include the TI extra variance, then add. Under stationarity that composition equals contemporaneous `T0VAR`. Evolving the constrained total as if it were all state (`e^{2 a Δt} p_stat + Q_Δt`) is not this map. The lagged covariance `trait + e^{a Δt}(−q / (2 a)) + (B / a)² v` omits `Q_Δt` and is not this map. `Q_Δt` is not this map. The interval must be event time and strictly positive. Equation 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v) + θ + ψ`. The lagged observed covariance omits `Q_Δt` and `θ`. `MANIFESTVAR` is not that later-occasion observed variance. The later-occasion latent variance is not the later-occasion observed variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-22T23:12Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T23:12Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-22T19:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar lagged covariance of §4.3 stationary `T0VAR`. Equation 3 writes `η(t) = exp(A Δt) η(t0) + …`. Equation 4 writes `cov(η_t, η_{t-1}) = A_Δt cov(η_{t-1})`. The contemporaneous constraint is `trait + −q / (2 a) + (B / a)² v`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not decay with `e^{a Δt}`. The lagged composition is `trait + e^{a Δt}(−q / (2 a)) + (B / a)² v`. Form the lagged within-subject covariance first, then include the trait, then include the TI extra variance, then add. As `Δt → ∞` with stable `a < 0` the state term vanishes. As `Δt → 0+` the lagged map approaches contemporaneous `T0VAR`. Those limits are not this finite-lag map. Evolving the constrained total as if it were all state is not this map. `trait + e^{a Δt} p` is not this map when `addedTIPREDVAR` is nonzero. Contemporaneous `T0VAR` is not this map. The interval must be event time and strictly positive. Equation 5 of that lagged covariance is `λ²(trait + e^{a Δt}(−q / (2 a)) + (B / a)² v) + ψ`. Independent `ε_t` does not enter. `MANIFESTVAR` is not that lagged observed covariance. Contemporaneous `Var(y_0)` includes `θ` and is not that lagged observed covariance. The lagged latent covariance is not the lagged observed covariance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-22T19:13Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T19:13Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). -- `psychometric_core` rustfmt-sorts the `event_time` test import list and wraps four long test signatures so `cargo fmt --check` matches 1.97.1. Nightly branch coverage on #49 head `a6bea47acc38de1a33ed403360eb5cacd3023df6` was 1691/1712: the 21 missing True sides in `event_time.rs` were later `||` operands and `!Δt.is_finite()` (as opposed to `Δt <= 0`) on lagged observed covariance, extra-process, asymptotic TI/CINT, T0 carry, and impulse-carry guards. Direct inner-map calls now execute those arms. `as_measurement_invariance_wire_name` maps only Configural/Metric/Strong onto `#84` `configural`/`metric`/`scalar` and returns `None` for local Strict (`as_str` remains `"strict"`). Parent-head coverage note on `ebd01c4` is historical. Meredith (1993) remains unread (Unpaywall 2026-08-22T16:13Z: `is_oa: false`; Springer `content/pdf` is HTML 200). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T16:13Z: `is_oa: false`; Springer `content/pdf` is HTML 200). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` covers the remaining fail-closed arms on `event_time.rs` lines 1995, 1998, 2063, 2065, 3695, 3706, 3751, 4078, 4089, and 4134 (nightly line/branch gaps on predecessor #49 head `ebd01c4`). Non-event clocks, non-positive and non-finite `Δt`, after-t0 extra-process interval errors after a successful `μ_t`, a zero extra-process contribution returning `μ_t`, Table 3 `T0TIPREDEFFECT`/`T0TDPREDEFFECT` effect errors through the carry, overflowing `a Δt` products, and those carry errors through the evolved-mean composition now execute. Meredith (1993) remains unread (Unpaywall 2026-08-22T12:15Z: `is_oa: false`; Springer `content/pdf` is HTML 200; Cambridge Core PDF 302 to a closed product page). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T12:15Z: `is_oa: false`; Springer `content/pdf` is HTML 200; NCES 404; ETS RR-91-18 404). Driver, Oud, and Voelkle (2017) JSS PDF re-opened 2026-08-22T12:17Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 5, p. 5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-22T03:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator variance of §4.3 stationary `T0VAR`. Section 4.3 constrains the first-occasion variance to the model-predicted variance when `stationary` includes `"T0VAR"`. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The constrained latent variance is `trait + −q / (2 a) + (B / a)² v`. The scalar composition is `Var(y_0) = λ²(trait + −q / (2 a) + (B / a)² v) + θ + ψ`. Form the stationary latent variance first, then `λ² p + θ + ψ`. A zero loading is exactly `θ + ψ`. A zero trait, a zero diffusion, and a zero TI contribution is exactly `θ + ψ`. `λ² p_0` for free `T0VAR` is not this composition. `λ²(−q / (2 a)) + θ` is not this composition when `TRAITVAR` or `addedTIPREDVAR` is nonzero. Evolving the constrained variance as if it were all state is not this composition when the trait or TI contribution is nonzero. `MANIFESTVAR` is not `Var(y_0)`. The constrained latent variance is not `Var(y_0)`. `TRAITVAR` is latent and is scaled by `λ²`; `MANIFESTTRAITVAR` is not. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-22T03:20Z: `is_oa: false`). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T03:20Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; p. 16; Table 2, p. 12; §7.2, pp. 20–21; Eq. 4, p. 5; JSS PDF re-opened 2026-08-22T03:07Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar stationary `T0VAR`. Section 4.3 constrains the first-occasion variance to the model-predicted variance when `stationary` includes `"T0VAR"`. Page 16 names `asymDIFFUSION` the total within-subject variance `-q / (2 a)`. Section 4.3 (p. 9) adds `TRAITVAR`. Section 7.2 names `addedTIPREDVAR` the stable between-subject variance accounted for by time-independent predictors, `(B / a)² v`. The scalar composition is `trait + −q / (2 a) + (B / a)² v`. Form the within-subject contribution first, then include the trait, then include the TI extra variance, then add. A zero trait, a zero diffusion, and a zero TI contribution is exactly zero. A zero diffusion and a zero TI contribution is exactly the trait. `a ≥ 0` cannot hold a finite process variance when the diffusion or the TI contribution is nonzero and fails closed. Trait-only variance does not require a stable drift. That constrained first-occasion variance is not free `T0VAR`, not `asymDIFFUSION` alone, not `TRAITVAR` alone, not `addedTIPREDVAR` alone, and not the finite-interval discrete latent variance. The printed 2-latent `addedTIPREDVAR` 2.838 is not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-22T03:07Z: request empty). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T03:07Z: request empty; ETS RR-88-45 PDF 404; Wiley PDF 403). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 5, p. 5; Table 2, p. 12; Eq. 3, p. 5; JSS PDF re-opened 2026-08-21T20:07Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of §4.3 stationary `T0MEANS`. Section 4.3 constrains the first-occasion mean to the model-predicted mean when `stationary` includes `"T0MEANS"`. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The constrained latent mean is `-κ / a + −B z / a`. The scalar composition is `E(y_0) = τ + λ(−κ / a + −B z / a)`. Form the stationary latent mean first, then `τ + λ` of that mean. A zero loading is exactly `τ`. A zero intercept and a zero TI contribution is exactly `τ`. Evolving from that stationary start with `CINT` and `TIPREDEFFECT` stays at the stationary mean. `τ + λ μ_0` for free `T0MEANS` is not this composition. `τ + λ(−κ / a)` is not this composition when `B z ≠ 0`. `τ + λ μ_t` is not this composition. `MANIFESTMEANS` is not `E(y_0)`. The constrained latent mean is not `E(y_0)`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall request empty this cycle). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-21T20:10Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16; Table 2, p. 12; Eq. 3, p. 5; JSS PDF opened 2026-08-21T16:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar stationary `T0MEANS`. Page 16 constrains `T0MEANS` to the model-implied values using `T0MEANSbase` / `T0MEANSfree` when the first observation is determined by the process in the same way as later observations. Those constraints include extra effects due to time-independent predictors (`asymTIPREDEFFECT`). For stable `a < 0` the scalar composition is `-κ / a + −B z / a`. Form the intercept contribution first, then include the TI extra effect, then add. A zero intercept and a zero TI contribution is exactly zero. `a ≥ 0` cannot hold a finite process-mean change when either contribution is nonzero and fails closed. That constrained first-occasion mean is not free `T0MEANS`, not `asymCINT` alone, not `asymTIPREDEFFECT` alone, and not the finite-interval discrete latent mean. The printed 2-latent `T0MEANS` 2.823 is not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T16:21Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12; Eq. 3, p. 5; §4.3 / p. 16; JSS PDF opened 2026-08-21T16:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar `asymCINT`. Table 2 names `κ` `CINT` and names `asymCINT` the asymptotic (`Δt = ∞`) expected change in processes for a 1 unit change in intercept. Equation 3 maps a finite event interval as `A^{-1}[e^{A Δt} − I] κ`. For stable `a < 0` that `Δt → ∞` limit is `-A^{-1} κ`. The scalar map is `-κ / a`. A unit intercept is `-1 / a`. Form `κ` first, then divide by `-a`. A zero intercept is exactly zero. `a ≥ 0` cannot hold a finite process-mean change and fails closed. `-κ / a` is not `κ`, not the finite-interval increment `A^{-1}[e^{A Δt} − I] κ`, not `T0MEANS`, and not `asymTIPREDEFFECT` `-B z / a`. Page 16 notes that a `T0MEANS` stationarity constraint includes time-independent predictors; that composition is not this intercept-only map. The printed 2-latent `CINT` values are not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T16:21Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; JSS PDF opened 2026-08-21T13:08Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar `addedTIPREDVAR`. Section 7.2 names that matrix the stable between-subject variance accounted for by time-independent predictors. For stable `a < 0` and predictor variance `v ≥ 0` the scalar map is `(B / a)² v`. Form the unit asymptotic effect `-B / a` first, then square, then multiply by `v`. A zero coefficient or zero predictor variance is exactly zero. `v < 0` fails closed. `a ≥ 0` cannot hold a finite process-mean change and fails closed. `(B / a)² v` is not `TRAITVAR`, not `asymDIFFUSION`, and not the expected total change `-B z / a`. The printed 2-latent `addedTIPREDVAR` 2.838 is not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T06:24Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; JSS PDF opened 2026-08-21T13:08Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar `asymTIPREDEFFECT`. Table 2 names `B` `TIPREDEFFECT`. Equation 3 maps a finite event interval as `A^{-1}[e^{A Δt} − I] B z`. Section 7.2 names `asymTIPREDEFFECT` the expected total change in process means given an increase of 1 on a time-independent predictor. For stable `a < 0` that total change is `-A^{-1} B`. The scalar map is `-B z / a`. Form `B z` first, then divide by `-a`. A zero coefficient or zero predictor is exactly zero. `a ≥ 0` cannot hold a finite process-mean change and fails closed. `-B z / a` is not the coefficient `B`, not the finite-interval increment `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, and not `M x`. Printed LeisureTime `TIPREDEFFECT` `−0.225` / `asymTIPREDEFFECT` `−1.673` and Happiness `0.549` / `0.219` reconstruct under this map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T06:24Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; §7.2, pp. 22–23; JSS PDF re-opened 2026-08-21T06:32Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of an extra-process `TDPREDEFFECT` after `t0`. Section 7.2 names `T0TDPREDEFFECT` when the extra process begins at `t = 0` and `TDPREDEFFECT` when it begins after `t = 0`. The printed extra process has `LAMBDA` 0. Original indicators load on the original process after the `DRIFT` coupling over `t − u` with `t0 < u < t` while `μ_t` still uses `Δt = t − t0`. The scalar composition is `E(y_t) = τ + λ(μ_t + a_{ηξ} x (e^{ε(t−u)} − e^{a(t−u)}) / (ε − a))`. The first-occasion extra-process observed mean uses `Δt` for both the evolution and the extra drive and is not this composition when `u ≠ t0`. The evolved observed mean `τ + λ μ_t` is not this composition. The impulse-carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is a Dirac on the original process and is not this `DRIFT` drive. An impulse at `u = t0` or `u = t` is not interior. A zero original-indicator loading is exactly `τ`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T06:24Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; §7.2, pp. 22–23; Eq. 1–3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-21T06:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of the extra near-zero-drift latent process contribution. Section 7.2's printed extra process has `LAMBDA` 0 and is not an observed indicator. Original indicators load on the original process after the `DRIFT` coupling `a_{ηξ}`. After a unit identification impulse the latent process at `t` is `μ_t + a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)`. The scalar composition is `E(y_t) = τ + λ(μ_t + a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a))`. Form the evolved-plus-contribution latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition. The extra-process contribution is not `E(y_t)`. The evolved-plus-contribution latent mean is not `E(y_t)`. A zero original-indicator loading is exactly `τ`. A zero coupling recovers `τ + λ μ_t`. `ε ≥ 0` fails closed. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T06:24Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 22–23; Eq. 1–3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T23:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar contribution of the extra near-zero-drift latent process. Section 7.2 specifies a lasting level change by that extra process: `T0MEANS`, `CINT`, `T0VAR`, `DIFFUSION`, and `TRAITVAR` of it are fixed to 0; `TDPREDEFFECT` on it is fixed to 1; its `DRIFT` diagonal is very close to 0 (printed example `−0.000001`; precisely 0 causes computational problems); and its effect on the original process is the `DRIFT` coupling `a_{ηξ}`. After a unit identification impulse the scalar contribution is `a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)` (`ε = a` is `a_{ηξ} x Δt e^{a Δt}`). Form `a_{ηξ} x` first. A zero coupling or zero predictor is exactly zero. `ε ≥ 0` fails closed. That contribution is not `κ = −a m x`, not `(1 − e^{a Δt}) m x`, and not the dissipating Dirac `m x`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T23:10Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 20–21; Eq. 3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T19:50Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar discrete increment of the lasting level-change `CINT`. Section 7.2 sets `CINT` to `TDPREDEFFECT * −DRIFT` (`κ = −a m x`). Equation 3 maps that intercept through `A^{-1}[e^{A Δt} − I] κ`. With `κ = −a m x` the scalar increment is `(e^{a Δt} − 1)/a · (−a m x) = (1 − e^{a Δt}) m x`. Form the level-change `CINT` first, then the discrete intercept map. Underflow of `e^{a Δt}` to `+0` keeps the equilibrium offset `m x`. `(1 − e^{a Δt}) m x` is not the contemporaneous jump `m x`. `(1 − e^{a Δt}) m x` is not `κ`. `(1 − e^{a Δt}) m x` is not `A^{-1}[e^{A Δt} − I] B z`. Stable `a < 0` is required. A zero effect or zero predictor is exactly zero. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T19:45Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 20–21; Eq. 1–3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T19:45Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar lasting level-change `CINT`. Section 7.2 contrasts a sudden Dirac that dissipates back to the process mean with a lasting level change. To generate that lasting change, `CINT` is set to `TDPREDEFFECT * −DRIFT`. The scalar setting is `κ = −a m x`. Form `m x` first, then multiply by `−a`. Stable `a < 0` is required so `−κ / a = m x` is an equilibrium offset. `a ≥ 0` cannot hold a new process mean. `−a m x` is not the contemporaneous jump `m x`. `−a m x` is not a free `CINT`. `−a m x` is not `A^{-1}[e^{A Δt} − I] B z`. The extra near-zero-drift latent process also named in §7.2 is a different specification and is not this `CINT` setting. A zero effect or zero predictor is exactly zero. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T19:45Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 3 first summand, p. 5; Table 3, p. 13; JSS PDF re-opened 2026-08-20T19:07Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a first-occasion time-dependent predictor. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. Table 3 names `T0TDPREDEFFECT` the effect of time-dependent predictors on latents at `T0`. Equation 3's first summand carries that shift as `e^{A Δt} t0_m x0`. The scalar composition is `E(y_t) = τ + λ(μ_t + e^{a Δt} t0_m x0)`. Form the evolved-plus-carry latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The process-increment map `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition. The impulse-carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not this composition when `u ≠ t0`. The first-occasion TI map `τ + λ(μ_t + e^{a Δt} t0_b z)` is not this composition. `MANIFESTMEANS` is not `E(y_t)`. The evolved-plus-carry latent mean is not `E(y_t)`. `T0TDPREDEFFECT` is the coefficient, not that observed mean. Same numbers as `T0TIPREDEFFECT` yield the same product; Table 3 names a different matrix. A zero loading is exactly `τ`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T19:09Z: `is_oa: false`). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13; Eq. 3 first summand, p. 5; JSS PDF re-opened 2026-08-20T19:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar first-occasion time-dependent predictor shift and its carry. Table 3 names `T0TDPREDEFFECT` the effect of time-dependent predictors on latents at `T0`. Table 2 / Table 3 name `TDPREDEFFECT` `M`, which enters Equation 3 as the printed fourth-summand Dirac `M x` at `u = t`. Those are not the same matrix. The scalar first-occasion shift is `t0_m x0`. Equation 3's first summand carries that shift as `e^{A Δt} t0_m x0`. Form `t0_m x0` first, then `e^{a Δt} t0_m x0`. Form `μ_t` first, then add that carry. A zero drift is `t0_m x0` with no dissipation. Binary64 underflow of `e^{a Δt}` to `+0` is a vanishing carry of the first-occasion shift and is kept. `t0_m x0` is not `M x`, not `e^{A(t−u)} M x` for `t0 < u < t`, not `t0_b z`, not `A^{-1}[e^{A Δt} − I] B z`, and not `κ`. `e^{A Δt} t0_m x0` is not `t0_m x0`. `T0TDPREDEFFECT` is the coefficient, not `t0_m x0`. An impulse at `u ≤ t0` that used `M` is already in `η(t0)` as `TDPREDEFFECT`, not as `T0TDPREDEFFECT`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T19:09Z: `is_oa: false`). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 3 first summand, p. 5; Table 3, p. 13; JSS PDF re-opened 2026-08-20T15:28Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a first-occasion time-independent predictor. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. Table 3 names `T0TIPREDEFFECT` the effect of time-independent predictors on latents at `T0`. Equation 3's first summand carries that shift as `e^{A Δt} t0_b z`. The scalar composition is `E(y_t) = τ + λ(μ_t + e^{a Δt} t0_b z)`. Form the evolved-plus-carry latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The process-increment map `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition. The impulse-carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not this composition when `u ≠ t0`. `MANIFESTMEANS` is not `E(y_t)`. The evolved-plus-carry latent mean is not `E(y_t)`. `T0TIPREDEFFECT` is the coefficient, not that observed mean. A zero loading is exactly `τ`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T15:14Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13; Eq. 3 first summand, p. 5; JSS PDF opened 2026-08-20T15:14Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar first-occasion time-independent predictor shift and its carry. Table 3 names `T0TIPREDEFFECT` the effect of time-independent predictors on latents at `T0`. Table 2 / Table 3 name `TIPREDEFFECT` `B`, which enters Equation 3 as `A^{-1}[e^{A(t−t0)} − I] B z`. Those are not the same matrix. The scalar first-occasion shift is `t0_b z`. Equation 3's first summand carries that shift as `e^{A Δt} t0_b z`. Form `t0_b z` first, then `e^{a Δt} t0_b z`. Form `μ_t` first, then add that carry. A zero drift is `t0_b z` with no dissipation. Binary64 underflow of `e^{a Δt}` to `+0` is a vanishing carry of the first-occasion shift and is kept. `t0_b z` is not `A^{-1}[e^{A Δt} − I] B z`, not `κ`, and not `M x`. `e^{A Δt} t0_b z` is not `t0_b z`. `T0TIPREDEFFECT` is the coefficient, not `t0_b z`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T15:14Z: `is_oa: false`; Springer `content/pdf` is HTML 200). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 3, p. 5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T12:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a time-independent predictor. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. Equation 3 prints the `TIPREDEFFECT` increment as the addend `A^{-1}[e^{A(t−t0)} − I] B z_i` after the `T0MEANS` carry and the `CINT` increment. Table 2 names `B` `TIPREDEFFECT`. The scalar composition is `E(y_t) = τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)`. Form the evolved-plus-increment latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition. The carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not this composition when `u ≠ t`. `MANIFESTMEANS` is not `E(y_t)`. The evolved-plus-increment latent mean is not `E(y_t)`. `TIPREDEFFECT` is `B`, not that observed mean. A zero loading is exactly `τ`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T05:12Z: `is_oa: false`). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 1–3, pp. 4–5; Table 2, p. 12; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-20T09:01Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a contemporaneous time-dependent impulse. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The latent process at `t` after a contemporaneous Dirac (`u = t`) is `μ_t + m x`. The scalar composition is `E(y_t) = τ + λ(μ_t + m x)`. Form the evolved-plus-impulse latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not this composition when `u ≠ t`. `MANIFESTMEANS` is not `E(y_t)`. The evolved-plus-impulse latent mean is not `E(y_t)`. A zero loading is exactly `τ`. The §7.2 level-change form is a different specification and is not this map. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T05:12Z: `is_oa: false`). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 1–2, pp. 4–5; Eq. 3 exponential map; Table 2, p. 12; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-20T05:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a within-interval time-dependent impulse carry. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The latent process at `t` after a Dirac that occurred strictly inside `(t0, t)` is `μ_t + e^{a(t−u)} m x`. The scalar composition is `E(y_t) = τ + λ(μ_t + e^{a(t−u)} m x)`. Form the carried latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition when `u ≠ t`. `MANIFESTMEANS` is not `E(y_t)`. The carried latent mean is not `E(y_t)`. A zero loading is exactly `τ`. The §7.2 level-change form is a different specification and is not this map. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T05:12Z: `is_oa: false`). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 1–2, pp. 4–5; Eq. 3 exponential map; Table 2, p. 12; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-20T10:33Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar within-interval time-dependent predictor impulse carry. Equation 1 writes `dη = (A η + ξ + B z + M χ(t)) dt + G dW`. Equation 2 writes `χ_i(t) = Σ x_{i,u} δ(t − u)`. The Green-function integral of that Dirac on `(t0, t)` is `e^{A(t−u)} M x`. The printed Eq. 3 fourth summand is the contemporaneous jump `M x` at `u = t`. This map is the strictly within-interval case `t0 < u < t`. Form `m x` first, then `e^{a(t−u)} m x`. A zero drift is `m x` with no dissipation. Underflow of `e^{a(t−u)}` to `+0` is vanishing dissipation back to the process mean and is kept. Form `μ_t` first, then add the carry. `e^{A(t−u)} M x` is not the contemporaneous Dirac, not `CINT`, not `A^{-1}[e^{A Δt} − I] B z` (`TIPREDEFFECT`), and not Voelkle et al. (2012, Eq. 14) `a_{yx} Δt`. An impulse at `u = t` is the contemporaneous map. An impulse at `u ≤ t0` is already in `η(t0)`. The §7.2 level-change form is a different specification and is not this map. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T10:33Z: `is_oa: false`). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 1–3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T10:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar time-independent predictor increment. Equation 1 writes `dη = (A η + b + A_{ηξ} ξ + B z) dt + G dW + M dχ`. Equation 3's second summand is `A^{-1}[e^{A Δt} − I](b + A_{ηξ} ξ + B z)`. Table 2 names `B` `TIPREDEFFECT`. Form `B z` first, then the discrete intercept map. A zero drift is `B z Δt`. Form `μ_t` first, then add that increment. `TIPREDEFFECT` is `B`, not the discrete increment. `A^{-1}[e^{A Δt} − I] B z` is not `CINT`, not `M x` (`TDPREDEFFECT`), and not Voelkle et al. (2012, Eq. 14) `a_{yx} Δt`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T10:13Z: `is_oa: false`). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 1–3, pp. 4–5; Table 2, p. 12; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-20T07:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar contemporaneous time-dependent predictor impulse. Equation 2 writes `χ_i(t) = Σ x_{i,u} δ(t − u)`. Equation 3's fourth summand is `M Σ x_{i,u} δ(t − u)`. Table 2 names `M` `TDPREDEFFECT`. Section 7.2 calls this a sudden impulse that dissipates back to the process mean and reports `TDPREDEFFECT` as the initial impact. The scalar jump is `m x`. Form `μ_t` first, then add `m x`. `TDPREDEFFECT` is not `CINT`. `M x` is not `A^{-1}[e^{A Δt} − I] B z` (`TIPREDEFFECT`). `M x` is not Voelkle et al. (2012, Eq. 14) `a_{yx} Δt`. The §7.2 level-change form is a different specification and is not this map. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T07:10Z: `is_oa: false`). -- `psychometric_core` caps two-observation two-group OLS residual invariance at strong/scalar. `ordinary_least_squares_fit` returns residual variance `0` when `n ≤ 2`; that identity is not an estimated residual and is not strict. Putnick and Bornstein (2016, PMC author manuscript PMC5145197 opened 2026-08-19T22:15Z from https://pmc.ncbi.nlm.nih.gov/articles/PMC5145197/) require scalar invariance before latent-mean comparison; residual invariance is not a prerequisite because residuals are not part of the latent factor. Matching loading and intercept with `n = 2` therefore stay strong/scalar and still license `(ȳ_c − ȳ_r)/λ`. This is still two-group OLS, not MGCFA. Meredith (1993) remains unread (OpenAlex/Semantic Scholar 2026-08-19T22:15Z: closed; Springer `content/pdf` is HTML 200). Vandenberg and Lance (2000) remains unread (cited by Putnick for the residual-not-required claim). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 3, p. 5; Eq. 5, p. 5; Table 2, p. 12; JSS PDF re-opened 2026-08-19T22:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar evolved observed-indicator mean. Equation 3 writes `η_i(t) = exp(A Δt) η_i(t0) + A^{-1}[exp(A Δt) − I] ξ_i + …` with `ξ_i ~ N(κ, φ_ξ)` (p. 4) and a stochastic integral of mean zero. Equation 5 writes `y_i(t) = Γ_i + Λ η_i(t) + ζ_i(t)` with `Γ ~ N(τ, Ψ)` and `ζ ~ N(0, Θ)`. The scalar composition is `E(y_t) = τ + λ μ_t` with `μ_t` the Eq. 3 expected-value map. Form `μ_t` first, then `τ + λ μ_t`. The first-occasion map `τ + λ μ_0` is not `E(y_t)`. `MANIFESTMEANS` is not `E(y_t)`. `T0MEANS` is not `E(y_t)`. `μ_t` is not `E(y_t)`. A zero-CINT overflow of `exp(a Δt)` fails the carried `T0MEANS` term closed (`a = 710`, `Δt = 1`). Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (OpenAlex 2026-08-19T22:10Z: closed; Springer `content/pdf` is HTML 200). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (OpenAlex/Semantic Scholar 2026-08-19T22:10Z: closed). Putnick and Bornstein (2016) PMC PDF was HTML/500 on this cycle. Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. Asparouhov and Muthén (2009) statmodel PDF re-opened 2026-08-19T22:10Z; it cites Meredith (1993) and discusses multiple-group intercept/mean structures but does not license this map. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 3, p. 4; Table 2, p. 12; JSS PDF re-opened 2026-08-19T18:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar expected-value latent mean. Equation 3 writes `η(t) = exp(A Δt) η(t0) + ∫ exp(A(t−s)) (b + …) ds` plus a stochastic integral of mean zero. Table 2 names the first-occasion latent mean `T0MEANS` and `κ` `CINT`. The scalar map is `μ_t = exp(a Δt) μ_0 + (exp(a Δt) − 1)/a κ`. Form the CINT increment first, then add the carried `T0MEANS` term. A zero drift is the Eq. 3 integral `κ Δt` (`A = 0` has no inverse). As `Δt → ∞` with stable `a < 0`, `μ_t → −κ / a`. Binary64 underflow of `exp(a Δt)` to `+0` drops the carried `T0MEANS` and keeps that equilibrium increment. `T0MEANS` is not `μ_t`. `CINT` is not the discrete increment. `CINT` is not `T0MEANS`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (OpenAlex 2026-08-19T18:10Z: closed; Springer `content/pdf` is HTML 200). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 2, p. 12; JSS PDF re-opened 2026-08-19T14:08Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. Table 2 names `τ` `MANIFESTMEANS`, `κ` `CINT`, and the first-occasion latent mean `T0MEANS`. The scalar map is `E(y) = τ + λ μ`. Form `λ μ` then add `τ`. Do not treat `MANIFESTMEANS` as `E(y)`. `E(η)` is not `E(y)`. `CINT` is not `MANIFESTMEANS`. `T0MEANS` is not `E(y)`. Forming `λ²` is the variance path, not this mean. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-19T14:08Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 3–4, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-19T04:18Z) scalar lagged observed-indicator covariance. Independent measurement error does not enter `cov(y_t, y_{t-1})`. The scalar map is `λ² cov(η_t, η_{t-1}) + ψ`. Form `(λ c) λ` then add `ψ`. Do not form `λ²` first (`λ = 1e308`, `c = 1e-308` → `1e308`). `MANIFESTVAR` is not lagged observed covariance. Lagged `Var(η)` path is not `cov(y)`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-19T04:25Z: closed). -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 2, p. 12; JSS PDF re-opened 2026-08-19T04:18Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator variance with `MANIFESTTRAITVAR`. Equation 5 writes `y_i(t) = τ_i + Λ η_i(t) + ε_i(t)` with `ε ~ N(0, Θ)` and `τ_i ~ N(μ_τ, Ψ_τ)`. Equation 1 (p. 4) is the latent SDE, not the measurement model. Table 2 names `Θ` `MANIFESTVAR` and `Ψ_τ` `MANIFESTTRAITVAR`; p. 16 restates those names. The scalar map is `Var(y) = λ² Var(η) + θ` when `Ψ_τ = 0` and `λ² Var(η) + θ + ψ` otherwise. Form `(λ p) λ` then add `θ`, then add `ψ`. `MANIFESTVAR` is not `Var(y)`. `MANIFESTTRAITVAR` is not `MANIFESTVAR`. `TRAITVAR` is latent additional variance and is scaled by `λ²`; `MANIFESTTRAITVAR` is not. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-19T04:18Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. -- `psychometric_core` evaluates the Driver, Oud, and Voelkle (2017, Eq. 4, p. 5; JSS PDF re-opened 2026-08-19T04:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) stationary within-subject variance as `q / -(2 a)` when the scalar Kronecker sum `2 a` is finite. The paper limit is `-q / (2 a)` (`A# = A ⊗ I + I ⊗ A`; p. 16 `asymDIFFUSION`). Forming `q / a` first overflows at `q = MAX`, `a = -0.75` while `MAX / 1.5` is finite (CodeRabbit finding on `75ecdd3`). When `2 a` overflows (`a = -1e308`), form `(q / a) * -0.5`. Do not form `0.5 q` first (`q = from_bits(1)` underflows). Still not a Kalman filter, not DSEM, not a matrix `expm`, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-19T04:10Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 1, p. 4; p. 16 `MANIFESTVAR`; JSS PDF re-opened 2026-08-19T00:14Z) scalar observed-indicator variance. Equation 1 writes `y_i(t) = Λ η_i(t) + τ + ε_i(t)` with `ε ~ N(0, Θ)`. The scalar map is `Var(y) = λ² Var(η) + θ`. Form `(λ p) λ` then add `θ`. Do not form `λ²` first (`λ = 1e308`, `p = 1e-308` → `1e308`). `MANIFESTVAR` is not `Var(y)`. `Var(η)` is not `Var(y)`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-19T00:14Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. -- `psychometric_core` evaluates the Driver, Oud, and Voelkle (2017, Eq. 4, p. 5; JSS PDF re-opened 2026-08-19T00:14Z) stationary within-subject variance as `(q / a) * -0.5`. The paper limit is `-q / (2 a)`. Forming `2 a` first overflows at `a = -1e308`. Forming `0.5 q` first underflows at `q = from_bits(1)`, `a = -from_bits(1)` and returns `+0` (CodeRabbit finding on `556e23d`); the representable Lyapunov solution is `0.5`. Still not a Kalman filter, not DSEM, not a matrix `expm`, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-19T00:14Z: closed; Springer `content/pdf` is HTML 200). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, p. 9; JSS PDF re-opened 2026-08-18T21:07Z) scalar trait-plus-state latent variance and lagged covariance. A stable trait process has `DRIFT` and `DIFFUSION` fixed to zero, so `Var = trait + state` and `cov(t, t-1) = trait + exp(a Δt) p`. The ctsem `TRAITVAR` rewrite that adds the trait to `DIFFUSION` does not license treating trait variance as process noise. Trait variance is not `asymDIFFUSION`. Evolving the summed variance as if it were all state is not this map. Still not RI-CLPM, not a Kalman filter, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-18T21:07Z: closed). Oud and Jansen (2000) remains unread. ZORA accepted manuscript re-opened via bitstream `424f9082-0eeb-4a67-b687-9845a4ed892f`. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 4, p. 5; §4.3 pp. 9–10; p. 16 `asymDIFFUSION`; JSS PDF re-opened 2026-08-18T18:03Z) scalar stationary within-subject variance. Eq. 4 writes `Q_Δt = irow(A#^{-1}[e^{A# Δt} − I] row(Q))` with `A# = A ⊗ I + I ⊗ A`. The scalar Kronecker sum is `2 a`. As `Δt → ∞` with stable `a < 0`, that limit is `-q / (2 a)`. Form `-0.5 q / a`; do not form `2 a` first (`a = -1e308`, `q = 1e308` → `0.5`). Starting from that variance, `Var(η_t)` is invariant across finite event intervals. A zero diffusion is exactly zero. `a ≥ 0` has no finite stationary variance. Finite-interval `Q_Δt` is not `asymDIFFUSION`. Still not a Kalman filter, not DSEM, not a matrix `expm`, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-18T18:03Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. -- `psychometric_core` refuses a zero-diffusion Driver, Oud, and Voelkle (2017, Eq. 3–4, pp. 4–5; JSS PDF re-opened 2026-08-18T14:04Z) latent variance when `2 (a Δt)` overflows to `+∞`. Zero diffusion is exactly `Q_Δt = 0` (Eq. 3 integral of a zero `G`). That skip does not license `Var(η_t) = exp(2 a Δt) p + 0` when the carried term is non-finite (`p = 2`, `q = 0`, `a = 1e308`, `Δt = 2`). Nightly uncovered production line `event_time.rs:596` on predecessor `321568a` is this arm. Still not a Kalman filter, not DSEM, and not a matrix `expm`. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex/Semantic Scholar 2026-08-18T14:04Z: closed; Springer `content/pdf` is HTML 200). Oud and Jansen (2000) remains unread. -- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 3–4, pp. 4–5; JSS PDF re-opened 2026-08-18T11:20Z) lagged latent covariance `cov(η_ti, η_{t-1,i}) = A_Δt cov(η_{t-1,i})` and the law-of-total-variance map `Var(η_ti) = A_Δt Var(η_{t-1,i}) A_Δt⊤ + Q_Δt`. Eq. 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral; Eq. 4 writes that the integral exhibits covariance `Q_Δt`. `Q_Δt` remains `cov(η_ti | η_{t-1,i})` for the homogeneous process (`ξ`, `z` given) and is refused as the unconditional variance. The JSS article has no numbered §2.2 (2.1 is Continuous time and SEM; §3 follows). Scalar `exp(a Δt) p` underflow to `+0` is a vanishing covariance and is kept. Finite-`a Δt` exponential overflow rewrites as `exp(ln p + a Δt)`. A finite `exp(a Δt)` whose product with `p` overflows fails closed. Still not a Kalman filter, not DSEM, and not a matrix `expm`. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex/Semantic Scholar 2026-08-18T11:05Z: closed). Oud and Jansen (2000) remains unread (Radboud 403). ZORA Anubis-blocked. -- `psychometric_core` closes nightly branch coverage on `event_time.rs` (160/164 on `6c13dfb`). The four remaining False sides were `assert!(a && b)` in the unit-test module (Eq. 12 equilibrium-increment and expm1-overflow oracles); they cannot take False on a passing test. Split into independent asserts. Lib-instantiation fail-closed arms for Voelkle et al. (2012, Eq. 14) and Driver, Oud, and Voelkle (2017, Eq. 3) stay in the integration contract. Driver JSS PDF already opened 2026-08-18T07:06Z, p. 4 (`L` remains identity; this is not a Kalman filter). Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-18T07:17Z: closed; Springer `content/pdf` is HTML 200, not a PDF). ERIC ED334221 is Singer and Willett (1991). ZORA Anubis-blocked. Oud and Jansen (2000) remains unread. -- `psychometric_core` refuses an overflowing Driver Eq. 3 rewrite scale `0.5 q / a` (JSS PDF re-opened 2026-08-18T03:07Z, p. 4). When `expm1(z)` overflows at a finite `z = 2(a Δt)` and `0.5 q / a` is non-finite (`q = 1e308`, `a = 0.1`, `Δt = 4000` → `z = 800`), `Q_Δt = q(e^{2aΔt}−1)/(2a)` is not finite and fails closed. Algebraically identical to the licensed integral. Still not a Kalman filter, not DSEM, and not a matrix `expm`. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex/Semantic Scholar/CORE 2026-08-18T03:07Z: closed). ERIC ED334221 is Singer and Willett (1991), not Mislevy (1991). ERIC ED333032 remains Mislevy, Sheehan, and Wingersky (1990). ZORA Anubis-blocked. Oud and Jansen (2000) remains unread. -- `psychometric_core` evaluates Driver, Oud, and Voelkle (2017, Eq. 3; JSS PDF re-opened 2026-08-17T21:03Z, p. 4) as \(0.5 q(\operatorname{expm1}(z)/a)\) with \(z=2(a\Delta t)\). Forming \(2a\) first overflows when \(|a|\) is at the binary64 extreme even if \(a\Delta t\) and \(Q_{\Delta t}\) are finite (`a=1e308`, `Δt=1e-308` → \(0.5(\mathrm{e}^{2}-1)/10^{308}\); `a=-1e308`, `q=1e308`, `Δt=2` → \(0.5\)). Algebraically identical to \(q(\mathrm{e}^{2a\Delta t}-1)/(2a)\). `expm1(−∞)` keeps \(-0.5 q/a\). \(z\to+\infty\) still fails closed. Still not a Kalman filter, not DSEM, and not a matrix `expm`. Meredith (1993), Mislevy (1991), and Oud and Jansen (2000) remain unread (Unpaywall/OpenAlex/Semantic Scholar 2026-08-17T21:03Z: closed; ZORA Anubis-blocked). -- `psychometric_core` recovers Voelkle et al. (2012, Eq. 14; ZORA accepted manuscript re-opened 2026-08-17T14:20Z, Introducing Intercepts, manuscript p. 21): the discrete effect of a time-varying predictor whose sampling interval equals its constancy interval is \(b^{*}_{y.x}(\Delta t)=a_{yx}\Delta t\). It does not depend on the predictor auto-effect. That product is not Eq. 12. Unmatched sampling and constancy intervals fail closed (Oud & Jansen, 2000, unread). An overflowing Eq. 12 rewrite scale \(a_{yx}/a_{xx}\) also fails closed. Still not DSEM. -- `psychometric_core` recovers Voelkle et al. (2012, Eq. 12) when `expm1(z)` overflows to `+∞` at a finite `z`. The rewrite is `sign(a_{yx}/a_{xx})\exp(\ln|a_{yx}|+z-\ln|a_{xx}|)-a_{yx}/a_{xx}` (algebraically identical to `(a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)`). A zero continuous effect is exactly zero even when `expm1` overflows (`0\cdot+\infty` is `NaN`). `z\to+\infty` remains fail-closed. ZORA accepted manuscript re-opened 2026-08-17T13:26Z, Introducing Intercepts, manuscript p. 20; Driver, Oud, and Voelkle (2017, Eq. 3) restated `A^{-1}[e^{A\Delta t}-I]\xi`. Still not DSEM. -- `psychometric_core` evaluates Voelkle et al. (2012, Eq. 12) as \(a_{yx}(\operatorname{expm1}(z)/a_{xx})\) with \(z=a_{xx}\Delta t\). That order is algebraically identical to \((a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)\). Dividing the increment by the finite auto-effect keeps the equilibrium increment \(-a_{yx}/a_{xx}\) when \(z\) overflows to \(-\infty\) (ZORA accepted manuscript, Introducing Intercepts: the exponential vanishes as \(\Delta t\) grows; CodeRabbit finding on `7ffb65b`). The prior \(a_{yx}\Delta t\) overflow case remains finite. Binary64 underflow of \(z\) to `+0` recovers the Eq. 12 limit \(a_{yx}\Delta t\); the first-order product is still not the general discrete effect. Still not DSEM. -- `psychometric_core` evaluates Voelkle et al. (2012, Eq. 12) as \(a_{yx}(\operatorname{expm1}(z)/z\cdot\Delta t)\) with \(z=a_{xx}\Delta t\). That order is algebraically identical to \((a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)\). Multiplying the unitless scale by \(\Delta t\) before \(a_{yx}\) keeps a finite Eq. 12 result when \(a_{yx}\Delta t\) overflows (ZORA accepted manuscript re-opened 2026-08-17T13:13Z, p. 16). Binary64 underflow of \(z\) to `+0` recovers the Eq. 12 limit \(a_{yx}\Delta t\); the first-order product is still not the general discrete effect. Driver, Oud, and Voelkle (2017, p. 4) restated the discrete intercept as a function of \(A\) and \(\Delta t\). Still not DSEM. -- `psychometric_core` evaluates Voelkle et al. (2012, Eq. 12) as \(a_{yx}\Delta t\,(\operatorname{expm1}(z)/z)\) with \(z=a_{xx}\Delta t\). That order is algebraically identical to \((a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)\). Binary64 underflow of \(z\) to `+0` recovers the Eq. 12 limit \(a_{yx}\Delta t\); the first-order product is still not the general discrete effect. Driver, Oud, and Voelkle (2017, p. 4) restated the discrete intercept as a function of \(A\) and \(\Delta t\) (PDF re-opened 2026-08-17T12:04Z). Still not DSEM. -- `psychometric_core` exact scalar discrete effect of a constant event-time predictor (Voelkle et al., 2012, Eq. 12): \(b^{*}_{y.x}(\Delta t)=(a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)\) for \(a_{xx}\neq 0\). The first-order product \(a_{yx}\Delta t\) is not that discrete effect. Still not DSEM. -- `psychometric_core` exact scalar forward map `φ(Δt) = exp(a Δt)` and interval remapping: a discrete lag at one event interval maps onto another through the Voelkle et al. (2012, Eq. 7) log-rate. Pooling discrete lags from unequal intervals fails closed. Still not a matrix `expm` and not DSEM. -- Fail-closed CWC-lag coverage in `psychometric_core`: singleton clusters are skipped, all-singleton series and overflowing CWC residuals fail closed, later-only residual overflow is checked with bitwise `is_finite`, the scalar Newton step refuses a non-finite exponential, score, start-skip, or deriv-INF, and Pearson empty/mismatch/left-INF paths are recovered. Dead post-OLS `pred_ss` and midpoint `require_finite` guards were removed because those values are already finite after OLS. -- `psychometric_core` multilevel/event-time recovery on the stacked psychometric PR: cluster-mean CWC within/between OLS, Kish ESS weighted slopes, event-time-only discrete lag-1 and exact scalar local log-rate, CWC-then-event-time residual lag, Rubin `T_m = Ū_m + (1+1/m) B_m` on draw-level OLS loadings, and two-group OLS strong/strict-gated latent-mean difference. Metric/weak is not a mean license. Not DSEM, not RI-CLPM, not MGCFA, not Mislevy PVs (ADR 0005; no new migration). -- `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 - -- `model_selection` fitted candidate-`K` scoring: each candidate is fitted with the CPU `f64` TRSL-TM reference, scored from the actual in-sample mixture log-likelihood and Schwarz's (1978) `ℓ − (p ln N)/2` penalty, then passed through the existing Pareto gate. A typed non-convergence, non-finite, or invalid-input failure is a failed candidate, not a fabricated diagnostic. LLM-vote-only `K` remains non-authoritative. TF-IDF, BM25, stopword-deletion, and LLM labels are refused as inferential coordinates. Known two-topic counts select `K=2` over `K=3` with selected-`K` RMSE `0` across seed replications. This is not GPU execution, full Bayesian sampling, or topic birth/split/merge (ADR 0012; issue #167 remaining slice). -- `relation_absence` identity gate: unobserved relation pairs cannot become evidence of no relationship; recovered observed/inferred/unobserved statuses match known truth at a higher computed rate than collapsing every status to observed (ADR 0003). -- `orchestrator_live` loopback HTTP/1.1 listener: `POST /v1/interpretation-runs` binds loopback only, replays matching idempotency keys, and refuses non-loopback binds, table-access hosts, review/Copilot/GitHub credentials, and scientific-authority promotion. Accepted output is always hypothetical. Not TLS termination or model execution (ADR 0010; ADR 0011). -- `role_contradiction` identity gate: customer and competitor cannot occupy the same group; recovered commercial-role labels match known truth at a higher computed rate than collapsing every role to customer (ADR 0003). -- `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). -- Coverage contract now excludes Rust multiline string continuation records emitted by LLVM LCOV, keeping the 100% authored-line gate focused on executable production lines. -- Coverage source classification now scans Rust normal/raw/byte strings, comments, and character literals with escape-aware state, preserving executable string method calls and ignoring quoted comments. -- Quality-gate coverage tests now exercise blank-predecessor structural commas and escaped character literals in the authored-line scanner, including the past-EOF fail-closed path. -- Restored Graham Neubig's correct APA 7 initial in the Liu et al. (2023) prompting-survey register entry after the protected-main rebase. -- After protected-main consolidation #215, the analysis-run execution decision is recorded as ADR 0022 so it does not collide with ADR 0021 LineageWeave project-history. -- Registered the analysis-engine gap-closure doctoring in the canonical documentation map so its product and scientific traceability record is discoverable. -- Authored Rust coverage classification now ignores standalone structural closing parentheses, preventing formatting-only LCOV rows from appearing as uncovered production behavior. -- `analysis_engine` vertical slice (ADR 0022): bounded Rust execution from an accepted analysis run to either a cutoff-safe readiness result or a validated `tepp.trsl_topic_lineage.v1` artifact from the ADR-0012 estimator. Topic artifacts preserve fitted predecessor/successor edges, connectable-post and lineage counts, request/snapshot/cutoff bindings, SHA-256 identity, and fail-closed non-convergence/tamper behavior with exact line/branch coverage. This remains active-PR evidence and does not claim causal or psychometric authority. -- Coverage classification preserves the final expression line of multiline Rust `match` guards while respecting preceding-arm boundaries, keeping the 100% authored-line gate conservative. -- `tepp_api` fail-closed analysis-result boundaries: status constructors reject - terminal envelopes that cannot fit the default 64 KiB status limit, and - standalone terminal results reject knowledge cutoffs in the future. -- `tepp_api` request-bound terminal analysis results and typed analysis-run status/read responses: accepted/running states cannot carry measurement evidence, terminal results bind exact request and receipt identities, and succeeded/failed payloads remain digest-bound or content-redacted. -- `evidence_core` embedded-image units: `data:image/;base64,...` URIs keep their original source spans and media types, and cannot be used as lexical inference text. -- `persistence_postgres` entity/project target SQL now rejects empty, oversized, or hostile type/status labels before insert; interpolated codes are restricted to lowercase ASCII `snake_case` characters so membership foreign keys remain referentially safe (ADR 0003 / ADR 0013). -- `persistence_postgres` live SQLx transport retains one pool-backed PostgreSQL connection per session so tenant binding and the following statement share a session, and closes the connection and owned runtime safely from another Tokio runtime (ADR 0013). -- The authored-line coverage gate now filters LLVM-only literal and expression continuation records while retaining branch coverage for their executable decisions; Rust function signatures and structural branch lines are no longer counted as uncovered statements. -- Stacked `analysis_engine` vertical slice (ADR 0021): bounded Rust execution - from an accepted analysis run to a cutoff-safe, multiple-membership-aware, - SHA-256-digest-bound terminal artifact or redacted no-eligible-evidence - result. This remains active-PR evidence and does not claim estimator - authority. -- `tepp_api` request-bound terminal analysis results and typed analysis-run - status/read responses: accepted/running states cannot carry measurement - evidence, and terminal results bind exact request and receipt identities. -- Coverage classification now preserves multiline Rust `match` guard expression - lines while ignoring structural closing parentheses and match-arm labels. -- `corpus_split` Unicode canonical identity: NFC/NFD-equivalent bodies produce `CanonicalEquivalent` leakage links and cannot occupy independent partitions; empty bodies and duplicate document identities fail closed (ADR 0004/0008/0013; PR #59). -- `semantic_core` binds exact `evidence_core` source spans as semantic units. Language profiles are `unresolved` or a primary ISO 639 subtag with an IANA-registered ISO 3166-1 alpha-2 or UN M.49 region (RFC 5646; IANA File-Date 2026-08-08); private-use and unknown regions fail closed. Unresolved metadata keeps the caller-supplied Korean `측정` span and does not retokenize. `SemanticIdentity::from_language_tag` fails closed. Korean and English report sentences remain distinct units. Not concept alignment, not invariance, not a topic estimator (ADR 0020; issue #168). The APA register cites RFC 5646 once, in the Unicode/language-tags section; the slice-specific note remains `docs/research/span-grounded-semantic-units.md`. -- `corpus_background` identity gate: corpus-level background wording is not unique latent content or a state transition; recovery tests distinguish background evidence from unique content. -- `modality_source` identity gate: non-lexical modality is not unique lexical content or a state transition; recovery tests keep modality evidence distinct from unique content. -- `copied_text` identity gate: copied-text residue is not unique latent content or a state transition; recovery tests distinguish copied-text evidence from genuinely new content. -- `style_source` identity gate: house-voice style residue is not unique latent content and is not erased by a stopword list; recovery tests distinguish style from unique content. -- `stopword_deletion` method gate: a default or global stopword list cannot erase repeated report language; recovery tests distinguish deliberate method treatment from stopword deletion. -- `copy_identity` identity gate: a template or pasted copy cannot reuse the source document identity or become a state transition; recovery tests distinguish copy kinds from source identity. -- `intake_authorization` identity gate: documents, serialized records, checkpoints, and LLM outputs require a purpose-bound grant in addition to identity, provenance, size, and depth validation; recovery tests reject ungranted intake. -- `tepp_api` LineageWeave temporal-context contract (v1): cutoff-safe event eligibility, deterministic event-time ordering, explicit non-causal association/gap boundaries, HTTPS interchange construction, and loopback listener handling at `POST /v1/temporal-context`; read-only context requests no longer require the write-only idempotency header, and no causal inference or completed-result service is included. -- `tepp_api` LineageWeave consumer-scoped analysis-run ingress: versioned, credential-free requests use a published consumer identity and isolate idempotency by consumer, tenant workspace, and opaque caller key; the one-shot restack workflow is removed after the protected-main merge is verified. -- ADR 0018 records the consumer-scoped analysis-run ingress, its in-memory loopback maturity, and the persistence boundary required before production use. -- ADR 0021 records the credential-free bounded LineageWeave project-history service boundary and keeps source authorization with LineageWeave while TEPP owns temporal validation and deterministic projection. -- `tepp_api` project-history wire-size symmetry (ADR 0019): request and projection serialization enforce the shared 256 KiB limit, and generated projections fail closed before returning when their deterministic response would exceed it. -- `summarizes_edge` identity gate: summaries may point to earlier event time without becoming state transitions or reusing source-document identity; recovery tests outperform collapsing every summary to the source. -- `outcome_order` identity gate: `input_to` and `process_to` require strict forward event-time rank, while `outcome_of` remains non-transition provenance; recovery tests outperform collapsing every kind to `input_to`. -- `location_membership` identity gate: geographic and market assignments are time-varying memberships, not permanent entity identity and not language channels; recovered location kinds match known truth at a higher computed rate than collapsing every assignment to entity identity (ADR 0003). -- `prompt_source` identity gate: instruction and prompt boilerplate is not unique latent content and is not erased by a stopword list; `identity_recovery_rate` reports exact kind matches, with a contract test comparing correct recovery with an all-unique collapse on a mixed known-truth fixture (ADR 0004/0012). -- `corpus_background` identity gate: corpus-level background wording is not unique latent content and is not erased by a stopword list; recovered background kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). -- `modality_source` identity gate: non-lexical modality is not unique latent content and is not erased by a stopword list; recovered modality kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). -- `copied_text` identity gate: copied and boilerplate residue is not unique latent content and is not erased by a stopword list; recovered copied-text kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). -- `style_source` identity gate: house-voice style residue is not unique latent content and is not erased by a stopword list; recovered style kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). -- `stopword_deletion` method gate: a default or global stopword list cannot erase repeated report language; recovered deletion kinds match known truth at a higher computed rate than collapsing every token treatment to stopword deletion (ADR 0004/0012). -- `persistence_postgres` retention/deletion/legal-hold (migration `0007`): policy rows, legal holds that block completed deletion, evidence tombstones without raw-source restore, analysis exclusion only for `logical_revocation`/`identity_tombstone` (not `cache_export_removal`), and deletion requests bound to the cited retention policy's tenant/class/purpose. -- `copy_identity` identity gate: a template or pasted copy cannot reuse the source document identity or become a state transition; recovered copy kinds match known truth at a higher computed rate than collapsing every copy to the source (ADR 0003). -- `provider_receipt` disclosure receipt: records provider field codes and - purpose-bound receipt metadata without persisting source text or source - identity (ADR 0009). -- `intake_authorization` identity gate: documents, serialized records, checkpoints, and LLM outputs cannot be accepted without a purpose-bound grant; size/identity/provenance bounds are not that grant; recovered grant-presence flags match known truth at a higher computed rate than accepting every intake (ADR 0009). -- `summarizes_edge` identity gate: a summary may point to earlier event time but cannot become a state transition or reuse the source document identity; recovered summary kinds match known truth at a higher computed rate than collapsing every summary to the source (ADR 0003). -- `outcome_order` identity gate: `input_to` and `process_to` cannot move backward or stay contemporaneous in event-time rank; `outcome_of` may point at an earlier producer and cannot become a state transition; recovered kinds match known truth at a higher computed rate than collapsing every kind to `input_to` (ADR 0002/0003). -- `retrospective_edge` identity gate: retrospective reporting may point to earlier event time but cannot become a state transition or a translation; recovered reporting kinds match known truth at a higher computed rate than collapsing every report to a contemporaneous forward report (ADR 0002/0003). -- `payload_bound` identity gate: documents, serialized records, model checkpoints, and LLM outputs stay untrusted until identity, provenance, size, and depth validate; recovered accept/reject flags match known truth at a higher computed rate than accepting every payload (ADR 0008/0013). -- `inferred_status` identity gate: inferred relations cannot be promoted to observed evidence or to state transitions; recovered observed/inferred labels match known truth at a higher computed rate than treating every status as observed (ADR 0003). -- `support_edge` identity gate: support, contradiction, summary, and `outcome_of` edges cannot become state transitions; recovered evidential kinds match known truth at a higher computed rate than collapsing every kind to support (ADR 0002/0003). -- `system_clock` identity gate: event, assertion, document, availability, and knowledge-cutoff time cannot stand in for system time; recovered system stamps match known truth at a higher computed rate than treating every stamp as event time (ADR 0002). -- `event_clock` identity gate: assertion, system, document, and availability time cannot stand in for event/valid time; recovered event stamps match known truth at a higher computed rate than treating every stamp as assertion time (ADR 0002). -- Dependabot Rust toolchain updates now use a seven-day cooldown so newly published versions receive a bounded review window before automated proposals. -- `assertion_clock` identity gate: event, system, document, and availability time cannot stand in for assertion time; recovered assertion stamps match known truth at a higher computed rate than treating every stamp as event time (ADR 0002). -- `cutoff_clock` identity gate: event time, system time, and availability time cannot stand in for knowledge cutoff; recovered cutoff stamps match known truth at a higher computed rate than treating every stamp as availability time (ADR 0002). -- `available_clock` identity gate: event time and system time cannot stand in for availability time; recovered availability stamps match known truth at a higher computed rate than treating every stamp as system time (ADR 0002). -- `document_clocks` six-clock gate: a document analytical row cannot omit assertion time or document time, and event/system time cannot stand in for those clocks; recovered completeness flags match known truth at a higher computed rate than treating every row as complete (ADR 0002/0013). -- `revision_order` system-time gate: a higher document revision number cannot carry earlier or equal system time; recovered order flags match known truth at a higher computed rate than accepting every pair (ADR 0002/0013). -- `encrypted_mapping` purpose-bound AES-256-GCM envelope: source identities are sealed with an operating-system-generated nonce and analytical/key identifiers as authenticated associated data, with a 1 MiB resource bound, so analytical, log, and model-artifact purposes cannot recover plaintext; recovered identities match known truth at a higher computed rate than collapsing every mapping to one name. Persistence and KMS wait for a later migration (ADR 0009). -- `citation_edge` provenance gate: citation, translation, revision, and retrospective-report edges may point to the past but cannot become input-process-outcome transitions; recovered kinds match known truth at a higher computed rate than collapsing every edge to citation (ADR 0002/0003). -- `psychometric_fit` CPU `f64` ESEM/DSEM fit: exploratory OLS recovers known cross-loadings from admitted log-ratio or logistic-normal coordinates with computed RMSE below a zero-loading collapse; reverse or zero event-time lagged paths fail closed; a good global fit cannot reclassify formative or network constructs as reflective (ADR 0005). No new migration number (`#45` still owns `0007`). -- `subevent_containment` parent-window gate: a half-open subevent interval that starts before or ends after its parent cannot attach; recovered containment flags match known truth at a higher computed rate than accepting every child (ADR 0003). -- `prediction_contradiction` promotion gate: `temporal_core` Allen classification refuses `before`/`after` as contradiction and `meets`/`met_by` as unsupported adjacency; `refuse_promotion` and `require_observed_coverage` refuse partial overlap that leaves unmatched predicted mass; `refuse_contradiction_or_adjacency` is the weaker contradiction/adjacency filter only; evidence available after the knowledge cutoff is ineligible. Label agreement is not RMSE recovery (ADR 0002, ADR 0016). Canonical docs name the crate, not a pull-request number, as the landable authority; `scripts/validate_documentation.py` fail-closes on `landable coverage gate is PR #N` and inverted or paraphrased forms (`PR #N is the landable coverage gate`, `the landable gate is PR #N`, `coverage-authority landing PR #N`, `merge PR #N as the coverage-authority`) including drafts #93, #94, #97, #101, #102, #104, #108, #109, #111, and #112. The hourly queue lock also fail-closes when those drafts are omitted from Keep-unmerged sentences, when a Keep-unmerged sentence is negated, or when the naruon live-HTTP *subject* is not PR #107 with #87 and #105 kept unmerged. -- `provider_receipt` disclosure audit: a receipt records purpose and field codes sent to a model provider; source text, source identity, and blanket PII masking fail closed; recovered field codes match known truth at a higher computed rate than a collapsed set (ADR 0009). -- `tepp_api` corpus-split leakage-audit manifest v1: cutoff exclusion counts, relation-component and partition digests, governed link-kind vocabulary, and a canonical `SHA-256` that binds to `corpus_split_manifest` without exporting source text. -- `persistence_postgres` `audit_event` inserts call `operational_log::try_record` before SQL is rendered: author/customer/project source text, source identity, and blanket-mask grants cannot enter `INSERT INTO audit_event`; clear inspection still persists a validated action code (ADR 0009; ISO/IEC 29100:2024). No new migration number. `OperationalLogRecord::new` stays crate-private. -- `operational_log` source separation: `try_record` is the only recording API and inspects source text, source identity, and blanket-mask intent before creating a line; `OperationalLogRecord::new` is crate-private; a source-identity `&str` cannot become an `AnalyticalSubject`; privileged-export / identity-mapping / diagnosis action codes keep author, customer, and project memberships distinct; replayed lines match known truth at a higher computed rate than a collapsed single-action or collapsed-subject log (ADR 0009; ISO/IEC 29100:2024). The live docstring crate-root count is bound to `EXPECTED_CRATES` so the eleventh crate cannot fail a hard-coded `10`. -- `service_tls` production TLS bind gates: non-loopback binds require rustls PEM material, loopback HTTP is development-only, orchestrator live ports refuse loopback plaintext, and table-access host labels fail closed. `TlsBindRequest` Debug output redacts certificate and private-key PEM. Recovered bind decisions are computed from `authorize_production_tls` / `authorize_orchestrator_live_port` outputs and match known truth at a higher rate than a collapsed production grant (ADR 0011). -- `derived_sensitivity` inheritance: topic, factor, and relation artifacts keep the source sensitivity class; unknown kind codes fail closed on both `inherit_sensitivity` and `DerivedArtifact::try_new`; derivation and blanket PII masking cannot declassify to public; paired kind-and-class recovery matches known 3×3 synthetic truth at a higher computed rate than a public collapse (ADR 0009; GDPR Art. 4(1)/Recital 26; WP 136). -- `longitudinal_core` within/between decomposition: unit means stay between-unit components, occasion residuals stay within-unit change, and recovered components match known truth with lower computed RMSE than a grand-mean pooled collapse. -- `topic_lineage` global P0 topic identity: activity may become dormant or reactivated without minting a new identity, and recovered identities match known truth at a higher computed rate than mint-on-reactivate replacements. -- `interpretation_gateway` evidence-bounded LLM interpretations: proposals must cite at least one evidence span, remain hypothetical, cannot become estimator results or observed facts, and a cited interpreter records a lower computed unsupported-claim rate than uncited promotion. -- `model_selection` candidate-`K` gates: statistical candidates require `K >= 2` and finite held-out log-likelihood/complexity, a Pareto front excludes dominated alternatives, LLM votes cannot define the numerical optimum, and selected `K` recovers known truth with computed RMSE. -- `event_core` mention-confidence Brier score: known-truth binary outcomes recover a computed Brier of 0 for perfect forecasts and 0.25 for constant 0.5, with empty or mismatched streams failing closed. -- `membership_core` nested ICC: CPU `f64` unbalanced ANOVA recovers a known cluster ICC and refuses to treat cross-classified or multiple-membership designs as a single hierarchy (ADR 0003). -- `persistence_postgres` typed `text_segment` SQL: insert/lookup of exact UTF-8 half-open byte spans on the existing `0006` table, cutoff-eligible document reads (`available_time <= knowledge_cutoff`), and live recovery of a known `hello` span. No new migration number (`#45` still owns `0007`). -- Hourly contextual-orchestrator discovery records all provider models but routes OpenCode only through general-chat candidates, excluding embedding, image, reranker, transcription, moderation, safety, and other endpoint-only identifiers before price selection. -- Live `docs/product-technical-gap-baseline.md` mapping operator-visible gaps to - protected-main maturity, exact current PR/issue state, stacked delivery order, - and closure evidence; placeholder-only issues #161 and #162 were closed as - queue hygiene. The documentation validator requires a dated UTC snapshot, a - 40-character protected-main SHA, an exact-head inventory matching the declared - open-PR count, and operator-gap closure evidence, and it rejects affirmative - queued-Checks-as-implemented-main claims even when wrapped across a line - break, and it rejects an unrelated `not` in the same span (`queued Checks are - not required; this PR is implemented-main`). Only never/do not/does not/ - cannot/must not plus promote/treat/make/mean counts as a promotion denial. -- `checkpoint_authority` estimator gate: a model checkpoint remains an untrusted run artifact until identity, canonical `SHA-256`, and model-run provenance validate, and it cannot replace the CPU `f64` estimator or promote a scientific claim; recovered roles match known truth at a higher computed rate than collapsing every artifact to the estimator (ADR 0001/0014). -- `event_core` now requires and retains `EventEvidenceLayer::PromotedTransition` when constructing an `EventInstance`; every other layer is rejected at the promotion boundary, and TDT story classification uses a caller-owned hash set for expected constant-time membership checks. -- `event_core` ADR 0016 evidence-status gates: TDT detections and CHRONOS predictions cannot admit a forward state transition; first-story detection scores miss/false-alarm rates against a known story stream (Allan 2002 task). -- `compute_backend` ADR 0006 first slice: VRAM profiles and reserve-aware micro-batching, executable successive OOM retry plans, CPU fallback, compensated `f64` reference arithmetic with scale-aware parity tolerance, grouped adaptation policies, and fail-closed estimand-preserving memory policies. -- `validation_core` ADR 0014 claim-promotion gates: `decision_accepted`, `implemented_main`, `scientifically_supported`, and `released` bind to an exact commit SHA; queued, predecessor, skipped-required, and LLM evidence fail closed; scientific promotion uses computed RMSE and its standard error rather than a hardcoded threshold (no new migration). -- `relation_graph` causal-identification gate: only `causes` and `intervenes_on` may be described as causal; association, temporal precedence, production, and provenance fail closed. -- `temporal_core` interval-aware historical eligibility: `evaluate_historical_eligibility` admits an `AvailableTime` interval only when every possible availability instant is at or before `KnowledgeCutoff`; unknown and open-ended upper availability fail closed, and event/document time cannot be substituted. -- `event_core` TDT tracking contracts: hypothesized track assignments, fail-closed duplicate mentions, refusal to treat a track as an instance or state transition, and computed pair precision/recall, identity-switch rate, and RMSE against known-truth assignments. -- `event_core` CHRONOS schema-slot gate: predicted role fillers stay distinct from promoted instances and transitions, slot precision/recall are computed from known-truth fills, and production label/confidence APIs produce calibrated occupancy RMSE ≈ 0.1411 versus always-fill ≈ 0.7071 in the contract fixture. -- `event_core` TDT story-segmentation contracts: ordered unit partitions, fail-closed empty/mismatched windows, refusal to treat a detected story cut as an instance or state transition, and computed `WindowDiff`, `Pk`, boundary precision/recall, plus RMSE against known-truth boundaries. -- `event_core` CHRONOS occurrence-prediction calibration: forecasts stay hypothetical, refuse promotion to event instances, and recover a computed Brier score against later-observed occurrence truth, with empty or mismatched streams failing closed. -- `persistence_postgres` entity/project target SQL: fail-closed insert/lookup for `entity_record` and `project_record` so membership foreign keys cannot be seeded from empty, oversized, or hostile type/status labels. No new migration number (ADR 0003 / ADR 0013). -- `cutoff_clock` identity gate: event time, system time, and availability time cannot stand in for knowledge cutoff; recovered cutoff stamps match known truth at a higher computed rate than treating every stamp as availability time (ADR 0002). -- `assertion_clock` identity gate: event, system, document, and availability time cannot stand in for assertion time; recovered assertion stamps match known truth at a higher computed rate than treating every stamp as event time (ADR 0002). -- `event_clock` identity gate: assertion, system, document, and availability time cannot stand in for event/valid time; recovered event stamps match known truth at a higher computed rate than treating every stamp as assertion time (ADR 0002). -- `system_clock` identity gate: event, assertion, document, availability, and knowledge-cutoff time cannot stand in for system time; recovered system stamps match known truth at a higher computed rate than treating every stamp as event time (ADR 0002). -- `support_edge` identity gate: support, contradiction, summary, and `outcome_of` edges cannot become state transitions; recovered evidential kinds match known truth at a higher computed rate than collapsing every kind to support (ADR 0002/0003). -- `inferred_status` identity gate: inferred relations cannot be promoted to observed evidence or to state transitions; recovered observed/inferred labels match known truth at a higher computed rate than treating every status as observed (ADR 0003). -- `payload_bound` identity gate: documents, serialized records, model checkpoints, and LLM outputs stay untrusted until identity, provenance, size, and depth validate; recovered accept/reject flags match known truth at a higher computed rate than accepting every payload (ADR 0008/0013). -- `outcome_order` identity gate: `input_to` and `process_to` cannot move backward or stay contemporaneous in event-time rank; `outcome_of` may point at an earlier producer and cannot become a state transition; recovered kinds match known truth at a higher computed rate than collapsing every kind to `input_to` (ADR 0002/0003). -- `summarizes_edge` identity gate: a summary may point to earlier event time but cannot become a state transition or reuse the source document identity; recovered summary kinds match known truth at a higher computed rate than collapsing every summary to the source (ADR 0003). -- `provider_receipt` disclosure receipt: records provider field codes and - purpose-bound receipt metadata without persisting source text or source - identity (ADR 0009). -- `intake_authorization` identity gate: documents, serialized records, checkpoints, and LLM outputs cannot be accepted without a purpose-bound grant; size/identity/provenance bounds are not that grant; recovered grant-presence flags match known truth at a higher computed rate than accepting every intake (ADR 0009). -- `copy_identity` identity gate: a template or pasted copy cannot reuse the source document identity or become a state transition; recovered copy kinds match known truth at a higher computed rate than collapsing every copy to the source (ADR 0003). -- `stopword_deletion` method gate: a default or global stopword list cannot erase repeated report language; recovered deletion kinds match known truth at a higher computed rate than collapsing every token treatment to stopword deletion (ADR 0004/0012). -- `episode_membership` identity gate: a document's episode membership cannot start before or end after the episode event-time interval; recovered containment flags match known truth at a higher computed rate than accepting every membership (ADR 0003). -- `style_source` identity gate: house-voice style residue is not unique latent content and is not erased by a stopword list; recovered style kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). -- `modality_source` identity gate: non-lexical modality is not unique latent content and is not erased by a stopword list; recovered modality kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). -- `corpus_background` identity gate: corpus-level background wording is not unique latent content and is not erased by a stopword list; recovered background kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). -- `prompt_source` identity gate: instruction and prompt boilerplate is not unique latent content and is not erased by a stopword list; `identity_recovery_rate` reports exact kind matches, with a contract test comparing correct recovery with an all-unique collapse on a mixed known-truth fixture (ADR 0004/0012). -- `location_membership` identity gate: geographic and market assignments are time-varying memberships, not permanent entity identity and not language channels; recovered location kinds match known truth at a higher computed rate than collapsing every assignment to entity identity (ADR 0003). -- `membership_target` identity gate: language, episode, template, department, and opportunity-pool memberships cannot collapse into the entity/project pair stored by migration `0006`; comparison-contract tests record recovered target kinds against an entity-collapse baseline (ADR 0003). -- `corpus_split` inferential-weight gate: only group-normalized ESS and uniform observation weights may enter an estimator; TF-IDF, BM25, and default global stopword deletion fail closed, with computed RMSE showing the retrieval surrogate recovers known shares worse than `group_normalized_ess`. -- `event_core` TDT link-detection contracts: undirected mention-pair hypotheses, fail-closed self-links, refusal to treat a detected link as an instance or state transition, and computed precision/recall plus RMSE against known-truth pairs. -- `event_core` first-story detection gate: first-story versus follow-up labels stay distinct from promoted instances, false-alarm and miss rates are computed from known truth, and calibrated detection scores recover the binary first-story target with lower RMSE than an always-first detector. -- `tepp_api` naruon live loopback HTTP/1.1 listener: `serve_one` installs a read/write deadline, requires a loopback `Host`, refuses `Transfer-Encoding` and NIM/proxy credential headers, parses `knowledge_cutoff` as RFC 3339 and refuses a future cutoff, keys analysis-run idempotency by tenant plus key, and proves both analysis-run and export POSTs over a real `TcpStream`. Not a production TLS/`$PORT` service (ADR 0011). -- `tepp_api` adaptive orchestration router (ADR 0010): versioned `direct`/`verify`/`committee`/`conductor`/`abstain` selection from CPU `f64` risk, ambiguity, evidence, and token-budget inputs; recorded stages, recursion, decomposition, access lists, and role-specific reasoning effort; fail-closed document-controlled policy/access/credentials; LLM plans remain proposals under deterministic statistical authority; comparable-budget ablation requires a direct baseline; credential-free contextual-orchestrator binding. Live NIM HTTP remains accepted-target. -- `tepp_api` purpose-bound provider-payload minimization: time-bounded `PurposeGrant` evaluation, fail-closed expired/not-yet-valid/inverted/cross-tenant/impossible-calendar denial, semantic UTC calendar validation, refusal to copy identity mappings into model-provider payloads or ordinary logs, preservation of opaque analytical identifiers and membership roles (no blanket PII mask), a separately authorized scientific re-identification path, and an internally bound FIPS 180-4 SHA-256 audit digest appended through `ReidentificationAuditSink` before disclosure. -- `persistence_postgres` backup/restore integrity: restored snapshots stay unusable until tenant, canonical `SHA-256`, knowledge-cutoff eligibility, temporal window order, and append-only triggers revalidate; SQL probes raise `restore integrity failed` (ADR 0013). -- `persistence_postgres` concurrent document-write stress: atomic revise `DO` block that requires exactly one open `system_to` close, SQLSTATE mapping onto `ConcurrentWriteConflict` / `DuplicateDocumentRecord`, and live multi-session insert/revise/append-only proofs. No new migration number. -- `tepp_api` naruon HTTP interchange: versioned `https` POST contracts for analysis-run create and modular export authorization that refuse table-access URLs, provider-specific API-key/secret and review/Copilot credential headers, malformed extra HTTP fields, reserved standard-header redefinition, principal-only export idempotency keys, and lexical inference claims (ADR 0011). -- `persistence_postgres` audit-event SQL contracts: append-only insert that refuses empty, oversized, or hostile `action_code` values before SQL is rendered. -- `network_analysis` compositional cluster gates: raw topic proportions cannot be treated as Euclidean coordinates; recovered clusters are scored with label-invariant pair precision and recall against known truth. -- `persistence_postgres` event-instance SQL contracts: bitemporal insert and as-known-at lookup that refuse inverted valid/system windows and hostile type/lifecycle labels before SQL is rendered. -- `persistence_postgres` event-mention SQL contracts: mention identity cannot equal the instance it supports; confidence must be finite and in `(0, 1]`. -- `persistence_postgres` event-relation SQL contracts: closed ERD transition/provenance vocabulary bound to `transition_edge`, fail-closed unknown types and transition self-loops, live insert of `causes`/`references`. -- `persistence_postgres` source-artifact SQL contracts: append-only insert and primary-key lookup that refuse non-canonical `SHA-256` digests, negative sizes, and hostile media-type or object-store labels before SQL is rendered; identical-identity retries are `ON CONFLICT DO NOTHING` plus a stored-row match assertion, and a same-id payload change fails closed as `ConflictingSourceArtifact`. -- `persistence_postgres` typed membership assignment (migration `0006`): `entity_record`, `project_record`, and `text_segment` plus exactly-one observed-unit and target constraints that replace the polymorphic `membership_target_id` stub, with SQL insert/lookup, fail-closed inverted-window and backslash-label refusal, and live proof that one document persists two entity memberships and one project membership. -- Actions workflow fleet auditor (`scripts/actions_workflow_fleet.py`): paginated registry inventory bound to the exact default-branch SHA/tree, classification of present/orphan/disabled/GitHub-dynamic identities, and fail-closed orphan disable that confirms GitHub's official `disabled_manually` state. -- `persistence_postgres` temporal interval ordering migration (`0005`): multi-word CHECK constraints on `document_record`, `event_instance`, and `membership_assignment` that reject inverted valid/system windows and non-positive document revisions while preserving open-ended NULL upper bounds and equal point bounds; catalog validation and live inverted-window proof. -- `persistence_postgres` append-only immutability migration (`0004`): `reject_append_only_mutation`, statement-level `BEFORE UPDATE OR DELETE OR TRUNCATE` triggers on identity/manifest tables, `REVOKE UPDATE`/`DELETE`/`TRUNCATE` from `tepp_app_runtime`, executable DDL/rollback contracts, and live representative mutation proof. -- `persistence_postgres` model-run artifact chain: migration `0003_model_run_artifact_chain` for append-only `corpus_split_manifest`, `model_run`, and `model_artifact` with FORCE RLS; SQL insert/lookup contracts and live repository methods binding runs to reproducibility manifests and optional splits. -- `persistence_postgres` append-only reproducibility-manifest SQL contracts and live repository methods (`insert_reproducibility_manifest`, digest/id lookup) with fail-closed SHA-256 and commit identity validation for `reproducibility_manifest`. -- `persistence_postgres` tenant row-level security: migration `0002_tenant_row_level_security`, `tepp_app_runtime` role, session GUC `tepp.current_tenant_record_id`, multi-word isolation policies with FORCE RLS, session helpers, contract validation, and live isolation proof under `TEPP_LIVE_POSTGRES=1`. -- `persistence_postgres` live PostgreSQL CI: `live-postgres` job with Postgres 16 service, `TEPP_LIVE_POSTGRES=1` gate, and integration coverage for pool open, foundation+RLS migrations, document insert/revise/as-of, audit SQL, and tenant isolation. -- Repository release evidence tooling: `scripts/release_evidence.py` generates CycloneDX 1.5 SBOM, exact-head provenance, and SHA-256 checksums from `Cargo.lock`/`Cargo.toml`, with fail-closed validation and CI generation on every quality gate. -- `persistence_postgres` `live-sqlx` feature: real `SQLx`/`PgPool` open/execute behind validated `DATABASE_URL` and `LiveSqlxPoolOptions`, with offline/live executor backends and CI coverage exclusion for the transport module. -- `persistence_postgres` live pool open gate: validated `LiveSqlxPoolOptions`, fail-closed `open_live_sqlx_pool` / `LiveSqlxPool` (`SqlSession`) with offline test backend; optional `live-sqlx` attaches real `SQLx`/`PgPool` after `DATABASE_URL` validation. -- `validation_core` recovery metrics: parameter matching, RMSE/bias with standard errors, interval coverage with Wilson bounds, relation-edge precision/recall, temporal-order accuracy, Monte Carlo summaries, and SE-aware acceptance gates with machine-readable reports. -- `tepp_api` versioned analysis-run DTOs, content-redacting error envelopes, reproducibility manifests, JSON-LD and GraphML export contracts, purpose-bound export authorization (no blanket PII masking), plus committed schemas/examples. -- `relation_graph` forward-only state-transition DAG with past-pointing provenance edges and cycle rejection. -- `tepp_simulation` deterministic truth-corpus generator with delayed reporting, multilevel memberships, method-effect variants, relation noise, and digest-bound truth manifests. -- `corpus_split` leakage-safe knowledge-cutoff snapshots, relation-connected co-partition groups, rolling-origin windows, and group-normalized ESS weight contracts. -- `persistence_postgres` live SQL port: `SqlSession` transport, migration batch applicator, document/audit SQL contracts, `LiveDocumentRepository`, and fail-closed `DATABASE_URL`/`LiveSqlxConfig` gate for SQLx pool wiring (optional `live-sqlx` driver attaches `PgPool`). -- `membership_core` Kish effective sample size, design effect, and group-normalized ESS helpers for multiple-membership estimation inputs. -- Credential-separated hourly NVIDIA NIM/OpenCode product-development workflow (issue #2): proposal, independent verification, and late Maintainer-App publication with `NVIDIA_NIM_API_KEY` only for model work. -- Hourly product-development queue gate now fails closed when either an open pull request or an open issue exists, including a second queue check immediately before publication. -- Documented modular naruon consumer contract for TEPP analysis-run and export surfaces, with a committed example request payload. -- Documented contextual-orchestrator interpretation port boundary and credential separation for TEPP. -- Foundation validation/release-readiness ledger at `docs/validation/temporal-event-foundation.md` tracking capability maturity and scientific acceptance gates. -- Research doctoring for multilevel/multiple-membership measurement and atomistic fallacy prevention. -- `persistence_postgres` bitemporal foundation: multi-word migration contracts, knowledge-cutoff eligibility, and in-memory as-known-at / as-valid-at document replay (live SQLx/PostgreSQL execution remains accepted-target). -- `event_core` mention/instance separation with explicit promotion, typed roles, event-time validity, and fail-closed mention-as-instance refusal. -- `membership_core` time-varying weighted multiple-membership network with contextual roles, event-time validity, and atomistic-fallacy prevention contracts. -- Bounded Allen interval algebra and path-consistency reasoner in `temporal_core` (Task 4; PR #9), with identity-isolated variables, resource budgets, inverse/composition, and conservative provenance. -- Approved Temporal Event Psychometrics Platform PRD v0.4 baseline. -- Canonical technical documentation map, TRD, UML/scientific runtime views, logical/planned ERD, scientific test strategy, operability/recovery guide, and requirements/research/evidence traceability with explicit implementation maturity. -- Whole-conversation documentation fitness assessment plus canonical API/MSA contract, threat model, privacy/data-governance contract, CSAP/SOC 2/ISO/NIST assurance-readiness mapping, and adaptive LLM orchestration/test-time-compute contract. -- ADR policy separating architectural **Decision status** from **Implementation maturity**, defining partial supersession, and making the ADR index the canonical decision-ownership map. -- ADR 0009 for purpose-bound PII governance without blanket masking, ADR 0010 for adaptive direct-versus-multi-agent LLM orchestration, and ADR 0011 for standalone/modular CWL service authority. -- ADR 0012 for Temporal Relational Shared-Latent Topic Measurement (TRSL-TM), global topic identity/backend compatibility/method-effect/model-selection authority. -- ADR 0013 for bitemporal persistence, immutable reproducibility/run/split manifests, relation-aware partitions, recovery, and PostgreSQL adapter authority. -- ADR 0014 separating accepted design, protected-main implementation, scientific/product claim promotion, and release evidence authority. -- ADR 0015 separating autonomous model proposal, deterministic verification, publication, independent review, and merge/release authority. -- ADR 0016 separating Event Ontology observation, TDT detection/tracking, CHRONOS schema prediction, symbolic temporal consistency, and promoted transition authority. -- Added APA 7 research traceability for ICLR 2026 TRINITY and Conductor, the 2026 Sakana Fugu technical report, ISO/IEC 42001:2023, ISO/IEC 23894:2023, NIST AI RMF/GAI Profile, AICPA Trust Services Criteria, and KISA CSAP guidance. -- Eight-phase delivery roadmap and Temporal/Event Foundation implementation plan. -- Immutable evidence, six-clock temporal semantics, interval reasoning, event ontology, typed relation graph, and time-varying multiple-membership contracts. -- Shared-latent multilingual topic measurement architecture with native lexical channels and language-profile validation. -- Longitudinal ESEM/DSEM and continuous-time structural modeling requirements. -- Rust-first CPU `f64`, multithreaded CPU, GPU, VRAM-adaptive streaming, and CPU/GPU parity requirements. -- Topic correlation, consensus clustering, TDT, CHRONOS, and evidence-grounded LLM interpretation requirements. -- APA 7th research traceability, source archive manifests, ADRs, governance, security, and contribution contracts. -- Hourly centralized PR-maintenance workflow and a documented requirement for a future credential-separated NVIDIA NIM/OpenCode product-development loop. -- Rust 1.97.1 virtual Cargo workspace with eleven explicit modular foundation crates. -- Repository contract, public-rustdoc, line-coverage, and nightly branch-coverage gates. -- Pinned `cargo-nextest` 0.9.140, `cargo-llvm-cov` 0.8.6, `cargo-deny` 0.19.7, and Coverage.py 7.15.2 quality tooling. -- Task 1 architecture decision and workspace-foundation validation report. -- Version-keyed, executable-only GitHub Actions caches for pinned Rust quality tools. -- Immutable `evidence_core` records with independent RFC 9562 `UUIDv7` identities, canonical `SHA-256` content digests, owned source bytes and UTF-8 text, exact byte/Unicode-scalar spans, and bounded page-layout coordinates. -- Strict versioned JSON wire contracts for artifacts, documents, exact spans, and nested page locations without exposing private domain storage. -- ADR 0008 and APA 7 doctoring for evidence identity, hashing, JSON interchange, UTF-8 boundaries, Unicode segmentation limits, and future W3C PROV integration. -- Same-run exact missing-line and missing-branch diagnostics for failed 100% Rust coverage gates. - ### Changed -- ALR and ILR inverse normalization now fails closed when division would turn - a representable subnormal weight into a zero simplex part; runtime images - are pinned to the reviewed multi-platform Rust and Debian OCI digests. -- `psychometric_core` scalar forward map `φ(Δt) = exp(a Δt)` now refuses binary64 underflow to `+0`. Voelkle et al. (2012, Eq. 7; ZORA accepted manuscript p. 16) write discrete auto-effects as `e^{a Δt}`, which are strictly positive; `a = ln(φ) / Δt` requires `φ > 0`. Direct overflow already failed closed. The Newton residual path refuses a mapped `+0` the same way. -- The docstring discovery test compares crate-root names to `EXPECTED_CRATES` instead of a hardcoded count of 10, so `semantic_core` is required and an unapproved extra crate fails closed. -- The LineageWeave temporal-context read exchange no longer emits a fabricated - `idempotency-key`; that header remains reserved for retryable write/export - operations with a caller-owned operation key. -- `tepp_api` project-history requests and projections now share the strict - `temporal_core` RFC 3339 parser and nominal `KnowledgeCutoff` boundary, - rejecting unknown offsets and other timestamp forms that the transport - parser could otherwise accept. -- Coverage validation now ignores LLVM rows for multiline call and iterator - syntax that have no independently executable source coordinate, while - retaining the authored-line 100% gate. -- Removed the temporary PR-155 review-repair workflows and source-fix helper after the bounded repair; subsequent changes use the normal reviewed branch path. -- Pinned Rust branch-coverage workflows to `nightly-2026-08-21`, which is newer than the workspace Rust 1.98.0 MSRV and avoids the previous nightly/MSRV mismatch. -- Applied the documented `sqlx_live.rs` authored-coverage exclusion to the hourly release gate so live-PostgreSQL success-path coverage is not reported as a false source failure. -- Removed unreachable duplicate Naruon host-control validation because the shared `require_nonempty` boundary already rejects C0/C1 controls; retained a C1 regression case alongside the existing C0 case. -- Kept one maturity row per capability in the traceability matrix while recording the active provider-receipt evidence without duplicating or downgrading existing capabilities. -- `tepp_api` corpus-split manifest validation now rejects governed link-kind arrays that are unsorted or duplicated, keeping untrusted JSON aligned with the schema's unique canonical representation and preventing equivalent audits from receiving different valid digests. -- Grounded `derived_sensitivity` doctoring on GDPR Article 4(1)/Recital 26 and WP29 Opinion 4/2007 (WP 136) as read from the official texts, and replaced the withdrawn ISO/IEC 29100:2011 use-limitation overclaim with the current 29100:2024 catalogue edition without quoting unread clause text. -- Added APA 7th method citations (Allen 1983; ISO 24617-1:2012; Hobbs & Pan 2017; Fox & Glas 2001; AERA/APA/NCME 2014; Blei & Lafferty 2006; Roberts et al. 2014, 2019; Chang & Blei 2009; Mimno et al. 2009; Asparouhov & Muthén 2009; Asparouhov et al. 2018; Marsh et al. 2014; Aitchison 1982; Allan 2002; Li et al. 2021; Anagnostopoulos et al. 2013) into ADRs 0002–0005, 0012, and 0016, plus TRACEABILITY/ARCHITECTURE/TRD method rows. Clarified that TRSL-TM is the product contract, STM-style logistic-normal is the reference family, ESEM/DSEM/TDT/CHRONOS remain accepted-target, and merged PRs #8/#9—not superseded drafts #5/#6—are the protected-main temporal lineage. -- Refreshed the live gap-baseline inventory to the 2026-08-24T05:41:54Z GitHub - snapshot (118 open PRs / 48 drafts / 12 issues; protected-main - `c45be17a9dbce95ef81cee230e9d128abc7160ac`), binding each operator-gap current - head SHA to that exact-head register, including #201 `6afd650667e1` (RFC 5646 - cited once; first GAP-005 slice, not implemented-main), stacked drafts - #202–#204, and #164 `ff2e645b1785` as the predecessor register head. Duplicate - PR #179 remains closed. Stacked-merged heads and queued Checks are not - implemented-main. -- Rust LCOV quality gating now ignores visibility-qualified function signatures - and structural match-arm labels that LLVM reports as zero-hit non-executable - lines. - PR #179 remains closed. Stacked-merged heads and queued Checks are not - implemented-main. -- Removed the completed one-shot PR #51 repair job from `docs-quality.yml`; the - workflow no longer invokes deleted repair scripts or requests write authority - after the executable compute implementation is already present. -- `persistence_postgres` entity and project target inserts now bind their tenant session context before rendering SQL, keeping `FORCE ROW LEVEL SECURITY` behavior consistent with every other tenant-scoped write; live coverage still proves raw wrong-tenant rejection. -- Clarified ADR 0001 so it owns Rust-first numerical/reference-backend authority while ADR 0011 owns cross-service MSA/service authority. -- Clarified ADR 0006 so it owns GPU/VRAM and model-credential boundaries; ADR 0010 now owns LLM orchestration policy and ADR 0015 owns autonomous repository-write/review/merge authority. -- Expanded ADR 0002–0005 and 0009–0011 with explicit implementation maturity, alternatives, failure/recovery, compatibility/migration, verification, and rollback/supersession boundaries where they were previously implicit. +- Protected `main` advanced through #489 to `b18bca1c69ef8d1799fcd3af6bf4412498e007c3`: the repository-local hourly PR-maintenance caller is removed in favor of the central required scheduler, PR validation concurrency is isolated by repository and pull request, duplicate crate-only documentation runs are removed, and line/branch coverage share one sequential runner while retaining both 100% gates and diagnostics. +- Delivery-authority recovery (#435 / #175) records the fresh live queue as **134 open pull requests: 134 Draft and 0 non-Draft**, with 16 open issues, on protected `main@b18bca1c69ef8d1799fcd3af6bf4412498e007c3`. The observed queue peak in this recovery cycle was 149. Organization ruleset `18156473`, not classic branch-protection status alone, remains merge authority. +- Longitudinal Modeling PR #310 is the surviving `landing_vehicle`. Former PR #441 is closed after its corrected two-marginal lagged-correlation, typed event-time, overflow/underflow, recovery, and traceability evidence was folded into #310. #310 is **not merge-ready** until its exact-current-head required workflows terminate GREEN and qualifying independent review exists. +- One-map Drafts #476 (`DIFFUSIONstd`) and #477 (`discreteDIFFUSIONstd`) were retired only after their distinct stationarity, interval, numerical-edge, refusal, and `research_candidate` evidence was verified in #310 under `longitudinal_core`. +- Reusable covariance-to-correlation standardisation is owned upstream by `ContextualWisdomLab/fast-mlsirm` surviving PR #1722 and Published Language candidate `fast_mlsirm.covariance_standardization@1.0.0`. The narrower concurrent #1723 was closed unmerged only after its exact-unit scalar evidence was preserved in #1722. TEPP #272 is retired; TEPP #315 remains Draft adapter lineage and must remove duplicate local arithmetic only after a released/versioned upstream contract is available and parity is proven. +- Documentation fitness now fails closed on malformed rows inside the priority exact-head inventory rather than silently omitting them when another valid row exists. ADR validation also requires repository-wide identity plus index/file agreement for Decision status and Implementation maturity, and rejects repeated authority declarations even when their values are identical. +- ADR 0004 and ADR 0008 authority metadata were normalized so active implementation evidence is not presented as protected-main capability. The ADR index now mirrors canonical file status/maturity for the repaired rows. The historical 0021 collision remains byte-preserved under `docs/adr/archive/`; the former colliding 0024 text is not falsely represented as an archive when verified original bytes are unavailable, and ADR 0026 remains only a Proposed successor identity. + +### DDD ownership -### Security +- TEPP owns temporal/event composition, six-clock semantics, event ontology/temporal graph, longitudinal invariance/drift/alignment, leakage-safe knowledge cutoffs, and time-varying multilevel/cross-classified/multiple-membership policy. +- fast-mlsirm owns reusable static/generalized-mixed/dependence-aware psychometric numerical kernels, including reusable covariance standardisation and LSIRM/MLSIRM/DLSJM computation. +- Validation Evidence and Scientific Claim Promotion remain separate authorities; transport/application layers cannot promote a scientific claim. +- contextual-orchestrator owns provider/LLM execution and routing. LLM output never becomes numerical or scientific authority. +- `context-graph-contracts` and `enterprise-architecture-core` are read-only to the TEPP writer while their Context Fabric owner loop is active. Open heads are candidate evidence, not released contracts. -- Naruon interchange refuses `x-apikey`, `x-api_key`, and hyphenated `api-key` credential-header aliases, not only `x-api-key`. -- GitHub HTTPS fleet transport maps request, response, and close-path network exceptions to `upstream_unavailable` without leaking raw provider exception text. -- Disabled-state classification and live disable confirmation now accept GitHub's official `disabled_manually`, `disabled_fork`, `disabled_inactivity`, and `deleted` registry states so orphan bootstrap/repair identities can be retired without name-only heuristics. -- Prohibited `COPILOT_GITHUB_TOKEN` and reserved `NVIDIA_NIM_API_KEY` for approved LLM test and development workflows. -- Defined purpose-bound PII access, opaque analytical identifiers, separately protected identity mapping, selective model-provider disclosure, retention/deletion, and privileged audit controls instead of destructive blanket masking. -- Added explicit threat classes for temporal leakage, relation/membership poisoning, model/artifact poisoning, numerical divergence, cross-tenant disclosure, prompt injection, evidence substitution, resource exhaustion, and scientific-integrity failures. -- Removed the bootstrap branch's credential-co-resident OpenCode workflow: no model process may receive repository-write authority, and scheduled product development remains disabled until proposal, independent verification, and late publication authority are separated across fresh jobs. -- Removed completed bootstrap materializers, encoded payload fragments, readiness sentinels, and push probes from the reviewable tree. -- Required full-commit GitHub Action pins, minimum permissions, concurrency controls, immutable audit evidence, SBOM, and provenance. -- Kept ordinary Rust CI free of LLM and reviewer credentials and disabled persisted checkout credentials. -- Refused to cache mutable Cargo registry, Git source, or target trees; cached quality binaries are keyed and checked by exact version. -- Copied caller-provided source bytes and document text before acceptance and kept validated evidence fields private. -- Made empty, oversized, malformed-digest, invalid UTF-8-boundary, coordinate-mismatch, cross-document, nonfinite-geometry, and out-of-page evidence fail closed with content-redacting errors. -- Rejected malformed or extended wire payloads, unsupported schema versions, invalid identifiers and byte values, digest/content substitution, stale document ownership, and invalid nested geometry during reconstruction. +### Release integrity -### Quality +- Queued, pending, skipped-required, predecessor-head, self-review, or local-only evidence is non-passing. +- Release requires a clean protected-main integration state, exact protected-head CI/security evidence, claim-scoped scientific/recovery acceptance, reproducible artifacts with SBOM and provenance, validated migration/upgrade/rollback/recovery where applicable, consistent version metadata, an updated current changelog, accessibility and operability evidence for user-facing components, and no unresolved scientific/privacy/security/supply-chain blocker. +- No force-push, routine protection bypass, coverage exclusion, fail-open security substitution, or scientific claim promotion is authorized by this changelog. +- Deployable Context Graph/EA integration binds only to released/versioned contracts with provenance and passing compatibility evidence; TEPP latent estimates, scores, inferred event relations, and validity evidence are not copied into EA as authoritative architecture facts. -- Required 100% production line and branch coverage and complete public API docstrings. -- Required true-parameter recovery, RMSE, bias, interval coverage, temporal leakage, graph recovery, invariance, and CPU/GPU parity evidence. -- Expanded documentation contracts to require the canonical threat/privacy/assurance/API/orchestration/fitness documents, ADR policy, and every numbered ADR present in the canonical index to remain indexed and structurally complete. -- Added deterministic validation that ADR files and the index have identical decision numbers and that every ADR declares valid decision status, implementation maturity, supersession scope, core decision sections, verification, and rollback behavior. -- Added 100% statement and branch coverage for the repository quality-gate scripts. -- Made a zero executable-code coverage denominator explicit for the skeleton-only slice rather than treating it as evidence of implemented behavior. -- Denied warnings, missing public documentation, and unsafe Rust across the workspace. -- Added known digest vectors, mutation detection, hostile multibyte Unicode, exact-coordinate, page-boundary, stable-error, and invalid-input regression tests for the first evidence slice. -- Added strict wire round trips, unknown-field and version rejection, digest reconstruction, configured-limit, hostile JSON, and generated multilingual span tests. +## Historical record -The repository has not yet cut a stable implementation release, so no compare reference is published for `[Unreleased]` yet. +The complete prior changelog, including the historical `[0.2.0]` source-version record and detailed scientific branch lineage accumulated before queue/DDD normalization, is retained without rewriting at [`docs/archive/CHANGELOG-pre-queue-normalization-2026-09-01.md`](docs/archive/CHANGELOG-pre-queue-normalization-2026-09-01.md). Its archived statements remain provenance for their historical source state and do not override current protected-main, release, DDD, or scientific-promotion authority. diff --git a/CLAUDE.md b/CLAUDE.md index 339692cf0..2092da3c6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,7 +14,7 @@ Read and follow `AGENTS.md` before changing this repository. The repository-wide - Do not convert association, temporal precedence, or document links into causal language without identification evidence. - Do not remove repeated report language with global stopword lists or use TF-IDF/BM25 as inferential weights. Model template, section, copied-text, style, modality, and corpus-background sources explicitly. - Do not treat raw topic proportions as ordinary Euclidean indicators. Use logistic-normal coordinates or valid log-ratio coordinates and propagate posterior uncertainty into ESEM/DSEM. -- Do not treat metric/weak invariance as a latent-mean license. Strong (equal loading and intercept) or strict is required; `#84` `metric` licenses shared metric meaning only. Putnick and Bornstein (2016, PMC5145197 opened 2026-08-19T22:15Z) require scalar invariance before latent-mean comparison; residual invariance is not a prerequisite. Two-observation series have no residual degrees of freedom (`ordinary_least_squares_fit` returns residual variance `0`) and cap at strong/scalar; they still license means. This is two-group OLS, not MGCFA. Meredith (1993) names remain unread labels (Unpaywall/OpenAlex 2026-08-25T11:32Z: closed). +- Do not treat metric/weak invariance as a latent-mean license. Strong (equal loading and intercept) or strict is required; `#84` `metric` licenses shared metric meaning only. Putnick and Bornstein (2016, PMC5145197 opened 2026-08-19T22:15Z) require scalar invariance before latent-mean comparison; residual invariance is not a prerequisite. Two-observation series have no residual degrees of freedom (`ordinary_least_squares_fit` returns residual variance `0`) and cap at strong/scalar; they still license means. This is two-group OLS, not MGCFA. Meredith (1993) names remain unread labels (Unpaywall/OpenAlex 2026-09-01T10:22Z: still closed, `is_oa: false`, 0 OA locations). - Do not use the difference quotient as a continuous-time rate. The scalar map is `a = ln(φ) / Δt` on event time. Discrete lags from unequal event intervals are not one coefficient; remap them through that log-rate. Binary64 `exp(a Δt) = 0` is not a discrete lag. A constant predictor's discrete effect is Voelkle et al. (2012, Eq. 12), evaluated as `a_yx (expm1(z) / a_xx)` with `z = a_xx Δt` so a finite result is not lost when `z` overflows to `-∞` or when `a_yx Δt` overflows. When `expm1(z)` overflows at a finite `z`, rewrite in log space; a zero continuous effect is exactly zero; an overflowing `a_yx/a_xx` rewrite term fails closed. The first-order product is the underflow limit of that equation, not the general constant-predictor discrete effect. A time-varying predictor whose sampling interval equals its constancy interval uses Voelkle et al. (2012, Eq. 14): `b* = a_yx Δt`. Unmatched intervals fail closed (Oud & Jansen, 2000, unread). Discrete process noise is Driver et al. (2017, Eq. 3): `Q_Δt = 0.5 q (expm1(z) / a)` with `z = 2 (a Δt)` and `q = G G⊤ ≥ 0`; do not form `2 a` first; `a = 0` and `z → 0` recover `q Δt`; a zero diffusion is exactly zero; an overflowing rewrite scale `0.5 q / a` fails closed; this is not a Kalman filter. `Q_Δt` is `cov(η_t | η_{t-1})`, not `Var(η_t)`. The lagged covariance is `exp(a Δt) p` and the unconditional variance is `exp(2 a Δt) p + Q_Δt` (Driver et al., 2017, Eq. 3–4, pp. 4–5; JSS has no numbered §2.2). A zero diffusion whose `2 (a Δt)` overflows to `+∞` is not a finite `Var(η_t)`. The stationary within-subject variance is the `Δt → ∞` limit of Eq. 4: `-q / (2 a)` for stable `a < 0` (JSS p. 16 `asymDIFFUSION`; §4.3). When `2 a` is finite, form `q / -(2 a)` so `q / a` overflow does not lose a finite result (`q = MAX`, `a = -0.75` → `MAX / 1.5`). When `2 a` overflows, form `(q / a) * -0.5`. Do not form `0.5 q` first (`q = from_bits(1)` underflows). `a ≥ 0` has no finite stationary variance. Finite-interval `Q_Δt` is not that limit. Trait-plus-state variance is `trait + state` and lagged covariance is `trait + exp(a Δt) p` (Driver et al., 2017, §4.3, p. 9). Trait variance is not process noise and not `asymDIFFUSION`. Evolving the summed variance as if it were all state is not that map. This is not RI-CLPM. Observed-indicator variance is `λ² Var(η) + θ` when `MANIFESTTRAITVAR` is zero and `λ² Var(η) + θ + ψ` otherwise (Driver et al., 2017, Eq. 5, p. 5; Table 2, p. 12). Lagged observed covariance is `λ² cov(η_t, η_{t-1}) + ψ`; `MANIFESTVAR` does not enter. Observed-indicator mean is `τ + λ μ` (Driver et al., 2017, Eq. 5; Table 2, p. 12). `MANIFESTMEANS` is `τ`, not `E(y)`. `E(η)` is not `E(y)`. `CINT` is not `MANIFESTMEANS`. `T0MEANS` is not `E(y)`. The discrete latent mean is `μ_t = exp(a Δt) μ_0 + (exp(a Δt) − 1)/a κ` (Driver et al., 2017, Eq. 3, p. 4; Table 2, p. 12). `T0MEANS` is not `μ_t`. `CINT` is not that discrete increment. A zero drift is `κ Δt`. Underflow of `exp(a Δt)` to `+0` drops the carried `T0MEANS` and keeps `−κ / a`. The evolved observed mean is `τ + λ μ_t` (Driver et al., 2017, Eq. 5 of that Eq. 3 map). The first-occasion map `τ + λ μ_0` is not `E(y_t)`. `μ_t` is not `E(y_t)`. The contemporaneous time-dependent predictor impulse is `m x` (Driver et al., 2017, Eq. 3 fourth summand; Table 2 `TDPREDEFFECT` is `M`). Form `μ_t` first, then add `m x`. `TDPREDEFFECT` is not `CINT`. `M x` is not `A^{-1}[e^{A Δt} − I] B z` and is not Voelkle et al. (2012, Eq. 14). The §7.2 level-change form is not that impulse. The observed mean of that contemporaneous impulse is `τ + λ(μ_t + m x)` (Driver et al., 2017, Eq. 5 of the Eq. 3 fourth-summand composition). The evolved map `τ + λ μ_t` is not that observed mean. The carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not that observed mean when `u ≠ t`. The evolved-plus-impulse latent mean is not `E(y_t)`. The time-independent predictor increment is `A^{-1}[e^{A Δt} − I] B z` (Driver et al., 2017, Eq. 3 second summand; Table 2 `TIPREDEFFECT` is `B`). Form `B z` first, then the discrete intercept map. A zero drift is `B z Δt`. `TIPREDEFFECT` is `B`, not that discrete increment. `A^{-1}[e^{A Δt} − I] B z` is not `CINT`, not `M x`, and not Voelkle et al. (2012, Eq. 14). The observed mean of that increment is `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` (Driver et al., 2017, Eq. 5 of the Eq. 3 printed addend after the `T0MEANS` carry and the `CINT` increment). The evolved map `τ + λ μ_t` is not that observed mean. The contemporaneous map `τ + λ(μ_t + m x)` is not that observed mean. The carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not that observed mean when `u ≠ t`. The evolved-plus-increment latent mean is not `E(y_t)`. The within-interval time-dependent impulse carry is `e^{A(t−u)} M x` for `t0 < u < t` (Driver et al., 2017, Eq. 1–2 Green-function integral of Eq. 2; §7.2 dissipation). Form `m x` first, then `e^{a(t−u)} m x`. A zero drift is `m x` with no dissipation. Underflow of `e^{a(t−u)}` to `+0` is vanishing dissipation and is kept. `e^{A(t−u)} M x` is not the contemporaneous Dirac, not `CINT`, not `TIPREDEFFECT`, and not Voelkle et al. (2012, Eq. 14). An impulse at `u = t` is the contemporaneous map. An impulse at `u ≤ t0` is already in `η(t0)`. The observed mean of that carry is `τ + λ(μ_t + e^{a(t−u)} m x)` (Driver et al., 2017, Eq. 5 of the Eq. 1–2 carried latent mean). The evolved map `τ + λ μ_t` is not that observed mean. The contemporaneous map `τ + λ(μ_t + m x)` is not that observed mean when `u ≠ t`. `MANIFESTMEANS` is not `E(y_t)`. The carried latent mean is not `E(y_t)`. The first-occasion time-independent predictor shift is `t0_b z` (Driver et al., 2017, Table 3 `T0TIPREDEFFECT`; Eq. 3 first summand). Form `t0_b z` first, then `e^{a Δt} t0_b z`. Form `μ_t` first, then add that carry. A zero drift is `t0_b z`. Underflow of `e^{a Δt}` to `+0` is a vanishing carry of the first-occasion shift and is kept. `t0_b z` is not `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, and not `M x`. `e^{A Δt} t0_b z` is not `t0_b z`. `T0TIPREDEFFECT` is the coefficient, not the shift. The observed mean of that first-occasion carry is `τ + λ(μ_t + e^{a Δt} t0_b z)` (Driver et al., 2017, Eq. 5 of the Table 3 / Eq. 3 first-summand composition). The evolved map `τ + λ μ_t` is not that observed mean. The process-increment map `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not that observed mean. The contemporaneous map `τ + λ(μ_t + m x)` is not that observed mean. The impulse-carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not that observed mean when `u ≠ t0`. The evolved-plus-carry latent mean is not `E(y_t)`. The first-occasion time-dependent predictor shift is `t0_m x0` (Driver et al., 2017, Table 3 `T0TDPREDEFFECT`; Eq. 3 first summand; JSS PDF re-opened 2026-08-20T19:10Z). Form `t0_m x0` first, then `e^{a Δt} t0_m x0`. Form `μ_t` first, then add that carry. A zero drift is `t0_m x0`. Underflow of `e^{a Δt}` to `+0` is a vanishing carry of the first-occasion shift and is kept. `t0_m x0` is not `M x`, not `e^{A(t−u)} M x` for `t0 < u < t`, not `t0_b z`, not `A^{-1}[e^{A Δt} − I] B z`, and not `CINT`. `e^{A Δt} t0_m x0` is not `t0_m x0`. `T0TDPREDEFFECT` is the coefficient, not the shift. An impulse at `u ≤ t0` that used `M` is already in `η(t0)` as `TDPREDEFFECT`, not as `T0TDPREDEFFECT`. The observed mean of that first-occasion TD carry is `τ + λ(μ_t + e^{a Δt} t0_m x0)` (Driver et al., 2017, Eq. 5 of the Table 3 / Eq. 3 first-summand TD composition; JSS PDF re-opened 2026-08-20T19:07Z). The evolved map `τ + λ μ_t` is not that observed mean. The process-increment map `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not that observed mean. The contemporaneous map `τ + λ(μ_t + m x)` is not that observed mean. The impulse-carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not that observed mean when `u ≠ t0`. The first-occasion TI map `τ + λ(μ_t + e^{a Δt} t0_b z)` is not that observed mean. The evolved-plus-carry latent mean is not `E(y_t)`. The lasting level-change `CINT` is `κ = −a m x` (Driver et al., 2017, §7.2, pp. 20–21; JSS PDF re-opened 2026-08-20T19:45Z). Form `m x` first, then multiply by `−a`. Stable `a < 0` is required so `−κ / a = m x` is an equilibrium offset. `a ≥ 0` cannot hold a new process mean. `−a m x` is not the dissipating Dirac `m x`, not a free `CINT`, and not `A^{-1}[e^{A Δt} − I] B z`. The extra near-zero-drift latent process also named in §7.2 is a different specification and is not this `CINT` setting. Equation 3 maps that intercept as `(1 − e^{a Δt}) m x` (JSS PDF re-opened 2026-08-20T19:50Z). Form the level-change `CINT` first, then the discrete intercept map. Underflow of `e^{a Δt}` to `+0` keeps `m x`. `(1 − e^{a Δt}) m x` is not `m x`, not `κ`, and not `A^{-1}[e^{A Δt} − I] B z`. The printed §7.2 lasting level change is an extra near-zero-drift latent process (Driver et al., 2017, §7.2, pp. 22–23; JSS PDF re-opened 2026-08-20T23:10Z). `T0MEANS`, `CINT`, `T0VAR`, `DIFFUSION`, and `TRAITVAR` of that process are fixed to 0; `TDPREDEFFECT` on it is fixed to 1; its `DRIFT` diagonal is very close to 0 (printed example `−0.000001`; precisely 0 causes computational problems); the original process is driven by the `DRIFT` coupling `a_{ηξ}`. After a unit identification impulse the scalar contribution is `a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)` (`ε = a` is `a_{ηξ} x Δt e^{a Δt}`). Form `a_{ηξ} x` first. A zero coupling or zero predictor is exactly zero. `ε ≥ 0` fails closed. That contribution is not `κ = −a m x`, not `(1 − e^{a Δt}) m x`, and not the dissipating Dirac `m x`. The observed mean of that extra-process contribution is `τ + λ(μ_t + a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a))` (Driver et al., 2017, Eq. 5 of that §7.2 contribution; JSS PDF re-opened 2026-08-21T06:12Z). The extra process has `LAMBDA` 0 and is not an observed indicator. Original indicators load on the original process after the `DRIFT` coupling. The evolved map `τ + λ μ_t` is not that observed mean. The contemporaneous map `τ + λ(μ_t + m x)` is not that observed mean. The contribution is not `E(y_t)`. The evolved-plus-contribution latent mean is not `E(y_t)`. `T0TDPREDEFFECT` on the extra process begins at `t = 0` and uses `Δt = t − t0` for both the original-process evolution and the extra drive. `TDPREDEFFECT` after `t0` uses `t − u` with `t0 < u < t` for the extra drive while `μ_t` still uses `Δt`. The observed mean of that after-t0 extra-process contribution is `τ + λ(μ_t + a_{ηξ} x (e^{ε(t−u)} − e^{a(t−u)}) / (ε − a))` (Driver et al., 2017, Eq. 5 of that §7.2 after-t0 contribution; JSS PDF re-opened 2026-08-21T06:32Z). The first-occasion extra-process observed mean is not that observed mean when `u ≠ t0`. The impulse-carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is a Dirac on the original process and is not that `DRIFT` drive. An impulse at `u = t0` or `u = t` is not interior. The asymptotic time-independent predictor effect is `-B z / a` (Driver et al., 2017, §7.2, pp. 20–21; JSS PDF opened 2026-08-21T13:08Z). Form `B z` first, then divide by `-a`. Stable `a < 0` is required. `a ≥ 0` cannot hold a finite process-mean change. `-B z / a` is not the coefficient `B`, not `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, and not `M x`. The asymptotic time-independent predictor variance is `(B / a)² v` (Driver et al., 2017, §7.2, pp. 20–21 `addedTIPREDVAR`). Form the unit asymptotic effect first, then square, then multiply by `v`. `(B / a)² v` is not `TRAITVAR`, not `asymDIFFUSION`, and not `-B z / a`. The asymptotic continuous intercept is `-κ / a` (Driver et al., 2017, Table 2, p. 12 `asymCINT`; Eq. 3 as `Δt → ∞`; JSS PDF opened 2026-08-21T16:13Z). Form `κ` first, then divide by `-a`. Stable `a < 0` is required. `-κ / a` is not `κ`, not `A^{-1}[e^{A Δt} − I] κ`, not `T0MEANS`, and not `-B z / a`. The p. 16 stationary `T0MEANS` constraint is `-κ / a + −B z / a`. Form the intercept contribution first, then include the TI extra effect, then add. That constrained first-occasion mean is not free `T0MEANS`, not `asymCINT` alone, not `asymTIPREDEFFECT` alone, and not the finite-interval discrete latent mean. Equation 5 of that constrained mean is `τ + λ(−κ / a + −B z / a)` (Driver et al., 2017, §4.3, pp. 9–10; Eq. 5, p. 5; JSS PDF re-opened 2026-08-21T20:07Z). Form the stationary latent mean first, then `τ + λ` of that mean. `τ + λ μ_0` for free `T0MEANS` is not that composition. `τ + λ(−κ / a)` is not that composition when `B z ≠ 0`. `τ + λ μ_t` is not that composition. `MANIFESTMEANS` is not `E(y_0)`. The constrained latent mean is not `E(y_0)`. The p. 16 constrained first-occasion variance `trait + −q / (2 a) + (B / a)² v` is not free `T0VAR`, not `asymDIFFUSION` alone, not `TRAITVAR` alone, not `addedTIPREDVAR` alone, and not the finite-interval discrete latent variance. Eq. 5 of that constrained variance is `λ²(trait + −q / (2 a) + (B / a)² v) + θ + ψ` (JSS PDF re-opened 2026-08-22T03:20Z; form the stationary latent variance first, then `λ² p + θ + ψ`; `λ² p_0` is not that observed variance; `λ²(−q / (2 a)) + θ` is not that observed variance when `TRAITVAR` or `addedTIPREDVAR` is nonzero; `MANIFESTVAR` is not `Var(y_0)`; the constrained latent variance is not `Var(y_0)`). The lagged covariance of that constrained process is `trait + e^{a Δt}(−q / (2 a)) + (B / a)² v` (Driver et al., 2017, Eq. 3–4 of §4.3 / p. 16 `T0VAR`; JSS PDF re-opened 2026-08-22T19:13Z). Trait and `addedTIPREDVAR` do not decay with `e^{a Δt}`. Contemporaneous `T0VAR` is not that lagged map. Decaying the constrained total as if it were all state is not that lagged map. Equation 5 of that lagged covariance is `λ²(trait + e^{a Δt}(−q / (2 a)) + (B / a)² v) + ψ`. `Θ` does not enter. Contemporaneous `Var(y_0)` is not that lagged observed covariance. The lagged latent covariance is not that observed covariance. The later-occasion variance of that constrained process is `trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v` (Driver et al., 2017, Eq. 3–4 of §4.3 / p. 16 `T0VAR`; JSS PDF re-opened 2026-08-22T23:12Z). Trait and `addedTIPREDVAR` do not enter `Q_Δt`. Under stationarity that composition equals contemporaneous `T0VAR`. Evolving the constrained total as if it were all state is not that later map. The lagged covariance omits `Q_Δt` and is not that later map. `Q_Δt` is not that later map. Equation 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v) + θ + ψ`. The lagged observed covariance omits `Q_Δt` and `θ`. `MANIFESTVAR` is not `Var(y_t)`. The later-occasion latent variance is not `Var(y_t)`. The later-occasion variance of §4.3 predetermined `T0VAR` is `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v` (Driver et al., 2017, Eq. 3–4 of §4.3 predetermined first occasion; JSS PDF re-opened 2026-08-23T05:12Z). Trait and `addedTIPREDVAR` do not enter `Q_Δt`. Free `T0VAR` `p_0` is not that later map. Setting `p_0 = −q / (2 a)` recovers the stationary later-occasion map. Stationary later variance uses `−q / (2 a)` in place of `p_0` and is not that later map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state is not that later map. As `Δt → ∞` with stable `a < 0` the composition approaches contemporaneous stationary `T0VAR`. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. Nonzero diffusion with `a ≥ 0` is a growing process and is kept. Equation 5 of that predetermined later-occasion variance is `λ²(trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not `Var(y_t)`. The predetermined later-occasion latent variance is not `Var(y_t)`. Stationary later observed variance is not that observed variance when `p_0` is free. The lagged covariance of §4.3 predetermined `T0VAR` is `trait + e^{a Δt} p_0 + (B / a)² v` (Driver et al., 2017, Eq. 3–4 of §4.3 predetermined first occasion; JSS PDF re-opened 2026-08-23T09:04Z). Trait and `addedTIPREDVAR` do not decay with `e^{a Δt}`. Free `T0VAR` `p_0` is not that lagged map. Setting `p_0 = −q / (2 a)` recovers the stationary lagged map. Stationary lagged covariance uses `−q / (2 a)` in place of `p_0` and is not that lagged map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state is not that lagged map. Later-occasion variance includes `Q_Δt` and is not that lagged map. As `Δt → ∞` with stable `a < 0` the state term vanishes. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. Equation 5 of that predetermined lagged covariance is `λ²(trait + e^{a Δt} p_0 + (B / a)² v) + ψ`. `MANIFESTVAR` does not enter. The predetermined lagged latent covariance is not that observed covariance. Predetermined later observed variance includes `Q_Δt` and `θ` and is not that lagged observed covariance. Stationary lagged observed covariance is not that observed covariance when `p_0` is free. The predetermined first-occasion variance of §4.3 predetermined `T0VAR` is `trait + p_0 + (B / a)² v`. Free `p_0` is not that map. Stationary first-occasion variance uses `−q / (2 a)` in place of `p_0` and is not that map when `p_0` is free. Lagged covariance decays the state and is not that map. Later-occasion variance includes `Q_Δt` and is not that map. Equation 5 of that predetermined first-occasion variance is `λ²(trait + p_0 + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not that first-occasion observed variance. The predetermined first-occasion latent variance is not that observed variance. Stationary first-occasion observed variance is not that observed variance when `p_0` is free. Predetermined later observed variance includes `Q_Δt` and is not that first-occasion observed variance. Later-start lagged covariance of predetermined `T0VAR` is `trait + e^{a s}(e^{2 a u} p_0 + Q_u) + (B / a)² v` (Driver et al., 2017, §4.3 `startoffset`; Eq. 4; JSS PDF re-opened 2026-08-23T10:27Z). First-occasion lagged omits `e^{a s} Q_u`. Later-occasion variance does not lag. Stationary lagged uses `−q / (2 a)`. Decaying the later total is not that map. Equation 5 of that later-start lagged covariance is `λ²` of it plus `ψ`. Independent `ε_t` does not enter. First-occasion lagged observed omits `e^{a s} Q_u`. Predetermined later observed variance includes `Q_u` and `θ` and is not that later-start lagged observed covariance. Later-start later-occasion variance of predetermined `T0VAR` is `trait + e^{2 a s}(e^{2 a u} p_0 + Q_u) + Q_s + (B / a)² v` (Driver et al., 2017, §4.3 `startoffset`; Eq. 3–4 Chapman–Kolmogorov `Q_{u+s} = e^{2 a s} Q_u + Q_s`; JSS PDF re-opened 2026-08-23T11:05Z). Later-occasion variance at `u` omits `Q_s`. Later-start lagged covariance omits `Q_s`. Stationary later uses `−q / (2 a)`. Evolving the later total as if it were all state is not that map. Ignoring `startoffset` omits `e^{2 a s} Q_u`. Equation 5 of that later-start later-occasion variance is `λ²` of it plus `θ + ψ`. `MANIFESTVAR` is not that observed variance. Page 16 `discreteDRIFTstd` is `e^{a Δt}` after strictly positive `asymDIFFUSION` `-q / (2 a)` (Driver et al., 2017, p. 16; footnote 4; §7.1; JSS PDF re-opened 2026-08-23T11:40Z). Unstandardised `e^{a Δt}` is defined for growing `a ≥ 0` and for zero diffusion and is not `discreteDRIFTstd`. The §7.1 trait-plus-state autocorrelation `(trait + e^{a Δt} p + added) / (trait + p + added)` uses `TRAITVAR` and is not `discreteDRIFTstd`. `TRAITVAR` is not the standardisation variance. Page 16 `discreteDIFFUSIONstd` is `Q_Δt / (−q / (2 a))` after strictly positive `asymDIFFUSION` `-q / (2 a)` (Driver et al., 2017, p. 16; Eq. 4; footnote 4; JSS PDF re-opened 2026-08-23T13:06Z). Unstandardised `Q_Δt` is defined for growing `a ≥ 0` and for zero diffusion and is not `discreteDIFFUSIONstd`. The continuous standardisation `−2 a` is not `discreteDIFFUSIONstd`. `Q_Δt / (trait + p + added)` uses `TRAITVAR` and is not `discreteDIFFUSIONstd`. `TRAITVAR` is not the standardisation variance. Page 16 `DIFFUSIONstd` is `q / (−q / (2 a)) = −2 a` after strictly positive `asymDIFFUSION` `-q / (2 a)` (Driver et al., 2017, p. 16; Eq. 4; footnote 4; JSS PDF re-opened 2026-08-23T13:20Z). Unstandardised `q` is defined for growing `a ≥ 0` and for zero diffusion and is not `DIFFUSIONstd`. The discrete standardisation `Q_Δt / (−q / (2 a))` depends on `Δt` and is not `DIFFUSIONstd`. `q / (trait + p + added)` uses `TRAITVAR` and is not `DIFFUSIONstd`. `TRAITVAR` is not the standardisation variance. Page 16 `DRIFTstd` is the continuous auto-effect after strictly positive `asymDIFFUSION` `-q / (2 a)` (Driver et al., 2017, p. 16; Eq. 1; footnote 4; JSS PDF re-opened 2026-08-23T13:28Z). Unstandardised `a` is defined for growing `a ≥ 0` and for zero diffusion and is not `DRIFTstd`. The discrete standardisation `e^{a Δt}` depends on the event interval and is not `DRIFTstd`. `a p / (trait + p + added)` uses `TRAITVAR` and is not `DRIFTstd`. `TRAITVAR` is not the standardisation variance. Page 16 `asymTIPREDEFFECTstd` is `(-B / a) · √v / √(-q / (2 a))` after strictly positive `asymDIFFUSION` `-q / (2 a)` and strictly positive predictor variance `v` (Driver et al., 2017, p. 16; §7.2; footnote 4; JSS PDF re-opened 2026-08-23T14:25Z). Unstandardised `-B / a` is defined for a zero coefficient and for zero predictor variance and is not `asymTIPREDEFFECTstd`. The finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not `asymTIPREDEFFECTstd`. `(-B / a) · √v / √(trait + p + added)` uses `TRAITVAR` and is not `asymTIPREDEFFECTstd`. `TRAITVAR` is not the standardisation variance. Page 16 `TIPREDEFFECTstd` is `B · √v / √(-q / (2 a))` after strictly positive `asymDIFFUSION` `-q / (2 a)` and strictly positive predictor variance `v` (Driver et al., 2017, p. 16; §7.2; footnote 4; JSS PDF re-opened 2026-08-23T16:21Z). Unstandardised `B` is defined for a zero coefficient and for zero predictor variance and is not `TIPREDEFFECTstd`. The asymptotic standardisation `(-B / a) · √v / √p` is the total change and is not `TIPREDEFFECTstd`. The finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not `TIPREDEFFECTstd`. `B · √v / √(trait + p + added)` uses `TRAITVAR` and is not `TIPREDEFFECTstd`. `TRAITVAR` is not the standardisation variance. Page 16 / Table 3 `T0TIPREDEFFECTstd` is `t0_b · √v / √p_0` after strictly positive free `T0VAR` `p_0` and strictly positive predictor variance `v` (Driver et al., 2017, Table 3, p. 13; p. 16; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T17:20Z). The affected variance is free first-occasion `T0VAR`, not `asymDIFFUSION`. Unstandardised `t0_b` is defined for a zero coefficient and for zero predictor variance and is not `T0TIPREDEFFECTstd`. `TIPREDEFFECTstd` `B · √v / √(-q / (2 a))` is the continuous coefficient and is not `T0TIPREDEFFECTstd`. `asymTIPREDEFFECTstd` `(-B / a) · √v / √p` is the total change and is not `T0TIPREDEFFECTstd`. `t0_b · √v / √(trait + p_0 + added)` uses `TRAITVAR` and is not `T0TIPREDEFFECTstd`. `TRAITVAR` is not the standardisation variance. 2017-era `addedT0TIPREDVAR` is `t0_b² v` after a first-occasion time-independent predictor (Driver et al., 2017, Table 3, p. 13; p. 16; §7.2; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T18:20Z). Form `t0_b` first, then square, then multiply by `v`. A zero coefficient or zero predictor variance is exactly zero. Free `T0TIPREDEFFECT` does not require `a < 0`. `(B / a)² v` is `addedTIPREDVAR` and is not this first-occasion map. `t0_b · √v / √p_0` is `T0TIPREDEFFECTstd` and is not this variance. Free `T0VAR` is not this extra TI variance. `TRAITVAR` is not this extra TI variance. Equation 5 of 2017-era `addedT0TIPREDVAR` is `λ² t0_b² v` (Driver et al., 2017, Eq. 5, p. 5; Table 3, p. 13; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T19:10Z). Form `t0_b² v` first, then `(λ extra) λ` with `θ = 0`. A zero loading or zero extra is exactly zero. `t0_b² v` is the latent extra, not the observed extra. `λ² p_0 + θ` is first-occasion observed variance, not this extra. `λ² (B / a)² v` is Eq. 5 of `addedTIPREDVAR`, not this first-occasion observed extra. `MANIFESTVAR` `θ` is not this extra. Equation 5 of §7.2 `addedTIPREDVAR` is `λ² (B / a)² v` (Driver et al., 2017, Eq. 5, p. 5; Table 2, p. 12; §7.2, pp. 20–21; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T19:23Z). Form `(B / a)² v` first, then `(λ extra) λ` with `θ = 0`. A zero loading or zero extra is exactly zero. Lasting asymptotic extra requires `a < 0`. `(B / a)² v` is the latent extra, not the observed extra. `λ² t0_b² v` is first-occasion extra observed TI variance, not this extra. `λ² p + θ` is stationary observed variance, not this extra. `MANIFESTVAR` `θ` is not this extra. Page 16 `TDPREDEFFECTstd` is `m · √v / √(-q / (2 a))` after strictly positive `asymDIFFUSION` and strictly positive time-dependent predictor variance. Unstandardised `M` is not `TDPREDEFFECTstd`. `TIPREDEFFECTstd` is not `TDPREDEFFECTstd` even when `M = B`. intercept-style `A^{-1}[e^{A Δt} − I] M · √v / √p` is not `TDPREDEFFECTstd`. `m · √v / √(trait + p + added)` uses `TRAITVAR` and is not `TDPREDEFFECTstd`. Table 3 / p. 16 `T0TDPREDEFFECTstd` is `t0_m · √v / √p_0` after strictly positive free `T0VAR` and strictly positive TD predictor variance. Unstandardised `t0_m` is not `T0TDPREDEFFECTstd`. `TDPREDEFFECTstd` uses `asymDIFFUSION` and is not `T0TDPREDEFFECTstd`. `T0TIPREDEFFECTstd` is not `T0TDPREDEFFECTstd` even when `t0_m = t0_b`. `t0_m · √v / √(trait + p_0 + added)` uses `TRAITVAR` and is not `T0TDPREDEFFECTstd`. Free `T0VAR` does not require `a < 0`. Page 16 `T0VARstd` is `p_0 / p_0 = 1` after strictly positive free `T0VAR` (`solve(sqrt(diag(T0VAR))) %&% T0VAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; the default ridge is 0). Unstandardised `T0VAR` is not `T0VARstd`. `T0TDPREDEFFECTstd` is not `T0VARstd`. `addedT0TIPREDVAR` is not `T0VARstd`. Page 16 `TRAITVARstd` is `trait / trait = 1` after strictly positive `TRAITVAR` (`solve(sqrt(diag(TRAITVAR))) %&% TRAITVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; no ridge addend). Unstandardised `TRAITVAR` is not `TRAITVARstd`. `T0VARstd` is not `TRAITVARstd` even when both equal 1. `addedT0TIPREDVAR` is not `TRAITVARstd`. Page 16 `MANIFESTTRAITVARstd` is `ψ / ψ = 1` after strictly positive `MANIFESTTRAITVAR` (`solve(sqrt(diag(MANIFESTTRAITVAR))) %&% MANIFESTTRAITVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0). Unstandardised `MANIFESTTRAITVAR` is not `MANIFESTTRAITVARstd`. `TRAITVARstd` is not `MANIFESTTRAITVARstd` even when both equal 1. `MANIFESTVAR` is not `MANIFESTTRAITVARstd`. Page 16 `MANIFESTVARstd` is `θ / θ = 1` after strictly positive `MANIFESTVAR` (`solve(sqrt(diag(MANIFESTVAR))) %&% MANIFESTVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0; 2017-era `dimnames` assignment to `latentNames` is a source bug). Unstandardised `MANIFESTVAR` is not `MANIFESTVARstd`. `MANIFESTTRAITVARstd` is not `MANIFESTVARstd` even when both equal 1. Equation 5 `Var(y)` is not `MANIFESTVARstd`. Page 16 `TIPREDVARstd` is `v / v = 1` after strictly positive `TIPREDVAR` (`solve(sqrt(diag(TIPREDVAR))) %&% TIPREDVAR`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0; `dimnames` are `TIpredNames`). Unstandardised `TIPREDVAR` is not `TIPREDVARstd`. `MANIFESTVARstd` is not `TIPREDVARstd` even when both equal 1. Section 7.2 `addedTIPREDVAR` is not `TIPREDVARstd`. Page 16 `asymDIFFUSIONstd` is `p / p = 1` after strictly positive `asymDIFFUSION` (`solve(sqrt(diag(asymDIFFUSION))) %&% asymDIFFUSION`; OpenMx `%&%` is `t(A) %*% B %*% A`; 2017-era source adds ridging; default ridge is 0; `dimnames` are `latentNames`). Unstandardised `asymDIFFUSION` is not `asymDIFFUSIONstd`. `TIPREDVARstd` is not `asymDIFFUSIONstd` even when both equal 1. `DIFFUSIONstd` `−2 a` is not `asymDIFFUSIONstd`. Page 16 `discreteCINTstd` is `A^{-1}[e^{A Δt} − I] κ / √p` after strictly positive `asymDIFFUSION`. Unstandardised `discreteCINT` is not `discreteCINTstd`. `κ / √p` is not `discreteCINTstd`. `(-κ / a) / √p` is not `discreteCINTstd`. `asymCINTstd` is `(-κ / a) / √p` after strictly positive `asymDIFFUSION`. Unstandardised `asymCINT` is not `asymCINTstd`. `κ / √p` is not `asymCINTstd`. `discreteCINTstd` is not `asymCINTstd`. `T0MEANSstd` is `μ_0 / √p_0` after strictly positive free `T0VAR`. Unstandardised `T0MEANS` is not `T0MEANSstd`. `T0VARstd` is not `T0MEANSstd`. `μ_0 / √asymDIFFUSION` is not `T0MEANSstd`. Page 16 `MANIFESTMEANSstd` is `τ / √θ` after strictly positive `MANIFESTVAR`. Unstandardised `MANIFESTMEANS` is not `MANIFESTMEANSstd`. `MANIFESTVARstd` is not `MANIFESTMEANSstd`. `τ / √(λ² Var(η) + θ)` is not `MANIFESTMEANSstd`. Page 16 `CINTstd` is `κ / √p` after strictly positive `asymDIFFUSION`. Unstandardised `CINT` is not `CINTstd`. `asymCINTstd` is not `CINTstd`. `discreteCINTstd` is not `CINTstd`. `κ / √(trait + p + added)` is not `CINTstd`. Evolving from that stationary start with `CINT` and `TIPREDEFFECT` stays at the stationary mean. Equation 1 is the latent SDE, not the measurement model. Form `(λ p) λ` then add `θ`, then add `ψ`. `MANIFESTVAR` is `Θ`, not `Var(y)`. `MANIFESTTRAITVAR` is `Ψ_τ`, not `Θ`. `TRAITVAR` is latent and scaled by `λ²`. `Var(η)` is not `Var(y)`. - Separate cluster means before within-unit lag. CWC plus an event-time lag is not DSEM. Subtracting the person-specific mean from a raw autoregressive series does not isolate the lagged within-person effect (Curran & Bauer, 2011, pp. 607–608); already-centered residuals with irregular event intervals use the exact scalar map. - Do not treat the CWC cluster-mean coefficient as the between-cluster effect. It is the contextual effect `between − within` (Enders & Tofighi, 2007, Table 2, pp. 124–127). diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 6fa4b9683..8f62c1c42 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -1,18 +1,17 @@ # TEPP Documentation Map -TEPP's approved PRD v0.4 and implementation plan are the primary product baseline. This index makes the technical, data, scientific, security/privacy, integration, quality, operating, and assurance contracts discoverable without duplicating that source material. +TEPP's approved PRD v0.4 remains the product/measurement baseline. This map identifies the canonical technical, domain, scientific, security, operating, and delivery authorities without duplicating their content. An open PR, queued check, local test, or accepted ADR is not evidence of protected-main implementation unless the maturity and exact-head gates say so. | Area | Canonical document | |---|---| | Approved product requirements | [`docs/product/prd-v0.4-approved.md`](docs/product/prd-v0.4-approved.md) | | Live product and technical gap baseline | [`docs/product-technical-gap-baseline.md`](docs/product-technical-gap-baseline.md) | -| Whole-conversation documentation fitness | [`docs/DOCUMENTATION_ASSESSMENT.md`](docs/DOCUMENTATION_ASSESSMENT.md) | +| Whole-repository documentation assessment | [`docs/DOCUMENTATION_ASSESSMENT.md`](docs/DOCUMENTATION_ASSESSMENT.md) | | Technical requirements | [`docs/TRD.md`](docs/TRD.md) | | Architecture | [`ARCHITECTURE.md`](ARCHITECTURE.md) | +| DDD bounded-context and ownership map | [`docs/architecture/domain-context-map.md`](docs/architecture/domain-context-map.md) | +| Temporal/dependence composition boundary | [`docs/architecture/temporal-dependence-composition.md`](docs/architecture/temporal-dependence-composition.md) | | Modular/API integration contract | [`docs/API_CONTRACT.md`](docs/API_CONTRACT.md) | -| naruon modular consumer contract | [`docs/connectors/naruon-artifact-consumer.md`](docs/connectors/naruon-artifact-consumer.md) | -| contextual-orchestrator interpretation port | [`docs/connectors/contextual-orchestrator-interpretation-port.md`](docs/connectors/contextual-orchestrator-interpretation-port.md) | -| Orchestrator live HTTP doctoring | [`docs/research/orchestrator-live-http.md`](docs/research/orchestrator-live-http.md) | | UML/runtime/scientific flows | [`docs/UML.md`](docs/UML.md) | | Logical/physical ERD | [`docs/ERD.md`](docs/ERD.md) | | Security policy | [`SECURITY.md`](SECURITY.md) | @@ -29,150 +28,42 @@ TEPP's approved PRD v0.4 and implementation plan are the primary product baselin | Foundation implementation plan | [`docs/superpowers/plans/2026-08-05-temporal-event-foundation.md`](docs/superpowers/plans/2026-08-05-temporal-event-foundation.md) | | Foundation validation ledger | [`docs/validation/temporal-event-foundation.md`](docs/validation/temporal-event-foundation.md) | | Standards and APA 7 literature | [`docs/research/standards-and-literature.md`](docs/research/standards-and-literature.md) | -| Operational log / source-separation doctoring | [`docs/research/operational-log-source-separation.md`](docs/research/operational-log-source-separation.md) | -| Interval cutoff eligibility doctoring | [`docs/research/interval-cutoff-eligibility.md`](docs/research/interval-cutoff-eligibility.md) | +| LSIRM/MLSIRM/DLSJM primary research authority | [`docs/research/temporal-dependence-models.md`](docs/research/temporal-dependence-models.md) | +| Multilevel/event-time recovery doctoring | [`docs/research/multilevel-event-time-recovery.md`](docs/research/multilevel-event-time-recovery.md) | +| Posterior ESEM/DSEM input-gate doctoring | [`docs/research/posterior-esem-input-gates.md`](docs/research/posterior-esem-input-gates.md) | +| Interval cutoff eligibility | [`docs/research/interval-cutoff-eligibility.md`](docs/research/interval-cutoff-eligibility.md) | +| Scientific claim-promotion gates | [`docs/research/scientific-claim-promotion-gates.md`](docs/research/scientific-claim-promotion-gates.md) | +| Causal-identification gate | [`docs/research/causal-identification-gate.md`](docs/research/causal-identification-gate.md) | +| Topic log-ratio coordinates | [`docs/research/topic-logratio-coordinates.md`](docs/research/topic-logratio-coordinates.md) | +| VRAM budget / GPU fallback | [`docs/research/vram-budget-types.md`](docs/research/vram-budget-types.md) | +| TDT story segmentation | [`docs/research/tdt-story-segmentation.md`](docs/research/tdt-story-segmentation.md) | +| TDT link-detection calibration | [`docs/research/event-link-detection-calibration.md`](docs/research/event-link-detection-calibration.md) | +| First-story detection calibration | [`docs/research/first-story-detection-calibration.md`](docs/research/first-story-detection-calibration.md) | +| CHRONOS prediction calibration | [`docs/research/chronos-prediction-calibration.md`](docs/research/chronos-prediction-calibration.md) | +| CHRONOS schema-slot calibration | [`docs/research/chronos-schema-slot-calibration.md`](docs/research/chronos-schema-slot-calibration.md) | +| Event-tracking calibration | [`docs/research/event-tracking-calibration.md`](docs/research/event-tracking-calibration.md) | +| Provider payload minimization | [`docs/research/provider-payload-minimization.md`](docs/research/provider-payload-minimization.md) | +| Operational log/source separation | [`docs/research/operational-log-source-separation.md`](docs/research/operational-log-source-separation.md) | +| Adaptive orchestration | [`docs/research/adaptive-orchestration-router.md`](docs/research/adaptive-orchestration-router.md) | | Governance | [`GOVERNANCE.md`](GOVERNANCE.md) | | Agent development rules | [`AGENTS.md`](AGENTS.md) | | Agent context | [`CLAUDE.md`](CLAUDE.md) | -| Hourly NIM product-development operations | [`docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md`](docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md) | +| Hourly product-development operations | [`docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md`](docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md) | | Actions workflow fleet audit | [`docs/operations/ACTIONS_WORKFLOW_FLEET.md`](docs/operations/ACTIONS_WORKFLOW_FLEET.md) | -| Actions fleet research doctoring | [`docs/research/actions-workflow-fleet.md`](docs/research/actions-workflow-fleet.md) | -| Inferential TF-IDF/BM25/stopword refusal doctoring | [`docs/research/inferential-retrieval-weight-gate.md`](docs/research/inferential-retrieval-weight-gate.md) | -| Simulation cutoff-eligibility doctoring | [`docs/research/simulation-cutoff-eligibility.md`](docs/research/simulation-cutoff-eligibility.md) | -| Posterior ESEM/DSEM input-gate doctoring | [`docs/research/posterior-esem-input-gates.md`](docs/research/posterior-esem-input-gates.md) | -| Multilevel/event-time recovery doctoring | [`docs/research/multilevel-event-time-recovery.md`](docs/research/multilevel-event-time-recovery.md) | -| Rubin total-variance doctoring | [`docs/research/rubin-total-variance.md`](docs/research/rubin-total-variance.md) | -| Strong-invariance latent-mean doctoring | [`docs/research/strong-invariance-latent-means.md`](docs/research/strong-invariance-latent-means.md) | -| Mention-confidence Brier doctoring | [`docs/research/mention-confidence-brier.md`](docs/research/mention-confidence-brier.md) | -| Span-grounded mention extent doctoring | [`docs/research/span-grounded-mentions.md`](docs/research/span-grounded-mentions.md) | -| Span-grounded mention numeric provenance | [`docs/doctoring/span-grounded-mentions.md`](docs/doctoring/span-grounded-mentions.md) | -| Event-intelligence status-gate doctoring | [`docs/research/event-intelligence-status-gates.md`](docs/research/event-intelligence-status-gates.md) | -| TDT link-detection precision/recall doctoring | [`docs/research/event-link-detection-calibration.md`](docs/research/event-link-detection-calibration.md) | -| First-story detection FAR/miss doctoring | [`docs/research/first-story-detection-calibration.md`](docs/research/first-story-detection-calibration.md) | -| VRAM budget / GPU fallback doctoring | [`docs/research/vram-budget-types.md`](docs/research/vram-budget-types.md) | -| Causal-identification gate doctoring | [`docs/research/causal-identification-gate.md`](docs/research/causal-identification-gate.md) | -| TDT story-segmentation `WindowDiff`/`Pk` doctoring | [`docs/research/tdt-story-segmentation.md`](docs/research/tdt-story-segmentation.md) | -| CHRONOS prediction-calibration doctoring | [`docs/research/chronos-prediction-calibration.md`](docs/research/chronos-prediction-calibration.md) | -| CHRONOS schema-slot calibration doctoring | [`docs/research/chronos-schema-slot-calibration.md`](docs/research/chronos-schema-slot-calibration.md) | -| Event-tracking calibration doctoring | [`docs/research/event-tracking-calibration.md`](docs/research/event-tracking-calibration.md) | -| Episode-membership identity doctoring | [`docs/research/episode-membership-identity.md`](docs/research/episode-membership-identity.md) | -| Entity/project target SQL doctoring | [`docs/research/entity-project-sql.md`](docs/research/entity-project-sql.md) | -| Scientific claim-promotion gate doctoring | [`docs/research/scientific-claim-promotion-gates.md`](docs/research/scientific-claim-promotion-gates.md) | -| Retention/deletion/legal-hold doctoring | [`docs/research/retention-deletion-legal-hold.md`](docs/research/retention-deletion-legal-hold.md) | -| Provider-payload minimization doctoring | [`docs/research/provider-payload-minimization.md`](docs/research/provider-payload-minimization.md) | -| Relation absence is not negative evidence | [`docs/research/relation-absence-not-negative.md`](docs/research/relation-absence-not-negative.md) | -| Adaptive orchestration router doctoring | [`docs/research/adaptive-orchestration-router.md`](docs/research/adaptive-orchestration-router.md) | -| Mention-confidence Brier doctoring | [`docs/research/mention-confidence-brier.md`](docs/research/mention-confidence-brier.md) | -| Span-grounded mention extent doctoring | [`docs/research/span-grounded-mentions.md`](docs/research/span-grounded-mentions.md) | -| Span-grounded mention numeric provenance | [`docs/doctoring/span-grounded-mentions.md`](docs/doctoring/span-grounded-mentions.md) | -| Event-intelligence status-gate doctoring | [`docs/research/event-intelligence-status-gates.md`](docs/research/event-intelligence-status-gates.md) | -| Stopword-deletion doctoring | [`docs/research/stopword-deletion.md`](docs/research/stopword-deletion.md) | -| Topic log-ratio coordinate doctoring | [`docs/research/topic-logratio-coordinates.md`](docs/research/topic-logratio-coordinates.md) | -| Hourly NIM OpenCode doctoring | [`docs/doctoring/hourly-nim-opencode-development.md`](docs/doctoring/hourly-nim-opencode-development.md) | -| Analysis engine v1 doctoring | [`docs/doctoring/analysis-engine-v1.md`](docs/doctoring/analysis-engine-v1.md) | -| Analysis engine gap-closure doctoring | [`docs/doctoring/analysis-engine-gap-closure.md`](docs/doctoring/analysis-engine-gap-closure.md) | -| Corpus-split leakage-audit wire doctoring | [`docs/research/corpus-split-manifest-wire.md`](docs/research/corpus-split-manifest-wire.md) | -| Unicode canonical-identity doctoring | [`docs/research/unicode-canonical-identity.md`](docs/research/unicode-canonical-identity.md) | | Change history | [`CHANGELOG.md`](CHANGELOG.md) | -## Maturity vocabulary - -The canonical implementation-maturity vocabulary is defined in [`docs/adr/ADR_POLICY.md`](docs/adr/ADR_POLICY.md) and promotion evidence in [`docs/TRACEABILITY.md`](docs/TRACEABILITY.md). In particular, **an ADR with decision status `Accepted` is not automatically implemented or shipped.** - -- **implemented-main** — source is integrated on protected `main` and the relevant exact-current-head tests, scientific/recovery/validation evidence, security and supply-chain gates, and qualifying review required by live policy pass. -- **active-PR** — implementation exists only on an open PR and is not a protected-main claim. -- **partial** — an explicitly identified subset is implemented on protected main while the rest remains target work. -- **accepted-target** — accepted PRD/ADR architecture not yet integrated. -- **research-only** — evaluated research direction not accepted as production behavior. -- **out-of-scope** — explicitly outside TEPP ownership. -- **conceptual** — logical entity/service/model contract; not evidence of a migration or deployment. -- **deployment-owned** — evidence depends on a concrete deployed environment or organization and cannot be claimed by repository design alone. -- **external-assurance** — certification, attestation, legal opinion, or other independent assessment that TEPP cannot self-issue. +## Authority and maturity rules -## Documentation fitness - -The documentation graph is **design-sufficient** when a reviewer can reconstruct TEPP's product requirements, technical/scientific estimands, authority boundaries, temporal/event/membership semantics, data model, failure modes, security/privacy controls, validation strategy, API/integration contract, operability, research basis, ADR ownership/supersession, and release acceptance without chat history. - -It is **protected-main-sufficient** only after the canonical documents are integrated on protected `main`, remain semantically current with live code, and their required exact-head documentation/security/review gates pass. An active documentation PR can therefore be design-sufficient while the protected branch remains documentation-insufficient. - -At the time of this review, protected `main` at `7c29e7c971d7940e1fb3def1ed3aae2d1bc8ad4a` implements immutable evidence records/exact spans, the Rust workspace quality foundation, typed six-clock values/uncertain intervals (merged PR #8), Allen interval algebra and bounded path-consistency (merged PR #9), event ontology/membership, and PostgreSQL persistence through restore-integrity probes. Superseded PRs #5 and #6 remain historical lineage only, and drafts #93, #94, #97, #101, #102, #104, #108, #109, #111, and #112 are superseded non-landable lineage; unmerged or draft PRs are never implemented-main claims. The active-PR `prediction_contradiction` coverage gate requires observed Allen coverage (`during`, `starts`, `finishes`, or `equals`) before unmatched predicted mass may be authorized for promotion; `refuse_promotion` is that authority and not a contradiction-only filter — coverage may authorize promotion but does not convert a forecast into observed fact. Remaining TDT/CHRONOS intelligence, shared-latent topic estimation, GPU kernels, longitudinal ESEM/DSEM, visual analytics, production HTTP services, and deployment assurance stay accepted-target or deployment-owned unless a [`docs/TRACEABILITY.md`](docs/TRACEABILITY.md) row records a narrower implemented-main or partial subset. -# TEPP Documentation Map - -TEPP's approved PRD v0.4 and implementation plan are the primary product baseline. This index makes the technical, data, scientific, security/privacy, integration, quality, operating, and assurance contracts discoverable without duplicating that source material. - -| Area | Canonical document | -|---|---| -| Approved product requirements | [`docs/product/prd-v0.4-approved.md`](docs/product/prd-v0.4-approved.md) | -| Live product and technical gap baseline | [`docs/product-technical-gap-baseline.md`](docs/product-technical-gap-baseline.md) | -| Whole-conversation documentation fitness | [`docs/DOCUMENTATION_ASSESSMENT.md`](docs/DOCUMENTATION_ASSESSMENT.md) | -| Technical requirements | [`docs/TRD.md`](docs/TRD.md) | -| Architecture | [`ARCHITECTURE.md`](ARCHITECTURE.md) | -| Modular/API integration contract | [`docs/API_CONTRACT.md`](docs/API_CONTRACT.md) | -| naruon modular consumer contract | [`docs/connectors/naruon-artifact-consumer.md`](docs/connectors/naruon-artifact-consumer.md) | -| contextual-orchestrator interpretation port | [`docs/connectors/contextual-orchestrator-interpretation-port.md`](docs/connectors/contextual-orchestrator-interpretation-port.md) | -| UML/runtime/scientific flows | [`docs/UML.md`](docs/UML.md) | -| Logical/physical ERD | [`docs/ERD.md`](docs/ERD.md) | -| Security policy | [`SECURITY.md`](SECURITY.md) | -| Threat model | [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md) | -| Privacy and data governance | [`docs/PRIVACY_DATA_GOVERNANCE.md`](docs/PRIVACY_DATA_GOVERNANCE.md) | -| Compliance/assurance readiness | [`docs/COMPLIANCE_READINESS.md`](docs/COMPLIANCE_READINESS.md) | -| LLM orchestration/test-time compute | [`docs/LLM_ORCHESTRATION.md`](docs/LLM_ORCHESTRATION.md) | -| Test/scientific validation strategy | [`docs/TEST_STRATEGY.md`](docs/TEST_STRATEGY.md) | -| Operability/recovery/release | [`docs/OPERABILITY.md`](docs/OPERABILITY.md) | -| Requirement/research/evidence traceability | [`docs/TRACEABILITY.md`](docs/TRACEABILITY.md) | -| Architecture decision index / ownership map | [`docs/adr/README.md`](docs/adr/README.md) | -| ADR status, maturity, and supersession policy | [`docs/adr/ADR_POLICY.md`](docs/adr/ADR_POLICY.md) | -| Delivery roadmap | [`docs/roadmaps/2026-08-05-tepp-delivery-roadmap.md`](docs/roadmaps/2026-08-05-tepp-delivery-roadmap.md) | -| Foundation implementation plan | [`docs/superpowers/plans/2026-08-05-temporal-event-foundation.md`](docs/superpowers/plans/2026-08-05-temporal-event-foundation.md) | -| Foundation validation ledger | [`docs/validation/temporal-event-foundation.md`](docs/validation/temporal-event-foundation.md) | -| Standards and APA 7 literature | [`docs/research/standards-and-literature.md`](docs/research/standards-and-literature.md) | -| Operational log / source-separation doctoring | [`docs/research/operational-log-source-separation.md`](docs/research/operational-log-source-separation.md) | -| Interval cutoff eligibility doctoring | [`docs/research/interval-cutoff-eligibility.md`](docs/research/interval-cutoff-eligibility.md) | -| Governance | [`GOVERNANCE.md`](GOVERNANCE.md) | -| Agent development rules | [`AGENTS.md`](AGENTS.md) | -| Agent context | [`CLAUDE.md`](CLAUDE.md) | -| Hourly NIM product-development operations | [`docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md`](docs/operations/HOURLY_NIM_PRODUCT_DEVELOPMENT.md) | -| Actions workflow fleet audit | [`docs/operations/ACTIONS_WORKFLOW_FLEET.md`](docs/operations/ACTIONS_WORKFLOW_FLEET.md) | -| Actions fleet research doctoring | [`docs/research/actions-workflow-fleet.md`](docs/research/actions-workflow-fleet.md) | -| Mention-confidence Brier doctoring | [`docs/research/mention-confidence-brier.md`](docs/research/mention-confidence-brier.md) | -| Span-grounded mention extent doctoring | [`docs/research/span-grounded-mentions.md`](docs/research/span-grounded-mentions.md) | -| Span-grounded mention numeric provenance | [`docs/doctoring/span-grounded-mentions.md`](docs/doctoring/span-grounded-mentions.md) | -| Event-intelligence status-gate doctoring | [`docs/research/event-intelligence-status-gates.md`](docs/research/event-intelligence-status-gates.md) | -| VRAM budget / GPU fallback doctoring | [`docs/research/vram-budget-types.md`](docs/research/vram-budget-types.md) | -| Causal-identification gate doctoring | [`docs/research/causal-identification-gate.md`](docs/research/causal-identification-gate.md) | -| TDT story-segmentation `WindowDiff`/`Pk` doctoring | [`docs/research/tdt-story-segmentation.md`](docs/research/tdt-story-segmentation.md) | -| CHRONOS prediction-calibration doctoring | [`docs/research/chronos-prediction-calibration.md`](docs/research/chronos-prediction-calibration.md) | -| CHRONOS schema-slot calibration doctoring | [`docs/research/chronos-schema-slot-calibration.md`](docs/research/chronos-schema-slot-calibration.md) | -| Event-tracking calibration doctoring | [`docs/research/event-tracking-calibration.md`](docs/research/event-tracking-calibration.md) | -| Episode-membership identity doctoring | [`docs/research/episode-membership-identity.md`](docs/research/episode-membership-identity.md) | -| Entity/project target SQL doctoring | [`docs/research/entity-project-sql.md`](docs/research/entity-project-sql.md) | -| Scientific claim-promotion gate doctoring | [`docs/research/scientific-claim-promotion-gates.md`](docs/research/scientific-claim-promotion-gates.md) | -| Retention/deletion/legal-hold doctoring | [`docs/research/retention-deletion-legal-hold.md`](docs/research/retention-deletion-legal-hold.md) | -| Stopword-deletion doctoring | [`docs/research/stopword-deletion.md`](docs/research/stopword-deletion.md) | -| Provider-payload minimization doctoring | [`docs/research/provider-payload-minimization.md`](docs/research/provider-payload-minimization.md) | -| Relation absence is not negative evidence | [`docs/research/relation-absence-not-negative.md`](docs/research/relation-absence-not-negative.md) | -| Adaptive orchestration router doctoring | [`docs/research/adaptive-orchestration-router.md`](docs/research/adaptive-orchestration-router.md) | -| Hourly NIM OpenCode doctoring | [`docs/doctoring/hourly-nim-opencode-development.md`](docs/doctoring/hourly-nim-opencode-development.md) | -| Corpus-split leakage-audit wire doctoring | [`docs/research/corpus-split-manifest-wire.md`](docs/research/corpus-split-manifest-wire.md) | -| Unicode canonical-identity doctoring | [`docs/research/unicode-canonical-identity.md`](docs/research/unicode-canonical-identity.md) | -| Change history | [`CHANGELOG.md`](CHANGELOG.md) | +The implementation-maturity vocabulary is defined by [`docs/adr/ADR_POLICY.md`](docs/adr/ADR_POLICY.md), and scientific promotion evidence is governed by [`docs/TRACEABILITY.md`](docs/TRACEABILITY.md) and ADR 0014. In particular, an Accepted ADR is a decision, not proof of a shipped implementation. -## Maturity vocabulary +`docs/architecture/domain-context-map.md` owns the strategic DDD boundary vocabulary for the delivery-recovery cycle. `docs/architecture/temporal-dependence-composition.md` refines the cross-repository dependence/temporal composition boundary under ADR 0011; it cannot override the PRD, ADR 0011, or protected-main source. The dependence-family primary citations are maintained once in `docs/research/temporal-dependence-models.md`. -The canonical implementation-maturity vocabulary is defined in [`docs/adr/ADR_POLICY.md`](docs/adr/ADR_POLICY.md) and promotion evidence in [`docs/TRACEABILITY.md`](docs/TRACEABILITY.md). In particular, **an ADR with decision status `Accepted` is not automatically implemented or shipped.** +## Six-clock contract -- **implemented-main** — source is integrated on protected `main` and the relevant exact-current-head tests, scientific/recovery/validation evidence, security and supply-chain gates, and qualifying review required by live policy pass. -- **active-PR** — implementation exists only on an open PR and is not a protected-main claim. -- **partial** — an explicitly identified subset is implemented on protected main while the rest remains target work. -- **accepted-target** — accepted PRD/ADR architecture not yet integrated. -- **research-only** — evaluated research direction not accepted as production behavior. -- **out-of-scope** — explicitly outside TEPP ownership. -- **conceptual** — logical entity/service/model contract; not evidence of a migration or deployment. -- **deployment-owned** — evidence depends on a concrete deployed environment or organization and cannot be claimed by repository design alone. -- **external-assurance** — certification, attestation, legal opinion, or other independent assessment that TEPP cannot self-issue. +The canonical six temporal roles are event **or** valid time, assertion time, document time, system time, available time, and knowledge cutoff. Event instants and validity intervals are representations of the first role, not two independent analysis clocks. Historical eligibility requires available time at or before knowledge cutoff. Forward transition/state relations and retrospective/provenance relations remain distinct. ## Documentation fitness -The documentation graph is **design-sufficient** when a reviewer can reconstruct TEPP's product requirements, technical/scientific estimands, authority boundaries, temporal/event/membership semantics, data model, failure modes, security/privacy controls, validation strategy, API/integration contract, operability, research basis, ADR ownership/supersession, and release acceptance without chat history. +The graph is design-sufficient when a reviewer can reconstruct product requirements, technical/scientific estimands, DDD/service authority, temporal/event/membership semantics, data model, failure modes, security/privacy controls, validation strategy, API/integration contract, operability, research basis, ADR ownership/supersession, and release acceptance without chat history. -It is **protected-main-sufficient** only after the canonical documents are integrated on protected `main`, remain semantically current with live code, and their required exact-head documentation/security/review gates pass. An active documentation PR can therefore be design-sufficient while the protected branch remains documentation-insufficient. +It is protected-main-sufficient only after the relevant canonical documents are integrated on protected `main`, remain semantically current with live code, and their current-head documentation/security/review gates pass. Queued, stale, skipped, predecessor-head, or branch-local evidence is non-passing. \ No newline at end of file diff --git a/README.md b/README.md index e0f6b3dd2..80f59bf3d 100644 --- a/README.md +++ b/README.md @@ -1,110 +1,55 @@ # TEPP -TEPP is the **Temporal Event Psychometrics Platform**: a multilingual, temporal, -relational measurement system whose statistical and psychometric arithmetic is -implemented in Rust. - -## Current implementation state - -This branch preserves the protected-main Rust workspace and quality-gate -foundation. The workspace crates expose tested contracts only: immutable -evidence identities and exact spans, six-clock temporal values with Allen -algebra and cutoff eligibility, event mentions/instances with -evidence-layer intelligence gates, a forward-only relation graph, -cross-classified membership, bitemporal persistence, leakage-safe corpus -splits, simulation manifests, claim-promotion validation, API DTOs, the -purpose-bound privacy envelope, and longitudinal within/between -decomposition. It adds the independently usable `analysis_engine` vertical -slice: bounded cutoff-safe readiness work that emits a digest-bound terminal -artifact or a redacted no-eligible-evidence result. That slice is active-PR -evidence, not a psychometric estimator or a release claim. -The current workspace contains 50 independently documented Rust crates. Each -crate exposes a bounded, tested contract for evidence, temporal semantics, -event and relation reasoning, membership, persistence, simulation, validation, -API exchange, compute planning, or evidence-grounded interpretation. Numerical -and psychometric authority remains on the CPU `f64` reference path; streamed -accelerator plans must preserve the full observation set and fail closed to the -reference path when resources or validation are insufficient. -The repository currently implements 54 independently documented crates rather -than a full commercial release. The implemented crates include topic -measurement, the analysis engine, and psychometric input/recovery gates; they -do not claim a complete commercial estimator, -operator workspace, or supported release. - -- `topic_measurement`: the first production topic-measurement crate. It - estimates topic proportions from observed counts, maps those proportions into - additive log-ratio coordinates, and keeps posterior uncertainty attached so - later psychometric models do not treat raw topic proportions as ordinary - Euclidean indicators. -- `analysis_engine`: the first production analysis-run crate. It assembles one - cutoff-safe run from a validated design, documented evidence graph, and - estimator contract; persists the run with the six TEPP clocks; and emits a - typed terminal result. The crate does not claim buyer-visible product - completeness. -- `psychometric_core`: validated statistical-recovery APIs on already-mapped - coordinates. It does not implement a full ESEM/DSEM estimator. +[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ContextualWisdomLab/TEPP) -```text -crates/analysis_engine -crates/assertion_clock -crates/available_clock -crates/checkpoint_authority -crates/citation_edge -crates/compute_backend -crates/copied_text -crates/copy_identity -crates/corpus_background -crates/corpus_split -crates/cutoff_clock -crates/derived_sensitivity -crates/document_clocks -crates/encrypted_mapping -crates/episode_membership -crates/event_clock -crates/event_core -crates/evidence_core -crates/inferred_status -crates/intake_authorization -crates/interpretation_gateway -crates/location_membership -crates/longitudinal_core -crates/membership_core -crates/membership_target -crates/modality_source -crates/model_selection -crates/network_analysis -crates/operational_log -crates/outcome_order -crates/payload_bound -crates/persistence_postgres -crates/prediction_contradiction -crates/prompt_source -crates/provider_receipt -crates/psychometric_core -crates/psychometric_fit -crates/relation_absence -crates/relation_graph -crates/retrospective_edge -crates/revision_order -crates/role_contradiction -crates/semantic_core -crates/service_tls -crates/stopword_deletion -crates/style_source -crates/subevent_containment -crates/summarizes_edge -crates/support_edge -crates/system_clock -crates/temporal_core -crates/tepp_api -crates/tepp_simulation -crates/topic_lineage -crates/topic_measurement -crates/validation_core +**Temporal Event Psychometrics Platform for multilingual, relational, time-aware measurement.** -``` +TEPP measures documentary and event evidence as fallible observations of latent semantic, temporal, relational, and psychological structure. It preserves exact source evidence, multiple clocks, multilevel membership, measurement uncertainty, and relation history instead of flattening documents into independent rows or treating model output as scientific authority. + +Production mathematical and psychometric arithmetic belongs in Rust. Statistical claims remain gated by explicit evidence and validation contracts; LLMs may assist interpretation or proposal generation but do not become numerical estimators or claim-promotion authority. + +## Why TEPP + +Many analytical systems lose the context needed to decide whether an apparent change is real: when evidence became available, which revision was observed, which language or template expressed it, which people or organizations belonged to which groups at the time, and whether a result is measurement drift rather than substantive change. + +TEPP keeps those distinctions explicit. + +| Need | What TEPP is designed to preserve | +| --- | --- | +| Multilingual measurement | Shared concepts with language-specific expression and evidence-bound alignment | +| Time-aware analysis | Event, assertion, document, system, availability, and knowledge-cutoff clocks | +| Relational evidence | Documents, spans, events, entities, revisions, translations, citations, memberships, and provenance | +| Multilevel structure | Cross-classified and multiple membership without collapsing observations to one group | +| Measurement uncertainty | Posterior-aware and invariance-aware contracts instead of treating latent estimates as error-free scores | +| Scientific governance | Separate validation evidence, interpretation, and scientific claim promotion | +| Reproducibility | Immutable evidence identities, deterministic contracts, versioned decisions, and explicit failure boundaries | + +## Product boundary + +TEPP owns **temporal/event measurement composition**: evidence/time semantics, longitudinal and relational measurement context, analysis-run contracts, scientific validation boundaries, and the event-aware structures required to measure change responsibly. + +It does not absorb every adjacent capability: + +- [`fast-mlsirm`](https://github.com/ContextualWisdomLab/fast-mlsirm) owns reusable psychometric/static numerical kernels and model-family arithmetic that should not be duplicated here. +- [`contextual-orchestrator`](https://github.com/ContextualWisdomLab/contextual-orchestrator) owns model-provider execution, routing, credentials, and LLM orchestration. +- [`LineageWeave`](https://github.com/ContextualWisdomLab/LineageWeave) can preserve and render accepted lineage/evidence but is not TEPP's numerical authority. +- Consumer products such as Naruon own their workflow and decision semantics rather than becoming TEPP subdomains. + +Cross-product integrations must use released, versioned contracts. An open upstream branch or model response is never treated as production truth. -## Local verification +## Current maturity + +TEPP is an active technical platform under development, not a completed commercial release. Protected source contains a broad Rust-first contract foundation for evidence, temporal semantics, relations, membership, persistence, simulation, validation, API exchange, and selected analytical/recovery primitives. The approved PRD describes a larger target platform than the capabilities currently integrated and released. + +In particular, do not infer from the architecture that TEPP already ships a complete ESEM/DSEM/continuous-time estimator suite, production operator workspace, supported GPU backend, or generally available service. Candidate behavior in open pull requests remains candidate evidence until it reaches protected source through normal governance and, where applicable, a versioned release. + +The current product/technical gap and ownership evidence is maintained in [`docs/product-technical-gap-baseline.md`](docs/product-technical-gap-baseline.md). + +## Start here + +TEPP is currently consumed and developed from source; there is no generally available installation package or production endpoint advertised by this README. + +For a source checkout, verify the repository contract before relying on a branch: ```bash python3 scripts/check_workspace_contract.py @@ -121,32 +66,94 @@ cargo doc --workspace --all-features --no-deps cargo deny check ``` -Stable Rust line coverage is measured with `cargo-llvm-cov`. Branch coverage is -measured in a separately pinned nightly lane because Rust branch coverage remains -an unstable compiler capability. A zero denominator is reported explicitly for -any crate whose lane still ships no executable behavior; it must never conceal -uncovered production behavior. - -## Normative documents - -- `AGENTS.md` -- `ARCHITECTURE.md` -- `docs/product/prd-v0.4-approved.md` -- `docs/superpowers/plans/2026-08-05-temporal-event-foundation.md` -- `docs/research/standards-and-literature.md` - -No release, production-readiness, GPU, database, or statistical-recovery claim is -made by this foundation slice. - -The active stacked analysis-engine slice adds a bounded executable readiness path -from an accepted run to a digest-bound terminal artifact. It is not yet -implemented-main and does not replace scientific estimator contracts. -Validated statistical-recovery APIs exist only inside `psychometric_core`: OLS -loading recovery on already-mapped coordinates, posterior-draw point estimates, -the Rubin total-variance identity `T = U_bar + (1 + 1/m) B`, CWC/event-time/ -contextual recovery maps, and two-group OLS latent-mean comparison gated behind -typed strong/strict invariance evidence (`LatentMeanComparisonEvidence`; metric, -weak, or configural status cannot reduce to a passing flag). No release, -production-readiness, GPU, or database claim is made by this foundation slice, -and no crate yet implements a full ESEM/DSEM estimator (the two-group OLS -invariance gate is not MGCFA). +Stable Rust line coverage is measured with `cargo-llvm-cov`. Branch coverage uses a separately pinned nightly lane because Rust branch coverage remains an unstable compiler capability. A zero denominator is reported explicitly for a crate with no executable behavior; it must never hide uncovered production code. + +If you are evaluating TEPP as an integrator rather than developing the workspace, start with the product boundary and released-contract evidence rather than individual crate names. + +## Core concepts + +### Evidence before interpretation + +Source bytes, exact spans, identifiers, versions, provenance, and availability are first-class evidence. Derived fields and model outputs do not overwrite the observations that support them. + +### Six-clock temporal semantics + +TEPP distinguishes event/valid time, assertion time, document time, system time, availability time, and the analysis knowledge cutoff. Historical analyses exclude evidence that was not actually available by the declared cutoff. + +### Relational and multilevel measurement + +Documents and events can participate in revision, translation, citation, membership, project, organization, author, episode, and other time-varying relations. Membership can be cross-classified and multiple rather than forced into one hierarchy. + +### Measurement is not labeling + +A discovered topic, cluster, relation, or LLM explanation is not automatically a validated construct. Measurement invariance, uncertainty, known-truth recovery, model diagnostics, and external validity remain separate requirements appropriate to the claim being made. + +### Temporal precedence is not causality + +TEPP can preserve ordered events and analyze temporal association, but causal language requires an identified experimental, quasi-experimental, or defensible observational design. A successful API call, fit routine, or temporal ordering does not promote a causal claim. + +## Architecture at a glance + +```text +Documentary / event evidence + | + v ++-------------------------------+ +| Evidence & temporal semantics | +| exact spans / provenance | +| six clocks / cutoff rules | ++---------------+---------------+ + | + v ++-------------------------------+ +| Relational measurement layer | +| events / membership / lineage | +| multilingual measurement | ++---------------+---------------+ + | + v ++-------------------------------+ +| Analysis & validation | +| Rust numerical boundaries | +| recovery / invariance gates | ++---------------+---------------+ + | + v ++-------------------------------+ +| Evidence-grounded outputs | +| interpretation / audit | +| explicit claim authority | ++-------------------------------+ +``` + +Implementation crates are modular units inside these product responsibilities; crate count is not a customer capability metric and is intentionally not used as a maturity signal in this README. + +## Scientific and security guardrails + +TEPP is designed to fail closed when evidence, temporal identity, provenance, authorization, numerical validity, or claim-promotion requirements are absent or contradictory. The architecture deliberately separates statistical recovery from scientific acceptance and evidence-grounded interpretation from authoritative estimation. + +Production mathematical and psychometric arithmetic is Rust-owned. Python can support repository validation, interoperability, and independent-oracle testing, but does not become the production numerical core. + +Security, privacy, and access boundaries are part of the data contract: sensitive evidence is purpose-bound, consumer boundaries are explicit, and adjacent systems do not receive authority merely because they can call an API. + +## Documentation map + +Use the canonical documentation graph rather than treating this README as a complete technical specification: + +- [`DOCUMENTATION.md`](DOCUMENTATION.md) — documentation authority and navigation. +- [`ARCHITECTURE.md`](ARCHITECTURE.md) — system and bounded-context architecture. +- [`docs/product/prd-v0.4-approved.md`](docs/product/prd-v0.4-approved.md) — approved product requirements baseline. +- [`docs/architecture/domain-context-map.md`](docs/architecture/domain-context-map.md) — DDD ownership and dependency direction. +- [`docs/product-technical-gap-baseline.md`](docs/product-technical-gap-baseline.md) — current gaps, maturity, owners, and evidence limits. +- [`docs/adr/README.md`](docs/adr/README.md) — architecture decisions. +- [`docs/research/standards-and-literature.md`](docs/research/standards-and-literature.md) — standards and research basis. + +## Contributing and support + +Before changing product behavior, numerical authority, or cross-repository ownership, read [`AGENTS.md`](AGENTS.md), the architecture, applicable ADRs, and the product/technical gap baseline. Keep new behavior inside the bounded context that owns it, add executable evidence before promoting a claim, and update source, tests, documentation, and traceability together. + +Use repository issues for reproducible product defects, standards gaps, scientific-contract gaps, and integration problems. An open PR is not support evidence for a capability until it is integrated and released under the repository's normal governance. + +## License + +TEPP source and documentation are licensed under the [MIT License](LICENSE). Third-party dependencies and external services retain their own licenses and terms; commercially incompatible inbound software must not be treated as acceptable merely because TEPP itself is MIT-licensed. diff --git a/docs/adr/0004-shared-multilingual-latent-space.md b/docs/adr/0004-shared-multilingual-latent-space.md index 814998433..c50e3ef80 100644 --- a/docs/adr/0004-shared-multilingual-latent-space.md +++ b/docs/adr/0004-shared-multilingual-latent-space.md @@ -1,22 +1,7 @@ # ADR 0004 — Shared multilingual latent semantic space **Decision status:** Accepted -**Implementation maturity:** partial — default stopword-deletion refusal is `stopword_deletion` on the active PR; shared-space estimators, language profiles, and TF-IDF/BM25 inferential-weight refusal remain accepted-target -**Implementation maturity:** accepted-target — style-versus-unique-content identity in `style_source` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — modality-versus-unique-content identity in `modality_source` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — corpus-background-versus-unique-content identity in `corpus_background` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — prompt-versus-unique-content identity in `prompt_source` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — corpus-background-versus-unique-content identity in `corpus_background` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — modality-versus-unique-content identity in `modality_source` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — copied-versus-unique-content identity in `copied_text` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — style-versus-unique-content identity in `style_source` on the active PR; shared-space estimators remain accepted-target -**Decision status:** Accepted -**Implementation maturity:** accepted-target — prompt-versus-unique-content identity in `prompt_source` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — corpus-background-versus-unique-content identity in `corpus_background` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — modality-versus-unique-content identity in `modality_source` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — copied-versus-unique-content identity in `copied_text` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** accepted-target — style-versus-unique-content identity in `style_source` on the active PR; shared-space estimators remain accepted-target -**Implementation maturity:** partial — default stopword-deletion refusal is `stopword_deletion` on the active PR; shared-space estimators, language profiles, and TF-IDF/BM25 inferential-weight refusal remain accepted-target +**Implementation maturity:** partial — span/source-method refusal slices are active-PR evidence; shared-space estimators, language profiles, and TF-IDF/BM25 inferential-weight refusal remain accepted-target **Date:** 2026-08-05 **Supersedes:** None. ADR 0012 governs the complete topic-estimator/backend/global-topic contract built on this multilingual measurement decision. ADR 0020 owns the first span-grounded unit-identity slice as an active-PR; it is not shared-latent estimation. @@ -30,7 +15,7 @@ The product therefore needs a language-independent analytical contract while pre TEPP learns one shared latent semantic and topic space across languages. Equivalent meanings share concept prototypes, topic identities, and document coordinates. Language-specific morphology, script, syntax, lexical emissions, and content deviations remain explicit rather than being forced to match. -This ADR owns the multilingual measurement substrate. The product topic-estimator contract is **Temporal Relational Shared-Latent Topic Measurement (TRSL-TM)** under ADR 0012. Temporal topic identity follows the dynamic topic-model family (Blei & Lafferty, 2006). An STM-style logistic-normal document-coordinate model (Roberts et al., 2014, 2019) is the **reference family**, not a claim that every compliant backend is already shipped. Implementation maturity for this ADR and for TRSL-TM remains accepted-target. +This ADR owns the multilingual measurement substrate. The product topic-estimator contract is **Temporal Relational Shared-Latent Topic Measurement (TRSL-TM)** under ADR 0012. Temporal topic identity follows the dynamic topic-model family (Blei & Lafferty, 2006). An STM-style logistic-normal document-coordinate model (Roberts et al., 2014, 2019) is the **reference family**, not a claim that every compliant backend is already shipped. Implementation maturity remains partial: bounded refusal/identity slices exist on active PRs while shared-space estimation and language-profile validation remain accepted-target. Original text and exact source spans are preserved. Segmentation and morphology are language-tailored. Universal POS/dependency information may act as soft source evidence or priors but does not authorize irreversible deletion. LLM-proposed semantic units must resolve to exact source evidence and a versioned concept/semantic contract; unknown meaning can remain unresolved rather than being forced into a known concept. diff --git a/docs/adr/0008-immutable-evidence-identities-digests-and-spans.md b/docs/adr/0008-immutable-evidence-identities-digests-and-spans.md index e1154a991..05d33d41f 100644 --- a/docs/adr/0008-immutable-evidence-identities-digests-and-spans.md +++ b/docs/adr/0008-immutable-evidence-identities-digests-and-spans.md @@ -1,7 +1,7 @@ # ADR 0008 — Immutable evidence identities, digests, exact spans, and wire records **Decision status:** Accepted -**Implementation maturity:** implemented-main — inbound size/depth/identity/provenance refusal for untrusted documents, records, checkpoints, and LLM outputs is `payload_bound` on the active PR +**Implementation maturity:** active-PR — inbound size/depth/identity/provenance refusal for untrusted documents, records, checkpoints, and LLM outputs is `payload_bound` on active PR evidence and is not implemented-main until protected-main integration **Date:** 2026-08-05 **Decision owners:** Contextual Wisdom Lab **Supersedes:** None. ADR 0013 owns future persistence, reproducibility-manifest, and relation-aware split authority. diff --git a/docs/adr/0011-standalone-modular-msa-boundary.md b/docs/adr/0011-standalone-modular-msa-boundary.md index 89cdbee80..673ffc342 100644 --- a/docs/adr/0011-standalone-modular-msa-boundary.md +++ b/docs/adr/0011-standalone-modular-msa-boundary.md @@ -1,60 +1,73 @@ # ADR 0011 — Standalone operation and modular CWL MSA boundary -**Decision status:** Accepted -**Implementation maturity:** partial — Rust crates are independently usable; naruon HTTP interchange and loopback live listener (`POST /v1/analysis-runs` and `/v1/exports`, fail-closed table-access, NIM/proxy headers, RFC 3339 cutoff, stream deadline) is implemented-main; `service_tls` production rustls bind gates and orchestrator live-port refusal of loopback plaintext are on this active PR; the loopback consumer listener composition and terminal-result contract are composed on the active product branch; production TLS/`$PORT`, remaining live HTTP listeners, and remaining persistence integrations remain accepted-target The standalone loopback interpretation listener (`orchestrator_live`, `POST /v1/interpretation-runs`) is on this PR. +**Decision status:** Accepted +**Implementation maturity:** partial **Date:** 2026-08-10 -**Date:** 2026-08-10 -**Implementation maturity:** partial — Rust crates are independently usable; naruon HTTP interchange and loopback live listener (`POST /v1/analysis-runs` and `/v1/exports`, fail-closed table-access, NIM/proxy headers, RFC 3339 cutoff, stream deadline) are on the active PR (not implemented-main); production TLS/`$PORT` and remaining persistence integrations remain accepted-target -**Date:** 2026-08-10 -**Supersedes:** The broad cross-service ownership wording in ADR 0001. ADR 0001 remains authoritative for Rust-first numerical architecture. +**Supersedes:** The broad cross-service ownership wording in ADR 0001. ADR 0001 remains authoritative for Rust-first numerical/backend requirements. ## Context -TEPP must be independently deployable while also composing with ContextualWisdomLab services such as `naruon`, `contextual-orchestrator`, and organization control-plane workflows. Hidden database coupling or implicit cross-repository authority would make the product difficult to deploy, audit, version, acquire, or reuse. +TEPP must be independently deployable while also composing with ContextualWisdomLab services such as `naruon`, `contextual-orchestrator`, `fast-mlsirm`, and organization control-plane workflows. Hidden database coupling, copied scientific kernels, or implicit cross-repository authority would make the product difficult to deploy, audit, version, acquire, or reuse. + +The approved PRD defines TEPP's product and measurement target as multilingual temporal relational psychometrics. It does not require TEPP to duplicate reusable static psychometric kernels that have a separate canonical owner. The delivery recovery exposed both duplicated/static psychometric fragments in TEPP and an upstream `fast-mlsirm` model-specification/dependence contract under development. The ownership boundary therefore needs to be explicit without changing the approved measurement target. ## Decision -TEPP owns its evidence-domain contracts, temporal/event/membership state, psychometric/statistical model authority, model/artifact registry, run provenance, and TEPP-owned persistence. Other services integrate only through stable versioned APIs or immutable artifacts. Direct cross-service application-table reads/writes are prohibited. +TEPP owns its evidence-domain contracts, six-clock temporal semantics, event ontology and temporal graph, time-varying multilevel/cross-classified/multiple-membership composition, longitudinal invariance/drift, temporal state evolution, temporal recovery policy, TEPP model/run provenance, and TEPP-owned persistence. + +`fast-mlsirm` owns reusable static/generalized-mixed/dependence-aware psychometric model specification and reusable numerical kernels, including reusable LSIRM, MLSIRM, and DLSJM computation. TEPP consumes only released/versioned `fast-mlsirm` contracts through an anti-corruption layer and composes TEPP-owned temporal/event semantics around the full upstream candidate identity. An open upstream PR or branch is not a production dependency. + +Reusable computation discovered in TEPP that belongs to the `fast-mlsirm` domain is migrated through the canonical-owner path: establish a versioned public contract, prove numerical/recovery parity, switch TEPP to the adapter, then remove the duplicate production source. TEPP does not keep a second canonical implementation merely to avoid cross-repository work. -Standalone deployments may run CPU-only and may select local/private providers. Modular deployments preserve the same scientific and authorization contracts. +Standalone deployments may run CPU-only and may select local/private execution backends. Modular deployments preserve the same scientific, temporal, and authorization contracts. Authority boundaries: +- `fast-mlsirm` owns reusable static/generalized-mixed/dependence model specification and reusable psychometric kernels; it does not own TEPP event ontology, six-clock semantics, knowledge-cutoff policy, temporal graph, or temporal state-composition policy. - `naruon` may submit authorized evidence/analysis work and consume versioned TEPP results; it does not replace TEPP inference with lexical heuristics or directly query TEPP tables. -- `contextual-orchestrator` may execute approved model-routing/orchestration requests but does not own TEPP's source evidence, statistical truth, scientific gates, model registry, or release authority. +- `contextual-orchestrator` owns model-provider execution, routing, fallback, verifier/adjudicator execution, credentials, and model-call provenance; it does not own TEPP source evidence, numerical scientific truth, claim promotion, or release authority. - organization `.github` workflows own CI/review/security/release-control functions only; they are not runtime scientific authority. -- external PostgreSQL/object-storage/model providers remain separately authenticated trust domains. +- external PostgreSQL, object-storage, accelerator, and model-provider systems remain separately authenticated trust domains. ## Alternatives considered 1. **Shared organization database/schema** — rejected because it couples lifecycle, authorization, migrations, recovery, and acquisition boundaries. -2. **Repository-specific bespoke adapters without a common contract** — rejected because semantics drift and become difficult to validate. -3. **Standalone core plus versioned ports/artifacts** — accepted. +2. **Copy reusable psychometric kernels into TEPP** — rejected because duplicated numerical authority drifts and makes parity, recovery, and maintenance ambiguous. +3. **Repository-specific bespoke adapters without a common contract** — rejected because semantics drift and become difficult to validate. +4. **Standalone TEPP temporal/event core plus released versioned owner ports/artifacts** — accepted. ## Consequences -- Public contracts carry version, identity, provenance, error, bounded-resource, and compatibility semantics. +- Public contracts carry version, identity, provenance, error, bounded-resource, compatibility, and owner semantics. - Each service owns its credentials, migrations, retention, and application persistence. - Cross-service workflows use opaque identifiers and explicit authorization rather than implicit shared state. +- TEPP temporal dependence compilation is generic over the complete released upstream candidate identity rather than hard-coded LSIRM/MLSIRM/DLSJM family wrappers. +- Auto-expansion does not imply activation: novel combined static/dependence/temporal formulations remain `research_candidate` until equations, identification, estimator, citations, and recovery evidence are complete. - Breaking contract changes require compatibility/migration notes and an ADR where product/scientific meaning changes. -- Integration tests exercise both standalone and representative modular paths. +- Integration tests exercise standalone and representative modular paths, including contract-version/digest refusal. + +This decision clarifies service authority without changing PRD v0.4's approved product or measurement target, so it does not itself require a PRD version increment under AGENTS contract 14. ## Failure and recovery -If an integration service is unavailable, TEPP either uses an approved local/provider fallback or returns a bounded degraded/deferred state. It never fabricates external state or bypasses TEPP validation. Recovery revalidates artifact identity, authorization, temporal cutoff, and version compatibility before resuming. +If an integration service is unavailable, TEPP either uses an approved local/backend fallback that preserves the same scientific contract or returns a bounded degraded/deferred state. It never fabricates external state, copies an unreleased owner implementation, or bypasses TEPP validation. Recovery revalidates artifact identity, authorization, temporal cutoff, contract version/digest, and owner provenance before resuming. ## Security/privacy -Least-privilege service identities and purpose-bound access apply at every interface. A service receives only the evidence/artifact fields it is authorized to process. No service credential is reused as a model/reviewer/release credential simply because the services share an organization. +Least-privilege service identities and purpose-bound access apply at every interface. A service receives only the evidence/artifact fields it is authorized to process. No service credential is reused as a model/reviewer/release credential simply because the services share an organization. Cross-service SQL is prohibited. ## Compatibility and migration Every public API/artifact contract is versioned. A breaking consumer/provider change requires migration/rollback guidance and dual-version or negotiated compatibility where necessary. Persistence migrations remain TEPP-owned under ADR 0013; consumers never migrate TEPP tables directly. +Static-kernel migration follows: TEPP duplicate -> parity/recovery evidence -> released `fast-mlsirm` contract -> TEPP ACL/adaptor -> duplicate removal. Rollback restores the last released compatible adapter contract; it does not restore a divergent duplicate as canonical authority. + ## Verification -Required tests cover contract version negotiation, unauthorized cross-service access, idempotency, stale artifact/model identities, missing dependencies, standalone CPU operation, contextual-orchestrator optional integration, naruon consumer contracts, and absence of direct cross-service database coupling. +Required tests cover contract version/digest negotiation, unauthorized cross-service access, idempotency, stale artifact/model identities, missing dependencies, standalone CPU operation, contextual-orchestrator integration boundaries, naruon consumer contracts, absence of direct cross-service database coupling, and parity/recovery before any duplicated static kernel is removed. + +Architecture fitness tests must also reject dependency inversion in which `fast-mlsirm` imports TEPP temporal ontology or TEPP deployable behavior binds directly to an unreleased upstream PR head. -## Rollback and supersession +## Rollback -Rollback removes/disables an integration adapter without breaking standalone TEPP or rewriting scientific artifacts. Supersede only through an ADR that establishes a clearer ownership model without reducing standalone deployability, scientific authority separation, migration safety, or auditability. +Rollback removes or disables an integration adapter without breaking standalone TEPP or rewriting scientific artifacts. A failed owner migration returns to the last released compatible contract while retaining parity/recovery evidence and migration provenance. Supersede this ADR only through a repository-wide unique ADR that establishes a clearer ownership model without reducing standalone deployability, scientific authority separation, migration safety, or auditability. \ No newline at end of file diff --git a/docs/adr/0022-deterministic-analysis-run-execution.md b/docs/adr/0022-deterministic-analysis-run-execution.md index cb7fe646d..b67386e92 100644 --- a/docs/adr/0022-deterministic-analysis-run-execution.md +++ b/docs/adr/0022-deterministic-analysis-run-execution.md @@ -3,7 +3,7 @@ **Decision status:** Accepted **Implementation maturity:** active-PR — composed on the active product branch; not implemented-main **Date:** 2026-08-21 -**Supersedes:** None; complements ADR 0002, ADR 0003, ADR 0011, ADR 0013, and the terminal-result contract. +**Supersedes:** The pre-normalization colliding `0021-deterministic-analysis-run-execution.md` identity, whose original bytes are retained at `archive/pre-normalization-0021-deterministic-analysis-run-execution.md`; complements ADR 0002, ADR 0003, ADR 0011, ADR 0013, and the terminal-result contract. **Figma File ID:** N/A — this increment changes a Rust service crate and has no user-interface surface. **Storybook inventory:** N/A — no reusable web object or interaction changed. @@ -14,6 +14,12 @@ but a consumer needs a demonstrable path between those contracts. Without one bounded execution slice, an accepted run is only a receipt and consumers cannot verify cutoff safety, multiple-membership preservation, or artifact identity. +The branch-era decision originally reused ADR 0021, which later also identified +the LineageWeave project-history boundary. Repository-wide ADR identity cannot +be branch-local, so deterministic analysis-run execution is canonicalized as +ADR 0022 and the earlier colliding bytes are retained only as historical +provenance. + ## Decision Add the standalone `analysis_engine` Rust crate as the first executable vertical @@ -56,6 +62,8 @@ produce a consumer-verifiable terminal outcome. scientific execution would become one service boundary. 3. Add a bounded standalone engine behind the existing contracts — accepted because it is independently testable and composable without shared tables. +4. Keep both decisions under ADR 0021 — rejected because one repository-wide + architecture identity cannot denote two independent decisions. ## Consequences @@ -70,6 +78,9 @@ LineageWeave may consume the topic-lineage artifact as completed model evidence beside, but never inside, the project-history temporal-association claim. The two contracts keep separate schema identities and inference-status copy. +The archived pre-normalization ADR 0021 text is historical evidence only. New +architecture references use ADR 0022 for deterministic analysis-run execution. + ## Verification The stacked PR includes Rust unit and integration tests for cutoff exclusion, @@ -97,3 +108,7 @@ the readiness artifact while preserving the request and terminal-result DTOs. No persisted schema migration is introduced. Supersession requires a new ADR if execution changes cutoff semantics, artifact authority, privacy fields, or scientific estimands. + +Identity-normalization rollback never reuses ADR 0021 for this decision. If ADR +0022 is superseded, its number remains historical and a new ADR records the +successor. diff --git a/docs/adr/0024-lineage-pair-criterion-and-project-journey-posterior.md b/docs/adr/0024-lineage-pair-criterion-and-project-journey-posterior.md deleted file mode 100644 index 19ec5fcb2..000000000 --- a/docs/adr/0024-lineage-pair-criterion-and-project-journey-posterior.md +++ /dev/null @@ -1,128 +0,0 @@ -# ADR 0024 — Independent lineage-pair criterion and posterior Project Journey - -**Decision status:** Proposed -**Implementation maturity:** active-PR — strict wire contracts and Rust CPU independent-criterion estimator -**Date:** 2026-08-26 -**Supersedes:** None; narrows ADR 0016 and complements ADR 0021. - -## Context - -Event-Lineage channel weights require an independent pair-level criterion; -channel covariance, a fusion floor, keywords, or one run-level accepted flag do -not identify it. Project Journey cannot treat the earliest stored record or a -fixed sales lifecycle as its start: prior projects, customer requests, -procurement notices, direct or negotiated bids, external sensing, internal -discussions, and leads can be concurrent, uncertain, or branching. - -## Decision - -TEPP publishes `tepp.lineage_pair_criterion_posterior.v2` with bijective pair -identity, continuous criterion draws, separate record and event-time draws, -TDT/CHRONOS provenance, unique independent anchor alignment, and CPU/GPU -receipts over the same objective, parameters, and draws. On Apple Silicon the -accelerator receipt is `mlx_metal_macos_native`: Rust remains the computation -and validation authority. MLX Metal executes only in a macOS-native Rust-owned -service; Compose reaches it through an authenticated local Unix socket or an -authenticated host-gateway adapter. It never runs inside Colima's Linux VM. -Python never owns or reproduces the arithmetic. Linux container/CI may record -MLX CPU or CUDA only when that backend actually ran; it may never emit Metal. -The CPU f64 path is an explicitly tested portability/reference fallback, not a -silent replacement for a missing MLX execution. The parity bound is -method-derived by the producer; a consumer may not choose or repair it. - -TEPP separately publishes `tepp.project_journey_posterior.v1`. It retains every -event in stable identity order and every posterior temporal dependency, branch, -and transition draw. It has no start stage, earliest-row selection, total -ordering, rank, or causal status. Multiple predecessors and exact ties remain -first-class. - -The Rust CHRONOS relation slice compares common event-time draws directly and -publishes the complete `before`/`simultaneous`/`after` draw sequence and its -posterior frequencies. It estimates no timestamp, uses no tolerance or nearest -date, preserves exact ties, and cannot promote a predicted event into fact. -An owning estimator may hand the Rust core an identified discrete event-time -posterior as unique atoms with integer multiplicities. The core canonicalizes -and materializes that mass exactly; zero mass and duplicate atoms fail closed. -This operation does not estimate atom locations or posterior mass. - -For an independently observed binary TDT link criterion, the Rust scientific -core fits the Bernoulli likelihood with Jeffreys' invariant -`Beta(1/2, 1/2)` prior and emits posterior mean, variance, and deterministic -midpoint-quantile quadrature draws. This is not a thresholded channel score. -It does not turn a CHRONOS forecast into a fact, and it carries rather than -invents the temporal model's event-time draws. - -## Verification and invariants - -- record time never substitutes for event time; -- present transition draws never move backward in event time; -- anchor ties, mixed draw counts, missing evidence, non-finite draws, and - CPU/MLX digest or parity failures fail closed; -- synthetic tests cover record/event disagreement, multiple predecessors, - branches, ties, uncertain relations, backward-edge refusal, anchor ambiguity, - and hardware-receipt divergence. - -The Rust CPU independent-criterion estimator, exact event-time posterior -materializer, and qualitative temporal-relation posterior have deterministic -synthetic exact-recovery tests. Estimation of event-time atom locations and -mass, artifact assembly with estimator-bound MLX execution, and hardware parity -remain unavailable until their owning implementations and receipts pass the -same gates. - -`analysis_engine::fit_exhaustive_case_deletion` is the normative producer -orchestration prerequisite: it invokes one scientific fitter on `D` and every -actual `D \ {i}` retained set with mutually domain-separated randomness -identities, preserving deleted and retained document identities. It performs -no posterior reweighting or approximation. This runner does not make the topic -artifact available until a topic likelihood fitter, anchor alignment, incident -relation/membership removal receipts, and estimator-bound CPU/accelerator -receipts are connected. - -## Alternatives considered - -1. Earliest record as project start — rejected because reporting delay changes - the journey. -2. One fixed lifecycle — rejected because evidence forms different DAGs. -3. Threshold similarity into criterion truth — rejected as circular. -4. Posterior clocks and graph relations with independent criterion evidence — - accepted. - -## Consequences and trade-offs - -Consumers can render branches and uncertainty without local inference. -Artifacts are larger because draws, not point labels, cross the boundary. Until -the scientific producer exists, the capability remains unavailable. - -## Failure, recovery, security, and privacy - -Malformed, oversized, mixed-provenance, ambiguous, temporally reversed, or -hardware-divergent artifacts return redacted errors. A missing native Metal -receipt on Apple Silicon is unavailable; recovery is replay from -the owning fitted run; no consumer repair is permitted. Only opaque identities -and digests cross the contract. - -## Rollback and compatibility - -Both schemas are additive. Existing deterministic project history v1 is not -reinterpreted as posterior Journey evidence. Rollback disables the new adapter -and retains immutable artifacts. Estimator-target or temporal-semantics changes -require a superseding ADR and PRD version. - -## References - -Allan, J. (Ed.). (2002). *Topic detection and tracking: Event-based information -organization*. Kluwer Academic Publishers. - -Anagnostopoulos, E., Batsakis, S., & Petrakis, E. G. M. (2013). CHRONOS: A -reasoning engine for qualitative temporal information in OWL. *Procedia -Computer Science, 22*, 70–77. https://doi.org/10.1016/j.procs.2013.09.082 - -Li, M., Li, S., Wang, Z., Huang, L., Cho, K., Ji, H., Han, J., & Voss, C. -(2021). The future is not one-dimensional: Complex event schema induction by -graph modeling for event prediction. In *Proceedings of EMNLP 2021* (pp. -5203–5215). https://doi.org/10.18653/v1/2021.emnlp-main.422 - -Jeffreys, H. (1946). An invariant form for the prior probability in estimation -problems. *Proceedings of the Royal Society of London. Series A, Mathematical -and Physical Sciences, 186*(1007), 453–461. -https://doi.org/10.1098/rspa.1946.0056 diff --git a/docs/adr/0026-lineage-pair-criterion-and-project-journey-posterior.md b/docs/adr/0026-lineage-pair-criterion-and-project-journey-posterior.md new file mode 100644 index 000000000..c847cd5e1 --- /dev/null +++ b/docs/adr/0026-lineage-pair-criterion-and-project-journey-posterior.md @@ -0,0 +1,67 @@ +# ADR 0026 — Independent lineage-pair criterion and posterior Project Journey + +**Decision status:** Proposed +**Implementation maturity:** active-PR — strict wire contracts and Rust CPU independent-criterion estimator +**Date:** 2026-08-26 +**Supersedes:** The pre-normalization colliding identity `0024-lineage-pair-criterion-and-project-journey-posterior.md`; ADR 0024 remains the earlier posterior topic-context producer decision. This ADR narrows ADR 0016 and complements ADR 0021. + +## Context + +Event-Lineage channel weights require an independent pair-level criterion; channel covariance, a fusion floor, keywords, or one run-level accepted flag do not identify it. Project Journey cannot treat the earliest stored record or a fixed sales lifecycle as its start: prior projects, customer requests, procurement notices, direct or negotiated bids, external sensing, internal discussions, and leads can be concurrent, uncertain, or branching. + +The previous branch-local numbering collided with the already-existing ADR 0024 posterior topic-context producer contract. Architecture decision identity is repository-wide, so this genuinely distinct later decision is renumbered to ADR 0026 rather than sharing a numeric identity. + +## Decision + +TEPP publishes `tepp.lineage_pair_criterion_posterior.v2` with bijective pair identity, continuous criterion draws, separate record and event-time draws, TDT/CHRONOS provenance, unique independent anchor alignment, and CPU/GPU receipts over the same objective, parameters, and draws. On Apple Silicon the accelerator receipt is `mlx_metal_macos_native`: Rust remains the computation and validation authority. MLX Metal executes only in a macOS-native Rust-owned service; Compose reaches it through an authenticated local Unix socket or an authenticated host-gateway adapter. It never runs inside Colima's Linux VM. Python never owns or reproduces the arithmetic. Linux container/CI may record MLX CPU or CUDA only when that backend actually ran; it may never emit Metal. The CPU f64 path is an explicitly tested portability/reference fallback, not a silent replacement for a missing MLX execution. The parity bound is method-derived by the producer; a consumer may not choose or repair it. + +TEPP separately publishes `tepp.project_journey_posterior.v1`. It retains every event in deterministic, non-semantic identity serialization order and every posterior temporal dependency, branch, and transition draw. That serialization order exists only so identical artifacts produce identical bytes; consumers must not interpret it as temporal order, causal order, rank, priority, or evidence strength. The artifact has no start stage, earliest-row selection, total ordering, rank, or causal status. Multiple predecessors and exact ties remain first-class. + +The Rust CHRONOS relation slice compares common event-time draws directly and publishes the complete `before`/`simultaneous`/`after` draw sequence and its posterior frequencies. It estimates no timestamp, uses no tolerance or nearest date, preserves exact ties, and cannot promote a predicted event into fact. An owning estimator may hand the Rust core an identified discrete event-time posterior as unique atoms with integer multiplicities. The core canonicalizes and materializes that mass exactly; zero mass and duplicate atoms fail closed. This operation does not estimate atom locations or posterior mass. + +For an independently observed binary TDT link criterion, the Rust scientific core fits the Bernoulli likelihood with Jeffreys' invariant `Beta(1/2, 1/2)` prior and emits posterior mean, variance, and deterministic midpoint-quantile quadrature draws. This is not a thresholded channel score. It does not turn a CHRONOS forecast into a fact, and it carries rather than invents the temporal model's event-time draws. + +## Verification and invariants + +- record time never substitutes for event time; +- present transition draws never move backward in event time; +- anchor ties, mixed draw counts, missing evidence, non-finite draws, and CPU/MLX digest or parity failures fail closed; +- synthetic tests cover record/event disagreement, multiple predecessors, branches, ties, uncertain relations, backward-edge refusal, anchor ambiguity, and hardware-receipt divergence. + +The Rust CPU independent-criterion estimator, exact event-time posterior materializer, and qualitative temporal-relation posterior have deterministic synthetic exact-recovery tests. Estimation of event-time atom locations and mass, artifact assembly with estimator-bound MLX execution, and hardware parity remain unavailable until their owning implementations and receipts pass the same gates. + +`analysis_engine::fit_exhaustive_case_deletion` is the normative producer orchestration prerequisite: it invokes one scientific fitter on `D` and every actual `D \ {i}` retained set with mutually domain-separated randomness identities, preserving deleted and retained document identities. It performs no posterior reweighting or approximation. This runner does not make the topic artifact available until a topic likelihood fitter, anchor alignment, incident relation/membership removal receipts, and estimator-bound CPU/accelerator receipts are connected. + +## Alternatives considered + +1. Earliest record as project start — rejected because reporting delay changes the journey. +2. One fixed lifecycle — rejected because evidence forms different DAGs. +3. Threshold similarity into criterion truth — rejected as circular. +4. Posterior clocks and graph relations with independent criterion evidence — accepted. +5. Keep the colliding ADR 0024 number — rejected because repository-wide architecture authority requires one immutable identity per decision. + +## Consequences and trade-offs + +Consumers can render branches and uncertainty without local inference. Artifacts are larger because draws, not point labels, cross the boundary. Until the scientific producer exists, the capability remains unavailable. + +Historic branches or discussions that refer to `0024-lineage-pair-criterion-and-project-journey-posterior.md` remain provenance only; new canonical references use ADR 0026. The unrelated ADR 0024 posterior topic-context producer identity is unchanged. + +## Failure, recovery, security, and privacy + +Malformed, oversized, mixed-provenance, ambiguous, temporally reversed, or hardware-divergent artifacts return redacted errors. A missing native Metal receipt on Apple Silicon is unavailable; recovery is replay from the owning fitted run; no consumer repair is permitted. Identity-bearing references and error responses expose only opaque identifiers or digests. The versioned scientific payload still carries the schema-authorized posterior draws, relation sequences, frequencies, uncertainty, and execution receipts required by this decision; the opaque-identity rule does not erase those measurement fields or convert the wire contract into an identity-only envelope. + +## Rollback and compatibility + +Both schemas are additive. Existing deterministic project history v1 is not reinterpreted as posterior Journey evidence. Rollback disables the new adapter and retains immutable artifacts. Estimator-target or temporal-semantics changes require a superseding ADR and PRD version. + +Renumbering rollback does not reuse ADR 0024 for this decision; if ADR 0026 is rejected or superseded, its identity remains historical and a new repository-wide ADR records the successor. + +## References + +Allan, J. (Ed.). (2002). *Topic detection and tracking: Event-based information organization*. Kluwer Academic Publishers. + +Anagnostopoulos, E., Batsakis, S., & Petrakis, E. G. M. (2013). CHRONOS: A reasoning engine for qualitative temporal information in OWL. *Procedia Computer Science, 22*, 70–77. https://doi.org/10.1016/j.procs.2013.09.082 + +Li, M., Li, S., Wang, Z., Huang, L., Cho, K., Ji, H., Han, J., & Voss, C. (2021). The future is not one-dimensional: Complex event schema induction by graph modeling for event prediction. In *Proceedings of EMNLP 2021* (pp. 5203–5215). https://doi.org/10.18653/v1/2021.emnlp-main.422 + +Jeffreys, H. (1946). An invariant form for the prior probability in estimation problems. *Proceedings of the Royal Society of London. Series A, Mathematical and Physical Sciences, 186*(1007), 453–461. https://doi.org/10.1098/rspa.1946.0056 diff --git a/docs/adr/README.md b/docs/adr/README.md index 1254c8079..19471a2b1 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -1,148 +1,78 @@ # Architecture Decision Records -TEPP uses numbered ADRs for decisions that constrain latent-variable meaning, temporal semantics, event ontology, multilingual measurement, numerical backends, privacy/security, persistence, orchestration, automation authority, scientific claims, and modular service boundaries. +TEPP uses repository-wide numbered ADR identities for decisions that constrain latent-variable meaning, temporal semantics, event ontology, multilingual measurement, numerical backends, privacy/security, persistence, orchestration, automation authority, scientific claims, and modular service boundaries. -Read [`ADR_POLICY.md`](ADR_POLICY.md) first. **Decision status and implementation maturity are independent. `Accepted` means the architecture decision is authoritative; it does not mean the capability is implemented or released.** +Read [`ADR_POLICY.md`](ADR_POLICY.md) first. **Decision status and implementation maturity are independent. `Accepted` means the architecture decision is authoritative; it does not mean the capability is implemented or released.** One ADR identity appears exactly once in this index and exactly once in the numbered root of `docs/adr/`. Branch-local implementation slices update implementation evidence for the owning ADR rather than minting a second row for the same decision. | ADR | Decision | Decision status | Implementation maturity | Clarification / supersession | |---|---|---|---|---| -| [0001](0001-rust-first-modular-msa.md) | Rust-first numerical core and CPU `f64` reference | Accepted | partial | Rust owns production arithmetic and the CPU reference; GPU and estimator completion remain target work. | -| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical eligibility | Accepted | partial | Protected main owns typed clocks and Allen algebra; the active consolidation PR carries clock identity, availability/cutoff, revision, provenance, and ordering gates. | -| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying multiple membership | Accepted | partial | Protected main owns the membership network and forward-transition foundation; the active consolidation PR carries typed target and identity slices. Full multilevel/MMMC estimators and persistence remain target work. | -| [0004](0004-shared-multilingual-latent-space.md) | Shared multilingual latent semantic space | Accepted | accepted-target | Shared-space estimation and measurement invariance remain the scientific target; ADR 0020 owns span-grounded units. | -| [0005](0005-posterior-esem-dsem.md) | Posterior-aware ESEM/DSEM and compositional coordinates | Accepted | active-PR | CPU `f64` fit and longitudinal within/between slices are active; invariance and multilevel estimators remain target work. | -| [0006](0006-vram-gpu-nvidia-orchestration.md) | VRAM-adaptive GPU compute and credential boundary | Accepted | accepted-target | GPU streaming/parity and backend completion remain target work; orchestration policy belongs to ADR 0010. | -| [0007](0007-rust-workspace-quality-gates.md) | Rust workspace, toolchain, and quality gates | Accepted | implemented-main | Repository quality contracts are implemented; scientific claim promotion belongs to ADR 0014. | -| [0008](0008-immutable-evidence-identities-digests-and-spans.md) | Immutable evidence identities, digests, spans, and wire reconstruction | Accepted | partial | Identity and span contracts are implemented-main; untrusted payload bounds are active in the consolidation PR. | -| [0009](0009-purpose-bound-pii-governance.md) | Purpose-bound PII governance without blanket masking | Accepted | partial | Opaque analytical IDs, purpose grants, provider minimization, retention, and encrypted mapping are covered; deployment evidence and persistent access storage remain target work. | -| [0010](0010-adaptive-llm-orchestration.md) | Adaptive LLM orchestration and test-time compute | Accepted | partial | Direct/verify/committee routing and ablation contracts exist; live provider execution and production calibration remain target work. | -| [0011](0011-standalone-modular-msa-boundary.md) | Standalone operation and modular CWL MSA boundary | Accepted | partial | Versioned service boundaries and credential separation are authoritative; production TLS and live ports remain target work. | -| [0012](0012-temporal-relational-shared-latent-topic-measurement.md) | Temporal relational shared-latent topic measurement | Accepted | partial | Coordinates and the CPU `f64` reference estimator are implemented-main; fitted candidate-`K` scoring is this PR; method effects and GPU remain accepted-target. | -| [0013](0013-bitemporal-persistence-reproducibility-and-split-authority.md) | Bitemporal persistence, reproducibility, and split authority | Accepted | partial | Migration, tenant, append-only, interval, and live SQL contracts are present; physical ERD and recovery depth remain target work. | -| [0014](0014-scientific-claim-promotion-and-release-evidence.md) | Scientific claim promotion and release evidence | Accepted | partial | Exact-head promotion authority and repository evidence exist; the complete release bundle remains target work. | -| [0015](0015-autonomous-development-review-and-merge-authority.md) | Autonomous development, review, and merge authority separation | Accepted | active-PR | Proposal, deterministic verification, publication, independent review, and merge/release authority remain separate. | -| [0016](0016-tdt-chronos-event-intelligence-boundary.md) | TDT, CHRONOS, and event-intelligence boundary | Accepted | active-PR | Span-grounded mentions with exact-extent recovery are active on this PR; unified TDT/CHRONOS workflow, interval consistency, persistence, and exports remain target work. | -| [0017](0017-hourly-contextual-orchestrator-gateway.md) | Hourly contextual-orchestrator gateway and provider discovery | Accepted | active-PR | Proposal-model execution is pinned behind a loopback gateway and remains separate from verification and merge authority. | -| [0018](0018-consumer-scoped-analysis-run-ingress.md) | Consumer-scoped modular analysis-run ingress | Accepted | active-PR | Closed consumer registry, credential-free exchange, and consumer-qualified idempotency are active. | -| [0019](0019-project-history-wire-size-symmetry.md) | Symmetric LineageWeave project-history wire-size enforcement | Accepted | active-PR | Request serialization and generated project-history projections share bounded size rules. | -| [0020](0020-span-grounded-semantic-units.md) | Span-grounded semantic units; language tags are not identity | Accepted | active-PR | First ADR 0004 production slice; concept alignment, invariance, and topic estimation are not claimed. | -| [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. | -| [0024](0024-lineage-pair-criterion-and-project-journey-posterior.md) | Independent Event Lineage pair criterion and posterior Project Journey | Proposed | active-PR | Strict artifacts preserve criterion/event-time draws, branches, ties, and CPU/GPU receipts without claiming the scientific estimator is complete. | -| [0025](0025-macos-native-rust-mlx-metal-boundary.md) | macOS-native Rust-owned MLX Metal execution | Accepted | accepted-target | Compose authenticates to a native host service; Linux never claims Metal, and actual backend/parity receipts fail closed. | -| [0023](0023-lineage-criterion-anchor-contract.md) | TEPP-owned Event Lineage criterion anchor | Accepted | active-PR | PR #237 publishes the strict accepted/rejected artifact and identities; estimator execution remains fail-closed future work. | -| [0024](0024-independent-topic-importance-anchor.md) | Posterior topic-context producer contract | Accepted | contract-only active-PR | Strict DTO/schema only; the current estimator does not emit it. fast-mlsirm owns case-deletion influence. | -| [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); customer/competitor contradiction is `role_contradiction` on this 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); absence-is-not-negative identity is `relation_absence` on this 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. | -| [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. | -| [0006](0006-vram-gpu-nvidia-orchestration.md) | VRAM-adaptive GPU compute and model-credential boundary | Accepted | accepted-target | LLM orchestration policy superseded by ADR 0010; autonomous development authority governed by ADR 0015. | -| [0007](0007-rust-workspace-quality-gates.md) | Explicit Rust workspace, pinned toolchains, and exact quality gates | Accepted | implemented-main | ADR 0014 governs scientific/product claim promotion beyond repository-quality tooling. | -| [0008](0008-immutable-evidence-identities-digests-and-spans.md) | Immutable evidence identities, `SHA-256` digests, exact spans, and strict wire reconstruction | Accepted | implemented-main | ADR 0013 governs future persistence/reproducibility/split authority. | -| [0005](0005-posterior-esem-dsem.md) | Posterior-aware ESEM/DSEM and valid compositional coordinates | Accepted | partial | Input gates, posterior-draw point estimates, Rubin `T` on OLS loadings, CWC within/between OLS plus the contextual effect, event-time log-rate, constant- and time-varying-predictor discrete effects, exact scalar discrete process noise, lagged latent covariance and unconditional latent variance, stationary within-subject variance (`asymDIFFUSION`), trait-plus-state variance (`TRAITVAR`; not process noise), observed-indicator variance and lagged observed covariance (Eq. 5; Table 2 `MANIFESTVAR` is `Θ`, not `Var(y)`; `MANIFESTTRAITVAR` is not `MANIFESTVAR`; `Θ` does not enter lagged observed covariance; observed-indicator mean is `τ + λ μ`; `MANIFESTMEANS` is not `E(y)`; `CINT` is not `MANIFESTMEANS`; discrete latent mean is `exp(a Δt) μ_0 + (exp(a Δt) − 1)/a κ`; `T0MEANS` is not `μ_t`; evolved observed mean is `τ + λ μ_t`; `τ + λ μ_0` is not `E(y_t)`; Eq. 5 of the contemporaneous impulse is `τ + λ(μ_t + m x)`; `τ + λ μ_t` is not that observed mean; Eq. 5 of the time-independent predictor is `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)`; `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that observed mean; `τ + λ(μ_t + e^{a(t−u)} m x)` is not that observed mean when `u ≠ t`; Eq. 5 of the within-interval impulse carry is `τ + λ(μ_t + e^{a(t−u)} m x)`; `τ + λ μ_t` is not that observed mean; `τ + λ(μ_t + m x)` is not that carried observed mean when `u ≠ t`; Table 2 `asymCINT` is `-κ / a` for `a < 0` and is not `κ`, not the finite-interval increment, not `T0MEANS`, and not `-B z / a`; p. 16 stationary `T0MEANS` is `-κ / a + −B z / a` and is not free `T0MEANS`, not `asymCINT` alone, not `asymTIPREDEFFECT` alone, and not the finite-interval discrete latent mean; Eq. 5 of that constrained mean is `τ + λ(−κ / a + −B z / a)` (`τ + λ μ_0` is not that observed mean; `MANIFESTMEANS` is not `E(y_0)`); stationary `T0VAR` is `trait + −q / (2 a) + (B / a)² v` (not free `T0VAR`, not `asymDIFFUSION` alone, not `TRAITVAR` alone, not `addedTIPREDVAR` alone; Eq. 5 is `λ²(trait + −q / (2 a) + (B / a)² v) + θ + ψ` (`λ² p_0` is not `Var(y_0)`; `λ²(−q / (2 a)) + θ` is not `Var(y_0)` when trait or TI is nonzero; `MANIFESTVAR` is not `Var(y_0)`; the constrained latent variance is not `Var(y_0)`)); §7.2 `addedTIPREDVAR` is `(B / a)² v` and is not `TRAITVAR`, not `asymDIFFUSION`, and not `-B z / a`), irregular already-centered residual lag, and strong-gated latent means are on the stacked psychometric PR; full ESEM/DSEM estimator remains accepted-target. | -| [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; within/between decomposition in `longitudinal_core` is on the active PR; invariance/multilevel and remaining ESEM/DSEM fit remain accepted-target. ADR 0012 owns the upstream topic/network contract. | -| [0006](0006-vram-gpu-nvidia-orchestration.md) | VRAM-adaptive GPU compute and model-credential boundary | Accepted | accepted-target | LLM orchestration policy superseded by ADR 0010; autonomous development authority governed by ADR 0015. | -| [0007](0007-rust-workspace-quality-gates.md) | Explicit Rust workspace, pinned toolchains, and exact quality gates | Accepted | implemented-main | ADR 0014 governs scientific/product claim promotion beyond repository-quality tooling. | -| [0008](0008-immutable-evidence-identities-digests-and-spans.md) | Immutable evidence identities, `SHA-256` digests, exact spans, and strict wire reconstruction | Accepted | implemented-main | Identities/spans are implemented-main; inbound size/depth/identity/provenance refusal is `payload_bound` on the active PR. ADR 0013 governs persistence/split authority. | -| [0009](0009-purpose-bound-pii-governance.md) | Purpose-bound PII governance without blanket masking | Accepted | partial | Persistence retention/deletion/legal-hold (`0007`) and provider-payload minimization are implemented-main; authorization/export and deployment evidence remain accepted-target. | -| [0009](0009-purpose-bound-pii-governance.md) | Purpose-bound PII governance without blanket masking | Accepted | partial | Persistence retention/deletion/legal-hold (`0007`) and provider-payload minimization are implemented-main; untrusted-intake grant presence is `intake_authorization` on the active PR; deployment evidence remains accepted-target. | -| [0009](0009-purpose-bound-pii-governance.md) | Purpose-bound PII governance without blanket masking | Accepted | active-PR | `encrypted_mapping` AES-256-GCM envelope on the active PR; persistence retention/deletion/legal-hold (`0007`) and provider-payload minimization are implemented-main; persistence/KMS and remaining adapters stay accepted-target. Controls are not a certification claim. | -| [0009](0009-purpose-bound-pii-governance.md) | Purpose-bound PII governance without blanket masking | Accepted | partial | Retention/deletion/legal-hold and provider-payload minimization are implemented-main; provider-disclosure receipts are active-PR; deployment evidence remains accepted-target. | -| [0009](0009-purpose-bound-pii-governance.md) | Purpose-bound PII governance without blanket masking | Accepted | active-PR | Persistence retention/deletion/legal-hold (`0007`) and provider-payload minimization are implemented-main; `operational_log::try_record` and inspected `audit_event` inserts are on the active PR; tenant/purpose/role/lifetime storage, live HTTP, and certification evidence remain accepted-target. | -| [0010](0010-adaptive-llm-orchestration.md) | Adaptive LLM orchestration and test-time compute | Accepted | partial | `tepp_api` router/ablation/orchestrator binding are implemented-main; live NIM execution and production ablation evidence remain accepted-target. | -| [0010](0010-adaptive-llm-orchestration.md) | Adaptive LLM orchestration and test-time compute | Accepted | partial | `tepp_api` router/ablation/orchestrator binding are implemented-main; the `orchestrator_live` loopback interpretation listener is on this PR; live NIM execution, TLS, and production ablation evidence remain accepted-target. | -| [0009](0009-purpose-bound-pii-governance.md) | Purpose-bound PII governance without blanket masking | Accepted | active-PR | Persistence retention/deletion/legal-hold (`0007`) and provider-payload minimization implemented-main; `derived_sensitivity` inheritance on the active PR; deployment evidence remains accepted-target. | -| [0010](0010-adaptive-llm-orchestration.md) | Adaptive LLM orchestration and test-time compute | Accepted | partial | `tepp_api` router/ablation/orchestrator binding on the active PR; live NIM execution and production ablation evidence remain accepted-target. | -| [0011](0011-standalone-modular-msa-boundary.md) | Standalone operation and modular CWL MSA boundary | Accepted | partial | Owns cross-service persistence/credential/API authority; `service_tls` production bind gates are on the active PR; no direct cross-service application-table coupling. | -| [0011](0011-standalone-modular-msa-boundary.md) | Standalone operation and modular CWL MSA boundary | Accepted | partial | Owns cross-service persistence/credential/API authority; naruon interchange implemented-main and the `orchestrator_live` loopback interpretation HTTP/1.1 listener is on this PR; no direct cross-service application-table coupling. | -| [0009](0009-purpose-bound-pii-governance.md) | Purpose-bound PII governance without blanket masking | Accepted | partial | Persistence retention/deletion/legal-hold (`0007`) and provider-payload minimization implemented-main; deployment evidence remains accepted-target. | -| [0010](0010-adaptive-llm-orchestration.md) | Adaptive LLM orchestration and test-time compute | Accepted | partial | `tepp_api` router/ablation/orchestrator binding implemented-main; live NIM execution and production ablation evidence remain accepted-target. | -| [0011](0011-standalone-modular-msa-boundary.md) | Standalone operation and modular CWL MSA boundary | Accepted | partial | Owns cross-service persistence/credential/API authority; no direct cross-service application-table coupling. | -| [0012](0012-temporal-relational-shared-latent-topic-measurement.md) | Temporal Relational Shared-Latent Topic Measurement (TRSL-TM) | Accepted | partial | Coordinates and the CPU `f64` reference estimator are implemented-main; fitted candidate-`K` scoring is this PR; method effects and GPU remain accepted-target. | -| [0013](0013-bitemporal-persistence-reproducibility-and-split-authority.md) | Bitemporal persistence, reproducibility manifests, and relation-aware split authority | Accepted | partial | Owns PostgreSQL adapter semantics, immutable run/split manifests, leakage-safe partitions, and recovery identity; optional `live-sqlx` `PgPool`, live PG CI, tenant RLS, and `0006` membership implemented-main; `0007` retention/deletion/legal-hold on the active PR; remaining physical ERD/backup accepted-target. | -| [0014](0014-scientific-claim-promotion-and-release-evidence.md) | Scientific claim promotion and release evidence authority | Accepted | partial | Separates design, implementation, scientific/product claim, and release authority; repository SBOM/provenance generator implemented; checkpoint-versus-estimator refusal is `checkpoint_authority` on the active PR; full release bundle remaining. | -| [0015](0015-autonomous-development-review-and-merge-authority.md) | Autonomous development, review, and merge authority separation | Accepted | active-PR | Separates model proposal, deterministic verification, publication, independent review, and merge/release authority. | -| [0016](0016-tdt-chronos-event-intelligence-boundary.md) | TDT, CHRONOS, and Event Ontology intelligence boundary | Accepted | active-PR | TDT link precision/recall in existing `event_core`; remaining TDT/CHRONOS stack remains accepted-target. | -| [0016](0016-tdt-chronos-event-intelligence-boundary.md) | TDT, CHRONOS, and Event Ontology intelligence boundary | Accepted | accepted-target | Separates observed evidence, detection/tracking, prediction/schema inference, temporal consistency, and promoted transition authority. | -| [0021](0021-deterministic-analysis-run-execution.md) | Deterministic cutoff-safe analysis-run execution | Accepted | active-PR | Stacked on PR #157; closes the first executable buyer path from accepted run to digest-bound terminal result without claiming estimator authority. | -| [0016](0016-tdt-chronos-event-intelligence-boundary.md) | TDT, CHRONOS, and Event Ontology intelligence boundary | Accepted | active-PR | First-story FAR/miss in existing `event_core`; remaining TDT/CHRONOS stack remains accepted-target. | -| [0020](0020-span-grounded-semantic-units.md) | Span-grounded semantic units; language tags are not identity | Accepted | active-PR | First ADR 0004 production slice. Does not claim concept alignment, invariance, or a topic estimator. | -| [0017](0017-hourly-contextual-orchestrator-gateway.md) | Hourly contextual-orchestrator gateway and all-provider model discovery | Accepted | active-PR | Keeps proposal-model execution behind a pinned loopback gateway while preserving independent verifier, publisher, reviewer, and merge authority. | -| [0018](0018-consumer-scoped-analysis-run-ingress.md) | Consumer-scoped modular analysis-run ingress | Accepted | active-PR | Narrows ADR 0011 for the closed consumer registry, credential-free exchange, and consumer-qualified idempotency namespace; production TLS remains separate. | -| [0019](0019-project-history-wire-size-symmetry.md) | Symmetric project-history wire-size enforcement | Accepted | active-PR | Narrows ADR 0008 for request serialization and generated LineageWeave project-history projections. | -| [0021](0021-lineageweave-project-history-boundary.md) | LineageWeave project-history service boundary | Accepted | active-PR | Narrows ADR 0011 for the credential-free bounded project-history API and 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 | Owns production arithmetic and reference-backend authority; ADR 0011 owns cross-service boundaries. | +| [0002](0002-six-clock-temporal-semantics.md) | Six-clock temporal semantics and fail-closed historical eligibility | Accepted | partial | Owns event/valid, assertion, document, system, available, and knowledge-cutoff semantics plus temporal eligibility. | +| [0003](0003-relational-event-multiple-membership.md) | Relational event ontology and time-varying cross-classified multiple membership | Accepted | partial | Owns event/relation/membership semantics; full multilevel estimators and persistence remain separate implementation work. | +| [0004](0004-shared-multilingual-latent-space.md) | Shared multilingual latent semantic space | Accepted | partial | Owns multilingual latent-space and invariance intent; ADR 0020 owns span-grounded semantic-unit identity. | +| [0005](0005-posterior-esem-dsem.md) | Posterior-aware ESEM/DSEM and compositional coordinates | Accepted | partial | Owns longitudinal psychometric interpretation; reusable static kernels migrate to their canonical owner when applicable. | +| [0006](0006-vram-gpu-nvidia-orchestration.md) | VRAM-adaptive GPU compute and credential boundary | Accepted | active-PR | Owns compute-backend/VRAM policy; LLM orchestration belongs to ADR 0010. | +| [0007](0007-rust-workspace-quality-gates.md) | Rust workspace, toolchain, and quality gates | Accepted | implemented-main | Owns repository quality tooling; scientific claim promotion belongs to ADR 0014. | +| [0008](0008-immutable-evidence-identities-digests-and-spans.md) | Immutable evidence identities, digests, spans, and wire reconstruction | Accepted | active-PR | Owns source-evidence identity and bounded reconstruction; persistence authority belongs to ADR 0013. | +| [0009](0009-purpose-bound-pii-governance.md) | Purpose-bound PII governance without blanket masking | Accepted | partial | Owns purpose-bound disclosure and re-identification controls; implementation evidence does not imply certification. | +| [0010](0010-adaptive-llm-orchestration.md) | Adaptive LLM orchestration and test-time compute | Accepted | partial | All provider execution remains behind contextual-orchestrator; LLM output has no numerical authority. | +| [0011](0011-standalone-modular-msa-boundary.md) | Standalone operation and modular CWL MSA boundary | Accepted | partial | Owns cross-service API/credential/persistence boundaries and anti-corruption-layer direction. | +| [0012](0012-temporal-relational-shared-latent-topic-measurement.md) | Temporal relational shared-latent topic measurement | Accepted | partial | Owns TEPP topic-measurement contract and fitted artifact semantics; capability promotion remains evidence-gated. | +| [0013](0013-bitemporal-persistence-reproducibility-and-split-authority.md) | Bitemporal persistence, reproducibility, and split authority | Accepted | partial | Owns PostgreSQL adapter semantics, immutable manifests, and leakage-safe split identity. | +| [0014](0014-scientific-claim-promotion-and-release-evidence.md) | Scientific claim promotion and release evidence | Accepted | partial | Keeps Validation Evidence distinct from the decision that promotes a scientific/product claim. | +| [0015](0015-autonomous-development-review-and-merge-authority.md) | Autonomous development, review, and merge authority separation | Accepted | active-PR | Keeps proposal, verification, publication, independent review, and merge/release authority separate. | +| [0016](0016-tdt-chronos-event-intelligence-boundary.md) | TDT, CHRONOS, and Event Ontology intelligence boundary | Accepted | active-PR | Separates observed evidence, event detection/tracking, prediction/schema inference, consistency, and promoted transition authority. | +| [0017](0017-hourly-contextual-orchestrator-gateway.md) | Hourly contextual-orchestrator gateway and provider discovery | Accepted | active-PR | Owns proposal-model gateway/discovery boundary; deterministic verification and merge authority remain separate. | +| [0018](0018-consumer-scoped-analysis-run-ingress.md) | Consumer-scoped modular analysis-run ingress | Accepted | active-PR | Owns closed consumer admission and consumer-qualified idempotency semantics. | +| [0019](0019-project-history-wire-size-symmetry.md) | Symmetric project-history wire-size enforcement | Accepted | active-PR | Owns bounded request/result size symmetry for the LineageWeave project-history boundary. | +| [0020](0020-span-grounded-semantic-units.md) | Span-grounded semantic units; language tags are not identity | Accepted | active-PR | First production slice of ADR 0004; does not claim completed multilingual invariance. | +| [0021](0021-lineageweave-project-history-boundary.md) | LineageWeave project-history service boundary | Accepted | active-PR | Owns the credential-free bounded project-history API while LineageWeave retains its authorization/domain authority. | +| [0022](0022-deterministic-analysis-run-execution.md) | Deterministic cutoff-safe analysis-run execution | Accepted | active-PR | Canonical identity for the analysis-engine execution decision; the pre-normalization colliding 0021 text is preserved under `archive/`. | +| [0023](0023-lineage-criterion-anchor-contract.md) | TEPP-owned Event Lineage criterion anchor | Accepted | active-PR | Owns independent criterion-anchor contract; estimator execution remains separately evidence-gated. | +| [0024](0024-independent-topic-importance-anchor.md) | Posterior topic-context producer contract | Accepted | active-PR | Owns the topic-context producer DTO/schema; fast-mlsirm owns reusable case-deletion influence arithmetic. | +| [0025](0025-macos-native-rust-mlx-metal-boundary.md) | macOS-native Rust-owned MLX Metal execution | Accepted | accepted-target | Owns native Metal execution/parity receipt boundary; Linux must not claim Metal execution. | +| [0026](0026-lineage-pair-criterion-and-project-journey-posterior.md) | Independent lineage-pair criterion and posterior Project Journey | Proposed | active-PR | Proposed successor identity for the pre-normalization colliding 0024 decision; it is not architecture authority unless and until accepted. | + +## Pre-normalization lineage + +The historical file [`archive/pre-normalization-0021-deterministic-analysis-run-execution.md`](archive/pre-normalization-0021-deterministic-analysis-run-execution.md) preserves the earlier branch-era ADR 0021 text byte-for-byte after that number was found to collide with the LineageWeave project-history decision. The canonical analysis-run execution decision is ADR 0022. Historical branch references to the colliding identity remain provenance, not current architecture authority. + +The former lineage-pair/Project-Journey ADR 0024 collision is handled differently and this distinction is intentional. This branch does **not** claim a byte-for-byte archive for that former 0024 text. ADR 0026 is a newly proposed successor identity that records the surviving decision intent; it is not represented as an archived copy. Historical Git/PR evidence, where retained by the repository host, remains provenance but does not become canonical ADR text. Fabricating an archive without verified original bytes would create false lineage, so accepted ADR 0024 remains the Posterior topic-context producer contract and ADR 0026 remains merely Proposed until separately accepted. + +No historical collision authorizes reuse of a retired number for a new decision, and a proposed successor does not become architecture authority merely because implementation work exists. ## Decision ownership summary -Use the narrowest owning ADR when decisions overlap: +Use the narrowest owning **Accepted** ADR when decisions overlap. Proposed ADRs are recorded separately and are not architecture authority until accepted: -- **numerical implementation / reference backend:** ADR 0001; -- **clock/time eligibility:** ADR 0002; -- **event ontology / relation / membership semantics:** ADR 0003; -- **multilingual semantic alignment:** ADR 0004; span-grounded unit identity: ADR 0020; -- **ESEM/DSEM and psychometric interpretation:** ADR 0005; -- **GPU/VRAM and model-credential boundary:** ADR 0006; -- **repository quality tooling:** ADR 0007; -- **evidence identity / spans / wire reconstruction:** ADR 0008; -- **PII/privacy authority:** ADR 0009; -- **LLM test-time compute / orchestration:** ADR 0010; -- **standalone/CWL MSA service authority:** ADR 0011; -- **topic measurement / backend/global-K/method-effect contract:** ADR 0012; -- **persistence / manifests / leakage-safe split:** ADR 0013; -- **claim maturity / release evidence:** ADR 0014; -- **autonomous development/review/merge authority:** ADR 0015; -- **TDT/CHRONOS event intelligence:** ADR 0016; -- **accepted-run execution and terminal artifact production:** ADR 0021. -- **hourly proposal gateway and provider discovery:** ADR 0017. -- **modular consumer admission / replay identity:** ADR 0018. -- **project-history wire-size symmetry:** ADR 0019. -- **LineageWeave project-history service boundary:** ADR 0021. -- **accepted-run execution and terminal artifact production:** ADR 0022. -- **independent lineage criterion and posterior Project Journey:** ADR 0023. -- **macOS-native Rust-owned MLX Metal execution:** ADR 0024. +- numerical implementation/reference backend: ADR 0001; +- clock/time eligibility: ADR 0002; +- event ontology, relation, and membership semantics: ADR 0003; +- multilingual semantic alignment: ADR 0004; span-grounded unit identity: ADR 0020; +- ESEM/DSEM and longitudinal psychometric interpretation: ADR 0005; +- GPU/VRAM compute boundary: ADR 0006; +- repository quality tooling: ADR 0007; +- evidence identity/spans/wire reconstruction: ADR 0008; +- privacy and purpose-bound disclosure: ADR 0009; +- LLM test-time compute/orchestration: ADR 0010; +- standalone/CWL MSA service authority: ADR 0011; +- topic measurement and model-artifact contract: ADR 0012; +- persistence/manifests/leakage-safe split: ADR 0013; +- scientific claim maturity/release evidence: ADR 0014; +- autonomous development/review/merge authority: ADR 0015; +- TDT/CHRONOS event intelligence: ADR 0016; +- hourly contextual-orchestrator proposal gateway: ADR 0017; +- modular analysis-run consumer admission: ADR 0018; +- project-history wire-size symmetry: ADR 0019; +- LineageWeave project-history boundary: ADR 0021; +- deterministic analysis-run execution: ADR 0022; +- Event Lineage criterion anchor: ADR 0023; +- Posterior topic-context producer contract: ADR 0024; +- macOS-native Rust-owned MLX/Metal boundary: ADR 0025; +- proposed independent lineage-pair criterion and posterior Project Journey: ADR 0026 (`Proposed`; not current architecture authority). ## Change and supersession rule ADR status changes require a pull request, source traceability, tests/evidence for affected invariants, and corresponding PRD/Architecture/TRD/Traceability updates where the approved measurement target changes. Decisions that materially alter privacy authority, orchestration authority, service ownership, temporal semantics, ontology, persistence identity, scientific estimands, release evidence, or automation authority require a superseding ADR rather than silent drift. -Partial supersession must identify the exact moved decision scope in both the older ADR and this index. Historical ADR text remains evidence of why a decision existed; it must not be silently rewritten to make a later architecture appear original. +Partial supersession must identify the exact moved decision scope in both the older ADR and this index. Historical ADR text remains evidence of why a decision existed; it must not be silently rewritten to make a later architecture appear original. A pre-normalization collision may be archived outside the numbered root after its bytes are preserved and the canonical successor is explicit. diff --git a/docs/adr/0021-deterministic-analysis-run-execution.md b/docs/adr/archive/pre-normalization-0021-deterministic-analysis-run-execution.md similarity index 100% rename from docs/adr/0021-deterministic-analysis-run-execution.md rename to docs/adr/archive/pre-normalization-0021-deterministic-analysis-run-execution.md diff --git a/docs/architecture/domain-context-map.md b/docs/architecture/domain-context-map.md new file mode 100644 index 000000000..871e8fba1 --- /dev/null +++ b/docs/architecture/domain-context-map.md @@ -0,0 +1,118 @@ +# TEPP Domain Context Map + +**Status:** Delivery-refactoring authority for the 2026-09-01 queue-consolidation cycle. +**Cross-service authority:** ADR 0011. + +This document applies Domain-Driven Design to the protected-main product. Cargo crates are implementation units; they are not automatically bounded contexts. A crate, ADR number, refusal helper, transport operation, clock type, or equation earns a separate boundary only when it has an independently meaningful domain lifecycle, ubiquitous language, invariants, and reuse boundary. + +## Strategic design + +### Core subdomains + +| Bounded context | Product responsibility | Aggregate / authority | Current implementation nucleus | +| --- | --- | --- | --- | +| Evidence & Semantic Measurement | preserve source evidence and derive span-grounded semantic/concept observations without replacing source truth | `EvidenceCorpus`, `SemanticUnitSet`, `ConceptDictionaryRevision` | `evidence_core`, `semantic_core` | +| Temporal Event Knowledge | represent the six-clock contract, event identity, interval relations, typed provenance/transition edges, and time-varying memberships | `EventEpisode`, `TemporalRelationSet`, `MembershipAssignmentSet` | `temporal_core`, `event_core`, `relation_graph`, `membership_core` | +| Topic Measurement | estimate shared-latent temporal topic coordinates and uncertainty; preserve topic identity through activity/dormancy/reactivation | `TopicModelRun`, `TopicLineage` | `topic_measurement`, `topic_lineage`, `model_selection`, `network_analysis` | +| Longitudinal Modeling | compose TEPP-owned temporal/event state evolution, longitudinal invariance/drift, irregular time and time-varying generalized-mixed structure around released static psychometric contracts | `TemporalModelSpecification`, `TemporalModelRun` | `longitudinal_core`; reusable static kernels migrate to fast-mlsirm | +| Analysis Run | orchestrate cutoff-safe accepted work into durable execution and typed terminal artifacts without owning scientific formulas | `AnalysisRun` | `analysis_engine` | +| Scientific Validation | produce method-specific recovery/coverage/parity/invariance/convergence evidence | `ValidationStudy` | `validation_core`, `tepp_simulation` | +| Scientific Claim Promotion | decide whether a claim may be promoted under a preregistered complete evidence contract | `ClaimPromotionDecision` | ADR 0014 policy; implementation incomplete | +| Projection | publish authorized read models/exports without changing domain or scientific authority | projection-specific read models | `tepp_api`, artifact/export adapters | + +### Supporting subdomains + +| Bounded context | Responsibility | Implementation nucleus | +| --- | --- | --- | +| Interpretation | evidence-grounded interpretation and independent verification; never numerical authority | `interpretation_gateway` plus contextual-orchestrator ACL | +| Persistence & Recovery | durable run/artifact storage, restart/recovery, outbox/checkpoint semantics | `persistence_postgres`, `checkpoint_authority` | +| Runtime Security & Operations | authenticated intake, TLS, operational audit, provider receipts, encrypted mappings | runtime/security adapters | + +### Generic subdomains + +`compute_backend`, accelerator adapters, serialization, hashing, and transport framing are generic infrastructure. They may serve several bounded contexts but may not define domain truth or scientific validity. + +## Context map + +```mermaid +flowchart LR + ES[Evidence & Semantic Measurement] --> TE[Temporal Event Knowledge] + ES --> TM[Topic Measurement] + TE --> TM + TE --> LM[Longitudinal Modeling] + TM --> LM + TM --> AR[Analysis Run] + LM --> AR + AR --> VE[Scientific Validation] + VE --> CP[Scientific Claim Promotion] + AR --> PJ[Projection] + CP --> PJ + PJ --> IN[Interpretation] + AR --> PR[Persistence & Recovery] + AR --> RO[Runtime Security & Operations] + CB[Compute Backend] -. generic service .-> TM + CB -. generic service .-> LM + CB -. generic service .-> VE + FM[fast-mlsirm Model Specification / Numerical Kernel] -- released versioned contract --> LM + CO[contextual-orchestrator] -- ACL --> IN +``` + +Dependency direction follows the arrows. Transport, persistence, UI, and provider adapters may depend on domain/application contracts; domain code must not depend on HTTP, PostgreSQL, CLI, or provider-specific representations. + +## Anti-corruption layers + +- `tepp_api` is an HTTP/CLI/projection adapter around Analysis Run and published read models. It must not own scientific acceptance, estimator formulas, event semantics, or persistence truth. +- `contextual-orchestrator` provider vocabulary is translated into TEPP interpretation/application contracts before crossing the boundary. Direct provider calls are prohibited. +- `fast-mlsirm` is consumed through a released/versioned candidate and numerical-kernel contract. TEPP does not copy open-PR source as a dependency. +- `persistence_postgres` implements repositories owned by domain/application contexts. Other contexts must not query its tables directly. +- compute backends expose execution receipts; a backend receipt is not a scientific result. +- Naruon, LineageWeave, Context Graph, and EA Core are external contexts. Their identifiers and transport vocabulary remain behind explicit adapters rather than leaking into core aggregates. + +## Ubiquitous language and invariants + +- **Evidence** is immutable source-backed observation, not an inferred fact. +- **Semantic unit** is a span-grounded measured unit tied to source offsets and a versioned concept dictionary. +- **Event or valid time** is the first of six temporal roles; an event instant and validity interval are alternative representations of when a state/event holds, not separate analysis clocks. +- **Available time** is when evidence becomes usable; **knowledge cutoff** is an analysis eligibility boundary. They are never aliases for event/valid time. +- **Transition edge** is forward-only state/process change; citation, summary, retrospective report, and support are provenance/evidence relations and never become transitions by coercion. +- **Membership assignment** may be cross-classified or multiple-membership and must not collapse language, template, department, project, location, or role into one entity identity. +- **Temporal model specification** composes time around an exact released upstream candidate identity; it does not rewrite the base family or dependence semantics. +- **Analysis run** owns lifecycle, idempotency, execution identity, and terminal artifact binding; it does not redefine estimators. +- **Validation evidence** records method-specific recovery/coverage/parity/invariance/convergence evidence. It is not a global scientific acceptance decision. +- **Claim promotion decision** may be made only from a preregistered, versioned evidence contract whose required dimensions are complete. LLM output cannot satisfy a numerical evidence requirement. + +## Crate-boundary repair register + +The following protected-main crates look like rule fragments rather than independent bounded contexts. They are retained temporarily to preserve remote-head compatibility, but new work treats them as modules/value objects/invariants of the owning context and folds them when the corresponding product-vertical landing vehicle is replayed onto current main. + +| Current crate fragments | Owning bounded context | +| --- | --- | +| `system_clock`, `event_clock`, `assertion_clock`, `cutoff_clock`, `available_clock`, `document_clocks`, `revision_order` | Temporal Event Knowledge | +| `summarizes_edge`, `retrospective_edge`, `support_edge`, `citation_edge`, `outcome_order`, `subevent_containment`, `prediction_contradiction`, `relation_absence`, `role_contradiction` | Temporal Event Knowledge | +| `location_membership`, `episode_membership`, `membership_target` | Temporal Event Knowledge | +| `prompt_source`, `style_source`, `modality_source`, `copied_text`, `copy_identity`, `corpus_background`, `stopword_deletion`, `payload_bound`, `derived_sensitivity` | Evidence & Semantic Measurement | +| event-time correlation standardization | Longitudinal Modeling / `longitudinal_core` | +| reusable static/generalized-mixed/dependence psychometric arithmetic | `fast-mlsirm` owner path after parity/recovery | +| flat `analysis_engine` one-profile files | owning Analysis Run capability module | + +A fold is permitted only after comparing the exact remote head and preserving unique tests, doctoring, research citations, and public compatibility. Public compatibility, when required, is provided by explicit adapters/re-exports with a removal plan; legacy paths do not remain canonical merely to avoid a refactor. + +## Analysis Run directory rule + +New `analysis_engine` profiles are organized by the owning domain capability, not as an indefinitely growing flat list of one-file refusals or one-route features: + +```text +analysis_engine/src/ + runs/ + evidence_measurement/ + topic_measurement/ + longitudinal_modeling/ + event_intelligence/ + validation/ +``` + +Transport-only features stay in `tepp_api`; scientific claim promotion remains a separate policy boundary instead of being hidden inside one validation-run helper. + +## Migration rule + +Do not perform a repository-wide path rename while a large remote PR fleet is open. Apply path repairs incrementally inside the selected landing vehicle for each bounded context, then close or retarget superseded micro-PRs with exact-head replacement mappings. The target architecture is mandatory; the migration is staged only to preserve concurrent-agent intent and review evidence. \ No newline at end of file diff --git a/docs/architecture/temporal-dependence-composition.md b/docs/architecture/temporal-dependence-composition.md new file mode 100644 index 000000000..16359ba30 --- /dev/null +++ b/docs/architecture/temporal-dependence-composition.md @@ -0,0 +1,208 @@ +# Temporal dependence composition boundary + +**Status:** Accepted target; the upstream Published Language is not yet a released production dependency. +**Architecture authority:** ADR 0011. +**Research authority:** [`docs/research/temporal-dependence-models.md`](../research/temporal-dependence-models.md). + +This document defines the anti-corruption boundary between reusable static psychometric model specification in `ContextualWisdomLab/fast-mlsirm` and TEPP-owned temporal/event composition. It does not add a numerical estimator and does not make an upstream research candidate a supported TEPP model. + +## Ownership + +`fast-mlsirm` owns reusable response-family, dimensional, generalized-mixed, and dependence-aware psychometric specification and numerical kernels. Its Published Language must be a released, versioned, immutable candidate manifest whose structural identity covers the exact base response formulation, parameter blocks, dimensional structure, generalized-mixed structure, and dependence structure. + +TEPP owns only the temporal/event composition placed around that published candidate: + +- event or valid time, assertion time, document time, system time, available time, and knowledge cutoff; +- leakage-safe historical eligibility; +- measurement occasion as a method/rater facet distinct from substantive event time; +- irregular observation intervals; +- time-varying covariates, random effects, cross-classification, and multiple membership; +- longitudinal invariance and drift; +- latent-state evolution and transition equations; +- temporal alignment of dependence geometry; +- event ontology and temporal graph constraints; +- temporal known-truth recovery and rolling-origin validation. + +The first clock role is **event or valid time**, matching the approved six-clock contract. A state may be represented by an event instant or a validity interval, but TEPP does not mint a seventh independent clock by storing `event_time` and `valid_time` as unrelated analysis-time authorities. + +`contextual-orchestrator` owns every LLM provider call, routing decision, verifier/adjudicator workflow, credential, and model-call provenance. TEPP never calls a model provider directly. + +## Published-language intake + +The TEPP ACL consumes a released/versioned upstream candidate contract rather than branching on model-family names. At minimum the contract must carry: + +```text +candidate_id +contract_version +contract_digest +base_response_family +base_formulation_id +response_scale +base_parameter_blocks +dimensional_formulation +dimension_count +generalized_mixed_formulation +fixed_effect_blocks +random_effect_blocks +membership_formulation +dependence_kind +dependence_formulation_id +dependence_parameter_blocks +capability_status +estimator_evidence_reference +identification_evidence_reference +recovery_evidence_reference +primary_citation_references +``` + +The ACL rejects missing structural identity, unknown contract versions, digest mismatch, and a request that silently substitutes a local-independent candidate for a dependence-aware request. Identity-bearing fields and error responses expose only opaque identifiers or digests; this restriction does not remove schema-authorized model, event, posterior, relation, uncertainty, or statistical payload fields from the versioned ACL contract. + +TEPP does not duplicate the upstream `ResponseKernel`, `GeneralizedMixedStructure`, LSIRM, MLSIRM, or DLSJM implementation. When reusable static arithmetic currently exists locally in TEPP, its migration path is parity and recovery against the fast-mlsirm owner, followed by replacement with a released versioned adapter and removal of the duplicate production source. + +## Generic temporal compiler + +Temporal expansion is a composition over the upstream candidate identity, not a switch over names such as `rasch`, `2plm`, `mirt`, `ggum`, `lsirm`, or `dlsjm`. + +For each upstream candidate admitted by the ACL, TEPP materializes one temporal-candidate specification with an identity derived from the upstream candidate plus the complete temporal contract. New compatible base families therefore inherit temporal composition automatically when fast-mlsirm publishes them; TEPP does not add a family-specific temporal wrapper. + +A temporal candidate records at least: + +```text +temporal_candidate_id +upstream_candidate_id +upstream_contract_version +upstream_contract_digest +temporal_formulation_id +clock_role_contract +event_or_valid_time_semantics +occasion_facet_semantics +state_equation_id +temporal_identification_rules +alignment_rules +time_varying_covariates +time_varying_random_effects +time_varying_membership_contract +irregular_interval_contract +estimator_owner +estimator_id +temporal_recovery_contract +capability_status +primary_citation_references +extension_citation_references +``` + +The status is exactly one of `supported`, `research_candidate`, or `unsupported`. Auto-expansion is never auto-activation. + +`supported` requires an explicit combined generative/state equation, temporal identification, an implemented estimator owned by the correct repository, candidate-scoped recovery, and exact citations. A structurally representable but novel coupling is `research_candidate`. An incoherent coupling is `unsupported` with a machine-readable reason. Unknown combinations never fall back to a simpler model. + +## Base-family identity is preserved + +Temporal composition preserves exact base-family semantics and parameter meaning. + +- Rasch remains Rasch and is not renamed generic 1PL. +- 2PLM, justified 3PLM, formulation-qualified 4PLM and 5PLM retain their discrimination, asymptote, guessing, slipping, and asymmetry semantics. +- Confirmatory and exploratory MIRT retain their factor/loading contract; exploratory structure remains a hypothesis until confirmatory and recovery evidence supports longitudinal use. +- Ideal-point/GGUM response processes remain distinct from dominance models. Dependence and time are orthogonal operators and do not convert a dominance model to ideal-point response or vice versa. +- Testlet, rater/facet, nested, crossed, cross-classified, and multiple-membership structure remains explicit. A latent-space dependence layer cannot hide a known hierarchy, rater, method, item-family, or omitted covariate. + +## LSIRM and MLSIRM temporal composition + +LSIRM represents residual person-item interaction through person and item positions in an interaction space and a distance-related interaction effect. TEPP temporal composition preserves the base-model parameters plus the upstream person/item interaction positions, distances, and interaction-strength parameters while adding explicitly identified temporal state evolution. + +MLSIRM is the multidimensional-main-effect latent-space extension described by Kang and Jeon (2025). Multilevel, cross-classified, and multiple-membership operators are separate generalized-mixed dimensions of the specification; the acronym is not redefined as “multilevel LSIRM.” + +A temporal LSIRM/MLSIRM candidate must define how interaction geometry evolves and how successive maps are identified. Raw coordinates from two occasions cannot be compared before the declared translation/rotation/reflection alignment. If scale or orientation is not identified across time, the candidate remains `research_candidate` regardless of apparently smooth trajectories. + +The canonical primary-research scope and extension limits are maintained in [`docs/research/temporal-dependence-models.md`](../research/temporal-dependence-models.md). + +## DLSJM temporal composition + +DLSJM follows Jin and Jeon (2019) as the baseline formulation for joint local item dependence and local person dependence. It is not an LSIRM alias. + +The upstream candidate must preserve distinct parameter blocks for the item-dependence space and person-dependence space. TEPP then composes distinct time-indexed state processes over those spaces. Temporal DLSJM must specify, separately for each space: + +- state/evolution equation; +- translation, rotation, and reflection alignment; +- scale/identification constraints; +- cluster-label alignment when clustering is interpreted longitudinally; +- uncertainty for positions, distances, clusters, and transition parameters. + +No result may compare raw item or person maps across occasions without alignment. A novel response-family × generalized-mixed × DLSJM × temporal-state coupling remains an explicitly named extension and a `research_candidate` until its combined likelihood/state equation, identification, estimator, and recovery are established. + +## Generalized mixed, multilevel, cross-classified, and multiple membership + +Generalized-mixed structure composes orthogonally with dependence and time when the full formulation is scientifically coherent. + +One observation may belong simultaneously to multiple organizations, projects, teams, sources, languages, item families, judges, raters, templates, or event episodes. Cross-classification is not multiple membership; both remain explicit in the candidate identity. + +Multiple-membership weights are auditable and time-valid. They are either observed/normalized under the declared design or estimated by an explicit model. TEPP does not invent equal weights as a fallback. Membership changes are state input with event-or-valid/available-time provenance; future membership cannot enter a historical cutoff. + +## Explanatory and exploratory candidates + +Explanatory covariates preserve their knowledge cutoff and join the combined model rather than being attached in an unvalidated post-hoc regression when joint estimation is required. + +Exploratory factors/loadings and latent-space geometry are hypotheses. Auto-expansion may materialize temporal exploratory LSIRM/MLSIRM/DLSJM candidates, but they cannot become longitudinal production scoring structures without confirmatory identification, invariance, and recovery evidence. + +## Local-dependence diagnostic order + +The diagnostic boundary is explicit: + +1. Model known factors, testlets, item families, raters/methods, hierarchy, cross-classification, multiple membership, and justified covariates first. +2. Residual person-item interaction may motivate LSIRM/MLSIRM. +3. Joint residual local-item and local-person dependence may motivate DLSJM when its relational representation matches the substantive question. +4. Dependence geometry cannot be used to absorb known design structure or omitted explanatory variables. + +LLM item-generation lineage remains evidence from LineageWeave/contextual-orchestrator and is never numerical dependence evidence by itself. + +## Temporal recovery contract + +Every expanded temporal dependence candidate receives a generated recovery specification covering all parameters that exist in its composed identity. As applicable this includes: + +- latent states and trajectories; +- fixed and random effects and covariance; +- time-valid membership weights; +- factors and loadings; +- lower/upper asymptotes and asymmetry parameters; +- ideal-point locations; +- LSIRM/MLSIRM person and item positions, distances, and interaction strength; +- DLSJM item-space and person-space positions/distances/clusters separately; +- temporal transition/dynamic parameters; +- posterior/interval uncertainty and coverage. + +Known-truth simulation separates event-or-valid time from available time. The suite includes irregular gaps, delayed reports, retrospective documents, missing occasions, changing memberships, and language/source drift. Evaluation uses leakage-safe rolling origins. Monte Carlo uncertainty is reported for simulation summaries; arbitrary pass percentages or rule-of-thumb thresholds are not scientific promotion criteria. + +A recovery artifact is evidence. A separate Scientific Claim Promotion Decision applies the preregistered method-specific acceptance contract from ADR 0014. A transport success, mergeable PR, LLM judgment, or generic RMSE threshold cannot promote a candidate. + +## DDD context map + +```text +fast-mlsirm Model Specification / Numerical Core + Published Language: released versioned candidate manifest + | + v + TEPP anti-corruption layer + | + v +TEPP Temporal/Event Composition + Longitudinal Validation + | + +--------------+---------------+ + | | + v v + Analysis Run application Claim Promotion + adapters/persistence separate authority + +contextual-orchestrator --ACL--> Interpretation only +LineageWeave ------------ACL--> Evidence/lineage input only +``` + +Dependency direction is one-way. TEPP may depend on a released versioned fast-mlsirm contract. fast-mlsirm must not import TEPP temporal ontology. Neither repository accesses the other repository's database. + +## Current implementation status + +The upstream generalized-mixed/dependence candidate compiler is a contract-in-progress until it reaches the canonical fast-mlsirm protected branch and is released/versioned. TEPP must re-read its live identity each execution rather than treating a remembered PR number or SHA as authority. + +Until that contract is released, TEPP develops only ACL schema/tests and temporal composition semantics that do not duplicate the upstream compiler or numerical kernel. Any local reusable static psychometric implementation discovered during that work is a migration candidate, not a second canonical source. + +## Research basis + +The canonical research discussion and APA 7 references for LSIRM, MLSIRM, and DLSJM are in [`docs/research/temporal-dependence-models.md`](../research/temporal-dependence-models.md). This architecture document intentionally does not maintain a second independent citation authority. diff --git a/docs/archive/CHANGELOG-pre-queue-normalization-2026-09-01.md b/docs/archive/CHANGELOG-pre-queue-normalization-2026-09-01.md new file mode 100644 index 000000000..65f7682bb --- /dev/null +++ b/docs/archive/CHANGELOG-pre-queue-normalization-2026-09-01.md @@ -0,0 +1,453 @@ +# Changelog + +All notable changes to TEPP are documented here. The format follows Keep a Changelog and semantic versioning once the first implementation release is cut. + +## [0.2.0] - 2026-08-25 + +### Fixed + +- `network_analysis` posterior edge estimation landed with heuristic and fail-open defects that this release repairs before any consumer depends on it: a non-finite correlation now fails to the neutral p-value instead of masquerading as `|r| = 1`; negative-effect edges are excluded from the whole consensus perturbation pipeline rather than leaking into the union partition; the hardcoded 0.1 edge-drop probability became an explicit validated `edge_drop_probability` parameter; pseudo-p-values were replaced by exact two-sided Fisher z-transform p-values (Fisher, 1921) driving Benjamini–Hochberg admission (Benjamini & Hochberg, 1995) with percentile-bootstrap intervals (Efron, 1979); and 27 uncovered branch outcomes gained exact red-to-green cases. The workspace version is aligned to 0.2.0 across every crate manifest. + +### Added + +- **TDT/CHRONOS durable result contract**: canonical typed JSON and deterministic GraphML now export the actual bounded Allen reasoner result, observed/derived status, and conservative accepted-assertion support; canonical payload digest and `tdt_chronos_interval_consistency_v1` type bind the immutable bytes into ADR 0013's append-only `model_artifact` chain. +- **Analysis engine**: deterministic end-to-end analysis-run execution with cutoff-safe eligibility, immutable evidence binding, and reproducibility manifests (`analysis_engine` crate). +- **Restore Driver p.16 `MANIFESTVARstd`**: `recover_standardised_manifest_variance` maps `θ / θ = 1` with strictly positive `MANIFESTVAR`, refusing unstandardised manifest-variance, `MANIFESTTRAITVARstd`, and Equation 5 `Var(y)` substitutions (`psychometric_core`). +- **Posterior network estimator**: cross-draw Pearson correlations in ILR space, jackknife SE and CI, Benjamini–Hochberg FDR edge admission, nonparametric bootstrap stability, greedy modularity consensus clustering (`network_analysis` crate). +- **Topic measurement reference estimator**: bounded deterministic CPU `f64` TRSL-TM fitting with ALR/ILR coordinates, Aitchison distance, and lexical-inferential-weight refusal gates (`topic_measurement` crate). +- **Psychometric core**: Driver et al. (2017) SDE discrete-time recovery suite including drift, diffusion, T0VAR, TIPRED/TDPRED effects, standardised parameters, trait/state variance decomposition, and observed-indicator mapping — 18 K lines of production Rust with true-parameter RMSE tests. +- **Temporal six-clock architecture**: system, event, assertion, document, availability, and knowledge-cutoff clocks with forward-only transition enforcement and revision ordering (`temporal_core` + dedicated clock crates). +- **Membership and relation boundaries**: episode membership, role contradiction, relation absence detection, support-edge refusal, inferred-status gate, payload bounds, outcome ordering, summarises-edge identity, copy identity, citation/support non-transition, retrospective reporting, intake authorization, provider receipt, encrypted identity mapping, derived sensitivity inheritance, and purpose-bound PII governance. +- **Interpretation gateway**: loopback HTTP listener serving contextual-orchestrator interpretation POSTs with evidence-bound LLM claims and numerical-authority refusal. +- **Compute backend**: VRAM budget types with CPU `f64` fallback policy. +- **Persistence**: bitemporal PostgreSQL store with live sqlx integration, concurrent-write SQLSTATE classification, entity/project fail-closed SQL, audit-event inspection through try_record, and retention lifecycle. +- **Validation**: exact-head claim promotion gates, corpus-split leakage-audit manifests, documentation quality validation, and scientific claim boundary contracts. + +### Changed + +- Consolidated 99 open pull requests into protected main through batch integration vehicle (#215), hourly scheduler independent merges, and individual rebase-admin passes. +- Workspace grew from 10 to 57 crates covering evidence, semantic, temporal, event, relation, membership, persistence, simulation, validation, API, topic measurement, psychometric, network, interpretation, compute, and analysis-engine boundaries. +- All database objects use two-or-more-word `snake_case`; third normal form enforced; hot-partition readiness tracked as a separate acceptance gate. + +### Security + +- Purpose-bound authorization grants; blanket PII masking refused in favour of selective disclosure. +- Identity mappings sealed with HMAC; re-identification exports restricted to explicit purpose grants. +- Tenant roles bound to system-time lifetimes; privileged-access decisions replayed without source identity. +- Provider field codes recorded without source text; sensitivity inherited onto derived artifacts. + +## [Unreleased] + +### Changed + +- Delivery-authority recovery vehicle (#435 / #175) now records the live 2026-09-01T10:19:29Z queue as **136** open PRs (91 draft, 45 non-draft) on protected main `1bc02f580cf48e1d39da239f0e818453437c31c3`. Scientifically unsafe #356 is closed without merge. Longitudinal repair #441 advanced to `6f483224b3a03e8237c6f4f098a8b0e85e0a91f5` and is classified as a landing-vehicle candidate, not merge authority. Export-collection CLI #444 is classified `fold_into_landing_vehicle`. Queued checks remain non-passing. + +- `event_core` adds bounded Allen interval-consistency classification, atomic path-consistency closure, contradiction/resource refusals, and an explicit dependency-error fallback without claiming unrestricted global satisfiability. + +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `MANIFESTTRAITVAR`; §7.1, p. 19; p. 16 `MANIFESTTRAITVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-27T14:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised manifest-trait variance on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map (register items 83–84). Table 2 names `MANIFESTTRAITVAR` `Ψ_τ` the additional time-invariant variance-covariance on the measurement level and sets it `NULL` when there is no manifest trait. Equation 5 writes `Γ ~ N(τ, Ψ)` and names that covariance the manifest traits. Section 7.1 names manifest traits stable individual differences in indicator levels, distinct from process-level `TRAITVAR` `φ_ξ`. Page 16 prints standardised matrices with the suffix `std` when appropriate. The printed example on p. 16 is `discreteDRIFTstd`, not `MANIFESTTRAITVARstd`. Footnote 4 standardises using only the relevant variance, not the total. The relevant variance for that named indicator-level correlation is `MANIFESTTRAITVAR`, not process-level `TRAITVAR` and not residual `MANIFESTVAR` `θ`. The 2017-era source forms `MANIFESTTRAITVARstd` only when `MANIFESTTRAITVAR != 0`, as `solve(sqrt(diag(MANIFESTTRAITVAR) + ridging)) %&% MANIFESTTRAITVAR` when `verbose = TRUE`. OpenMx `%&%` is `t(A) %*% B %*% A`. Unlike `TRAITVARstd`, that formation adds `diag(c(ridging), n.manifest)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `ψ / ψ = 1` after strictly positive `MANIFESTTRAITVAR`. Form strictly positive `ψ` first, then `1 / √ψ`, then `(1 / √ψ) ψ (1 / √ψ)`. Unstandardised `MANIFESTTRAITVAR` is defined for a zero trait; standardised `MANIFESTTRAITVAR` is not. Zero `MANIFESTTRAITVAR` skips forming `MANIFESTTRAITVARstd` in the 2017-era source and fails closed here. Indicator-level trait variance is an event-time structural quantity, so a non-event clock fails closed. `MANIFESTTRAITVAR` does not require stable `a < 0`. Distinct positive `ψ` recover the same 1. `trait / trait = 1` is `TRAITVARstd` and recovers the same number and remains a distinct named quantity. `θ` is `MANIFESTVAR` and is measurement error, not this correlation. Meredith (1993) remains unread (web search 2026-08-27T14:20Z: Springer/Cambridge Core paywalled; Unpaywall historically `is_oa: false`; Springer `content/pdf` is an HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms (DOI `10.1007/bf02294457`). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. + +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `TRAITVAR`; §7.1, pp. 18–19; p. 16 `TRAITVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T17:45Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised trait variance on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map (register items 81–82). Table 2 names `TRAITVAR` `φ_ξ` the latent trait variance/covariance and sets it `NULL` when there is no trait. Section 7.1 names traits the stable between-subject differences (unit-level unobserved heterogeneity). Page 16 prints standardised matrices with the suffix `std` when appropriate. The printed example on p. 16 is `discreteDRIFTstd`, not `TRAITVARstd`. Footnote 4 standardises using only the relevant variance, not the total. The relevant variance for that named between-subject correlation is `TRAITVAR`, not free first-occasion `T0VAR` and not process-dynamics `asymDIFFUSION`. The 2017-era source forms `TRAITVARstd` only when `TRAITVAR != 0`, as `solve(sqrt(diag(TRAITVAR))) %&% TRAITVAR` when `verbose = TRUE`. OpenMx `%&%` is `t(A) %*% B %*% A`. Unlike `T0VARstd`, that formation uses `diag(diag(TRAITVAR))` and does not add `diag(c(ridging))`. The ridge is a `T0VAR` numerical hack and is not this exact map. The scalar correlation is `trait / trait = 1` after strictly positive `TRAITVAR`. Form strictly positive `trait` first, then `1 / √trait`, then `(1 / √trait) trait (1 / √trait)`. Unstandardised `TRAITVAR` is defined for a zero trait; standardised `TRAITVAR` is not. Zero `TRAITVAR` skips forming `TRAITVARstd` in the 2017-era source and fails closed here. Between-subject variance is an event-time structural quantity, so a non-event clock fails closed. `TRAITVAR` does not require stable `a < 0`. Distinct positive `trait` recover the same 1. `p_0 / p_0 = 1` is `T0VARstd` and recovers the same number and remains a distinct named quantity. `t0_b² v` is `addedT0TIPREDVAR` and is extra first-occasion TI variance, not this correlation. Meredith (1993) remains unread (Unpaywall 2026-08-26T17:20Z: `is_oa: false`; OpenAlex closed; Springer `content/pdf` is an HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms (DOI `10.1007/bf02294457`; Unpaywall `is_oa: false`). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymDIFFUSIONstd`; footnote 4; Eq. 4, p. 5; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T17:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic within-subject variance on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map (register items 89–90). Page 16 prints standardised matrices with the suffix `std` when appropriate, and names `asymDIFFUSION` the total within-subject variance as `Δt → ∞`. The printed example on p. 16 is `discreteDRIFTstd`, not `asymDIFFUSIONstd`. Footnote 4 standardises using only the relevant variance, not the total. The relevant variance for that named process-dynamics correlation is within-subject `asymDIFFUSION` `p = −q / (2 a)`, not free first-occasion `T0VAR`. The 2017-era source forms `asymDIFFUSIONstd` as `solve(sqrt(diag(asymDIFFUSION))) %&% asymDIFFUSION` when `verbose = TRUE`. OpenMx `%&%` is `t(A) %*% B %*% A`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `p / p = 1` after strictly positive `p`. Form strictly positive `p` first, then `1 / √p`, then `(1 / √p) p (1 / √p)`. Unstandardised `p` is defined for a zero process; standardised `asymDIFFUSION` is not. Zero `q` has no positive SD and fails closed. Lasting `p` requires stable `a < 0`. A non-event clock fails closed. Distinct positive `p` recover the same 1. `p_0 / p_0 = 1` is `T0VARstd` and recovers the same number and remains a distinct named quantity. `q / p = −2 a` is `DIFFUSIONstd` and is not this correlation. `v / v = 1` is `TIPREDVARstd` and recovers the same number and remains a distinct named quantity. Meredith (1993) remains unread (Unpaywall 2026-08-26T17:20Z: `is_oa: false`; OpenAlex closed; Springer `content/pdf` is an HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms (DOI `10.1007/bf02294457`; Unpaywall `is_oa: false`). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `T0VARstd`; Table 2, p. 12; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T07:17Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised initial latent variance on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map (register items 79–80). Page 16 prints standardised matrices with the suffix `std` when appropriate. The printed example on p. 16 is `discreteDRIFTstd`, not `T0VARstd`. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `T0VAR` the latent process initial variance/covariance. The first-occasion relevant variance is free `T0VAR` `p_0`, not process-dynamics `asymDIFFUSION` `-q / (2 a)`. The 2017-era source forms `T0VARstd` as `solve(sqrt(diag(T0VAR))) %&% T0VAR` when `verbose = TRUE`. OpenMx `%&%` is `t(A) %*% B %*% A`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `p_0 / p_0 = 1` after strictly positive `p_0`. Form strictly positive `p_0` first, then `1 / √p_0`, then `(1 / √p_0) p_0 (1 / √p_0)`. A zero first-occasion variance has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. Distinct positive `p_0` recover the same 1. `μ_0 / √p_0` is `T0MEANSstd` and recovers the same number when `μ_0 = √p_0` and remains a distinct named quantity. `p / p = 1` is `asymDIFFUSIONstd` and recovers the same number and remains a distinct named quantity. Meredith (1993) remains unread (Unpaywall 2026-08-26T07:17Z: `is_oa: false`; OpenAlex closed; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms (DOI `10.1007/bf02294457`; Unpaywall `is_oa: false`). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymCINTstd`; Eq. 3, p. 4; Table 2, p. 12; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T00:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic continuous intercept on current main after consolidation dropped the pre-consolidation `(-κ / a) / √p` slice. Page 16 prints standardised matrices with the suffix `std` when appropriate, and asymptotic values as `Δt → ∞`. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `κ` `CINT`. The relevant variance for that process intercept is within-subject `asymDIFFUSION` `p = −q / (2 a)`. The 2017-era source forms unstandardised `asymCINT` whenever `verbose = TRUE` as `-solve(DRIFT) %*% CINT` and does not form an `asymCINTstd` matrix. Form strictly positive `p` first, then the asymptotic intercept, then divide by `√p`. A zero intercept is exactly zero after that positive SD. Zero `q` has no positive process SD and fails closed. Lasting `p` requires stable `a < 0`. A non-event clock fails closed. `κ / √p` is `CINTstd` and is not this total-change map. `A^{-1}[e^{A Δt} − I] κ / √p` is `discreteCINTstd` and depends on the event interval. Meredith (1993) remains unread (Unpaywall 2026-08-25T18:22Z: `is_oa: false`; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991) remains unread on the same terms. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `T0MEANSstd`; Table 2, p. 12; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-26T04:09Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised initial latent mean on current main after `0ce16e8` dropped the pre-consolidation code while research notes already named the map. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `T0MEANS` the `n.latent × 1` matrix of latent process means at the first time point `T0` and names `T0VAR` the latent process initial variance/covariance. The first-occasion relevant variance is free `T0VAR` `p_0`, not process-dynamics `asymDIFFUSION` `-q / (2 a)`. The 2017-era source forms unstandardised `T0MEANS` and does not form a `T0MEANSstd` matrix; the scalar map is `μ_0 / √p_0` after strictly positive `p_0`. A zero mean is exactly zero. Zero `p_0` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0MEANS` does not require stable `a < 0`. `p_0 / p_0 = 1` recovers the same number when `μ_0 = √p_0` and remains a distinct named quantity. `μ_0 / √asymDIFFUSION` uses process-dynamics variance and is not this first-occasion map. Meredith (1993) remains unread (Unpaywall 2026-08-26T00:22Z: `is_oa: false`; OpenAlex closed; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread on the same terms. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `MANIFESTMEANSstd`; Table 2, p. 12; footnote 4; Eq. 5, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-25T11:32Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised manifest mean on current main after `0ce16e8` restored the pre-consolidation unstandardised slice. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `MANIFESTMEANS` `τ` the `n.manifest × 1` matrix of manifest means and `MANIFESTVAR` `Θ` the residual covariance of the indicators. The relevant variance for that named measurement intercept is residual `θ`, not total observed `Var(y) = λ² Var(η) + θ`. The 2017-era source forms unstandardised `MANIFESTMEANS` and does not form a `MANIFESTMEANSstd` matrix; the scalar map is `τ / √θ` after strictly positive `θ`. A zero mean is exactly zero. Zero `θ` has no positive SD and fails closed. A non-event clock fails closed. `MANIFESTMEANS` does not require stable `a < 0`. `θ / θ = 1` recovers the same number when `τ = √θ` and remains a distinct named quantity. `τ / √(λ² Var(η) + θ)` uses total observed variance and is not this residual map. Meredith (1993) remains unread (Unpaywall 2026-08-25T11:32Z: `is_oa: false`, 0 locations; OpenAlex closed; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-25T11:32Z: `is_oa: false`, 0 locations). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `CINTstd`; Eq. 1, p. 4; Table 2, p. 12; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-25T11:43Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous intercept on current main after consolidation dropped the pre-consolidation `κ / √p` slice. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `κ` `CINT`. The relevant variance for that process intercept is within-subject `asymDIFFUSION` `p = −q / (2 a)`, not total `trait + p + added`. Form strictly positive `p` first, then `κ / √p`. A zero intercept is exactly zero after that positive SD. Zero `q` has no positive process SD and fails closed. Lasting `p` requires stable `a < 0`. A non-event clock fails closed. `(-κ / a) / √p` is `asymCINTstd` and is not this continuous intercept. `A^{-1}[e^{A Δt} − I] κ / √p` is `discreteCINTstd` and depends on the event interval. `κ / √(trait + p + added)` uses the total and is not this residual map. `TRAITVAR` is not the standardisation variance. Meredith (1993) remains unread (Unpaywall 2026-08-25T11:43Z: `is_oa: false`; Springer `content/pdf` is a 3038-byte HTML stub). Mislevy (1991) remains unread on the same terms. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- Operator-gap register refreshed against protected main `c482ccea` (#239): workspace version 0.2.0, 57 crates, queue at seven open PRs with exact-head SHAs, issues #156/#168/#175 closed, GAP-009 advanced to estimator-core-plus-repairs with Leiden consensus remaining, GAP-001/GAP-012/GAP-017 closed on protected main, and a new Post-#239 state note recording both the estimator repairs and the non-release status of the version bump. Supersedes #236 whose base predated #239. +- `event_core` `EventMention` is the only constructible mention type and must be span-grounded: it cites one exact `SourceSpan`, document identity, six-clock evidence, extractor/model version, and proposed/reviewed status, and the surface is the document substring at that span. Exact-extent precision/recall recover known ACE extents with occupancy RMSE 0 versus whole-document RMSE 1; reviewed status and TDT/CHRONOS detections still cannot promote an instance. Interval consistency, persistence, and exports remain later #170 work. +- Restored protected-main gate integrity after the consolidation merges: hourly-scheduler prompt-contract tests now assert the gap-baseline-derived task contract (Gap ID naming, no invented weights) instead of stale increment-specific tokens, the operator-gap register inventory matches the live 33-PR queue, `evidence_core::image_unit` non-image/empty-subtype refusals and `load_union_branch_totals` valid-record accumulation have exact coverage, and the README crate fence plus duplicate registry entries stay deduped. +- Branch-coverage diagnostics on the post-consolidation head exposed two uncovered outcomes in `evidence_core::image_unit` (`is_image_media_type_token` non-image prefix and empty-subtype refusals), one uncovered authored line (the strip-prefix refusal), and lost valid-record coverage for `load_union_branch_totals`; exact red-to-green cases now cover the non-image/empty-subtype data URIs and per-coordinate True/False accumulation. +- Repaired post-consolidation merge fallout that left protected `main` red: restored the lost `return True` in the `check_coverage.py` match-guard branch, removed the shadowed duplicate `load_union_branch_totals` and `_is_multiline_match_guard` definitions plus duplicate workspace-crate entries (`episode_membership`, `analysis_engine`) from the contract tuple and Cargo member arrays, split two union-fused four-tuples back into `(variant, message)` pairs in the `event_core` error table, repaired the fused `identity_recovery_rate` body in `episode_membership::window`, deduplicated the checked-arithmetic eligible-count block in `analysis_engine`, fixed four-argument `unit()` test call sites, rebalanced the README crate-list fence around all 54 unique crates, and deduplicated the `location_membership`/`validation_core`/`tepp_api` architecture-table rows. Also documents private `PLAUSIBLE_IMAGE_MEDIA_TYPES` so `cargo doc -D warnings` passes. +- Branch coverage JSON now unique-folds `files[].branches` True/False counts across instantiations. Nightly totals on #49 head `1e3e2eb` reported `event_time.rs` 505/506 while every unique site had both arms taken (253 sites × 2 instantiations). Summary-only reports without branch arrays still fail closed on totals. The 100% contract is unique production arms, matching the LCOV authored-line gate. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` maps overflowing `expm1(a Δt)` / `expm1(2 a Δt)` in `recover_discrete_constant_predictor_effect` and `recover_discrete_process_noise` through the log-space rewrite without a redundant `if !argument.is_finite()` after overflow. Local crate llvm-cov on #49 head `559e7b399473ee90ba3234677dd9ef7f05f7fd2e` was 509/510: the same LLVM `exp`/`expm1` finite-argument proof as L768/L5040. Existing rewrite (`a = 800` / `a = 400`) and overflow (`a = 1e308`) tests remain the contract. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` maps overflowing `e^{a Δt}` / `e^{a(t−u)}` through the log-space rewrite without redundant `if !argument.is_finite()` after `exp` overflow on lagged covariance, T0 TI/TD carry, and impulse carry. Nightly branch coverage on #49 head `7e669babcc54408dd8407bbac56be0f304fa99e5` was 1713/1714: LLVM counted `event_time.rs` L5040 True and treated the finite-argument overflow False as uncovered after proving `exp` of a finite argument is finite, which binary64 overflow falsifies. `fit_scalar_log_rate` now also skips a zero earlier residual and a negative lag while still recovering from a valid pair. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` maps overflowing `e^{2 a Δt}` in `recover_discrete_latent_variance` through the log-space rewrite `(ln p + 2 a Δt).exp()` without a redundant `if !2 a Δt.is_finite()` after `exp` overflow. Nightly branch coverage on #49 head `e301e9706c0bd671ccad533063fb624cc568d0b3` was 1715/1716: LLVM counted `event_time.rs` L768 True and treated the finite-argument overflow False as uncovered after proving `exp` of a finite argument is finite, which binary64 overflow falsifies. Existing rewrite (`p = 1e-308`, `a = 400`, `Δt = 1`) and overflow (`a = 1e308`) tests remain the contract. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` executes the later `|| !log_rate.is_finite()` operand on `recover_discrete_time_independent_predictor_effect` from both the lib tests and the multilevel integration crate. Nightly branch coverage on #49 head `90b08bbe82cbe7776365a6c04df38857dfe5e53c` was 1714/1716: both True arms at `event_time.rs` L2480 were unhit because fail-closed tests supplied a non-finite `TIPREDEFFECT` or predictor before `a`. Direct `a = NaN` now takes those arms. `LagClock::as_str` is called through `black_box` so the outlined instantiation is not const-folded away. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` evaluates the Driver, Oud, and Voelkle (2017, §7.2) extra-process lag as `e^{ε Δt}` even when `ε Δt` underflows to `0` (`exp(0) = 1`). Nightly branch coverage on #49 head `22b8e68813ad59a9a91689bacfa4cf033dfad158` was 1718/1720: LLVM deleted `if extra_argument == 0.0` / `original_argument == 0.0` True after proving `ε < 0` and `Δt > 0` imply a nonzero product, which binary64 underflow falsifies. The public map now uses `exp` directly; `original_log_rate == 0` remains the Brownian `e^{0} = 1` path. Recovery tests assert the §7.2 identity `a_{ηξ} x e^{a Δt}(e^{(ε−a)Δt} − 1)/(ε − a)` on `(-min_subnormal) * 1e-320`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `MANIFESTMEANSstd`; Table 2, p. 12; footnote 4; Eq. 5, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-25T05:04Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised manifest mean. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `MANIFESTMEANS` `τ` the `n.manifest × 1` matrix of manifest means. Table 2 names `MANIFESTVAR` `Θ` the residual covariance of the indicators. The relevant variance for that named measurement intercept is residual `MANIFESTVAR` `θ`, not total observed `Var(y) = λ² Var(η) + θ`, matching `MANIFESTVARstd`. The 2017-era `summary.ctsemFit.R` forms unstandardised `MANIFESTMEANS` as `mxEval(MANIFESTMEANS, mxobj, compute=TRUE)`. That source does not form a `MANIFESTMEANSstd` matrix; the scalar map here is the footnote 4 standardisation of that named intercept: `τ / √θ`. Form strictly positive `θ` first, then divide `τ` by `√θ`. A zero mean is exactly zero. Unstandardised `MANIFESTMEANS` is defined for a zero residual; standardised `MANIFESTMEANS` is not. Zero `θ` has no positive SD and fails closed. Manifest means are an event-time measurement quantity, so a non-event clock fails closed. `MANIFESTMEANS` does not require stable `a < 0`. `MANIFESTVARstd` `θ / θ = 1` recovers the same number when `τ = √θ` and remains a distinct named quantity. `τ / √(λ² Var(η) + θ)` uses total observed variance and is not this residual map. The 2017-era source assigns `dimnames(MANIFESTMEANS)` to `list(manifestNames, manifestNames)` on an `n.manifest × 1` matrix; that assignment is a source bug and is not this map. `T0MEANSstd` `μ_0 / √p_0` recovers the same number when `τ = μ_0` and `θ = p_0` and remains a distinct named quantity. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-25T05:04Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-25T05:04Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `T0MEANSstd`; Table 2, p. 12; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-24T22:30Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised initial latent mean. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. Table 2 names `T0MEANS` the latent process means at the first time point `T0`. The first-occasion relevant variance is free `T0VAR` `p_0`, not process-dynamics `asymDIFFUSION` `-q / (2 a)`, matching Table 3 `T0TIPREDEFFECTstd`. The 2017-era `summary.ctsemFit.R` forms unstandardised `T0MEANS` as `OpenMx::mxEval(T0MEANS, mxobj, compute=TRUE)`. That source does not form a `T0MEANSstd` matrix; the scalar map here is the footnote 4 standardisation of that named first-occasion mean: `μ_0 / √p_0`. Form strictly positive `p_0` first, then divide `μ_0` by `√p_0`. A zero mean is exactly zero. Unstandardised `T0MEANS` is defined for a zero first-occasion variance; standardised `T0MEANS` is not. Zero `p_0` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0MEANS` does not require stable `a < 0`. `T0VARstd` `p_0 / p_0 = 1` recovers the same number when `μ_0 = √p_0` and remains a distinct named quantity. `μ_0 / √asymDIFFUSION` uses process-dynamics variance and is not this first-occasion map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymCINTstd`; Eq. 3, p. 4; footnote 4; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-24T09:05Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic continuous intercept. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. `CINT` is the process intercept of individual, or average individual, dynamics, so that relevant variance is within-subject `asymDIFFUSION` `p = −q / (2 a)`. The 2017-era `summary.ctsemFit.R` forms `asymCINT` whenever `verbose = TRUE`, as `-solve(DRIFT) %*% CINT`. That source does not form an `asymCINTstd` matrix; the scalar map here is the footnote 4 standardisation of that named asymptotic intercept: `(-κ / a) / √p`. Form strictly positive `p` first, then the asymptotic intercept, then divide by `√p`. A zero intercept is exactly zero. Unstandardised `asymCINT` is defined for a zero process; standardised `asymCINT` is not. Zero `q` has no positive process SD and fails closed. Lasting `asymDIFFUSION` requires stable `a < 0`. A non-event clock fails closed. `κ / √p` is the continuous intercept standardisation and is not this total-change map. `A^{-1}[e^{A Δt} − I] κ / √p` depends on the event interval and is not this `Δt → ∞` map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, not `CINTstd`, not `discreteCINTstd`, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `discreteCINTstd`; Eq. 3, p. 4; footnote 4; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-24T05:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised discrete continuous intercept. Page 16 prints discrete-time transformations for a chosen event interval and, when appropriate, standardised matrices with the suffix `std`. Footnote 4 standardises using only the relevant variance, not the total. `CINT` is the process intercept of individual, or average individual, dynamics, so that relevant variance is within-subject `asymDIFFUSION` `p = −q / (2 a)`. The 2017-era `summary.ctsemFit.R` forms `discreteCINT` whenever `verbose = TRUE`, as `solve(DRIFT) %*% (discreteDRIFT − I) %*% CINT`. That source does not form a `discreteCINTstd` matrix; the scalar map here is the footnote 4 standardisation of that named discrete intercept: `A^{-1}[e^{A Δt} − I] κ / √p`. Form strictly positive `p` first, then the discrete intercept, then divide by `√p`. A zero intercept is exactly zero. Unstandardised `discreteCINT` is defined for growing `a ≥ 0` and for zero diffusion; standardised `discreteCINT` is not. Zero `q` has no positive process SD and fails closed. Lasting `asymDIFFUSION` requires stable `a < 0`. A non-event clock fails closed. A non-positive event interval fails closed. `κ / √p` does not depend on `Δt` and is not this finite-interval map. `(-κ / a) / √p` is the standardised asymptotic intercept and is not this map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, not `CINTstd`, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymDIFFUSIONstd`; footnote 4; Eq. 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T23:02Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic within-subject variance. Page 16 names `asymDIFFUSION` the total within-subject variance as `Δt → ∞` and prints standardised matrices with the suffix `std` when appropriate. Footnote 4 standardises using only the relevant variance, not the total. The 2017-era `summary.ctsemFit.R` forms `asymDIFFUSIONstd` whenever `verbose = TRUE`, as `solve(sqrt(diag(asymDIFFUSION) + ridging)) %&% asymDIFFUSION`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. That formation adds `diag(c(ridging), n.latent)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The 2017-era source assigns `dimnames(asymDIFFUSIONstd)` to `latentNames`; that assignment matches the `n.latent × n.latent` matrix and is this map. The scalar correlation is `p / p = 1` after strictly positive Lyapunov `p = −q / (2 a)`. Form strictly positive `p` first, then `1 / √p`, then `(1 / √p) p (1 / √p)`. Unstandardised `asymDIFFUSION` is defined for a zero process; standardised `asymDIFFUSION` is not. Zero `q` makes `solve(sqrt(0))` fail in the 2017-era source and fails closed here. That source does not skip forming `asymDIFFUSIONstd` when `p = 0`. Within-subject variance is an event-time structural quantity, so a non-event clock fails closed. Lasting `asymDIFFUSION` requires stable `a < 0`. Distinct positive `p` recover the same 1. `TIPREDVARstd` `v / v = 1` recovers the same number and remains a distinct named quantity. `DIFFUSIONstd` `q / p = −2 a` is the continuous-diffusion ratio, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T08:02Z: `is_oa: false`, 0 locations; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `TIPREDVAR`; p. 16 `TIPREDVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:53Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised time-independent predictor variance. Table 2 names `TIPREDVAR` the variance/covariance of time-independent predictors. Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `TIPREDVARstd` whenever `verbose = TRUE` and `n.TIpred > 0`, as `solve(sqrt(diag(TIPREDVAR) + ridging)) %&% TIPREDVAR`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. Unlike `TRAITVARstd`, that formation adds `diag(c(ridging), n.TIpred)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The 2017-era source assigns `dimnames(TIPREDVARstd)` to `TIpredNames`; that assignment matches the `n.TIpred × n.TIpred` matrix and is this map. The scalar correlation is `v / v = 1` after strictly positive `TIPREDVAR`. Form strictly positive `v` first, then `1 / √v`, then `(1 / √v) v (1 / √v)`. Unstandardised `TIPREDVAR` is defined for a zero predictor; standardised `TIPREDVAR` is not. Zero `v` makes `solve(sqrt(0))` fail in the 2017-era source and fails closed here. Unlike `TRAITVAR` / `MANIFESTTRAITVAR`, that source does not skip forming `TIPREDVARstd` when `v = 0`. Predictor variance is an event-time structural quantity, so a non-event clock fails closed. `TIPREDVAR` does not require stable `a < 0`. Distinct positive `v` recover the same 1. `MANIFESTVARstd` `θ / θ = 1` recovers the same number and remains a distinct named quantity. Section 7.2 `addedTIPREDVAR` `(B / a)² v` is extra process variance, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers Equation 5 of the scalar analog of Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 2, p. 12 `TDPREDVAR` / `T0TDPREDCOV`; Table 3, p. 13 `T0TIPREDEFFECT`; p. 16; §7.2, pp. 20–21; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:26Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) extra first-occasion time-dependent predictor variance. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The 2017-era `summary.ctsemFit.R` forms the latent extra `addedT0TIPREDVAR` as `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`. That file comments out `TDPREDVAR` and does not form `addedT0TDPREDVAR`. The scalar analog of that quadratic form using the stack's first-occasion TD coefficient `t0_m` and Table 2 `TDPREDVAR` `v` is `t0_m² v`. Equation 5 of that analog extra, with `θ = 0` and `ψ = 0`, is `λ² t0_m² v`. Form the analog extra first, then `(λ extra) λ`. Do not form `λ²` first. A zero loading or zero extra is exactly zero. `v < 0` fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `t0_m` does not require stable `a < 0`. `t0_m² v` is the latent extra, not this observed extra. `λ² p_0 + θ` is first-occasion observed variance, not this extra. `λ² t0_b² v` is Eq. 5 of `addedT0TIPREDVAR` and is not this extra even when `t0_m = t0_b`. `MANIFESTVAR` `θ` is measurement error, not this extra. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:26Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:26Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `MANIFESTVAR`; Eq. 5, p. 5; p. 16 `MANIFESTVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:40Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised measurement-error variance. Table 2 names `MANIFESTVAR` `Θ` the residual covariance of the indicators. Equation 5 writes `ζ ~ N(0, Θ)`. Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `MANIFESTVARstd` whenever `verbose = TRUE`, as `solve(sqrt(diag(MANIFESTVAR) + ridging)) %&% MANIFESTVAR`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. Unlike `TRAITVARstd`, that formation adds `diag(c(ridging), n.manifest)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The 2017-era source assigns `dimnames(MANIFESTVARstd)` to `latentNames`; the matrix is `n.manifest × n.manifest`. That assignment is a source bug and is not this exact map. The scalar correlation is `θ / θ = 1` after strictly positive `MANIFESTVAR`. Form strictly positive `θ` first, then `1 / √θ`, then `(1 / √θ) θ (1 / √θ)`. Unstandardised `MANIFESTVAR` is defined for a zero residual; standardised `MANIFESTVAR` is not. Zero `θ` makes `solve(sqrt(0))` fail in the 2017-era source and fails closed here. Unlike `TRAITVAR` / `MANIFESTTRAITVAR`, that source does not skip forming `MANIFESTVARstd` when `θ = 0`. Measurement-error variance is an event-time structural quantity, so a non-event clock fails closed. `MANIFESTVAR` does not require stable `a < 0`. Distinct positive `θ` recover the same 1. `MANIFESTTRAITVARstd` `ψ / ψ = 1` recovers the same number and remains a distinct named quantity. Equation 5 `λ² Var(η) + θ` is `Var(y)`, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `MANIFESTTRAITVAR`; §7.1, p. 19; p. 16 `MANIFESTTRAITVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:28Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised manifest-trait variance. Table 2 names `MANIFESTTRAITVAR` `Ψ_τ` the additional time-invariant variance-covariance on the measurement level and sets it `NULL` when there is no manifest trait. Section 7.1 names manifest traits stable individual differences in indicator levels, distinct from process-level `TRAITVAR` `φ_ξ`. Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `MANIFESTTRAITVARstd` only when `MANIFESTTRAITVAR != 0`, as `solve(sqrt(diag(MANIFESTTRAITVAR) + ridging)) %&% MANIFESTTRAITVAR` when `verbose = TRUE`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. Unlike `TRAITVARstd`, that formation adds `diag(c(ridging), n.manifest)`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `ψ / ψ = 1` after strictly positive `MANIFESTTRAITVAR`. Form strictly positive `ψ` first, then `1 / √ψ`, then `(1 / √ψ) ψ (1 / √ψ)`. Unstandardised `MANIFESTTRAITVAR` is defined for a zero trait; standardised `MANIFESTTRAITVAR` is not. Zero `MANIFESTTRAITVAR` skips forming `MANIFESTTRAITVARstd` in the 2017-era source and fails closed here. Indicator-level trait variance is an event-time structural quantity, so a non-event clock fails closed. `MANIFESTTRAITVAR` does not require stable `a < 0`. Distinct positive `ψ` recover the same 1. `TRAITVARstd` `trait / trait = 1` recovers the same number and remains a distinct named quantity. `MANIFESTVAR` `θ` is measurement error, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the scalar analog of Driver, Oud, and Voelkle (2017, Table 2, p. 12 `TDPREDVAR` / `T0TDPREDCOV`; Table 3, p. 13 `T0TIPREDEFFECT`; p. 16; §7.2, pp. 20–21; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) extra first-occasion time-dependent predictor variance. The 2017-era `summary.ctsemFit.R` forms `addedT0TIPREDVAR` as `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`. That file comments out `TDPREDVAR` and does not form `addedT0TDPREDVAR`. Table 2 names `T0TDPREDCOV` the covariance between latents at `T0` and time-dependent predictors, not this extra variance. Table 3 names `T0TIPREDEFFECT`, not a TD first-occasion effect matrix. The scalar analog of that quadratic form using the stack's first-occasion TD coefficient `t0_m` and Table 2 `TDPREDVAR` `v` is `t0_m² v`. Form `t0_m` first, then square, then multiply by `v`. A zero coefficient or zero predictor variance is exactly zero. `v < 0` fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `t0_m` does not require stable `a < 0`. `t0_b² v` is `addedT0TIPREDVAR` and is not this extra even when `t0_m = t0_b`. `t0_m · √v / √p_0` is `T0TDPREDEFFECTstd` and is not this variance. `T0TDPREDCOV` is the covariance, not `t0_m² v`. Free `T0VAR` `p_0` is the first-occasion state, not the extra TD variance. `TRAITVAR` is a zero-drift latent process, not `t0_m² v`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T21:34Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T21:34Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `TRAITVAR`; §7.1, pp. 18–19; p. 16 `TRAITVARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:21Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised trait variance. Table 2 names `TRAITVAR` `φ_ξ` the latent trait variance/covariance and sets it `NULL` when there is no trait. Section 7.1 names traits the stable between-subject differences (unit-level unobserved heterogeneity). Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `TRAITVARstd` only when `TRAITVAR != 0`, as `solve(sqrt(diag(TRAITVAR))) %&% TRAITVAR` when `verbose = TRUE`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. Unlike `T0VARstd`, that formation uses `diag(diag(TRAITVAR))` and does not add `diag(c(ridging))`. The ridge is a `T0VAR` numerical hack and is not this exact map. The scalar correlation is `trait / trait = 1` after strictly positive `TRAITVAR`. Form strictly positive `trait` first, then `1 / √trait`, then `(1 / √trait) trait (1 / √trait)`. Unstandardised `TRAITVAR` is defined for a zero trait; standardised `TRAITVAR` is not. Zero `TRAITVAR` skips forming `TRAITVARstd` in the 2017-era source and fails closed here. Between-subject variance is an event-time structural quantity, so a non-event clock fails closed. `TRAITVAR` does not require stable `a < 0`. Distinct positive `trait` recover the same 1. `T0VARstd` `p_0 / p_0 = 1` recovers the same number and remains a distinct named quantity. `addedT0TIPREDVAR` `t0_b² v` is extra first-occasion TI variance, not this correlation. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:21Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13 `T0TDPREDEFFECTstd`; Table 2, p. 12 `TDPREDVAR`; p. 16; footnote 4; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T18:17Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised first-occasion time-dependent predictor effect. Table 3 names `T0TDPREDEFFECT` the effect of time-dependent predictors on latents at `T0`. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is time-dependent predictor variance `TDPREDVAR` `v_x`, not `TIPREDVAR`. The affected variance is free first-occasion `T0VAR` `p_0`, not within-subject `asymDIFFUSION` `-q / (2 a)`, because Table 3 is the first occasion, not the process dynamics. Form strictly positive `p_0` first, then strictly positive `v_x`, then `t0_m · √v_x / √p_0`. Unstandardised `t0_m` is defined for a zero coefficient and for zero predictor variance; standardised `T0TDPREDEFFECT` is not. Zero `p_0` or zero `v_x` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. Same numbers as `T0TIPREDEFFECTstd` yield the same product; Table 3 names a different matrix. The continuous standardisation `B · √v / √(-q / (2 a))` uses `asymDIFFUSION` and is not this first-occasion map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `t0_m · √v_x / √(trait + p_0 + added)` uses the total, not free `T0VAR`, and is not `T0TDPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T18:17Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T18:17Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16; §7.2, pp. 20–21; Table 2, p. 12; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T21:22Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised extra time-independent predictor variance `addedTIPREDVARstd`. Page 16 prints standardised matrices with the suffix `std` when appropriate. After `addedTIPREDVAR` as `asymTIPREDEFFECT %*% TIPREDVAR %*% t(asymTIPREDEFFECT)`, the 2017-era `summary.ctsemFit.R` forms `addedTIPREDVARstd = solve(sqrt(diag(addedTIPREDVAR))) %&% addedTIPREDVAR`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `extra / extra = 1` after strictly positive extra. Form `addedTIPREDVAR` first, then the ratio. A zero extra has no positive extra SD and fails closed. Unstandardised `(B / a)² v` is defined for a zero coefficient and for zero predictor variance; standardised `addedTIPREDVAR` is not. `λ² (B / a)² v` is Eq. 5 of the extra, not this correlation. `t0_b² v` is `addedT0TIPREDVAR`, not this asymptotic extra correlation. `TRAITVAR` is not the standardisation variance. The printed 2-latent `addedTIPREDVAR` 2.838 is not this scalar 1. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T21:22Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T21:22Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `TDPREDEFFECTstd`; Table 2, p. 12; Eq. 3, p. 5; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T21:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous time-dependent predictor effect. Page 16 prints continuous-time parameters and, when appropriate, standardised matrices with the suffix `std`. Table 2 names `M` `TDPREDEFFECT`. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is time-dependent predictor variance `v`. The affected variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because the process dynamics are individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then strictly positive `v`, then `m · √v / √(-q / (2 a))`. Unstandardised `M` is defined for a zero coefficient and for zero predictor variance; standardised `TDPREDEFFECT` is not. Zero `asymDIFFUSION` or zero `v` has no positive SD and fails closed. `TIPREDEFFECTstd` `B · √v / √p` is a different named matrix even when `M = B` and the predictor variances match. The finite-interval intercept-style standardisation `A^{-1}[e^{A Δt} − I] M · √v / √p` depends on the event interval and is not this continuous Dirac coefficient. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `m · √v / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `TDPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Predecessor `event_time.rs` asymptotic-std `process_sd == 0` / `predictor_sd == 0` gates after already-checked `within == 0` and `v == 0` were unreachable; this slice drops them so stacked line/branch coverage can close. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T21:10Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T21:10Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `CINTstd`; Eq. 1, p. 4; Table 2, p. 12; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T17:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous intercept. Page 16 prints continuous-time parameters and, when appropriate, standardised matrices with the suffix `std`. Table 2 names `κ` `CINT`. Footnote 4: standardisations use only the relevant variance, not the total. `CINT` is the process intercept of individual, or average individual, dynamics, so that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`. Form strictly positive `asymDIFFUSION` first, then `κ / √(-q / (2 a))`. Unstandardised `κ` is defined for growing `a ≥ 0` and for zero diffusion; standardised `CINT` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. The asymptotic standardisation `(-κ / a) / √p` is the total change, not this continuous intercept. The finite-interval standardisation `A^{-1}[e^{A Δt} − I] κ / √p` depends on the event interval and is not this continuous map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `κ / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `CINTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `TIPREDEFFECTstd`; §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; footnote 4; JSS PDF re-opened 2026-08-23T16:21Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous time-independent predictor effect. Page 16 prints continuous-time parameters and, when appropriate, standardised matrices with the suffix `std`. Table 2 names `B` `TIPREDEFFECT`. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is predictor variance `TIPREDVAR` `v`. The affected variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because the process dynamics are individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then strictly positive `v`, then `B · √v / √(-q / (2 a))`. Unstandardised `B` is defined for a zero coefficient and for zero predictor variance; standardised `TIPREDEFFECT` is not. Zero `asymDIFFUSION` or zero `v` has no positive SD and fails closed. The asymptotic standardisation `(-B / a) · √v / √p` is the total change, not this continuous coefficient. The finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not this continuous map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `B · √v / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `TIPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `asymTIPREDEFFECTstd`; §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; footnote 4; JSS PDF re-opened 2026-08-23T14:25Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised asymptotic time-independent predictor effect. Page 16 prints continuous-time parameters and, when appropriate, standardised matrices with the suffix `std`. Section 7.2 names `asymTIPREDEFFECT` the expected total change in process means given a unit increase on a time-independent predictor. The scalar map is `-B / a` for stable `a < 0`. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is predictor variance `TIPREDVAR` `v`. The affected variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because the process dynamics are individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then strictly positive `v`, then the unit asymptotic effect, then `(-B / a) · √v / √(-q / (2 a))`. Unstandardised `-B / a` is defined for a zero coefficient and for zero predictor variance; standardised `asymTIPREDEFFECT` is not. Zero `asymDIFFUSION` or zero `v` has no positive SD and fails closed. The finite-interval standardisation `A^{-1}[e^{A Δt} − I] B · √v / √p` depends on the event interval and is not this `Δt → ∞` map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `(-B / a) · √v / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `asymTIPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `DRIFTstd`; Eq. 1, p. 4; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T13:28Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous `DRIFT`. Page 16 prints continuous-time parameters (e.g., `DRIFT`) and, when appropriate, standardised matrices with the suffix `std`. Footnote 4: standardisations use only the relevant variance, not the total. For `DRIFT` that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because `DRIFT` is intended to represent individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first. In the scalar stationary case the within-subject SD ratio is 1, so the standardised auto-effect equals the unstandardised log-rate numerically; those remain distinct named quantities. Unstandardised `a` is defined for growing `a ≥ 0` and for zero diffusion; standardised `DRIFT` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. The discrete standardisation `e^{a Δt}` depends on the event interval and is not the continuous map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `a p / (trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `DRIFTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `DIFFUSIONstd`; Eq. 4, p. 5; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T13:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised continuous `DIFFUSION`. Page 16 prints continuous-time parameters (e.g., `DRIFT`, `DIFFUSION`) and, when appropriate, standardised matrices with the suffix `std`. Footnote 4: standardisations use only the relevant variance, not the total. Process noise is within-subject stochastic input, so that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`, the same footnote 4 variance used for `DRIFT`. Form strictly positive `asymDIFFUSION` first, then `q / (−q / (2 a))`. In the scalar stationary case that ratio equals `-2 a` and does not depend on `q` once `q > 0`. Unstandardised `q` is defined for growing `a ≥ 0` and for zero diffusion; standardised `DIFFUSION` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. The discrete standardisation `Q_Δt / (−q / (2 a)) = 1 − exp(2 a Δt)` depends on the event interval and is not the continuous map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `q / (trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `DIFFUSIONstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:19Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `discreteDIFFUSIONstd`; Eq. 3–4, pp. 4–5; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T13:06Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised discrete `DIFFUSION`. Page 16 prints discrete-time transformations for a chosen event interval (`discreteDRIFT`, `discreteDIFFUSION`) and, when appropriate, standardised matrices with the suffix `std`. Footnote 4: standardisations use only the relevant variance, not the total. Process noise is within-subject stochastic input, so that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`, the same footnote 4 variance used for `DRIFT`. Form strictly positive `asymDIFFUSION` first, then `Q_Δt` from Equation 4, then `Q_Δt / (−q / (2 a))`. In the scalar stationary case that ratio equals `1 − exp(2 a Δt)`. Unstandardised `Q_Δt` is defined for growing `a ≥ 0` and for zero diffusion; standardised `DIFFUSION` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. The continuous standardisation `q / (−q / (2 a)) = −2 a` is not the discrete map. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `Q_Δt / (trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `discreteDIFFUSIONstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T13:06Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T13:06Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 `discreteDRIFTstd`; Eq. 3, p. 5; footnote 4; §7.1, pp. 18–19; JSS PDF re-opened 2026-08-23T11:40Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised discrete `DRIFT`. Page 16 prints `discreteDRIFT` as `expm(DRIFT Δt)` and, when appropriate, `discreteDRIFTstd`. Footnote 4: standardisations use only the relevant variance, not the total. For `DRIFT` that relevant variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because `DRIFT` is intended to represent individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then `φ = exp(a Δt)`. In the scalar stationary case the within-subject SD ratio is 1, so the standardised auto-effect equals the unstandardised discrete lag numerically; those remain distinct named quantities. Unstandardised `e^{a Δt}` is defined for growing `a ≥ 0` and for zero diffusion; standardised `DRIFT` is not. Zero `asymDIFFUSION` has no positive SD and fails closed. Section 7.1 warns that omitting trait variance confounds between- and within-person information. The trait-plus-state autocorrelation `(trait + e^{a Δt} p + added) / (trait + p + added)` uses the total, not `asymDIFFUSION`, and is not `discreteDRIFTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T11:40Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T11:40Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 5, p. 5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T10:03Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar first-occasion variance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Between-subject `TRAITVAR` and `addedTIPREDVAR` are inherently stationary. The first-occasion composition is `trait + p_0 + (B / a)² v`. Form the free first-occasion state variance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary first-occasion map. Stationary first-occasion variance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Free `T0VAR` `p_0` is not this map. The lagged map `trait + e^{a Δt} p_0 + (B / a)² v` decays the state and is not this map. The later-occasion map `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v` includes `Q_Δt` and is not this map. As `Δt → 0+` those maps approach this composition. A zero trait, a zero initial variance, and a zero TI contribution is exactly zero. A zero initial variance and a zero TI contribution is exactly the trait. Trait-only variance does not require a stable drift. `a ≥ 0` cannot hold a finite TI extra variance when that contribution is nonzero and fails closed. Equation 5 of that first-occasion variance is `λ²(trait + p_0 + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not that first-occasion observed variance. The predetermined first-occasion latent variance is not the predetermined first-occasion observed variance. Stationary first-occasion observed variance is not that observed variance when `p_0` is free. Predetermined later observed variance includes `Q_Δt` and is not that first-occasion observed variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T10:03Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T10:03Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T20:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar lagged covariance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Equation 3 writes `η(t) = exp(A Δt) η(t0) + …`. Equation 4 writes `cov(η_t, η_{t-1}) = A_Δt cov(η_{t-1})`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not decay with `e^{a Δt}`. The lagged composition is `trait + e^{a Δt} p_0 + (B / a)² v`. Form the lagged free first-occasion covariance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary lagged map. Stationary lagged covariance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state (`e^{a Δt}` of that total) is not this map. Free `T0VAR` `p_0` is not this map. The later-occasion map `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v` includes `Q_Δt` and is not this map. As `Δt → ∞` with stable `a < 0` the state term vanishes. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. A zero-diffusion carry with `a ≥ 0` is `e^{a Δt} p_0` and is kept. Trait-only variance does not require a stable drift. The interval must be event time and strictly positive. Equation 5 of that lagged covariance is `λ²(trait + e^{a Δt} p_0 + (B / a)² v) + ψ`. Independent `ε_t` does not enter. `MANIFESTVAR` is not that lagged observed covariance. The predetermined lagged latent covariance is not the predetermined lagged observed covariance. Predetermined later observed variance includes `Q_Δt` and `θ` and is not that lagged observed covariance. Stationary lagged observed covariance is not that observed covariance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T20:20Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T20:20Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T20:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-occasion variance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. The process gradually transitions from the variances of the initial parameters toward those of the parameters when the model is stationary. Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes that the integral exhibits covariance `Q_Δt`. The law of total variance on the within-subject state is `e^{2 a Δt} p_0 + Q_Δt`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not enter that process-noise integral. The later-occasion composition is `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v`. Form the evolved free first-occasion variance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary later-occasion map. Stationary later-occasion variance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state (`e^{2 a Δt}` of that total plus `Q_Δt`) is not this map. Free `T0VAR` `p_0` is not this map. As `Δt → ∞` with stable `a < 0` the carried `p_0` vanishes and `Q_Δt` approaches `−q / (2 a)`, so the composition approaches contemporaneous stationary `T0VAR`. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. Nonzero diffusion with `a ≥ 0` is a growing process and is kept. The interval must be event time and strictly positive. Equation 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not that later-occasion observed variance. The predetermined later-occasion latent variance is not the predetermined later-occasion observed variance. Stationary later-occasion observed variance is not that observed variance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T20:20Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T20:20Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16 finite-interval standardised `TIPREDEFFECT`; §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; footnote 4; JSS PDF re-opened 2026-08-24T01:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised finite-interval time-independent predictor effect. Page 16 prints discrete-time transformations for a chosen event interval and, when appropriate, standardised matrices with the suffix `std`. Equation 3 maps a finite event interval as `A^{-1}[e^{A Δt} − I] B`. Table 2 names `B` `TIPREDEFFECT`. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is predictor variance `TIPREDVAR` `v`. The affected variance is within-subject `asymDIFFUSION` `-q / (2 a)`, because the process dynamics are individual, or average individual, temporal dynamics. Form strictly positive `asymDIFFUSION` first, then strictly positive `v`, then the unit discrete increment, then `A^{-1}[e^{A Δt} − I] B · √v / √(-q / (2 a))`. Unstandardised `A^{-1}[e^{A Δt} − I] B` is defined for a zero coefficient and for zero predictor variance; standardised finite-interval `TIPREDEFFECT` is not. Zero `asymDIFFUSION` or zero `v` has no positive SD and fails closed. Page 16 `asymTIPREDEFFECTstd` `(-B / a) · √v / √p` is the `Δt → ∞` map and is not this finite interval. A later event interval yields a different standardised increment. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `A^{-1}[e^{A Δt} − I] B · √v / √(trait + p + added)` uses the total, not `asymDIFFUSION`, and is not the finite-interval map when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-24T01:20Z: `is_oa: false`; Springer `content/pdf` is HTML 200; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-24T01:20Z: `is_oa: false`; Springer `content/pdf` is HTML 200; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12 `T0VAR`; p. 16 `T0VARstd`; footnote 4; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T22:06Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised first-occasion latent variance. Table 2 names `T0VAR` the latent process initial variance/covariance. Page 16 prints standardised matrices with the suffix `std` when appropriate. The 2017-era `summary.ctsemFit.R` forms `T0VARstd` as `solve(sqrt(diag(T0VAR))) %&% T0VAR` when `verbose = TRUE`. OpenMx `%&%` is the quadratic form `t(A) %*% B %*% A`. The default `ridging = FALSE` adds 0, not `0.0001`; that ridge is a numerical hack and is not this exact map. The scalar correlation is `p_0 / p_0 = 1` after strictly positive free `T0VAR`. Form strictly positive `p_0` first, then `1 / √p_0`, then `(1 / √p_0) p_0 (1 / √p_0)`. Unstandardised `T0VAR` is defined for a zero first-occasion variance; standardised `T0VAR` is not. Zero `p_0` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. Distinct positive `p_0` recover the same 1. `T0TDPREDEFFECTstd` `t0_m · √v / √p_0` depends on `p_0` and is not this correlation. `addedT0TIPREDVAR` `t0_b² v` is extra TI variance, not this correlation. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T22:06Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T22:06Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13 `T0TDPREDEFFECTstd`; Table 2, p. 12; p. 16; footnote 4; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T21:34Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised first-occasion time-dependent predictor effect. Table 3 names `T0TDPREDEFFECT` the effect of time-dependent predictors on latents at `T0`. Table 2 names `M` `TDPREDEFFECT` and names `T0TDPREDCOV` the first-occasion covariance, not this coefficient. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is time-dependent predictor variance `v`, not `TIPREDVAR`. The affected variance is free first-occasion `T0VAR` `p_0`, not within-subject `asymDIFFUSION` `-q / (2 a)`, because Table 3 is the first occasion, not the process dynamics. Form strictly positive `p_0` first, then strictly positive `v`, then `t0_m · √v / √p_0`. Unstandardised `t0_m` is defined for a zero coefficient and for zero predictor variance; standardised `T0TDPREDEFFECT` is not. Zero `p_0` or zero `v` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. The continuous standardisation `m · √v / √(-q / (2 a))` uses `asymDIFFUSION` and is not this first-occasion map. `T0TIPREDEFFECTstd` `t0_b · √v / √p_0` is a different named matrix even when `t0_m = t0_b` and the predictor variances match. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `t0_m · √v / √(trait + p_0 + added)` uses the total, not free `T0VAR`, and is not `T0TDPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T21:34Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T21:34Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 2, p. 12; §7.2, pp. 20–21; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T19:23Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar extra observed-indicator time-independent predictor variance of §7.2 `addedTIPREDVAR`. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The 2017-era `summary.ctsemFit.R` forms the latent extra `addedTIPREDVAR` as `asymTIPREDEFFECT %*% TIPREDVAR %*% t(asymTIPREDEFFECT)`. The scalar latent extra is `(B / a)² v`. Equation 5 of that extra, with `θ = 0` and `ψ = 0`, is `λ² (B / a)² v`. Form `addedTIPREDVAR` first, then `(λ extra) λ`. Do not form `λ²` first. A zero loading or zero extra is exactly zero. `v < 0` fails closed. A non-event clock fails closed. `a ≥ 0` cannot hold a finite process-mean change when the extra is nonzero and fails closed. `(B / a)² v` is the latent extra, not this observed extra. `λ² t0_b² v` is Eq. 5 of `addedT0TIPREDVAR`, not this asymptotic observed extra. `λ² p + θ` is stationary observed variance, not this extra. `MANIFESTVAR` `θ` is measurement error, not this extra. `Ψ` is intercept variance and is not extra TI. The printed 2-latent `addedTIPREDVAR` 2.838 is not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T19:10Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T19:10Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 3, p. 13 `T0TIPREDEFFECT`; Table 2, p. 12; p. 16; §7.2, pp. 20–21; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T19:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar extra observed-indicator time-independent predictor variance of 2017-era `addedT0TIPREDVAR`. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The 2017-era `summary.ctsemFit.R` forms the latent extra `addedT0TIPREDVAR` as `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`. The scalar latent extra is `t0_b² v`. Equation 5 of that extra, with `θ = 0` and `ψ = 0`, is `λ² t0_b² v`. Form `addedT0TIPREDVAR` first, then `(λ extra) λ`. Do not form `λ²` first. A zero loading or zero extra is exactly zero. `v < 0` fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0TIPREDEFFECT` does not require stable `a < 0`. `t0_b² v` is the latent extra, not this observed extra. `λ² p_0 + θ` is first-occasion observed variance, not this extra. `λ² (B / a)² v` is Eq. 5 of `addedTIPREDVAR`, not this first-occasion observed extra. `MANIFESTVAR` `θ` is measurement error, not this extra. `Ψ` is intercept variance and is not extra TI. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T19:10Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T19:10Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13 `T0TIPREDEFFECT`; p. 16; §7.2, pp. 20–21; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T18:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar first-occasion extra time-independent predictor variance `addedT0TIPREDVAR`. Table 3 names `T0TIPREDEFFECT` the effect of time-independent predictors on latents at `T0`. Page 16 prints extra summary matrices when `verbose = TRUE`. The 2017-era `summary.ctsemFit.R` forms `addedT0TIPREDVAR` as `T0TIPREDEFFECT %*% TIPREDVAR %*% t(T0TIPREDEFFECT)` immediately after `T0TIPREDEFFECTstd`. Section 7.2 names `addedTIPREDVAR` the stable between-subject variance accounted for by time-independent predictors at the process asymptote, `(B / a)² v`. The first-occasion analogue uses free `T0TIPREDEFFECT`, not `-B / a`. The scalar map is `t0_b² v`. Form `t0_b` first, then square, then multiply by `v`. A zero coefficient or zero predictor variance is exactly zero. `v < 0` fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0TIPREDEFFECT` does not require stable `a < 0`. `(B / a)² v` is `addedTIPREDVAR` and is not this first-occasion map. `t0_b · √v / √p_0` is `T0TIPREDEFFECTstd` and is not this variance. Free `T0VAR` `p_0` is the first-occasion state, not the extra TI variance. `TRAITVAR` is a zero-drift latent process, not `t0_b² v`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T18:20Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T18:20Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13 `T0TIPREDEFFECTstd`; p. 16; footnote 4; Eq. 3, p. 5; 2017-era ctsem `summary.ctsemFit.R`; JSS PDF re-opened 2026-08-23T17:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar standardised first-occasion time-independent predictor effect. Table 3 names `T0TIPREDEFFECT` the effect of time-independent predictors on latents at `T0`. Page 16 prints standardised matrices with the suffix `std` when appropriate. Footnote 4: standardisations use only the relevant variance, not the total. The affecting variance is predictor variance `TIPREDVAR` `v`. The affected variance is free first-occasion `T0VAR` `p_0`, not within-subject `asymDIFFUSION` `-q / (2 a)`, because Table 3 is the first occasion, not the process dynamics. Form strictly positive `p_0` first, then strictly positive `v`, then `t0_b · √v / √p_0`. Unstandardised `t0_b` is defined for a zero coefficient and for zero predictor variance; standardised `T0TIPREDEFFECT` is not. Zero `p_0` or zero `v` has no positive SD and fails closed. `T0` is an event-time occasion, so a non-event clock fails closed. Free `T0VAR` does not require stable `a < 0`. The continuous standardisation `B · √v / √(-q / (2 a))` uses `asymDIFFUSION` and is not this first-occasion map. The asymptotic standardisation `(-B / a) · √v / √p` is the total change, not this first-occasion coefficient. Section 7.1 warns that omitting trait variance confounds between- and within-person information. `t0_b · √v / √(trait + p_0 + added)` uses the total, not free `T0VAR`, and is not `T0TIPREDEFFECTstd` when `TRAITVAR` is nonzero. `TRAITVAR` is not the standardisation variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T17:20Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T17:20Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T11:05Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-start later-occasion variance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Section 4.3 notes that the process gradually transitions from the initial variances toward the stationary variances, and that the initial time point need not reflect the first measurement occasion (`startoffset`). Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes that the integral exhibits covariance `Q_Δt`. After a later start `u` the within-subject state variance is `e^{2 a u} p_0 + Q_u`. Evolving that later start over `s` is `e^{2 a s}(e^{2 a u} p_0 + Q_u) + Q_s`. Chapman–Kolmogorov writes `Q_{u+s} = e^{2 a s} Q_u + Q_s`, so the later-occasion map over `u + s` is the same composition. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not enter `Q_s`. The later-start later-occasion composition is `trait + e^{2 a s}(e^{2 a u} p_0 + Q_u) + Q_s + (B / a)² v`. Form the later-start within-subject variance first, then evolve that state, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary later-occasion map. Stationary later-occasion variance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Later-occasion variance at `u` omits `Q_s` and is not this map when `s > 0`. Later-start lagged covariance is `e^{a s}` of the later state and omits `Q_s`; it is not this map. Evolving the later total as if it were all state (`e^{2 a s}` of `trait + e^{2 a u} p_0 + Q_u + (B / a)² v` plus `Q_s`) is not this map. Later-occasion variance over the lag interval alone ignores `startoffset` and omits `e^{2 a s} Q_u`; it is not this map when `u > 0`. As `u → 0+` the composition approaches later-occasion variance over `s`. As `s → 0+` the composition approaches later-occasion variance at `u`. As `s → ∞` with stable `a < 0` the carried later state vanishes and `Q_s` approaches `−q / (2 a)`, so the composition approaches contemporaneous stationary `T0VAR`. A zero trait, a zero initial variance, a zero diffusion, and a zero TI contribution is exactly zero. A zero initial variance, a zero diffusion, and a zero TI contribution is exactly the trait. Trait-only variance does not require a stable drift. `a ≥ 0` cannot hold a finite TI extra variance when that contribution is nonzero and fails closed. Nonzero diffusion with `a ≥ 0` is a growing process and is kept. Both intervals must be event time and strictly positive. Equation 5 of that later-start later-occasion variance is `λ²(trait + e^{2 a s}(e^{2 a u} p_0 + Q_u) + Q_s + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not that later-start later-occasion observed variance. The later-start later-occasion latent variance is not the later-start later-occasion observed variance. Predetermined later observed variance at `u` omits `Q_s` and is not that observed variance when `s > 0`. Later-start lagged observed covariance omits `Q_s` and `θ` and is not that observed variance. Stationary later-occasion observed variance is not that observed variance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T11:05Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T11:05Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T10:27Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-start lagged covariance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Section 4.3 notes that the process gradually transitions from the initial variances toward the stationary variances, and that the initial time point need not reflect the first measurement occasion (`startoffset`). Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes `cov(η_t, η_{t-1}) = A_Δt cov(η_{t-1})`. After a later start `u` the within-subject state variance is `e^{2 a u} p_0 + Q_u`. Lagging that later start over `s` is `e^{a s}(e^{2 a u} p_0 + Q_u)`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not decay with `e^{a s}`. The lagged composition is `trait + e^{a s}(e^{2 a u} p_0 + Q_u) + (B / a)² v`. Form the later-start within-subject variance first, then lag that state, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary lagged map. Stationary lagged covariance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. First-occasion lagged covariance `trait + e^{a s} p_0 + (B / a)² v` omits `e^{a s} Q_u` and is not this map when `u > 0`. Later-occasion variance includes `Q_u` without lagging that later state and is not this map. Evolving the later total as if it were all state (`e^{a s}` of `trait + e^{2 a u} p_0 + Q_u + (B / a)² v`) is not this map. As `u → 0+` the composition approaches first-occasion lagged covariance. As `s → 0+` the composition approaches later-occasion variance at `u`. As `s → ∞` with stable `a < 0` the state term vanishes. A zero trait, a zero initial variance, a zero diffusion, and a zero TI contribution is exactly zero. A zero initial variance, a zero diffusion, and a zero TI contribution is exactly the trait. Trait-only variance does not require a stable drift. `a ≥ 0` cannot hold a finite TI extra variance when that contribution is nonzero and fails closed. Nonzero diffusion with `a ≥ 0` is a growing process and is kept. Both intervals must be event time and strictly positive. Equation 5 of that later-start lagged covariance is `λ²(trait + e^{a s}(e^{2 a u} p_0 + Q_u) + (B / a)² v) + ψ`. Independent `ε_t` does not enter. `MANIFESTVAR` is not that later-start lagged observed covariance. The later-start lagged latent covariance is not the later-start lagged observed covariance. First-occasion lagged observed covariance omits `e^{a s} Q_u` and is not that observed covariance when `u > 0`. Predetermined later observed variance includes `Q_u` and `θ` and is not that later-start lagged observed covariance. Stationary lagged observed covariance is not that observed covariance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T10:27Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T10:27Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T09:04Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar lagged covariance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. Equation 3 writes `η(t) = exp(A Δt) η(t0) + …`. Equation 4 writes `cov(η_t, η_{t-1}) = A_Δt cov(η_{t-1})`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not decay with `e^{a Δt}`. The lagged composition is `trait + e^{a Δt} p_0 + (B / a)² v`. Form the lagged free first-occasion covariance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary lagged map. Stationary lagged covariance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state (`e^{a Δt}` of that total) is not this map. Free `T0VAR` `p_0` is not this map. The later-occasion map `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v` includes `Q_Δt` and is not this map. As `Δt → ∞` with stable `a < 0` the state term vanishes. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. A zero-diffusion carry with `a ≥ 0` is `e^{a Δt} p_0` and is kept. Trait-only variance does not require a stable drift. The interval must be event time and strictly positive. Equation 5 of that lagged covariance is `λ²(trait + e^{a Δt} p_0 + (B / a)² v) + ψ`. Independent `ε_t` does not enter. `MANIFESTVAR` is not that lagged observed covariance. The predetermined lagged latent covariance is not the predetermined lagged observed covariance. Predetermined later observed variance includes `Q_Δt` and `θ` and is not that lagged observed covariance. Stationary lagged observed covariance is not that observed covariance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T09:04Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T09:04Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-23T05:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-occasion variance of §4.3 predetermined `T0VAR`. Section 4.3 treats the first time point as predetermined when no assumptions are made about the process prior to the initial time point. Free `T0VAR` `p_0` is then estimated. The process gradually transitions from the variances of the initial parameters toward those of the parameters when the model is stationary. Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes that the integral exhibits covariance `Q_Δt`. The law of total variance on the within-subject state is `e^{2 a Δt} p_0 + Q_Δt`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not enter that process-noise integral. The later-occasion composition is `trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v`. Form the evolved free first-occasion variance first, then include the trait, then include the TI extra variance, then add. Setting `p_0 = −q / (2 a)` recovers the stationary later-occasion map. Stationary later-occasion variance uses `−q / (2 a)` in place of `p_0` and is not this map when `p_0` is free. Evolving `trait + p_0 + (B / a)² v` as if it were all state (`e^{2 a Δt}` of that total plus `Q_Δt`) is not this map. Free `T0VAR` `p_0` is not this map. As `Δt → ∞` with stable `a < 0` the carried `p_0` vanishes and `Q_Δt` approaches `−q / (2 a)`, so the composition approaches contemporaneous stationary `T0VAR`. As `Δt → 0+` the composition approaches `trait + p_0 + (B / a)² v`. Nonzero diffusion with `a ≥ 0` is a growing process and is kept. The interval must be event time and strictly positive. Equation 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt} p_0 + Q_Δt + (B / a)² v) + θ + ψ`. `MANIFESTVAR` is not that later-occasion observed variance. The predetermined later-occasion latent variance is not the predetermined later-occasion observed variance. Stationary later-occasion observed variance is not that observed variance when `p_0` is free. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-23T05:12Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-23T05:12Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- Branch coverage JSON now unique-folds `files[].branches` True/False counts across instantiations. Nightly totals on #49 head `1e3e2eb` reported `event_time.rs` 505/506 while every unique site had both arms taken (253 sites × 2 instantiations). Summary-only reports without branch arrays still fail closed on totals. The 100% contract is unique production arms, matching the LCOV authored-line gate. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` maps overflowing `expm1(a Δt)` / `expm1(2 a Δt)` in `recover_discrete_constant_predictor_effect` and `recover_discrete_process_noise` through the log-space rewrite without a redundant `if !argument.is_finite()` after overflow. Local crate llvm-cov on #49 head `559e7b399473ee90ba3234677dd9ef7f05f7fd2e` was 509/510: the same LLVM `exp`/`expm1` finite-argument proof as L768/L5040. Existing rewrite (`a = 800` / `a = 400`) and overflow (`a = 1e308`) tests remain the contract. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` maps overflowing `e^{a Δt}` / `e^{a(t−u)}` through the log-space rewrite without redundant `if !argument.is_finite()` after `exp` overflow on lagged covariance, T0 TI/TD carry, and impulse carry. Nightly branch coverage on #49 head `7e669babcc54408dd8407bbac56be0f304fa99e5` was 1713/1714: LLVM counted `event_time.rs` L5040 True and treated the finite-argument overflow False as uncovered after proving `exp` of a finite argument is finite, which binary64 overflow falsifies. `fit_scalar_log_rate` now also skips a zero earlier residual and a negative lag while still recovering from a valid pair. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` maps overflowing `e^{2 a Δt}` in `recover_discrete_latent_variance` through the log-space rewrite `(ln p + 2 a Δt).exp()` without a redundant `if !2 a Δt.is_finite()` after `exp` overflow. Nightly branch coverage on #49 head `e301e9706c0bd671ccad533063fb624cc568d0b3` was 1715/1716: LLVM counted `event_time.rs` L768 True and treated the finite-argument overflow False as uncovered after proving `exp` of a finite argument is finite, which binary64 overflow falsifies. Existing rewrite (`p = 1e-308`, `a = 400`, `Δt = 1`) and overflow (`a = 1e308`) tests remain the contract. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` executes the later `|| !log_rate.is_finite()` operand on `recover_discrete_time_independent_predictor_effect` from both the lib tests and the multilevel integration crate. Nightly branch coverage on #49 head `90b08bbe82cbe7776365a6c04df38857dfe5e53c` was 1714/1716: both True arms at `event_time.rs` L2480 were unhit because fail-closed tests supplied a non-finite `TIPREDEFFECT` or predictor before `a`. Direct `a = NaN` now takes those arms. `LagClock::as_str` is called through `black_box` so the outlined instantiation is not const-folded away. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` evaluates the Driver, Oud, and Voelkle (2017, §7.2) extra-process lag as `e^{ε Δt}` even when `ε Δt` underflows to `0` (`exp(0) = 1`). Nightly branch coverage on #49 head `22b8e68813ad59a9a91689bacfa4cf033dfad158` was 1718/1720: LLVM deleted `if extra_argument == 0.0` / `original_argument == 0.0` True after proving `ε < 0` and `Δt > 0` imply a nonzero product, which binary64 underflow falsifies. The public map now uses `exp` directly; `original_log_rate == 0` remains the Brownian `e^{0} = 1` path. Recovery tests assert the §7.2 identity `a_{ηξ} x e^{a Δt}(e^{(ε−a)Δt} − 1)/(ε − a)` on `(-min_subnormal) * 1e-320`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` integration tests now execute the Driver, Oud, and Voelkle (2017, Eq. 3 first-summand carry) overflow rewrite of Table 3 `T0TIPREDEFFECT` / `T0TDPREDEFFECT` (`sign(t0_b z) exp(ln|t0_b z| + a Δt)` and the same form for `t0_m x0`). Nightly branch coverage on #49 head `d634f5849ed8e9f75af1b43c2e59d8e7d6301b45` was 1718/1720: the two missing records were the unused non-`cfg(test)` instantiations of `if !drift_interval.is_finite()` at the T0 TI and T0 TD carry overflow rewrites (`event_time.rs` L4245 and L4628). Lib tests already covered both sides; integration tests now take overflowing `a Δt` (`1e308 * 2`) and finite-`a Δt` overflowed `exp` (`710`) on those public maps. Meredith (1993) remains unread (Unpaywall 2026-08-22T23:12Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T23:12Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-22T23:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar later-occasion variance of §4.3 stationary `T0VAR`. Section 4.3 constrains first-occasion variance according to the model-predicted variances across all time points. Equation 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral. Equation 4 writes that the integral exhibits covariance `Q_Δt`. The law of total variance on the within-subject state is `e^{2 a Δt}(−q / (2 a)) + Q_Δt`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not enter that process-noise integral. The later-occasion composition is `trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v`. Form the evolved within-subject variance first, then include the trait, then include the TI extra variance, then add. Under stationarity that composition equals contemporaneous `T0VAR`. Evolving the constrained total as if it were all state (`e^{2 a Δt} p_stat + Q_Δt`) is not this map. The lagged covariance `trait + e^{a Δt}(−q / (2 a)) + (B / a)² v` omits `Q_Δt` and is not this map. `Q_Δt` is not this map. The interval must be event time and strictly positive. Equation 5 of that later-occasion variance is `λ²(trait + e^{2 a Δt}(−q / (2 a)) + Q_Δt + (B / a)² v) + θ + ψ`. The lagged observed covariance omits `Q_Δt` and `θ`. `MANIFESTVAR` is not that later-occasion observed variance. The later-occasion latent variance is not the later-occasion observed variance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-22T23:12Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T23:12Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 3–5, pp. 4–5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-22T19:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar lagged covariance of §4.3 stationary `T0VAR`. Equation 3 writes `η(t) = exp(A Δt) η(t0) + …`. Equation 4 writes `cov(η_t, η_{t-1}) = A_Δt cov(η_{t-1})`. The contemporaneous constraint is `trait + −q / (2 a) + (B / a)² v`. Trait variance and `addedTIPREDVAR` are time-invariant between-subject and do not decay with `e^{a Δt}`. The lagged composition is `trait + e^{a Δt}(−q / (2 a)) + (B / a)² v`. Form the lagged within-subject covariance first, then include the trait, then include the TI extra variance, then add. As `Δt → ∞` with stable `a < 0` the state term vanishes. As `Δt → 0+` the lagged map approaches contemporaneous `T0VAR`. Those limits are not this finite-lag map. Evolving the constrained total as if it were all state is not this map. `trait + e^{a Δt} p` is not this map when `addedTIPREDVAR` is nonzero. Contemporaneous `T0VAR` is not this map. The interval must be event time and strictly positive. Equation 5 of that lagged covariance is `λ²(trait + e^{a Δt}(−q / (2 a)) + (B / a)² v) + ψ`. Independent `ε_t` does not enter. `MANIFESTVAR` is not that lagged observed covariance. Contemporaneous `Var(y_0)` includes `θ` and is not that lagged observed covariance. The lagged latent covariance is not the lagged observed covariance. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-22T19:13Z: `is_oa: false`; title *Measurement Invariance, Factor Analysis and Factorial Invariance*). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T19:13Z: `is_oa: false`; title *Randomization-Based Inference about Latent Variables from Complex Samples*). +- `psychometric_core` rustfmt-sorts the `event_time` test import list and wraps four long test signatures so `cargo fmt --check` matches 1.97.1. Nightly branch coverage on #49 head `a6bea47acc38de1a33ed403360eb5cacd3023df6` was 1691/1712: the 21 missing True sides in `event_time.rs` were later `||` operands and `!Δt.is_finite()` (as opposed to `Δt <= 0`) on lagged observed covariance, extra-process, asymptotic TI/CINT, T0 carry, and impulse-carry guards. Direct inner-map calls now execute those arms. `as_measurement_invariance_wire_name` maps only Configural/Metric/Strong onto `#84` `configural`/`metric`/`scalar` and returns `None` for local Strict (`as_str` remains `"strict"`). Parent-head coverage note on `ebd01c4` is historical. Meredith (1993) remains unread (Unpaywall 2026-08-22T16:13Z: `is_oa: false`; Springer `content/pdf` is HTML 200). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T16:13Z: `is_oa: false`; Springer `content/pdf` is HTML 200). Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` covers the remaining fail-closed arms on `event_time.rs` lines 1995, 1998, 2063, 2065, 3695, 3706, 3751, 4078, 4089, and 4134 (nightly line/branch gaps on predecessor #49 head `ebd01c4`). Non-event clocks, non-positive and non-finite `Δt`, after-t0 extra-process interval errors after a successful `μ_t`, a zero extra-process contribution returning `μ_t`, Table 3 `T0TIPREDEFFECT`/`T0TDPREDEFFECT` effect errors through the carry, overflowing `a Δt` products, and those carry errors through the evolved-mean composition now execute. Meredith (1993) remains unread (Unpaywall 2026-08-22T12:15Z: `is_oa: false`; Springer `content/pdf` is HTML 200; Cambridge Core PDF 302 to a closed product page). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T12:15Z: `is_oa: false`; Springer `content/pdf` is HTML 200; NCES 404; ETS RR-91-18 404). Driver, Oud, and Voelkle (2017) JSS PDF re-opened 2026-08-22T12:17Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 5, p. 5; Table 2, p. 12; p. 16; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-22T03:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator variance of §4.3 stationary `T0VAR`. Section 4.3 constrains the first-occasion variance to the model-predicted variance when `stationary` includes `"T0VAR"`. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The constrained latent variance is `trait + −q / (2 a) + (B / a)² v`. The scalar composition is `Var(y_0) = λ²(trait + −q / (2 a) + (B / a)² v) + θ + ψ`. Form the stationary latent variance first, then `λ² p + θ + ψ`. A zero loading is exactly `θ + ψ`. A zero trait, a zero diffusion, and a zero TI contribution is exactly `θ + ψ`. `λ² p_0` for free `T0VAR` is not this composition. `λ²(−q / (2 a)) + θ` is not this composition when `TRAITVAR` or `addedTIPREDVAR` is nonzero. Evolving the constrained variance as if it were all state is not this composition when the trait or TI contribution is nonzero. `MANIFESTVAR` is not `Var(y_0)`. The constrained latent variance is not `Var(y_0)`. `TRAITVAR` is latent and is scaled by `λ²`; `MANIFESTTRAITVAR` is not. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-22T03:20Z: `is_oa: false`). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T03:20Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; p. 16; Table 2, p. 12; §7.2, pp. 20–21; Eq. 4, p. 5; JSS PDF re-opened 2026-08-22T03:07Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar stationary `T0VAR`. Section 4.3 constrains the first-occasion variance to the model-predicted variance when `stationary` includes `"T0VAR"`. Page 16 names `asymDIFFUSION` the total within-subject variance `-q / (2 a)`. Section 4.3 (p. 9) adds `TRAITVAR`. Section 7.2 names `addedTIPREDVAR` the stable between-subject variance accounted for by time-independent predictors, `(B / a)² v`. The scalar composition is `trait + −q / (2 a) + (B / a)² v`. Form the within-subject contribution first, then include the trait, then include the TI extra variance, then add. A zero trait, a zero diffusion, and a zero TI contribution is exactly zero. A zero diffusion and a zero TI contribution is exactly the trait. `a ≥ 0` cannot hold a finite process variance when the diffusion or the TI contribution is nonzero and fails closed. Trait-only variance does not require a stable drift. That constrained first-occasion variance is not free `T0VAR`, not `asymDIFFUSION` alone, not `TRAITVAR` alone, not `addedTIPREDVAR` alone, and not the finite-interval discrete latent variance. The printed 2-latent `addedTIPREDVAR` 2.838 is not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall 2026-08-22T03:07Z: request empty). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-22T03:07Z: request empty; ETS RR-88-45 PDF 404; Wiley PDF 403). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, pp. 9–10; Eq. 5, p. 5; Table 2, p. 12; Eq. 3, p. 5; JSS PDF re-opened 2026-08-21T20:07Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of §4.3 stationary `T0MEANS`. Section 4.3 constrains the first-occasion mean to the model-predicted mean when `stationary` includes `"T0MEANS"`. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The constrained latent mean is `-κ / a + −B z / a`. The scalar composition is `E(y_0) = τ + λ(−κ / a + −B z / a)`. Form the stationary latent mean first, then `τ + λ` of that mean. A zero loading is exactly `τ`. A zero intercept and a zero TI contribution is exactly `τ`. Evolving from that stationary start with `CINT` and `TIPREDEFFECT` stays at the stationary mean. `τ + λ μ_0` for free `T0MEANS` is not this composition. `τ + λ(−κ / a)` is not this composition when `B z ≠ 0`. `τ + λ μ_t` is not this composition. `MANIFESTMEANS` is not `E(y_0)`. The constrained latent mean is not `E(y_0)`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (Unpaywall request empty this cycle). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (Unpaywall 2026-08-21T20:10Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, p. 16; Table 2, p. 12; Eq. 3, p. 5; JSS PDF opened 2026-08-21T16:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar stationary `T0MEANS`. Page 16 constrains `T0MEANS` to the model-implied values using `T0MEANSbase` / `T0MEANSfree` when the first observation is determined by the process in the same way as later observations. Those constraints include extra effects due to time-independent predictors (`asymTIPREDEFFECT`). For stable `a < 0` the scalar composition is `-κ / a + −B z / a`. Form the intercept contribution first, then include the TI extra effect, then add. A zero intercept and a zero TI contribution is exactly zero. `a ≥ 0` cannot hold a finite process-mean change when either contribution is nonzero and fails closed. That constrained first-occasion mean is not free `T0MEANS`, not `asymCINT` alone, not `asymTIPREDEFFECT` alone, and not the finite-interval discrete latent mean. The printed 2-latent `T0MEANS` 2.823 is not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T16:21Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 2, p. 12; Eq. 3, p. 5; §4.3 / p. 16; JSS PDF opened 2026-08-21T16:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar `asymCINT`. Table 2 names `κ` `CINT` and names `asymCINT` the asymptotic (`Δt = ∞`) expected change in processes for a 1 unit change in intercept. Equation 3 maps a finite event interval as `A^{-1}[e^{A Δt} − I] κ`. For stable `a < 0` that `Δt → ∞` limit is `-A^{-1} κ`. The scalar map is `-κ / a`. A unit intercept is `-1 / a`. Form `κ` first, then divide by `-a`. A zero intercept is exactly zero. `a ≥ 0` cannot hold a finite process-mean change and fails closed. `-κ / a` is not `κ`, not the finite-interval increment `A^{-1}[e^{A Δt} − I] κ`, not `T0MEANS`, and not `asymTIPREDEFFECT` `-B z / a`. Page 16 notes that a `T0MEANS` stationarity constraint includes time-independent predictors; that composition is not this intercept-only map. The printed 2-latent `CINT` values are not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T16:21Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; JSS PDF opened 2026-08-21T13:08Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar `addedTIPREDVAR`. Section 7.2 names that matrix the stable between-subject variance accounted for by time-independent predictors. For stable `a < 0` and predictor variance `v ≥ 0` the scalar map is `(B / a)² v`. Form the unit asymptotic effect `-B / a` first, then square, then multiply by `v`. A zero coefficient or zero predictor variance is exactly zero. `v < 0` fails closed. `a ≥ 0` cannot hold a finite process-mean change and fails closed. `(B / a)² v` is not `TRAITVAR`, not `asymDIFFUSION`, and not the expected total change `-B z / a`. The printed 2-latent `addedTIPREDVAR` 2.838 is not this scalar map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T06:24Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 20–21; Eq. 3, p. 5; Table 2, p. 12; JSS PDF opened 2026-08-21T13:08Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar `asymTIPREDEFFECT`. Table 2 names `B` `TIPREDEFFECT`. Equation 3 maps a finite event interval as `A^{-1}[e^{A Δt} − I] B z`. Section 7.2 names `asymTIPREDEFFECT` the expected total change in process means given an increase of 1 on a time-independent predictor. For stable `a < 0` that total change is `-A^{-1} B`. The scalar map is `-B z / a`. Form `B z` first, then divide by `-a`. A zero coefficient or zero predictor is exactly zero. `a ≥ 0` cannot hold a finite process-mean change and fails closed. `-B z / a` is not the coefficient `B`, not the finite-interval increment `A^{-1}[e^{A Δt} − I] B z`, not `CINT`, and not `M x`. Printed LeisureTime `TIPREDEFFECT` `−0.225` / `asymTIPREDEFFECT` `−1.673` and Happiness `0.549` / `0.219` reconstruct under this map. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T06:24Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; §7.2, pp. 22–23; JSS PDF re-opened 2026-08-21T06:32Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of an extra-process `TDPREDEFFECT` after `t0`. Section 7.2 names `T0TDPREDEFFECT` when the extra process begins at `t = 0` and `TDPREDEFFECT` when it begins after `t = 0`. The printed extra process has `LAMBDA` 0. Original indicators load on the original process after the `DRIFT` coupling over `t − u` with `t0 < u < t` while `μ_t` still uses `Δt = t − t0`. The scalar composition is `E(y_t) = τ + λ(μ_t + a_{ηξ} x (e^{ε(t−u)} − e^{a(t−u)}) / (ε − a))`. The first-occasion extra-process observed mean uses `Δt` for both the evolution and the extra drive and is not this composition when `u ≠ t0`. The evolved observed mean `τ + λ μ_t` is not this composition. The impulse-carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is a Dirac on the original process and is not this `DRIFT` drive. An impulse at `u = t0` or `u = t` is not interior. A zero original-indicator loading is exactly `τ`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T06:24Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; §7.2, pp. 22–23; Eq. 1–3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-21T06:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of the extra near-zero-drift latent process contribution. Section 7.2's printed extra process has `LAMBDA` 0 and is not an observed indicator. Original indicators load on the original process after the `DRIFT` coupling `a_{ηξ}`. After a unit identification impulse the latent process at `t` is `μ_t + a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)`. The scalar composition is `E(y_t) = τ + λ(μ_t + a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a))`. Form the evolved-plus-contribution latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition. The extra-process contribution is not `E(y_t)`. The evolved-plus-contribution latent mean is not `E(y_t)`. A zero original-indicator loading is exactly `τ`. A zero coupling recovers `τ + λ μ_t`. `ε ≥ 0` fails closed. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-21T06:24Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 22–23; Eq. 1–3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T23:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar contribution of the extra near-zero-drift latent process. Section 7.2 specifies a lasting level change by that extra process: `T0MEANS`, `CINT`, `T0VAR`, `DIFFUSION`, and `TRAITVAR` of it are fixed to 0; `TDPREDEFFECT` on it is fixed to 1; its `DRIFT` diagonal is very close to 0 (printed example `−0.000001`; precisely 0 causes computational problems); and its effect on the original process is the `DRIFT` coupling `a_{ηξ}`. After a unit identification impulse the scalar contribution is `a_{ηξ} x (e^{ε Δt} − e^{a Δt}) / (ε − a)` (`ε = a` is `a_{ηξ} x Δt e^{a Δt}`). Form `a_{ηξ} x` first. A zero coupling or zero predictor is exactly zero. `ε ≥ 0` fails closed. That contribution is not `κ = −a m x`, not `(1 − e^{a Δt}) m x`, and not the dissipating Dirac `m x`. Still not a Kalman filter, not a matrix `expm`, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T23:10Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 20–21; Eq. 3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T19:50Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar discrete increment of the lasting level-change `CINT`. Section 7.2 sets `CINT` to `TDPREDEFFECT * −DRIFT` (`κ = −a m x`). Equation 3 maps that intercept through `A^{-1}[e^{A Δt} − I] κ`. With `κ = −a m x` the scalar increment is `(e^{a Δt} − 1)/a · (−a m x) = (1 − e^{a Δt}) m x`. Form the level-change `CINT` first, then the discrete intercept map. Underflow of `e^{a Δt}` to `+0` keeps the equilibrium offset `m x`. `(1 − e^{a Δt}) m x` is not the contemporaneous jump `m x`. `(1 − e^{a Δt}) m x` is not `κ`. `(1 − e^{a Δt}) m x` is not `A^{-1}[e^{A Δt} − I] B z`. Stable `a < 0` is required. A zero effect or zero predictor is exactly zero. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T19:45Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §7.2, pp. 20–21; Eq. 1–3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T19:45Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar lasting level-change `CINT`. Section 7.2 contrasts a sudden Dirac that dissipates back to the process mean with a lasting level change. To generate that lasting change, `CINT` is set to `TDPREDEFFECT * −DRIFT`. The scalar setting is `κ = −a m x`. Form `m x` first, then multiply by `−a`. Stable `a < 0` is required so `−κ / a = m x` is an equilibrium offset. `a ≥ 0` cannot hold a new process mean. `−a m x` is not the contemporaneous jump `m x`. `−a m x` is not a free `CINT`. `−a m x` is not `A^{-1}[e^{A Δt} − I] B z`. The extra near-zero-drift latent process also named in §7.2 is a different specification and is not this `CINT` setting. A zero effect or zero predictor is exactly zero. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T19:45Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 3 first summand, p. 5; Table 3, p. 13; JSS PDF re-opened 2026-08-20T19:07Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a first-occasion time-dependent predictor. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. Table 3 names `T0TDPREDEFFECT` the effect of time-dependent predictors on latents at `T0`. Equation 3's first summand carries that shift as `e^{A Δt} t0_m x0`. The scalar composition is `E(y_t) = τ + λ(μ_t + e^{a Δt} t0_m x0)`. Form the evolved-plus-carry latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The process-increment map `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition. The impulse-carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not this composition when `u ≠ t0`. The first-occasion TI map `τ + λ(μ_t + e^{a Δt} t0_b z)` is not this composition. `MANIFESTMEANS` is not `E(y_t)`. The evolved-plus-carry latent mean is not `E(y_t)`. `T0TDPREDEFFECT` is the coefficient, not that observed mean. Same numbers as `T0TIPREDEFFECT` yield the same product; Table 3 names a different matrix. A zero loading is exactly `τ`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T19:09Z: `is_oa: false`). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13; Eq. 3 first summand, p. 5; JSS PDF re-opened 2026-08-20T19:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar first-occasion time-dependent predictor shift and its carry. Table 3 names `T0TDPREDEFFECT` the effect of time-dependent predictors on latents at `T0`. Table 2 / Table 3 name `TDPREDEFFECT` `M`, which enters Equation 3 as the printed fourth-summand Dirac `M x` at `u = t`. Those are not the same matrix. The scalar first-occasion shift is `t0_m x0`. Equation 3's first summand carries that shift as `e^{A Δt} t0_m x0`. Form `t0_m x0` first, then `e^{a Δt} t0_m x0`. Form `μ_t` first, then add that carry. A zero drift is `t0_m x0` with no dissipation. Binary64 underflow of `e^{a Δt}` to `+0` is a vanishing carry of the first-occasion shift and is kept. `t0_m x0` is not `M x`, not `e^{A(t−u)} M x` for `t0 < u < t`, not `t0_b z`, not `A^{-1}[e^{A Δt} − I] B z`, and not `κ`. `e^{A Δt} t0_m x0` is not `t0_m x0`. `T0TDPREDEFFECT` is the coefficient, not `t0_m x0`. An impulse at `u ≤ t0` that used `M` is already in `η(t0)` as `TDPREDEFFECT`, not as `T0TDPREDEFFECT`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T19:09Z: `is_oa: false`). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 3 first summand, p. 5; Table 3, p. 13; JSS PDF re-opened 2026-08-20T15:28Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a first-occasion time-independent predictor. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. Table 3 names `T0TIPREDEFFECT` the effect of time-independent predictors on latents at `T0`. Equation 3's first summand carries that shift as `e^{A Δt} t0_b z`. The scalar composition is `E(y_t) = τ + λ(μ_t + e^{a Δt} t0_b z)`. Form the evolved-plus-carry latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The process-increment map `τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition. The impulse-carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not this composition when `u ≠ t0`. `MANIFESTMEANS` is not `E(y_t)`. The evolved-plus-carry latent mean is not `E(y_t)`. `T0TIPREDEFFECT` is the coefficient, not that observed mean. A zero loading is exactly `τ`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T15:14Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Table 3, p. 13; Eq. 3 first summand, p. 5; JSS PDF opened 2026-08-20T15:14Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar first-occasion time-independent predictor shift and its carry. Table 3 names `T0TIPREDEFFECT` the effect of time-independent predictors on latents at `T0`. Table 2 / Table 3 name `TIPREDEFFECT` `B`, which enters Equation 3 as `A^{-1}[e^{A(t−t0)} − I] B z`. Those are not the same matrix. The scalar first-occasion shift is `t0_b z`. Equation 3's first summand carries that shift as `e^{A Δt} t0_b z`. Form `t0_b z` first, then `e^{a Δt} t0_b z`. Form `μ_t` first, then add that carry. A zero drift is `t0_b z` with no dissipation. Binary64 underflow of `e^{a Δt}` to `+0` is a vanishing carry of the first-occasion shift and is kept. `t0_b z` is not `A^{-1}[e^{A Δt} − I] B z`, not `κ`, and not `M x`. `e^{A Δt} t0_b z` is not `t0_b z`. `T0TIPREDEFFECT` is the coefficient, not `t0_b z`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T15:14Z: `is_oa: false`; Springer `content/pdf` is HTML 200). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 3, p. 5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T12:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a time-independent predictor. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. Equation 3 prints the `TIPREDEFFECT` increment as the addend `A^{-1}[e^{A(t−t0)} − I] B z_i` after the `T0MEANS` carry and the `CINT` increment. Table 2 names `B` `TIPREDEFFECT`. The scalar composition is `E(y_t) = τ + λ(μ_t + A^{-1}[e^{A Δt} − I] B z)`. Form the evolved-plus-increment latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition. The carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not this composition when `u ≠ t`. `MANIFESTMEANS` is not `E(y_t)`. The evolved-plus-increment latent mean is not `E(y_t)`. `TIPREDEFFECT` is `B`, not that observed mean. A zero loading is exactly `τ`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T05:12Z: `is_oa: false`). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 1–3, pp. 4–5; Table 2, p. 12; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-20T09:01Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a contemporaneous time-dependent impulse. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The latent process at `t` after a contemporaneous Dirac (`u = t`) is `μ_t + m x`. The scalar composition is `E(y_t) = τ + λ(μ_t + m x)`. Form the evolved-plus-impulse latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The carry map `τ + λ(μ_t + e^{a(t−u)} m x)` is not this composition when `u ≠ t`. `MANIFESTMEANS` is not `E(y_t)`. The evolved-plus-impulse latent mean is not `E(y_t)`. A zero loading is exactly `τ`. The §7.2 level-change form is a different specification and is not this map. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T05:12Z: `is_oa: false`). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 1–2, pp. 4–5; Eq. 3 exponential map; Table 2, p. 12; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-20T05:12Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean of a within-interval time-dependent impulse carry. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. The latent process at `t` after a Dirac that occurred strictly inside `(t0, t)` is `μ_t + e^{a(t−u)} m x`. The scalar composition is `E(y_t) = τ + λ(μ_t + e^{a(t−u)} m x)`. Form the carried latent mean first, then `τ + λ` of that mean. The evolved observed mean `τ + λ μ_t` is not this composition. The contemporaneous map `τ + λ(μ_t + m x)` is not this composition when `u ≠ t`. `MANIFESTMEANS` is not `E(y_t)`. The carried latent mean is not `E(y_t)`. A zero loading is exactly `τ`. The §7.2 level-change form is a different specification and is not this map. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T05:12Z: `is_oa: false`). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 1–2, pp. 4–5; Eq. 3 exponential map; Table 2, p. 12; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-20T10:33Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar within-interval time-dependent predictor impulse carry. Equation 1 writes `dη = (A η + ξ + B z + M χ(t)) dt + G dW`. Equation 2 writes `χ_i(t) = Σ x_{i,u} δ(t − u)`. The Green-function integral of that Dirac on `(t0, t)` is `e^{A(t−u)} M x`. The printed Eq. 3 fourth summand is the contemporaneous jump `M x` at `u = t`. This map is the strictly within-interval case `t0 < u < t`. Form `m x` first, then `e^{a(t−u)} m x`. A zero drift is `m x` with no dissipation. Underflow of `e^{a(t−u)}` to `+0` is vanishing dissipation back to the process mean and is kept. Form `μ_t` first, then add the carry. `e^{A(t−u)} M x` is not the contemporaneous Dirac, not `CINT`, not `A^{-1}[e^{A Δt} − I] B z` (`TIPREDEFFECT`), and not Voelkle et al. (2012, Eq. 14) `a_{yx} Δt`. An impulse at `u = t` is the contemporaneous map. An impulse at `u ≤ t0` is already in `η(t0)`. The §7.2 level-change form is a different specification and is not this map. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T10:33Z: `is_oa: false`). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 1–3, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-20T10:13Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar time-independent predictor increment. Equation 1 writes `dη = (A η + b + A_{ηξ} ξ + B z) dt + G dW + M dχ`. Equation 3's second summand is `A^{-1}[e^{A Δt} − I](b + A_{ηξ} ξ + B z)`. Table 2 names `B` `TIPREDEFFECT`. Form `B z` first, then the discrete intercept map. A zero drift is `B z Δt`. Form `μ_t` first, then add that increment. `TIPREDEFFECT` is `B`, not the discrete increment. `A^{-1}[e^{A Δt} − I] B z` is not `CINT`, not `M x` (`TDPREDEFFECT`), and not Voelkle et al. (2012, Eq. 14) `a_{yx} Δt`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T10:13Z: `is_oa: false`). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 1–3, pp. 4–5; Table 2, p. 12; §7.2, pp. 20–21; JSS PDF re-opened 2026-08-20T07:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar contemporaneous time-dependent predictor impulse. Equation 2 writes `χ_i(t) = Σ x_{i,u} δ(t − u)`. Equation 3's fourth summand is `M Σ x_{i,u} δ(t − u)`. Table 2 names `M` `TDPREDEFFECT`. Section 7.2 calls this a sudden impulse that dissipates back to the process mean and reports `TDPREDEFFECT` as the initial impact. The scalar jump is `m x`. Form `μ_t` first, then add `m x`. `TDPREDEFFECT` is not `CINT`. `M x` is not `A^{-1}[e^{A Δt} − I] B z` (`TIPREDEFFECT`). `M x` is not Voelkle et al. (2012, Eq. 14) `a_{yx} Δt`. The §7.2 level-change form is a different specification and is not this map. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993), Vandenberg and Lance (2000), and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-20T07:10Z: `is_oa: false`). +- `psychometric_core` caps two-observation two-group OLS residual invariance at strong/scalar. `ordinary_least_squares_fit` returns residual variance `0` when `n ≤ 2`; that identity is not an estimated residual and is not strict. Putnick and Bornstein (2016, PMC author manuscript PMC5145197 opened 2026-08-19T22:15Z from https://pmc.ncbi.nlm.nih.gov/articles/PMC5145197/) require scalar invariance before latent-mean comparison; residual invariance is not a prerequisite because residuals are not part of the latent factor. Matching loading and intercept with `n = 2` therefore stay strong/scalar and still license `(ȳ_c − ȳ_r)/λ`. This is still two-group OLS, not MGCFA. Meredith (1993) remains unread (OpenAlex/Semantic Scholar 2026-08-19T22:15Z: closed; Springer `content/pdf` is HTML 200). Vandenberg and Lance (2000) remains unread (cited by Putnick for the residual-not-required claim). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 3, p. 5; Eq. 5, p. 5; Table 2, p. 12; JSS PDF re-opened 2026-08-19T22:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar evolved observed-indicator mean. Equation 3 writes `η_i(t) = exp(A Δt) η_i(t0) + A^{-1}[exp(A Δt) − I] ξ_i + …` with `ξ_i ~ N(κ, φ_ξ)` (p. 4) and a stochastic integral of mean zero. Equation 5 writes `y_i(t) = Γ_i + Λ η_i(t) + ζ_i(t)` with `Γ ~ N(τ, Ψ)` and `ζ ~ N(0, Θ)`. The scalar composition is `E(y_t) = τ + λ μ_t` with `μ_t` the Eq. 3 expected-value map. Form `μ_t` first, then `τ + λ μ_t`. The first-occasion map `τ + λ μ_0` is not `E(y_t)`. `MANIFESTMEANS` is not `E(y_t)`. `T0MEANS` is not `E(y_t)`. `μ_t` is not `E(y_t)`. A zero-CINT overflow of `exp(a Δt)` fails the carried `T0MEANS` term closed (`a = 710`, `Δt = 1`). Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) remains unread (OpenAlex 2026-08-19T22:10Z: closed; Springer `content/pdf` is HTML 200). Mislevy (1991, *Psychometrika, 56*, 177–196) remains unread (OpenAlex/Semantic Scholar 2026-08-19T22:10Z: closed). Putnick and Bornstein (2016) PMC PDF was HTML/500 on this cycle. Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. Asparouhov and Muthén (2009) statmodel PDF re-opened 2026-08-19T22:10Z; it cites Meredith (1993) and discusses multiple-group intercept/mean structures but does not license this map. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 3, p. 4; Table 2, p. 12; JSS PDF re-opened 2026-08-19T18:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar expected-value latent mean. Equation 3 writes `η(t) = exp(A Δt) η(t0) + ∫ exp(A(t−s)) (b + …) ds` plus a stochastic integral of mean zero. Table 2 names the first-occasion latent mean `T0MEANS` and `κ` `CINT`. The scalar map is `μ_t = exp(a Δt) μ_0 + (exp(a Δt) − 1)/a κ`. Form the CINT increment first, then add the carried `T0MEANS` term. A zero drift is the Eq. 3 integral `κ Δt` (`A = 0` has no inverse). As `Δt → ∞` with stable `a < 0`, `μ_t → −κ / a`. Binary64 underflow of `exp(a Δt)` to `+0` drops the carried `T0MEANS` and keeps that equilibrium increment. `T0MEANS` is not `μ_t`. `CINT` is not the discrete increment. `CINT` is not `T0MEANS`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (OpenAlex 2026-08-19T18:10Z: closed; Springer `content/pdf` is HTML 200). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 2, p. 12; JSS PDF re-opened 2026-08-19T14:08Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator mean. Equation 5 writes `y_i(t) = Γ + Λ η_i(t) + ζ_i(t)` with `ζ ~ N(0, Θ)` and `Γ ~ N(τ, Ψ)`. Table 2 names `τ` `MANIFESTMEANS`, `κ` `CINT`, and the first-occasion latent mean `T0MEANS`. The scalar map is `E(y) = τ + λ μ`. Form `λ μ` then add `τ`. Do not treat `MANIFESTMEANS` as `E(y)`. `E(η)` is not `E(y)`. `CINT` is not `MANIFESTMEANS`. `T0MEANS` is not `E(y)`. Forming `λ²` is the variance path, not this mean. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-19T14:08Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Eq. 3–4, pp. 4–5; Table 2, p. 12; JSS PDF re-opened 2026-08-19T04:18Z) scalar lagged observed-indicator covariance. Independent measurement error does not enter `cov(y_t, y_{t-1})`. The scalar map is `λ² cov(η_t, η_{t-1}) + ψ`. Form `(λ c) λ` then add `ψ`. Do not form `λ²` first (`λ = 1e308`, `c = 1e-308` → `1e308`). `MANIFESTVAR` is not lagged observed covariance. Lagged `Var(η)` path is not `cov(y)`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall 2026-08-19T04:25Z: closed). +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 5, p. 5; Table 2, p. 12; JSS PDF re-opened 2026-08-19T04:18Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) scalar observed-indicator variance with `MANIFESTTRAITVAR`. Equation 5 writes `y_i(t) = τ_i + Λ η_i(t) + ε_i(t)` with `ε ~ N(0, Θ)` and `τ_i ~ N(μ_τ, Ψ_τ)`. Equation 1 (p. 4) is the latent SDE, not the measurement model. Table 2 names `Θ` `MANIFESTVAR` and `Ψ_τ` `MANIFESTTRAITVAR`; p. 16 restates those names. The scalar map is `Var(y) = λ² Var(η) + θ` when `Ψ_τ = 0` and `λ² Var(η) + θ + ψ` otherwise. Form `(λ p) λ` then add `θ`, then add `ψ`. `MANIFESTVAR` is not `Var(y)`. `MANIFESTTRAITVAR` is not `MANIFESTVAR`. `TRAITVAR` is latent additional variance and is scaled by `λ²`; `MANIFESTTRAITVAR` is not. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-19T04:18Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. +- `psychometric_core` evaluates the Driver, Oud, and Voelkle (2017, Eq. 4, p. 5; JSS PDF re-opened 2026-08-19T04:10Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) stationary within-subject variance as `q / -(2 a)` when the scalar Kronecker sum `2 a` is finite. The paper limit is `-q / (2 a)` (`A# = A ⊗ I + I ⊗ A`; p. 16 `asymDIFFUSION`). Forming `q / a` first overflows at `q = MAX`, `a = -0.75` while `MAX / 1.5` is finite (CodeRabbit finding on `75ecdd3`). When `2 a` overflows (`a = -1e308`), form `(q / a) * -0.5`. Do not form `0.5 q` first (`q = from_bits(1)` underflows). Still not a Kalman filter, not DSEM, not a matrix `expm`, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-19T04:10Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 1, p. 4; p. 16 `MANIFESTVAR`; JSS PDF re-opened 2026-08-19T00:14Z) scalar observed-indicator variance. Equation 1 writes `y_i(t) = Λ η_i(t) + τ + ε_i(t)` with `ε ~ N(0, Θ)`. The scalar map is `Var(y) = λ² Var(η) + θ`. Form `(λ p) λ` then add `θ`. Do not form `λ²` first (`λ = 1e308`, `p = 1e-308` → `1e308`). `MANIFESTVAR` is not `Var(y)`. `Var(η)` is not `Var(y)`. Still not a Kalman filter, not ESEM estimation, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-19T00:14Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. +- `psychometric_core` evaluates the Driver, Oud, and Voelkle (2017, Eq. 4, p. 5; JSS PDF re-opened 2026-08-19T00:14Z) stationary within-subject variance as `(q / a) * -0.5`. The paper limit is `-q / (2 a)`. Forming `2 a` first overflows at `a = -1e308`. Forming `0.5 q` first underflows at `q = from_bits(1)`, `a = -from_bits(1)` and returns `+0` (CodeRabbit finding on `556e23d`); the representable Lyapunov solution is `0.5`. Still not a Kalman filter, not DSEM, not a matrix `expm`, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-19T00:14Z: closed; Springer `content/pdf` is HTML 200). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, §4.3, p. 9; JSS PDF re-opened 2026-08-18T21:07Z) scalar trait-plus-state latent variance and lagged covariance. A stable trait process has `DRIFT` and `DIFFUSION` fixed to zero, so `Var = trait + state` and `cov(t, t-1) = trait + exp(a Δt) p`. The ctsem `TRAITVAR` rewrite that adds the trait to `DIFFUSION` does not license treating trait variance as process noise. Trait variance is not `asymDIFFUSION`. Evolving the summed variance as if it were all state is not this map. Still not RI-CLPM, not a Kalman filter, not DSEM, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-18T21:07Z: closed). Oud and Jansen (2000) remains unread. ZORA accepted manuscript re-opened via bitstream `424f9082-0eeb-4a67-b687-9845a4ed892f`. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 4, p. 5; §4.3 pp. 9–10; p. 16 `asymDIFFUSION`; JSS PDF re-opened 2026-08-18T18:03Z) scalar stationary within-subject variance. Eq. 4 writes `Q_Δt = irow(A#^{-1}[e^{A# Δt} − I] row(Q))` with `A# = A ⊗ I + I ⊗ A`. The scalar Kronecker sum is `2 a`. As `Δt → ∞` with stable `a < 0`, that limit is `-q / (2 a)`. Form `-0.5 q / a`; do not form `2 a` first (`a = -1e308`, `q = 1e308` → `0.5`). Starting from that variance, `Var(η_t)` is invariant across finite event intervals. A zero diffusion is exactly zero. `a ≥ 0` has no finite stationary variance. Finite-interval `Q_Δt` is not `asymDIFFUSION`. Still not a Kalman filter, not DSEM, not a matrix `expm`, and not ctsem estimation. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-18T18:03Z: closed). Oud and Jansen (2000) remains unread. ZORA Anubis-blocked. +- `psychometric_core` refuses a zero-diffusion Driver, Oud, and Voelkle (2017, Eq. 3–4, pp. 4–5; JSS PDF re-opened 2026-08-18T14:04Z) latent variance when `2 (a Δt)` overflows to `+∞`. Zero diffusion is exactly `Q_Δt = 0` (Eq. 3 integral of a zero `G`). That skip does not license `Var(η_t) = exp(2 a Δt) p + 0` when the carried term is non-finite (`p = 2`, `q = 0`, `a = 1e308`, `Δt = 2`). Nightly uncovered production line `event_time.rs:596` on predecessor `321568a` is this arm. Still not a Kalman filter, not DSEM, and not a matrix `expm`. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex/Semantic Scholar 2026-08-18T14:04Z: closed; Springer `content/pdf` is HTML 200). Oud and Jansen (2000) remains unread. +- `psychometric_core` recovers the Driver, Oud, and Voelkle (2017, Eq. 3–4, pp. 4–5; JSS PDF re-opened 2026-08-18T11:20Z) lagged latent covariance `cov(η_ti, η_{t-1,i}) = A_Δt cov(η_{t-1,i})` and the law-of-total-variance map `Var(η_ti) = A_Δt Var(η_{t-1,i}) A_Δt⊤ + Q_Δt`. Eq. 3 writes `η(t) = exp(A Δt) η(t0) + … +` the stochastic integral; Eq. 4 writes that the integral exhibits covariance `Q_Δt`. `Q_Δt` remains `cov(η_ti | η_{t-1,i})` for the homogeneous process (`ξ`, `z` given) and is refused as the unconditional variance. The JSS article has no numbered §2.2 (2.1 is Continuous time and SEM; §3 follows). Scalar `exp(a Δt) p` underflow to `+0` is a vanishing covariance and is kept. Finite-`a Δt` exponential overflow rewrites as `exp(ln p + a Δt)`. A finite `exp(a Δt)` whose product with `p` overflows fails closed. Still not a Kalman filter, not DSEM, and not a matrix `expm`. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex/Semantic Scholar 2026-08-18T11:05Z: closed). Oud and Jansen (2000) remains unread (Radboud 403). ZORA Anubis-blocked. +- `psychometric_core` closes nightly branch coverage on `event_time.rs` (160/164 on `6c13dfb`). The four remaining False sides were `assert!(a && b)` in the unit-test module (Eq. 12 equilibrium-increment and expm1-overflow oracles); they cannot take False on a passing test. Split into independent asserts. Lib-instantiation fail-closed arms for Voelkle et al. (2012, Eq. 14) and Driver, Oud, and Voelkle (2017, Eq. 3) stay in the integration contract. Driver JSS PDF already opened 2026-08-18T07:06Z, p. 4 (`L` remains identity; this is not a Kalman filter). Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex 2026-08-18T07:17Z: closed; Springer `content/pdf` is HTML 200, not a PDF). ERIC ED334221 is Singer and Willett (1991). ZORA Anubis-blocked. Oud and Jansen (2000) remains unread. +- `psychometric_core` refuses an overflowing Driver Eq. 3 rewrite scale `0.5 q / a` (JSS PDF re-opened 2026-08-18T03:07Z, p. 4). When `expm1(z)` overflows at a finite `z = 2(a Δt)` and `0.5 q / a` is non-finite (`q = 1e308`, `a = 0.1`, `Δt = 4000` → `z = 800`), `Q_Δt = q(e^{2aΔt}−1)/(2a)` is not finite and fails closed. Algebraically identical to the licensed integral. Still not a Kalman filter, not DSEM, and not a matrix `expm`. Meredith (1993) and Mislevy (1991, *Psychometrika, 56*, 177–196) remain unread (Unpaywall/OpenAlex/Semantic Scholar/CORE 2026-08-18T03:07Z: closed). ERIC ED334221 is Singer and Willett (1991), not Mislevy (1991). ERIC ED333032 remains Mislevy, Sheehan, and Wingersky (1990). ZORA Anubis-blocked. Oud and Jansen (2000) remains unread. +- `psychometric_core` evaluates Driver, Oud, and Voelkle (2017, Eq. 3; JSS PDF re-opened 2026-08-17T21:03Z, p. 4) as \(0.5 q(\operatorname{expm1}(z)/a)\) with \(z=2(a\Delta t)\). Forming \(2a\) first overflows when \(|a|\) is at the binary64 extreme even if \(a\Delta t\) and \(Q_{\Delta t}\) are finite (`a=1e308`, `Δt=1e-308` → \(0.5(\mathrm{e}^{2}-1)/10^{308}\); `a=-1e308`, `q=1e308`, `Δt=2` → \(0.5\)). Algebraically identical to \(q(\mathrm{e}^{2a\Delta t}-1)/(2a)\). `expm1(−∞)` keeps \(-0.5 q/a\). \(z\to+\infty\) still fails closed. Still not a Kalman filter, not DSEM, and not a matrix `expm`. Meredith (1993), Mislevy (1991), and Oud and Jansen (2000) remain unread (Unpaywall/OpenAlex/Semantic Scholar 2026-08-17T21:03Z: closed; ZORA Anubis-blocked). +- `psychometric_core` recovers Voelkle et al. (2012, Eq. 14; ZORA accepted manuscript re-opened 2026-08-17T14:20Z, Introducing Intercepts, manuscript p. 21): the discrete effect of a time-varying predictor whose sampling interval equals its constancy interval is \(b^{*}_{y.x}(\Delta t)=a_{yx}\Delta t\). It does not depend on the predictor auto-effect. That product is not Eq. 12. Unmatched sampling and constancy intervals fail closed (Oud & Jansen, 2000, unread). An overflowing Eq. 12 rewrite scale \(a_{yx}/a_{xx}\) also fails closed. Still not DSEM. +- `psychometric_core` recovers Voelkle et al. (2012, Eq. 12) when `expm1(z)` overflows to `+∞` at a finite `z`. The rewrite is `sign(a_{yx}/a_{xx})\exp(\ln|a_{yx}|+z-\ln|a_{xx}|)-a_{yx}/a_{xx}` (algebraically identical to `(a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)`). A zero continuous effect is exactly zero even when `expm1` overflows (`0\cdot+\infty` is `NaN`). `z\to+\infty` remains fail-closed. ZORA accepted manuscript re-opened 2026-08-17T13:26Z, Introducing Intercepts, manuscript p. 20; Driver, Oud, and Voelkle (2017, Eq. 3) restated `A^{-1}[e^{A\Delta t}-I]\xi`. Still not DSEM. +- `psychometric_core` evaluates Voelkle et al. (2012, Eq. 12) as \(a_{yx}(\operatorname{expm1}(z)/a_{xx})\) with \(z=a_{xx}\Delta t\). That order is algebraically identical to \((a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)\). Dividing the increment by the finite auto-effect keeps the equilibrium increment \(-a_{yx}/a_{xx}\) when \(z\) overflows to \(-\infty\) (ZORA accepted manuscript, Introducing Intercepts: the exponential vanishes as \(\Delta t\) grows; CodeRabbit finding on `7ffb65b`). The prior \(a_{yx}\Delta t\) overflow case remains finite. Binary64 underflow of \(z\) to `+0` recovers the Eq. 12 limit \(a_{yx}\Delta t\); the first-order product is still not the general discrete effect. Still not DSEM. +- `psychometric_core` evaluates Voelkle et al. (2012, Eq. 12) as \(a_{yx}(\operatorname{expm1}(z)/z\cdot\Delta t)\) with \(z=a_{xx}\Delta t\). That order is algebraically identical to \((a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)\). Multiplying the unitless scale by \(\Delta t\) before \(a_{yx}\) keeps a finite Eq. 12 result when \(a_{yx}\Delta t\) overflows (ZORA accepted manuscript re-opened 2026-08-17T13:13Z, p. 16). Binary64 underflow of \(z\) to `+0` recovers the Eq. 12 limit \(a_{yx}\Delta t\); the first-order product is still not the general discrete effect. Driver, Oud, and Voelkle (2017, p. 4) restated the discrete intercept as a function of \(A\) and \(\Delta t\). Still not DSEM. +- `psychometric_core` evaluates Voelkle et al. (2012, Eq. 12) as \(a_{yx}\Delta t\,(\operatorname{expm1}(z)/z)\) with \(z=a_{xx}\Delta t\). That order is algebraically identical to \((a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)\). Binary64 underflow of \(z\) to `+0` recovers the Eq. 12 limit \(a_{yx}\Delta t\); the first-order product is still not the general discrete effect. Driver, Oud, and Voelkle (2017, p. 4) restated the discrete intercept as a function of \(A\) and \(\Delta t\) (PDF re-opened 2026-08-17T12:04Z). Still not DSEM. +- `psychometric_core` exact scalar discrete effect of a constant event-time predictor (Voelkle et al., 2012, Eq. 12): \(b^{*}_{y.x}(\Delta t)=(a_{yx}/a_{xx})(\exp(a_{xx}\Delta t)-1)\) for \(a_{xx}\neq 0\). The first-order product \(a_{yx}\Delta t\) is not that discrete effect. Still not DSEM. +- `psychometric_core` exact scalar forward map `φ(Δt) = exp(a Δt)` and interval remapping: a discrete lag at one event interval maps onto another through the Voelkle et al. (2012, Eq. 7) log-rate. Pooling discrete lags from unequal intervals fails closed. Still not a matrix `expm` and not DSEM. +- Fail-closed CWC-lag coverage in `psychometric_core`: singleton clusters are skipped, all-singleton series and overflowing CWC residuals fail closed, later-only residual overflow is checked with bitwise `is_finite`, the scalar Newton step refuses a non-finite exponential, score, start-skip, or deriv-INF, and Pearson empty/mismatch/left-INF paths are recovered. Dead post-OLS `pred_ss` and midpoint `require_finite` guards were removed because those values are already finite after OLS. +- `psychometric_core` multilevel/event-time recovery on the stacked psychometric PR: cluster-mean CWC within/between OLS, Kish ESS weighted slopes, event-time-only discrete lag-1 and exact scalar local log-rate, CWC-then-event-time residual lag, Rubin `T_m = Ū_m + (1+1/m) B_m` on draw-level OLS loadings, and two-group OLS strong/strict-gated latent-mean difference. Metric/weak is not a mean license. Not DSEM, not RI-CLPM, not MGCFA, not Mislevy PVs (ADR 0005; no new migration). +- `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 + +- `model_selection` fitted candidate-`K` scoring: each candidate is fitted with the CPU `f64` TRSL-TM reference, scored from the actual in-sample mixture log-likelihood and Schwarz's (1978) `ℓ − (p ln N)/2` penalty, then passed through the existing Pareto gate. A typed non-convergence, non-finite, or invalid-input failure is a failed candidate, not a fabricated diagnostic. LLM-vote-only `K` remains non-authoritative. TF-IDF, BM25, stopword-deletion, and LLM labels are refused as inferential coordinates. Known two-topic counts select `K=2` over `K=3` with selected-`K` RMSE `0` across seed replications. This is not GPU execution, full Bayesian sampling, or topic birth/split/merge (ADR 0012; issue #167 remaining slice). +- `relation_absence` identity gate: unobserved relation pairs cannot become evidence of no relationship; recovered observed/inferred/unobserved statuses match known truth at a higher computed rate than collapsing every status to observed (ADR 0003). +- `orchestrator_live` loopback HTTP/1.1 listener: `POST /v1/interpretation-runs` binds loopback only, replays matching idempotency keys, and refuses non-loopback binds, table-access hosts, review/Copilot/GitHub credentials, and scientific-authority promotion. Accepted output is always hypothetical. Not TLS termination or model execution (ADR 0010; ADR 0011). +- `role_contradiction` identity gate: customer and competitor cannot occupy the same group; recovered commercial-role labels match known truth at a higher computed rate than collapsing every role to customer (ADR 0003). +- `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). +- Coverage contract now excludes Rust multiline string continuation records emitted by LLVM LCOV, keeping the 100% authored-line gate focused on executable production lines. +- Coverage source classification now scans Rust normal/raw/byte strings, comments, and character literals with escape-aware state, preserving executable string method calls and ignoring quoted comments. +- Quality-gate coverage tests now exercise blank-predecessor structural commas and escaped character literals in the authored-line scanner, including the past-EOF fail-closed path. +- Restored Graham Neubig's correct APA 7 initial in the Liu et al. (2023) prompting-survey register entry after the protected-main rebase. +- After protected-main consolidation #215, the analysis-run execution decision is recorded as ADR 0022 so it does not collide with ADR 0021 LineageWeave project-history. +- Registered the analysis-engine gap-closure doctoring in the canonical documentation map so its product and scientific traceability record is discoverable. +- Authored Rust coverage classification now ignores standalone structural closing parentheses, preventing formatting-only LCOV rows from appearing as uncovered production behavior. +- `analysis_engine` vertical slice (ADR 0022): bounded Rust execution from an accepted analysis run to either a cutoff-safe readiness result or a validated `tepp.trsl_topic_lineage.v1` artifact from the ADR-0012 estimator. Topic artifacts preserve fitted predecessor/successor edges, connectable-post and lineage counts, request/snapshot/cutoff bindings, SHA-256 identity, and fail-closed non-convergence/tamper behavior with exact line/branch coverage. This remains active-PR evidence and does not claim causal or psychometric authority. +- Coverage classification preserves the final expression line of multiline Rust `match` guards while respecting preceding-arm boundaries, keeping the 100% authored-line gate conservative. +- `tepp_api` fail-closed analysis-result boundaries: status constructors reject + terminal envelopes that cannot fit the default 64 KiB status limit, and + standalone terminal results reject knowledge cutoffs in the future. +- `tepp_api` request-bound terminal analysis results and typed analysis-run status/read responses: accepted/running states cannot carry measurement evidence, terminal results bind exact request and receipt identities, and succeeded/failed payloads remain digest-bound or content-redacted. +- `evidence_core` embedded-image units: `data:image/;base64,...` URIs keep their original source spans and media types, and cannot be used as lexical inference text. +- `persistence_postgres` entity/project target SQL now rejects empty, oversized, or hostile type/status labels before insert; interpolated codes are restricted to lowercase ASCII `snake_case` characters so membership foreign keys remain referentially safe (ADR 0003 / ADR 0013). +- `persistence_postgres` live SQLx transport retains one pool-backed PostgreSQL connection per session so tenant binding and the following statement share a session, and closes the connection and owned runtime safely from another Tokio runtime (ADR 0013). +- The authored-line coverage gate now filters LLVM-only literal and expression continuation records while retaining branch coverage for their executable decisions; Rust function signatures and structural branch lines are no longer counted as uncovered statements. +- Stacked `analysis_engine` vertical slice (ADR 0021): bounded Rust execution + from an accepted analysis run to a cutoff-safe, multiple-membership-aware, + SHA-256-digest-bound terminal artifact or redacted no-eligible-evidence + result. This remains active-PR evidence and does not claim estimator + authority. +- `tepp_api` request-bound terminal analysis results and typed analysis-run + status/read responses: accepted/running states cannot carry measurement + evidence, and terminal results bind exact request and receipt identities. +- Coverage classification now preserves multiline Rust `match` guard expression + lines while ignoring structural closing parentheses and match-arm labels. +- `corpus_split` Unicode canonical identity: NFC/NFD-equivalent bodies produce `CanonicalEquivalent` leakage links and cannot occupy independent partitions; empty bodies and duplicate document identities fail closed (ADR 0004/0008/0013; PR #59). +- `semantic_core` binds exact `evidence_core` source spans as semantic units. Language profiles are `unresolved` or a primary ISO 639 subtag with an IANA-registered ISO 3166-1 alpha-2 or UN M.49 region (RFC 5646; IANA File-Date 2026-08-08); private-use and unknown regions fail closed. Unresolved metadata keeps the caller-supplied Korean `측정` span and does not retokenize. `SemanticIdentity::from_language_tag` fails closed. Korean and English report sentences remain distinct units. Not concept alignment, not invariance, not a topic estimator (ADR 0020; issue #168). The APA register cites RFC 5646 once, in the Unicode/language-tags section; the slice-specific note remains `docs/research/span-grounded-semantic-units.md`. +- `corpus_background` identity gate: corpus-level background wording is not unique latent content or a state transition; recovery tests distinguish background evidence from unique content. +- `modality_source` identity gate: non-lexical modality is not unique lexical content or a state transition; recovery tests keep modality evidence distinct from unique content. +- `copied_text` identity gate: copied-text residue is not unique latent content or a state transition; recovery tests distinguish copied-text evidence from genuinely new content. +- `style_source` identity gate: house-voice style residue is not unique latent content and is not erased by a stopword list; recovery tests distinguish style from unique content. +- `stopword_deletion` method gate: a default or global stopword list cannot erase repeated report language; recovery tests distinguish deliberate method treatment from stopword deletion. +- `copy_identity` identity gate: a template or pasted copy cannot reuse the source document identity or become a state transition; recovery tests distinguish copy kinds from source identity. +- `intake_authorization` identity gate: documents, serialized records, checkpoints, and LLM outputs require a purpose-bound grant in addition to identity, provenance, size, and depth validation; recovery tests reject ungranted intake. +- `tepp_api` LineageWeave temporal-context contract (v1): cutoff-safe event eligibility, deterministic event-time ordering, explicit non-causal association/gap boundaries, HTTPS interchange construction, and loopback listener handling at `POST /v1/temporal-context`; read-only context requests no longer require the write-only idempotency header, and no causal inference or completed-result service is included. +- `tepp_api` LineageWeave consumer-scoped analysis-run ingress: versioned, credential-free requests use a published consumer identity and isolate idempotency by consumer, tenant workspace, and opaque caller key; the one-shot restack workflow is removed after the protected-main merge is verified. +- ADR 0018 records the consumer-scoped analysis-run ingress, its in-memory loopback maturity, and the persistence boundary required before production use. +- ADR 0021 records the credential-free bounded LineageWeave project-history service boundary and keeps source authorization with LineageWeave while TEPP owns temporal validation and deterministic projection. +- `tepp_api` project-history wire-size symmetry (ADR 0019): request and projection serialization enforce the shared 256 KiB limit, and generated projections fail closed before returning when their deterministic response would exceed it. +- `summarizes_edge` identity gate: summaries may point to earlier event time without becoming state transitions or reusing source-document identity; recovery tests outperform collapsing every summary to the source. +- `outcome_order` identity gate: `input_to` and `process_to` require strict forward event-time rank, while `outcome_of` remains non-transition provenance; recovery tests outperform collapsing every kind to `input_to`. +- `location_membership` identity gate: geographic and market assignments are time-varying memberships, not permanent entity identity and not language channels; recovered location kinds match known truth at a higher computed rate than collapsing every assignment to entity identity (ADR 0003). +- `prompt_source` identity gate: instruction and prompt boilerplate is not unique latent content and is not erased by a stopword list; `identity_recovery_rate` reports exact kind matches, with a contract test comparing correct recovery with an all-unique collapse on a mixed known-truth fixture (ADR 0004/0012). +- `corpus_background` identity gate: corpus-level background wording is not unique latent content and is not erased by a stopword list; recovered background kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). +- `modality_source` identity gate: non-lexical modality is not unique latent content and is not erased by a stopword list; recovered modality kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). +- `copied_text` identity gate: copied and boilerplate residue is not unique latent content and is not erased by a stopword list; recovered copied-text kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). +- `style_source` identity gate: house-voice style residue is not unique latent content and is not erased by a stopword list; recovered style kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). +- `stopword_deletion` method gate: a default or global stopword list cannot erase repeated report language; recovered deletion kinds match known truth at a higher computed rate than collapsing every token treatment to stopword deletion (ADR 0004/0012). +- `persistence_postgres` retention/deletion/legal-hold (migration `0007`): policy rows, legal holds that block completed deletion, evidence tombstones without raw-source restore, analysis exclusion only for `logical_revocation`/`identity_tombstone` (not `cache_export_removal`), and deletion requests bound to the cited retention policy's tenant/class/purpose. +- `copy_identity` identity gate: a template or pasted copy cannot reuse the source document identity or become a state transition; recovered copy kinds match known truth at a higher computed rate than collapsing every copy to the source (ADR 0003). +- `provider_receipt` disclosure receipt: records provider field codes and + purpose-bound receipt metadata without persisting source text or source + identity (ADR 0009). +- `intake_authorization` identity gate: documents, serialized records, checkpoints, and LLM outputs cannot be accepted without a purpose-bound grant; size/identity/provenance bounds are not that grant; recovered grant-presence flags match known truth at a higher computed rate than accepting every intake (ADR 0009). +- `summarizes_edge` identity gate: a summary may point to earlier event time but cannot become a state transition or reuse the source document identity; recovered summary kinds match known truth at a higher computed rate than collapsing every summary to the source (ADR 0003). +- `outcome_order` identity gate: `input_to` and `process_to` cannot move backward or stay contemporaneous in event-time rank; `outcome_of` may point at an earlier producer and cannot become a state transition; recovered kinds match known truth at a higher computed rate than collapsing every kind to `input_to` (ADR 0002/0003). +- `retrospective_edge` identity gate: retrospective reporting may point to earlier event time but cannot become a state transition or a translation; recovered reporting kinds match known truth at a higher computed rate than collapsing every report to a contemporaneous forward report (ADR 0002/0003). +- `payload_bound` identity gate: documents, serialized records, model checkpoints, and LLM outputs stay untrusted until identity, provenance, size, and depth validate; recovered accept/reject flags match known truth at a higher computed rate than accepting every payload (ADR 0008/0013). +- `inferred_status` identity gate: inferred relations cannot be promoted to observed evidence or to state transitions; recovered observed/inferred labels match known truth at a higher computed rate than treating every status as observed (ADR 0003). +- `support_edge` identity gate: support, contradiction, summary, and `outcome_of` edges cannot become state transitions; recovered evidential kinds match known truth at a higher computed rate than collapsing every kind to support (ADR 0002/0003). +- `system_clock` identity gate: event, assertion, document, availability, and knowledge-cutoff time cannot stand in for system time; recovered system stamps match known truth at a higher computed rate than treating every stamp as event time (ADR 0002). +- `event_clock` identity gate: assertion, system, document, and availability time cannot stand in for event/valid time; recovered event stamps match known truth at a higher computed rate than treating every stamp as assertion time (ADR 0002). +- Dependabot Rust toolchain updates now use a seven-day cooldown so newly published versions receive a bounded review window before automated proposals. +- `assertion_clock` identity gate: event, system, document, and availability time cannot stand in for assertion time; recovered assertion stamps match known truth at a higher computed rate than treating every stamp as event time (ADR 0002). +- `cutoff_clock` identity gate: event time, system time, and availability time cannot stand in for knowledge cutoff; recovered cutoff stamps match known truth at a higher computed rate than treating every stamp as availability time (ADR 0002). +- `available_clock` identity gate: event time and system time cannot stand in for availability time; recovered availability stamps match known truth at a higher computed rate than treating every stamp as system time (ADR 0002). +- `document_clocks` six-clock gate: a document analytical row cannot omit assertion time or document time, and event/system time cannot stand in for those clocks; recovered completeness flags match known truth at a higher computed rate than treating every row as complete (ADR 0002/0013). +- `revision_order` system-time gate: a higher document revision number cannot carry earlier or equal system time; recovered order flags match known truth at a higher computed rate than accepting every pair (ADR 0002/0013). +- `encrypted_mapping` purpose-bound AES-256-GCM envelope: source identities are sealed with an operating-system-generated nonce and analytical/key identifiers as authenticated associated data, with a 1 MiB resource bound, so analytical, log, and model-artifact purposes cannot recover plaintext; recovered identities match known truth at a higher computed rate than collapsing every mapping to one name. Persistence and KMS wait for a later migration (ADR 0009). +- `citation_edge` provenance gate: citation, translation, revision, and retrospective-report edges may point to the past but cannot become input-process-outcome transitions; recovered kinds match known truth at a higher computed rate than collapsing every edge to citation (ADR 0002/0003). +- `psychometric_fit` CPU `f64` ESEM/DSEM fit: exploratory OLS recovers known cross-loadings from admitted log-ratio or logistic-normal coordinates with computed RMSE below a zero-loading collapse; reverse or zero event-time lagged paths fail closed; a good global fit cannot reclassify formative or network constructs as reflective (ADR 0005). No new migration number (`#45` still owns `0007`). +- `subevent_containment` parent-window gate: a half-open subevent interval that starts before or ends after its parent cannot attach; recovered containment flags match known truth at a higher computed rate than accepting every child (ADR 0003). +- `prediction_contradiction` promotion gate: `temporal_core` Allen classification refuses `before`/`after` as contradiction and `meets`/`met_by` as unsupported adjacency; `refuse_promotion` and `require_observed_coverage` refuse partial overlap that leaves unmatched predicted mass; `refuse_contradiction_or_adjacency` is the weaker contradiction/adjacency filter only; evidence available after the knowledge cutoff is ineligible. Label agreement is not RMSE recovery (ADR 0002, ADR 0016). Canonical docs name the crate, not a pull-request number, as the landable authority; `scripts/validate_documentation.py` fail-closes on `landable coverage gate is PR #N` and inverted or paraphrased forms (`PR #N is the landable coverage gate`, `the landable gate is PR #N`, `coverage-authority landing PR #N`, `merge PR #N as the coverage-authority`) including drafts #93, #94, #97, #101, #102, #104, #108, #109, #111, and #112. The hourly queue lock also fail-closes when those drafts are omitted from Keep-unmerged sentences, when a Keep-unmerged sentence is negated, or when the naruon live-HTTP *subject* is not PR #107 with #87 and #105 kept unmerged. +- `provider_receipt` disclosure audit: a receipt records purpose and field codes sent to a model provider; source text, source identity, and blanket PII masking fail closed; recovered field codes match known truth at a higher computed rate than a collapsed set (ADR 0009). +- `tepp_api` corpus-split leakage-audit manifest v1: cutoff exclusion counts, relation-component and partition digests, governed link-kind vocabulary, and a canonical `SHA-256` that binds to `corpus_split_manifest` without exporting source text. +- `persistence_postgres` `audit_event` inserts call `operational_log::try_record` before SQL is rendered: author/customer/project source text, source identity, and blanket-mask grants cannot enter `INSERT INTO audit_event`; clear inspection still persists a validated action code (ADR 0009; ISO/IEC 29100:2024). No new migration number. `OperationalLogRecord::new` stays crate-private. +- `operational_log` source separation: `try_record` is the only recording API and inspects source text, source identity, and blanket-mask intent before creating a line; `OperationalLogRecord::new` is crate-private; a source-identity `&str` cannot become an `AnalyticalSubject`; privileged-export / identity-mapping / diagnosis action codes keep author, customer, and project memberships distinct; replayed lines match known truth at a higher computed rate than a collapsed single-action or collapsed-subject log (ADR 0009; ISO/IEC 29100:2024). The live docstring crate-root count is bound to `EXPECTED_CRATES` so the eleventh crate cannot fail a hard-coded `10`. +- `service_tls` production TLS bind gates: non-loopback binds require rustls PEM material, loopback HTTP is development-only, orchestrator live ports refuse loopback plaintext, and table-access host labels fail closed. `TlsBindRequest` Debug output redacts certificate and private-key PEM. Recovered bind decisions are computed from `authorize_production_tls` / `authorize_orchestrator_live_port` outputs and match known truth at a higher rate than a collapsed production grant (ADR 0011). +- `derived_sensitivity` inheritance: topic, factor, and relation artifacts keep the source sensitivity class; unknown kind codes fail closed on both `inherit_sensitivity` and `DerivedArtifact::try_new`; derivation and blanket PII masking cannot declassify to public; paired kind-and-class recovery matches known 3×3 synthetic truth at a higher computed rate than a public collapse (ADR 0009; GDPR Art. 4(1)/Recital 26; WP 136). +- `longitudinal_core` within/between decomposition: unit means stay between-unit components, occasion residuals stay within-unit change, and recovered components match known truth with lower computed RMSE than a grand-mean pooled collapse. +- `topic_lineage` global P0 topic identity: activity may become dormant or reactivated without minting a new identity, and recovered identities match known truth at a higher computed rate than mint-on-reactivate replacements. +- `interpretation_gateway` evidence-bounded LLM interpretations: proposals must cite at least one evidence span, remain hypothetical, cannot become estimator results or observed facts, and a cited interpreter records a lower computed unsupported-claim rate than uncited promotion. +- `model_selection` candidate-`K` gates: statistical candidates require `K >= 2` and finite held-out log-likelihood/complexity, a Pareto front excludes dominated alternatives, LLM votes cannot define the numerical optimum, and selected `K` recovers known truth with computed RMSE. +- `event_core` mention-confidence Brier score: known-truth binary outcomes recover a computed Brier of 0 for perfect forecasts and 0.25 for constant 0.5, with empty or mismatched streams failing closed. +- `membership_core` nested ICC: CPU `f64` unbalanced ANOVA recovers a known cluster ICC and refuses to treat cross-classified or multiple-membership designs as a single hierarchy (ADR 0003). +- `persistence_postgres` typed `text_segment` SQL: insert/lookup of exact UTF-8 half-open byte spans on the existing `0006` table, cutoff-eligible document reads (`available_time <= knowledge_cutoff`), and live recovery of a known `hello` span. No new migration number (`#45` still owns `0007`). +- Hourly contextual-orchestrator discovery records all provider models but routes OpenCode only through general-chat candidates, excluding embedding, image, reranker, transcription, moderation, safety, and other endpoint-only identifiers before price selection. +- Live `docs/product-technical-gap-baseline.md` mapping operator-visible gaps to + protected-main maturity, exact current PR/issue state, stacked delivery order, + and closure evidence; placeholder-only issues #161 and #162 were closed as + queue hygiene. The documentation validator requires a dated UTC snapshot, a + 40-character protected-main SHA, an exact-head inventory matching the declared + open-PR count, and operator-gap closure evidence, and it rejects affirmative + queued-Checks-as-implemented-main claims even when wrapped across a line + break, and it rejects an unrelated `not` in the same span (`queued Checks are + not required; this PR is implemented-main`). Only never/do not/does not/ + cannot/must not plus promote/treat/make/mean counts as a promotion denial. +- `checkpoint_authority` estimator gate: a model checkpoint remains an untrusted run artifact until identity, canonical `SHA-256`, and model-run provenance validate, and it cannot replace the CPU `f64` estimator or promote a scientific claim; recovered roles match known truth at a higher computed rate than collapsing every artifact to the estimator (ADR 0001/0014). +- `event_core` now requires and retains `EventEvidenceLayer::PromotedTransition` when constructing an `EventInstance`; every other layer is rejected at the promotion boundary, and TDT story classification uses a caller-owned hash set for expected constant-time membership checks. +- `event_core` ADR 0016 evidence-status gates: TDT detections and CHRONOS predictions cannot admit a forward state transition; first-story detection scores miss/false-alarm rates against a known story stream (Allan 2002 task). +- `compute_backend` ADR 0006 first slice: VRAM profiles and reserve-aware micro-batching, executable successive OOM retry plans, CPU fallback, compensated `f64` reference arithmetic with scale-aware parity tolerance, grouped adaptation policies, and fail-closed estimand-preserving memory policies. +- `validation_core` ADR 0014 claim-promotion gates: `decision_accepted`, `implemented_main`, `scientifically_supported`, and `released` bind to an exact commit SHA; queued, predecessor, skipped-required, and LLM evidence fail closed; scientific promotion uses computed RMSE and its standard error rather than a hardcoded threshold (no new migration). +- `relation_graph` causal-identification gate: only `causes` and `intervenes_on` may be described as causal; association, temporal precedence, production, and provenance fail closed. +- `temporal_core` interval-aware historical eligibility: `evaluate_historical_eligibility` admits an `AvailableTime` interval only when every possible availability instant is at or before `KnowledgeCutoff`; unknown and open-ended upper availability fail closed, and event/document time cannot be substituted. +- `event_core` TDT tracking contracts: hypothesized track assignments, fail-closed duplicate mentions, refusal to treat a track as an instance or state transition, and computed pair precision/recall, identity-switch rate, and RMSE against known-truth assignments. +- `event_core` CHRONOS schema-slot gate: predicted role fillers stay distinct from promoted instances and transitions, slot precision/recall are computed from known-truth fills, and production label/confidence APIs produce calibrated occupancy RMSE ≈ 0.1411 versus always-fill ≈ 0.7071 in the contract fixture. +- `event_core` TDT story-segmentation contracts: ordered unit partitions, fail-closed empty/mismatched windows, refusal to treat a detected story cut as an instance or state transition, and computed `WindowDiff`, `Pk`, boundary precision/recall, plus RMSE against known-truth boundaries. +- `event_core` CHRONOS occurrence-prediction calibration: forecasts stay hypothetical, refuse promotion to event instances, and recover a computed Brier score against later-observed occurrence truth, with empty or mismatched streams failing closed. +- `persistence_postgres` entity/project target SQL: fail-closed insert/lookup for `entity_record` and `project_record` so membership foreign keys cannot be seeded from empty, oversized, or hostile type/status labels. No new migration number (ADR 0003 / ADR 0013). +- `cutoff_clock` identity gate: event time, system time, and availability time cannot stand in for knowledge cutoff; recovered cutoff stamps match known truth at a higher computed rate than treating every stamp as availability time (ADR 0002). +- `assertion_clock` identity gate: event, system, document, and availability time cannot stand in for assertion time; recovered assertion stamps match known truth at a higher computed rate than treating every stamp as event time (ADR 0002). +- `event_clock` identity gate: assertion, system, document, and availability time cannot stand in for event/valid time; recovered event stamps match known truth at a higher computed rate than treating every stamp as assertion time (ADR 0002). +- `system_clock` identity gate: event, assertion, document, availability, and knowledge-cutoff time cannot stand in for system time; recovered system stamps match known truth at a higher computed rate than treating every stamp as event time (ADR 0002). +- `support_edge` identity gate: support, contradiction, summary, and `outcome_of` edges cannot become state transitions; recovered evidential kinds match known truth at a higher computed rate than collapsing every kind to support (ADR 0002/0003). +- `inferred_status` identity gate: inferred relations cannot be promoted to observed evidence or to state transitions; recovered observed/inferred labels match known truth at a higher computed rate than treating every status as observed (ADR 0003). +- `payload_bound` identity gate: documents, serialized records, model checkpoints, and LLM outputs stay untrusted until identity, provenance, size, and depth validate; recovered accept/reject flags match known truth at a higher computed rate than accepting every payload (ADR 0008/0013). +- `outcome_order` identity gate: `input_to` and `process_to` cannot move backward or stay contemporaneous in event-time rank; `outcome_of` may point at an earlier producer and cannot become a state transition; recovered kinds match known truth at a higher computed rate than collapsing every kind to `input_to` (ADR 0002/0003). +- `summarizes_edge` identity gate: a summary may point to earlier event time but cannot become a state transition or reuse the source document identity; recovered summary kinds match known truth at a higher computed rate than collapsing every summary to the source (ADR 0003). +- `provider_receipt` disclosure receipt: records provider field codes and + purpose-bound receipt metadata without persisting source text or source + identity (ADR 0009). +- `intake_authorization` identity gate: documents, serialized records, checkpoints, and LLM outputs cannot be accepted without a purpose-bound grant; size/identity/provenance bounds are not that grant; recovered grant-presence flags match known truth at a higher computed rate than accepting every intake (ADR 0009). +- `copy_identity` identity gate: a template or pasted copy cannot reuse the source document identity or become a state transition; recovered copy kinds match known truth at a higher computed rate than collapsing every copy to the source (ADR 0003). +- `stopword_deletion` method gate: a default or global stopword list cannot erase repeated report language; recovered deletion kinds match known truth at a higher computed rate than collapsing every token treatment to stopword deletion (ADR 0004/0012). +- `episode_membership` identity gate: a document's episode membership cannot start before or end after the episode event-time interval; recovered containment flags match known truth at a higher computed rate than accepting every membership (ADR 0003). +- `style_source` identity gate: house-voice style residue is not unique latent content and is not erased by a stopword list; recovered style kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). +- `modality_source` identity gate: non-lexical modality is not unique latent content and is not erased by a stopword list; recovered modality kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). +- `corpus_background` identity gate: corpus-level background wording is not unique latent content and is not erased by a stopword list; recovered background kinds match known truth at a higher computed rate than collapsing every token to unique content (ADR 0004/0012). +- `prompt_source` identity gate: instruction and prompt boilerplate is not unique latent content and is not erased by a stopword list; `identity_recovery_rate` reports exact kind matches, with a contract test comparing correct recovery with an all-unique collapse on a mixed known-truth fixture (ADR 0004/0012). +- `location_membership` identity gate: geographic and market assignments are time-varying memberships, not permanent entity identity and not language channels; recovered location kinds match known truth at a higher computed rate than collapsing every assignment to entity identity (ADR 0003). +- `membership_target` identity gate: language, episode, template, department, and opportunity-pool memberships cannot collapse into the entity/project pair stored by migration `0006`; comparison-contract tests record recovered target kinds against an entity-collapse baseline (ADR 0003). +- `corpus_split` inferential-weight gate: only group-normalized ESS and uniform observation weights may enter an estimator; TF-IDF, BM25, and default global stopword deletion fail closed, with computed RMSE showing the retrieval surrogate recovers known shares worse than `group_normalized_ess`. +- `event_core` TDT link-detection contracts: undirected mention-pair hypotheses, fail-closed self-links, refusal to treat a detected link as an instance or state transition, and computed precision/recall plus RMSE against known-truth pairs. +- `event_core` first-story detection gate: first-story versus follow-up labels stay distinct from promoted instances, false-alarm and miss rates are computed from known truth, and calibrated detection scores recover the binary first-story target with lower RMSE than an always-first detector. +- `tepp_api` naruon live loopback HTTP/1.1 listener: `serve_one` installs a read/write deadline, requires a loopback `Host`, refuses `Transfer-Encoding` and NIM/proxy credential headers, parses `knowledge_cutoff` as RFC 3339 and refuses a future cutoff, keys analysis-run idempotency by tenant plus key, and proves both analysis-run and export POSTs over a real `TcpStream`. Not a production TLS/`$PORT` service (ADR 0011). +- `tepp_api` adaptive orchestration router (ADR 0010): versioned `direct`/`verify`/`committee`/`conductor`/`abstain` selection from CPU `f64` risk, ambiguity, evidence, and token-budget inputs; recorded stages, recursion, decomposition, access lists, and role-specific reasoning effort; fail-closed document-controlled policy/access/credentials; LLM plans remain proposals under deterministic statistical authority; comparable-budget ablation requires a direct baseline; credential-free contextual-orchestrator binding. Live NIM HTTP remains accepted-target. +- `tepp_api` purpose-bound provider-payload minimization: time-bounded `PurposeGrant` evaluation, fail-closed expired/not-yet-valid/inverted/cross-tenant/impossible-calendar denial, semantic UTC calendar validation, refusal to copy identity mappings into model-provider payloads or ordinary logs, preservation of opaque analytical identifiers and membership roles (no blanket PII mask), a separately authorized scientific re-identification path, and an internally bound FIPS 180-4 SHA-256 audit digest appended through `ReidentificationAuditSink` before disclosure. +- `persistence_postgres` backup/restore integrity: restored snapshots stay unusable until tenant, canonical `SHA-256`, knowledge-cutoff eligibility, temporal window order, and append-only triggers revalidate; SQL probes raise `restore integrity failed` (ADR 0013). +- `persistence_postgres` concurrent document-write stress: atomic revise `DO` block that requires exactly one open `system_to` close, SQLSTATE mapping onto `ConcurrentWriteConflict` / `DuplicateDocumentRecord`, and live multi-session insert/revise/append-only proofs. No new migration number. +- `tepp_api` naruon HTTP interchange: versioned `https` POST contracts for analysis-run create and modular export authorization that refuse table-access URLs, provider-specific API-key/secret and review/Copilot credential headers, malformed extra HTTP fields, reserved standard-header redefinition, principal-only export idempotency keys, and lexical inference claims (ADR 0011). +- `persistence_postgres` audit-event SQL contracts: append-only insert that refuses empty, oversized, or hostile `action_code` values before SQL is rendered. +- `network_analysis` compositional cluster gates: raw topic proportions cannot be treated as Euclidean coordinates; recovered clusters are scored with label-invariant pair precision and recall against known truth. +- `persistence_postgres` event-instance SQL contracts: bitemporal insert and as-known-at lookup that refuse inverted valid/system windows and hostile type/lifecycle labels before SQL is rendered. +- `persistence_postgres` event-mention SQL contracts: mention identity cannot equal the instance it supports; confidence must be finite and in `(0, 1]`. +- `persistence_postgres` event-relation SQL contracts: closed ERD transition/provenance vocabulary bound to `transition_edge`, fail-closed unknown types and transition self-loops, live insert of `causes`/`references`. +- `persistence_postgres` source-artifact SQL contracts: append-only insert and primary-key lookup that refuse non-canonical `SHA-256` digests, negative sizes, and hostile media-type or object-store labels before SQL is rendered; identical-identity retries are `ON CONFLICT DO NOTHING` plus a stored-row match assertion, and a same-id payload change fails closed as `ConflictingSourceArtifact`. +- `persistence_postgres` typed membership assignment (migration `0006`): `entity_record`, `project_record`, and `text_segment` plus exactly-one observed-unit and target constraints that replace the polymorphic `membership_target_id` stub, with SQL insert/lookup, fail-closed inverted-window and backslash-label refusal, and live proof that one document persists two entity memberships and one project membership. +- Actions workflow fleet auditor (`scripts/actions_workflow_fleet.py`): paginated registry inventory bound to the exact default-branch SHA/tree, classification of present/orphan/disabled/GitHub-dynamic identities, and fail-closed orphan disable that confirms GitHub's official `disabled_manually` state. +- `persistence_postgres` temporal interval ordering migration (`0005`): multi-word CHECK constraints on `document_record`, `event_instance`, and `membership_assignment` that reject inverted valid/system windows and non-positive document revisions while preserving open-ended NULL upper bounds and equal point bounds; catalog validation and live inverted-window proof. +- `persistence_postgres` append-only immutability migration (`0004`): `reject_append_only_mutation`, statement-level `BEFORE UPDATE OR DELETE OR TRUNCATE` triggers on identity/manifest tables, `REVOKE UPDATE`/`DELETE`/`TRUNCATE` from `tepp_app_runtime`, executable DDL/rollback contracts, and live representative mutation proof. +- `persistence_postgres` model-run artifact chain: migration `0003_model_run_artifact_chain` for append-only `corpus_split_manifest`, `model_run`, and `model_artifact` with FORCE RLS; SQL insert/lookup contracts and live repository methods binding runs to reproducibility manifests and optional splits. +- `persistence_postgres` append-only reproducibility-manifest SQL contracts and live repository methods (`insert_reproducibility_manifest`, digest/id lookup) with fail-closed SHA-256 and commit identity validation for `reproducibility_manifest`. +- `persistence_postgres` tenant row-level security: migration `0002_tenant_row_level_security`, `tepp_app_runtime` role, session GUC `tepp.current_tenant_record_id`, multi-word isolation policies with FORCE RLS, session helpers, contract validation, and live isolation proof under `TEPP_LIVE_POSTGRES=1`. +- `persistence_postgres` live PostgreSQL CI: `live-postgres` job with Postgres 16 service, `TEPP_LIVE_POSTGRES=1` gate, and integration coverage for pool open, foundation+RLS migrations, document insert/revise/as-of, audit SQL, and tenant isolation. +- Repository release evidence tooling: `scripts/release_evidence.py` generates CycloneDX 1.5 SBOM, exact-head provenance, and SHA-256 checksums from `Cargo.lock`/`Cargo.toml`, with fail-closed validation and CI generation on every quality gate. +- `persistence_postgres` `live-sqlx` feature: real `SQLx`/`PgPool` open/execute behind validated `DATABASE_URL` and `LiveSqlxPoolOptions`, with offline/live executor backends and CI coverage exclusion for the transport module. +- `persistence_postgres` live pool open gate: validated `LiveSqlxPoolOptions`, fail-closed `open_live_sqlx_pool` / `LiveSqlxPool` (`SqlSession`) with offline test backend; optional `live-sqlx` attaches real `SQLx`/`PgPool` after `DATABASE_URL` validation. +- `validation_core` recovery metrics: parameter matching, RMSE/bias with standard errors, interval coverage with Wilson bounds, relation-edge precision/recall, temporal-order accuracy, Monte Carlo summaries, and SE-aware acceptance gates with machine-readable reports. +- `tepp_api` versioned analysis-run DTOs, content-redacting error envelopes, reproducibility manifests, JSON-LD and GraphML export contracts, purpose-bound export authorization (no blanket PII masking), plus committed schemas/examples. +- `relation_graph` forward-only state-transition DAG with past-pointing provenance edges and cycle rejection. +- `tepp_simulation` deterministic truth-corpus generator with delayed reporting, multilevel memberships, method-effect variants, relation noise, and digest-bound truth manifests. +- `corpus_split` leakage-safe knowledge-cutoff snapshots, relation-connected co-partition groups, rolling-origin windows, and group-normalized ESS weight contracts. +- `persistence_postgres` live SQL port: `SqlSession` transport, migration batch applicator, document/audit SQL contracts, `LiveDocumentRepository`, and fail-closed `DATABASE_URL`/`LiveSqlxConfig` gate for SQLx pool wiring (optional `live-sqlx` driver attaches `PgPool`). +- `membership_core` Kish effective sample size, design effect, and group-normalized ESS helpers for multiple-membership estimation inputs. +- Credential-separated hourly NVIDIA NIM/OpenCode product-development workflow (issue #2): proposal, independent verification, and late Maintainer-App publication with `NVIDIA_NIM_API_KEY` only for model work. +- Hourly product-development queue gate now fails closed when either an open pull request or an open issue exists, including a second queue check immediately before publication. +- Documented modular naruon consumer contract for TEPP analysis-run and export surfaces, with a committed example request payload. +- Documented contextual-orchestrator interpretation port boundary and credential separation for TEPP. +- Foundation validation/release-readiness ledger at `docs/validation/temporal-event-foundation.md` tracking capability maturity and scientific acceptance gates. +- Research doctoring for multilevel/multiple-membership measurement and atomistic fallacy prevention. +- `persistence_postgres` bitemporal foundation: multi-word migration contracts, knowledge-cutoff eligibility, and in-memory as-known-at / as-valid-at document replay (live SQLx/PostgreSQL execution remains accepted-target). +- `event_core` mention/instance separation with explicit promotion, typed roles, event-time validity, and fail-closed mention-as-instance refusal. +- `membership_core` time-varying weighted multiple-membership network with contextual roles, event-time validity, and atomistic-fallacy prevention contracts. +- Bounded Allen interval algebra and path-consistency reasoner in `temporal_core` (Task 4; PR #9), with identity-isolated variables, resource budgets, inverse/composition, and conservative provenance. +- Approved Temporal Event Psychometrics Platform PRD v0.4 baseline. +- Canonical technical documentation map, TRD, UML/scientific runtime views, logical/planned ERD, scientific test strategy, operability/recovery guide, and requirements/research/evidence traceability with explicit implementation maturity. +- Whole-conversation documentation fitness assessment plus canonical API/MSA contract, threat model, privacy/data-governance contract, CSAP/SOC 2/ISO/NIST assurance-readiness mapping, and adaptive LLM orchestration/test-time-compute contract. +- ADR policy separating architectural **Decision status** from **Implementation maturity**, defining partial supersession, and making the ADR index the canonical decision-ownership map. +- ADR 0009 for purpose-bound PII governance without blanket masking, ADR 0010 for adaptive direct-versus-multi-agent LLM orchestration, and ADR 0011 for standalone/modular CWL service authority. +- ADR 0012 for Temporal Relational Shared-Latent Topic Measurement (TRSL-TM), global topic identity/backend compatibility/method-effect/model-selection authority. +- ADR 0013 for bitemporal persistence, immutable reproducibility/run/split manifests, relation-aware partitions, recovery, and PostgreSQL adapter authority. +- ADR 0014 separating accepted design, protected-main implementation, scientific/product claim promotion, and release evidence authority. +- ADR 0015 separating autonomous model proposal, deterministic verification, publication, independent review, and merge/release authority. +- ADR 0016 separating Event Ontology observation, TDT detection/tracking, CHRONOS schema prediction, symbolic temporal consistency, and promoted transition authority. +- Added APA 7 research traceability for ICLR 2026 TRINITY and Conductor, the 2026 Sakana Fugu technical report, ISO/IEC 42001:2023, ISO/IEC 23894:2023, NIST AI RMF/GAI Profile, AICPA Trust Services Criteria, and KISA CSAP guidance. +- Eight-phase delivery roadmap and Temporal/Event Foundation implementation plan. +- Immutable evidence, six-clock temporal semantics, interval reasoning, event ontology, typed relation graph, and time-varying multiple-membership contracts. +- Shared-latent multilingual topic measurement architecture with native lexical channels and language-profile validation. +- Longitudinal ESEM/DSEM and continuous-time structural modeling requirements. +- Rust-first CPU `f64`, multithreaded CPU, GPU, VRAM-adaptive streaming, and CPU/GPU parity requirements. +- Topic correlation, consensus clustering, TDT, CHRONOS, and evidence-grounded LLM interpretation requirements. +- APA 7th research traceability, source archive manifests, ADRs, governance, security, and contribution contracts. +- Hourly centralized PR-maintenance workflow and a documented requirement for a future credential-separated NVIDIA NIM/OpenCode product-development loop. +- Rust 1.97.1 virtual Cargo workspace with eleven explicit modular foundation crates. +- Repository contract, public-rustdoc, line-coverage, and nightly branch-coverage gates. +- Pinned `cargo-nextest` 0.9.140, `cargo-llvm-cov` 0.8.6, `cargo-deny` 0.19.7, and Coverage.py 7.15.2 quality tooling. +- Task 1 architecture decision and workspace-foundation validation report. +- Version-keyed, executable-only GitHub Actions caches for pinned Rust quality tools. +- Immutable `evidence_core` records with independent RFC 9562 `UUIDv7` identities, canonical `SHA-256` content digests, owned source bytes and UTF-8 text, exact byte/Unicode-scalar spans, and bounded page-layout coordinates. +- Strict versioned JSON wire contracts for artifacts, documents, exact spans, and nested page locations without exposing private domain storage. +- ADR 0008 and APA 7 doctoring for evidence identity, hashing, JSON interchange, UTF-8 boundaries, Unicode segmentation limits, and future W3C PROV integration. +- Same-run exact missing-line and missing-branch diagnostics for failed 100% Rust coverage gates. + +### Changed + +- ALR and ILR inverse normalization now fails closed when division would turn + a representable subnormal weight into a zero simplex part; runtime images + are pinned to the reviewed multi-platform Rust and Debian OCI digests. +- `psychometric_core` scalar forward map `φ(Δt) = exp(a Δt)` now refuses binary64 underflow to `+0`. Voelkle et al. (2012, Eq. 7; ZORA accepted manuscript p. 16) write discrete auto-effects as `e^{a Δt}`, which are strictly positive; `a = ln(φ) / Δt` requires `φ > 0`. Direct overflow already failed closed. The Newton residual path refuses a mapped `+0` the same way. +- The docstring discovery test compares crate-root names to `EXPECTED_CRATES` instead of a hardcoded count of 10, so `semantic_core` is required and an unapproved extra crate fails closed. +- The LineageWeave temporal-context read exchange no longer emits a fabricated + `idempotency-key`; that header remains reserved for retryable write/export + operations with a caller-owned operation key. +- `tepp_api` project-history requests and projections now share the strict + `temporal_core` RFC 3339 parser and nominal `KnowledgeCutoff` boundary, + rejecting unknown offsets and other timestamp forms that the transport + parser could otherwise accept. +- Coverage validation now ignores LLVM rows for multiline call and iterator + syntax that have no independently executable source coordinate, while + retaining the authored-line 100% gate. +- Removed the temporary PR-155 review-repair workflows and source-fix helper after the bounded repair; subsequent changes use the normal reviewed branch path. +- Pinned Rust branch-coverage workflows to `nightly-2026-08-21`, which is newer than the workspace Rust 1.98.0 MSRV and avoids the previous nightly/MSRV mismatch. +- Applied the documented `sqlx_live.rs` authored-coverage exclusion to the hourly release gate so live-PostgreSQL success-path coverage is not reported as a false source failure. +- Removed unreachable duplicate Naruon host-control validation because the shared `require_nonempty` boundary already rejects C0/C1 controls; retained a C1 regression case alongside the existing C0 case. +- Kept one maturity row per capability in the traceability matrix while recording the active provider-receipt evidence without duplicating or downgrading existing capabilities. +- `tepp_api` corpus-split manifest validation now rejects governed link-kind arrays that are unsorted or duplicated, keeping untrusted JSON aligned with the schema's unique canonical representation and preventing equivalent audits from receiving different valid digests. +- Grounded `derived_sensitivity` doctoring on GDPR Article 4(1)/Recital 26 and WP29 Opinion 4/2007 (WP 136) as read from the official texts, and replaced the withdrawn ISO/IEC 29100:2011 use-limitation overclaim with the current 29100:2024 catalogue edition without quoting unread clause text. +- Added APA 7th method citations (Allen 1983; ISO 24617-1:2012; Hobbs & Pan 2017; Fox & Glas 2001; AERA/APA/NCME 2014; Blei & Lafferty 2006; Roberts et al. 2014, 2019; Chang & Blei 2009; Mimno et al. 2009; Asparouhov & Muthén 2009; Asparouhov et al. 2018; Marsh et al. 2014; Aitchison 1982; Allan 2002; Li et al. 2021; Anagnostopoulos et al. 2013) into ADRs 0002–0005, 0012, and 0016, plus TRACEABILITY/ARCHITECTURE/TRD method rows. Clarified that TRSL-TM is the product contract, STM-style logistic-normal is the reference family, ESEM/DSEM/TDT/CHRONOS remain accepted-target, and merged PRs #8/#9—not superseded drafts #5/#6—are the protected-main temporal lineage. +- Refreshed the live gap-baseline inventory to the 2026-08-24T05:41:54Z GitHub + snapshot (118 open PRs / 48 drafts / 12 issues; protected-main + `c45be17a9dbce95ef81cee230e9d128abc7160ac`), binding each operator-gap current + head SHA to that exact-head register, including #201 `6afd650667e1` (RFC 5646 + cited once; first GAP-005 slice, not implemented-main), stacked drafts + #202–#204, and #164 `ff2e645b1785` as the predecessor register head. Duplicate + PR #179 remains closed. Stacked-merged heads and queued Checks are not + implemented-main. +- Rust LCOV quality gating now ignores visibility-qualified function signatures + and structural match-arm labels that LLVM reports as zero-hit non-executable + lines. + PR #179 remains closed. Stacked-merged heads and queued Checks are not + implemented-main. +- Removed the completed one-shot PR #51 repair job from `docs-quality.yml`; the + workflow no longer invokes deleted repair scripts or requests write authority + after the executable compute implementation is already present. +- `persistence_postgres` entity and project target inserts now bind their tenant session context before rendering SQL, keeping `FORCE ROW LEVEL SECURITY` behavior consistent with every other tenant-scoped write; live coverage still proves raw wrong-tenant rejection. +- Clarified ADR 0001 so it owns Rust-first numerical/reference-backend authority while ADR 0011 owns cross-service MSA/service authority. +- Clarified ADR 0006 so it owns GPU/VRAM and model-credential boundaries; ADR 0010 now owns LLM orchestration policy and ADR 0015 owns autonomous repository-write/review/merge authority. +- Expanded ADR 0002–0005 and 0009–0011 with explicit implementation maturity, alternatives, failure/recovery, compatibility/migration, verification, and rollback/supersession boundaries where they were previously implicit. + +### Security + +- Naruon interchange refuses `x-apikey`, `x-api_key`, and hyphenated `api-key` credential-header aliases, not only `x-api-key`. +- GitHub HTTPS fleet transport maps request, response, and close-path network exceptions to `upstream_unavailable` without leaking raw provider exception text. +- Disabled-state classification and live disable confirmation now accept GitHub's official `disabled_manually`, `disabled_fork`, `disabled_inactivity`, and `deleted` registry states so orphan bootstrap/repair identities can be retired without name-only heuristics. +- Prohibited `COPILOT_GITHUB_TOKEN` and reserved `NVIDIA_NIM_API_KEY` for approved LLM test and development workflows. +- Defined purpose-bound PII access, opaque analytical identifiers, separately protected identity mapping, selective model-provider disclosure, retention/deletion, and privileged audit controls instead of destructive blanket masking. +- Added explicit threat classes for temporal leakage, relation/membership poisoning, model/artifact poisoning, numerical divergence, cross-tenant disclosure, prompt injection, evidence substitution, resource exhaustion, and scientific-integrity failures. +- Removed the bootstrap branch's credential-co-resident OpenCode workflow: no model process may receive repository-write authority, and scheduled product development remains disabled until proposal, independent verification, and late publication authority are separated across fresh jobs. +- Removed completed bootstrap materializers, encoded payload fragments, readiness sentinels, and push probes from the reviewable tree. +- Required full-commit GitHub Action pins, minimum permissions, concurrency controls, immutable audit evidence, SBOM, and provenance. +- Kept ordinary Rust CI free of LLM and reviewer credentials and disabled persisted checkout credentials. +- Refused to cache mutable Cargo registry, Git source, or target trees; cached quality binaries are keyed and checked by exact version. +- Copied caller-provided source bytes and document text before acceptance and kept validated evidence fields private. +- Made empty, oversized, malformed-digest, invalid UTF-8-boundary, coordinate-mismatch, cross-document, nonfinite-geometry, and out-of-page evidence fail closed with content-redacting errors. +- Rejected malformed or extended wire payloads, unsupported schema versions, invalid identifiers and byte values, digest/content substitution, stale document ownership, and invalid nested geometry during reconstruction. + +### Quality + +- Required 100% production line and branch coverage and complete public API docstrings. +- Required true-parameter recovery, RMSE, bias, interval coverage, temporal leakage, graph recovery, invariance, and CPU/GPU parity evidence. +- Expanded documentation contracts to require the canonical threat/privacy/assurance/API/orchestration/fitness documents, ADR policy, and every numbered ADR present in the canonical index to remain indexed and structurally complete. +- Added deterministic validation that ADR files and the index have identical decision numbers and that every ADR declares valid decision status, implementation maturity, supersession scope, core decision sections, verification, and rollback behavior. +- Added 100% statement and branch coverage for the repository quality-gate scripts. +- Made a zero executable-code coverage denominator explicit for the skeleton-only slice rather than treating it as evidence of implemented behavior. +- Denied warnings, missing public documentation, and unsafe Rust across the workspace. +- Added known digest vectors, mutation detection, hostile multibyte Unicode, exact-coordinate, page-boundary, stable-error, and invalid-input regression tests for the first evidence slice. +- Added strict wire round trips, unknown-field and version rejection, digest reconstruction, configured-limit, hostile JSON, and generated multilingual span tests. + +The repository has not yet cut a stable implementation release, so no compare reference is published for `[Unreleased]` yet. diff --git a/docs/delivery/pr-queue-authority-2026-09-01.md b/docs/delivery/pr-queue-authority-2026-09-01.md new file mode 100644 index 000000000..85a726651 --- /dev/null +++ b/docs/delivery/pr-queue-authority-2026-09-01.md @@ -0,0 +1,116 @@ +# PR Queue Delivery Authority — 2026-09-01 + +This is a live-recovery record for delivery issue #175. GitHub state supersedes this document whenever a head, review, check, or ruleset changes. + +## Snapshot + +- Protected default branch: `main` +- Protected-main SHA observed: `1bc02f580cf48e1d39da239f0e818453437c31c3` +- Snapshot stamp: `2026-09-01T12:12:35Z` +- Open pull requests: **132** +- Draft pull requests: **89** +- Non-draft pull requests: **43** +- Open issues: **14** +- Effective required-workflow ruleset: `18156473`, `CWL Central required workflows` +- GitHub releases: **0** +- `docs/product-technical-gap-baseline.md` is maintained on this recovery branch so it no longer presents a former zero-queue snapshot as current authority. + +The initial observation was 141/99. The queue later peaked at 149/100, fell through 140 and 139, and is now 132/89. This reduction is useful, but new one-operation Analysis Run slices can still recreate WIP while the recovery vehicle is open; each fresh run therefore compares the live count with the immediately preceding snapshot rather than treating any historical count as authority. A queued, skipped, cancelled, predecessor-head, or stale check is not passing evidence. + +## Queue authority classes + +Every open PR must be classified before merge or closure as one of: + +- `landing_vehicle`: the single current-main vehicle for a buyer-visible bounded-context outcome; +- `stacked_dependency`: unique work that must follow a named landing vehicle; +- `fold_into_landing_vehicle`: unique implementation/test/research evidence that belongs inside another bounded-context vehicle rather than remaining an independent product slice; +- `superseded`: no unique behavior remains after an exact-head replacement comparison; +- `duplicate`: same outcome and implementation authority as another PR, with unique evidence explicitly preserved or shown absent; +- `research_lineage_only`: useful scientific provenance that is not intended to ship as a separate runtime boundary; +- `blocked_external`: otherwise-valid work whose current blocker is external to TEPP and is recorded with an owning issue/PR. + +A PR title, ADR number, local green test, or separate crate does not establish an independent product boundary. There is no `landing_vehicle_candidate` class; a vehicle is either selected as `landing_vehicle` or remains one of the declared non-authority classes until selection is justified. + +## Landing order + +The active queue must be reduced in this order: + +1. **Delivery authority and DDD context ownership** — issue #175, this document, `docs/product-technical-gap-baseline.md`, and `docs/architecture/domain-context-map.md`. +2. **Evidence & Semantic Measurement vertical** — span-grounded semantic/concept input, method/source distinctions, immutable source offsets, concept dictionary versioning. +3. **Topic Measurement vertical** — real Rust CPU `f64` shared-latent estimator, uncertainty, true-parameter recovery, candidate-K fitting, topic lineage. +4. **Analysis Run / scientific evidence vertical** — durable lifecycle, estimator-bound validation evidence, persistence/recovery, terminal results, and operator retrieval. Scientific evidence production is separated from claim-promotion authority. +5. **Longitudinal Modeling vertical** — coherent ESEM/DSEM/multilevel measurement and event-time composition rather than scalar-equation PR proliferation. +6. **Event Intelligence vertical** — TDT/CHRONOS composition and event-time evidence under Temporal Event Knowledge. +7. **Commercial runtime vertical** — tenancy, durable jobs, observability, backup/restore, release provenance, support. + +New unrelated micro-PRs are release-excluded while this queue exceeds the active-queue target in issue #175. + +## First classification findings + +### PR #441 — event-time lagged association repair + +Classification: `landing_vehicle` under Longitudinal Modeling. The scientific root cause is repaired on exact head `6f483224b3a03e8237c6f4f098a8b0e85e0a91f5`, but the vehicle is not merge-ready until exact-head workflows succeed and a qualifying independent non-author APPROVE exists. + +The predecessor head exposed `(trait + e^{aΔt} p + added) / (trait + p + added)` as `expected_autocorrelation`. Review showed that a one-sided covariance/earlier-variance ratio is not a correlation under nonstationary marginals and can exceed one. The repair removes that public claim and its `psychometric_core` changes from the final diff. The replacement belongs to `longitudinal_core` and standardizes a supplied lagged covariance only when both marginal variances are available: + +`Cov(Y_t,Y_t+Δ) / sqrt(Var(Y_t) * Var(Y_t+Δ))`. + +The invalid predecessor commit remains only as RED/scientific-failure lineage. Review threads tied to the removed implementation are resolved. Canonical `ARCHITECTURE.md` and `CHANGELOG.md` record the event-time lagged-correlation standardizer; the one-shot self-modifying capability-record workflow was removed. Hosted exact-head Rust/documentation/security checks were still queued at this snapshot, so this PR is not yet a merge authority. + +### PR #356 — validation-run scientific evidence + +Classification: **closed without merge**. Useful cutoff/run-binding/metric evidence is preserved in branch and review history for fold into the Scientific Validation landing work tracked by #166. Do not reopen this exact vehicle. + +The closed head `df33bfa3e61ae4de3dbfae16df0deac12d2f4003` bound cutoff-safe evidence to a validation run, but review found a scientific-authority defect: the acceptance rule compared RMSE with a standard error derived from the same residual vector using a caller-selected preregistered multiplier. That gate can accept arbitrarily large recovery error for pathological residual shapes. The closed observation also accepted caller-supplied truth/recovered vectors and an `authored_by_llm` boolean rather than an estimator-owned, digest-bound provenance artifact. + +DDD correction for the next Scientific Validation vehicle: the run produces **Validation Evidence**. A distinct **Claim Promotion Decision** aggregate, governed by ADR 0014 and a method-specific preregistered evidence contract, decides whether a scientific claim is promotable. No generic standard-error multiplier, maximum-k, or other rule-of-thumb threshold may substitute for a research- or model-derived acceptance design. + +### PRs #443–#446 — Analysis Run export stack + +Classification: `fold_into_landing_vehicle` under one coherent Analysis Run/export vehicle. + +Preserve each slice's unique pagination, authorization, cancellation, CLI parsing, origin/credential/consumer refusal, and metric-free receipt tests. Do not retain one route or one binary as a separate product boundary or architecture authority merely because it has its own ADR or branch. + +### PR #447 — Analysis Run project-history cancel + +Classification: `fold_into_landing_vehicle` under the Analysis Run/project-history vehicle. Preserve its empty-body, path/credential refusal, cancellation-removal, and metric-free receipt evidence before folding. + +### PR #451 — temporal-context GET by id + +Classification: `fold_into_landing_vehicle` under the existing Analysis Run/temporal-context adapter vehicle. Its path parsing, control/NUL/slash refusal, no-header replay rule, LineageWeave-only metric-free identity contract, and backward-compatibility tests are unique evidence to preserve. A single GET route and branch-local ADR number do not create a new bounded context or architecture authority. + +### PRs #352 and #355 — same Driver/ctsem TIPREDEFFECT rewrite + +Classification: both `fold_into_landing_vehicle` under Longitudinal Modeling; neither is selected as a separate authority. + +Both implement the scalar `-a * B` rewrite from the same current-main base. They differ in public naming, refusal guards, tests, doctoring, and documentation edits. Closing either solely because the title and core equation match would discard unique evidence. The consolidation vehicle must retain the stronger named-quantity refusal coverage and realistic published-example tests while avoiding unrelated architecture mega-row edits. + +### Analysis Run transport slices + +PRs for one GET/POST/CLI/status/cancel/retry/export/project-history/temporal-context operation are not separate bounded contexts. Classify them under the Analysis Run application context and `tepp_api` adapter. Parent/child stacks remain documented until a current-main landing vehicle preserves their unique contract tests and consumer compatibility. + +### Evidence/method refusal slices + +PRs binding prompt/style/modality/copied-text/corpus-background/template-copy/location/membership/citation refusals to separate analysis profiles are not automatically independent products. Classify the invariant under Evidence & Semantic Measurement or Temporal Event Knowledge, then fold compatible profiles into one coherent admission/method-effect landing vehicle where the runtime contract does not require an independently versioned lifecycle. + +## Merge evidence required per landing vehicle + +Before merge: + +- re-read exact head/base and effective ruleset; +- compare current remote diff against all PRs marked fold/supersede/duplicate; +- preserve unique tests, public compatibility contracts, citations, and doctoring; +- resolve valid non-outdated review threads; +- obtain the approvals required by the effective ruleset and any stronger non-stale PR-specific bar; +- require all exact-head documentation, Rust, security, and other required workflows to succeed; +- for scientific/model vehicles, require realistic synthetic-truth evidence for the parameters the candidate actually claims: parameter/state recovery, RMSE, bias, interval/credible-interval coverage, temporal ordering and leakage safety, graph recovery where a graph is claimed, longitudinal invariance where longitudinal comparability is claimed, and CPU/GPU parity where an accelerator path is claimed; +- report Monte Carlo uncertainty for recovery summaries rather than applying arbitrary replication pass percentages; +- treat skipped, ignored, xfailed, source-rewritten, predecessor-head, or non-executed GPU tests as non-evidence; +- update `docs/product-technical-gap-baseline.md`, architecture/ADR/traceability/changelog when protected-main truth changes; +- do not use force push or protection bypass to simplify consolidation. + +A scientific vehicle that does not claim a GPU implementation does not manufacture a GPU-parity result; it records the accelerator path as unavailable/research-only. Conversely, a vehicle that claims an accelerator implementation cannot satisfy the gate by skipping that backend. + +## DDD delivery constraint + +Directory and crate moves are part of the owning product-vertical replay. Do not preserve a technical-layer or one-rule path as canonical if it obscures the domain responsibility. Conversely, do not rename all crates in one sweeping PR while 132 remote heads are active. The target bounded contexts are fixed in `docs/architecture/domain-context-map.md`; migration proceeds through safe, reviewable landing vehicles with explicit anti-corruption adapters and replacement mappings. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..8e5c8fc91 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,32 @@ +--- +title: TEPP +--- + +# TEPP + +TEPP is the Temporal Event Psychometrics Platform: a multilingual, temporal, relational measurement system whose statistical and psychometric arithmetic is implemented in Rust. + +## Start here + +The repository is currently an actively developed Rust workspace rather than a supported commercial release. For the current executable surface, verification commands, and explicit claim boundaries, start with the [README](https://github.com/ContextualWisdomLab/TEPP#readme). + +## Product and architecture + +TEPP owns temporal/event semantics, evidence identity and availability, relational and membership structure, analysis-run composition, persistence boundaries, and psychometric recovery gates. Reusable response-family and LSIRM/MLSIRM/DLSJM numerical kernels remain in [fast-mlsirm](https://github.com/ContextualWisdomLab/fast-mlsirm), while model-provider execution and LLM orchestration remain in [contextual-orchestrator](https://github.com/ContextualWisdomLab/contextual-orchestrator). + +The current delivery and bounded-context authority is documented in: + +- [Product and technical gap baseline](https://github.com/ContextualWisdomLab/TEPP/blob/main/docs/product-technical-gap-baseline.md) +- [Domain context map](https://github.com/ContextualWisdomLab/TEPP/blob/main/docs/architecture/domain-context-map.md) +- [Temporal-dependence composition](https://github.com/ContextualWisdomLab/TEPP/blob/main/docs/architecture/temporal-dependence-composition.md) +- [Approved PRD](https://github.com/ContextualWisdomLab/TEPP/blob/main/docs/product/prd-v0.4-approved.md) +- [Standards and literature](https://github.com/ContextualWisdomLab/TEPP/blob/main/docs/research/standards-and-literature.md) +- [Releases](https://github.com/ContextualWisdomLab/TEPP/releases) + +## Onboarding and verification + +TEPP is fail-closed about scientific and release claims. Branch-local tests, open pull requests, planning documents, or queued checks are evidence for review; they do not make a capability shipped on the protected default branch. The README and repository documentation contain the supported local quality gates and current implementation boundaries. + +For repository-grounded code and documentation questions, use [Ask DeepWiki](https://deepwiki.com/ContextualWisdomLab/TEPP). + +This page is a public documentation landing source. GitHub Pages publication is a separate repository-facing state and must be verified live before it is claimed available. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 5ea0c95bf..c8a48706a 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -1,397 +1,98 @@ # Product and Technical Gap Baseline -## 2026-08-27 Driver p.16 standardised-map recovery queue (three landed) +**Status:** Active delivery recovery +**Product:** Temporal Event Psychometrics Platform (TEPP) +**Snapshot:** 2026-09-06T05:32:00Z +**Protected-main evidence:** `a243f18da4a4ca8a8d068c39922537f1f8ed6ad0` +**Workspace version:** `0.2.0` -- Five Driver p.16 `std`-family estimator restorations remain individually - reviewable open PRs against protected `c7cf34b8`: `asymDIFFUSIONstd` (#267), - `TRAITVARstd` (#268), `MANIFESTTRAITVARstd` (#270), `MANIFESTVARstd` (#271), - and `TIPREDVARstd` (#272). Each is a small slice and lands only after - exact-head checks and independent review. -- The TDT/CHRONOS composition (#269) folds the two event-intelligence bounded - gates into one versioned workflow. It remains an active-PR slice: queued or - passing Checks do not promote it to implemented-main. -- This register refresh (PR #273) is itself open; snapshot facts were fetched - live at 2026-08-27T07:35:00Z against protected main `c7cf34b8`. +**Delivery authority:** issue [#175](https://github.com/ContextualWisdomLab/TEPP/issues/175), PR [#435](https://github.com/ContextualWisdomLab/TEPP/pull/435), and [`docs/delivery/pr-queue-authority-2026-09-01.md`](delivery/pr-queue-authority-2026-09-01.md). Historical exact source/test/fixture/contract/ADR evidence remains in repository ancestry, `docs/research/`, `docs/TRACEABILITY.md`, and surviving landing vehicles. This file is the current operator register rather than a duplicate of every predecessor narrative. -## 2026-08-26 Pair criterion and Project Journey posterior slice +## Delivery truth -- Active branch publishes strict Rust artifacts for - `tepp.lineage_pair_criterion_posterior.v2` and - `tepp.project_journey_posterior.v1`. -- The contracts preserve continuous criterion/event-time draws, distinct - record time, multiple predecessors, branches, transitions, exact ties, - TDT/CHRONOS provenance, unique anchor alignment, and method-derived CPU/MLX - parity receipts. They reject fixed starts, nearest-date substitution, - unsupported certainty, and consumer repair. -- Remaining release gap: no protected-main scientific estimator with - CHRONOS event-time draw generation and real macOS-native MLX Metal parity - produces these artifacts yet. The Rust CPU independent binary TDT-link - criterion posterior now has deterministic synthetic parameter-recovery tests, - and Rust qualitative relation draws have exact-recovery tests, but those - bounded estimators are not evidence that calibrated Project Journey or - channel-weight results are available. -- ADR 0025 is the normative Apple Silicon boundary: Rust-owned native MLX - Metal behind authenticated local transport, exact backend receipts, Linux - `rust_cpu`/`mlx_cpu`/`mlx_cuda`/`rust_opencl` portability, and fail-closed - parity. The native service and hardware E2E remain a release gap. -- `mlx_native_receipt` provides a macOS-only, Rust-owned MLX CPU execution - probe. Its receipt proves only the stated matrix objective and cannot be - reused as an Event Lineage estimator or Metal receipt. -- `event_core` now materializes producer-identified discrete event-time mass - into canonical complete draws and recovers synthetic mass exactly. Inferring - the event-time atoms/mass from admitted evidence and binding the estimator's - own MLX receipt remain open; record time and nearest-date substitution stay - prohibited. -- `analysis_engine` now executes exhaustive actual `D \ {i}` fitter calls and - retains full/deleted seed-domain and corpus identities. The remaining gap is - the scientific temporal topic fitter plus unique anchor alignment, incident - relation/membership deletion, artifact assembly, and estimator-bound backend - parity; the runner alone does not publish case-deletion influence. +A planning document, mergeable branch, local/source inspection, predecessor-head result, queued/skipped check, ADR number, bot status, or LLM judgment does not make a capability shipped. Only protected-main integration plus current required evidence establishes delivery. -## 2026-08-25 Event Lineage anchor contract slice +| Signal | Fresh evidence | Delivery implication | +| --- | ---: | --- | +| Protected `main` | `a243f18da4a4ca8a8d068c39922537f1f8ed6ad0` | #490 remains integrated; product claims are bounded to this protected head until main advances. | +| Open pull requests | **135** | WIP circuit breaker remains active; consolidate into existing bounded-context vehicles. | +| Draft pull requests | **134** | #492 is Ready for Review; every other open PR remains Draft. | +| Non-Draft pull requests | **1** | #492 remains gated by exact-head security/static-analysis checks and qualifying approval. | +| Open issues | **17** | #491 owns systemic Validation Evidence exact-proof budgeting. | +| TEPP GitHub releases | **0** | No open TEPP head is a released contract. | +| Organization ruleset | `18156473` | Approval, stale-review dismissal, thread resolution, central required workflows, and non-fast-forward/deletion prohibitions remain normal delivery gates. | -- Exact base: protected `main` `cf0e0ad74d23c5d2e0e33d389bb0bb4d37067c31`. -- This branch publishes TEPP's strict request identity and - `tepp.lineage_criterion_anchor.v1` accepted/rejected artifact contract. -- The buyer-visible integrity gain is fail-closed: LineageWeave cannot promote - fast-mlsirm's internal response structure into calibrated Event Lineage - weights without an exact TEPP-authored criterion result. -- Remaining product gap: the registered TEPP criterion estimator and terminal - artifact delivery are not implemented by this contract slice. Until they - exist and pass scientific recovery/validity gates, production activation - remains unavailable; the consumer must not invent a substitute. -- Acceptance evidence for this slice: complete `tepp_api` tests, warning-free - clippy, strict unknown-field/provenance rejection, schema and ADR/API - traceability, followed by exact-head protected checks and independent review. +Passing, queued, skipped, or predecessor-head checks on an open PR never promote that PR to implemented-main. Organization-admin bypass is not normal delivery evidence. -**Status:** Live delivery baseline -**Product:** Temporal Event Psychometrics Platform (TEPP) -**Snapshot:** 2026-08-27T14:40:00Z -**Protected-main evidence:** `9cd1b263926c456e8c56424c43679d3611310ddb` (merge of [PR #269](https://github.com/ContextualWisdomLab/TEPP/pull/269) TDT/CHRONOS composition at 2026-08-27T14:35Z, on top of #268 TRAITVARstd) -**Workspace version on protected main:** `0.2.0` -**Canonical gap-baseline authority:** [PR #164](https://github.com/ContextualWisdomLab/TEPP/pull/164). [PR #164](https://github.com/ContextualWisdomLab/TEPP/pull/164) merged; this file is now maintained by follow-up refresh PRs against protected main. +## Current priority evidence -## Purpose +#435 intentionally omits its own mutable branch SHA from this file. -This document is the executable operator-gap register for TEPP. It separates: +| PR / issue | Exact current evidence | Disposition | +| --- | --- | --- | +| #492 | `794ba9e6dda9f043aa499920fdf609b81b075d7e`, Ready for Review, base `main` | Canonical foundation repair for the stale repository-local cron contract exposed after #490 centralized hourly admission. Both CodeRabbit findings are repaired and their threads are resolved. Rust Foundation `34011189084` and Documentation Quality `34011189079` are exact-head GREEN. Security Scan `34011189087`, Semgrep `34011189073`, and CodeQL `34011189081` remain non-terminal; no qualifying APPROVED review is authority. | +| #488 | `c682aa22b9e4c0f76e21544b9763fec3de607d92`, Draft, base `main` | Validation Evidence landing vehicle. Production exact pair-distance admission remains `n=4..=16`. Represented-input characterization reaches Wide256 numerator recovery and the 136/140-bit exact-rounding boundary; `aab9fe9115cee97225f2aa81e54a55ceafb23336` adds an exponent-safe Wide256 scaled comparator that orders those candidate/midpoint operands without materializing oversized powers of two. This is characterization only. Rust Foundation `34014176851`, Documentation `34014176838`, CodeQL `34014176905`, Security `34014176883`, and Semgrep `34014176853` are queued/pending. #492 must land before its foundation correction is inherited. | +| #491 | open | Replace the sample-count staircase with a measured exact-proof budget. Wide256 numerator width is sufficient inside the canonical pair-admitted `u128` domain. Represented `n=2050` proves the old `u128` exact-rounding comparator is separately too narrow; the new exponent-safe characterization makes a bounded two-limb exact ordering algorithm feasible but authoritative integration, tie-to-even equivalence, exact-head GREEN/review, and measured resource evidence remain. | +| #416 | `aa730c63563eb4a33048d822b581036c8487bd47`, Draft | Validation / Analysis Run landing vehicle. Generic cutoff-before-identity repair remains inherited; fold children keep unique source/tests/doctoring until conflict-resolving inheritance is verified. | +| #310 | `c6680450152b1e0a2c9abb553772d74a23923335`, Draft | Longitudinal Modeling vehicle. Stable `Between` recovery is unit-level with canonical occasion `0`; `Within` retains actual occasion identity. Older base remains a non-destructive restack finding. | +| #480 | `5b2637f7b6142573ba1385a652c56632ecc9faa5`, Draft | contextual-orchestrator released-contract fail-closed integration vehicle. Mutable owner main is evidence only until an immutable release exists. | -- capabilities an operator can use from protected `main`; -- bounded work that exists only on open pull requests; -- product-completion issues with measurable acceptance evidence; and -- release claims that remain prohibited. +Exact-head evidence becomes stale after any source push. -A planning document, local test, queued check, predecessor-head result, LLM -judgment, or mergeable branch does not make a capability shipped. Re-read live -GitHub state before any customer, release, certification, or valuation claim. +## Domain ownership -## Snapshot facts +TEPP owns Temporal Semantics, Event Ontology, Temporal Graph composition, irregular event time, time-varying multilevel/cross-classified/multiple-membership semantics, Longitudinal Modeling, leakage-safe knowledge cutoff, temporal recovery, Validation Evidence, and Projection policy. `longitudinal_core` is the current Rust implementation path for Longitudinal Modeling. -| Signal | Snapshot evidence | Delivery implication | -|---|---:|---| -| Protected-main SHA | `c7cf34b84d087904bdcb4604479dda2ed8cfcf77` (2026-08-26T12:40Z, merge of [#266](https://github.com/ContextualWisdomLab/TEPP/pull/266)) | All as-built claims are bounded to this commit. | -| Workspace members | 58 unique Rust crates | The repository is modular, but the approved target still lacks complete semantic, compute, psychometric-engine, event-intelligence, interpretation, artifact, and visual product boundaries. | -| Workspace version | `0.2.0` (aligned across every crate manifest) | A version number alone does not establish a supported product release; no signed artifact or support policy exists yet. | -| Open pull requests | **3** | Active queue: #270 MANIFESTTRAITVARstd, #271 MANIFESTVARstd, #272 TIPREDVARstd. | -| Draft pull requests | **0** | No drafts are open at this snapshot; the previously referenced repair and life-cycle orchestration drafts are closed. | -| Open product issues | **9** | Issues #166–#167 and #169–#174 plus #176 remain open. Result-contract issue #156, semantic-units issue #168, queue-consolidation issue #175, and lineage-consumer issue #155 are all CLOSED. | -| Current package version | `0.2.0` | No supported product release is established by the repository version alone; the tagged cut remains queued. | +fast-mlsirm owns reusable static/generalized-mixed/dependence-aware psychometric specification and arithmetic. TEPP consumes only immutable released/versioned contracts through an ACL; source copying and mutable sibling-head dependencies are prohibited. Current owner evidence remains fast-mlsirm protected `main@493326f2de49ea1704da0ded19868ed05d2fe00f` with latest immutable release `v0.9.1`. -The pull-request counts come from the live GitHub search at this snapshot. The -full exact-head classification lives in this register; re-read live GitHub -state immediately before every mutation. Passing or queued Checks on an open PR never -promote that PR to implemented-main. +contextual-orchestrator owns provider/model routing and semantic LLM execution. Current owner evidence remains protected `main@414f22973658c4ddc3d4320fcf7acd9b4e8ba991` with no GitHub release, so TEPP must fail closed rather than consume mutable main as a production semantic-LLM contract. Cross-service SQL and source copying are prohibited. -### Post-#239/#266 state note +The clock contract separates event/valid time, assertion time, document time, system time, availability time, and knowledge cutoff. Retrospective evidence may describe an earlier event but cannot enter an earlier knowledge cutoff. Forward state/transition edges remain distinct from retrospective/citation/revision/provenance relations. -[#239](https://github.com/ContextualWisdomLab/TEPP/pull/239) (`c482ccea`) and -[#266](https://github.com/ContextualWisdomLab/TEPP/pull/266) (`c7cf34b8`) merged -as squash and landed things operators must know: +## Scientific and implementation invariants -1. **network_analysis estimator repairs and provider-owned analysis-run status - HTTP exchange:** exact two-sided Fisher z-transform p-values replace - pseudo-p-values; fail-closed guard ordering for non-finite correlations and - short samples; negative-effect edges excluded from the whole consensus - perturbation pipeline; explicit validated `edge_drop_probability`; - bounds-safe admission helpers; and the provider-owned status/read HTTP - exchange for caller-scoped analysis-run probes. This advances GAP-009's - estimator core beyond the #230 merge (`a69eb3e2`) it builds on. -2. **Workspace version alignment 0.1.0 → 0.2.0** across every crate manifest, - matching the CHANGELOG `[0.2.0] - 2026-08-25` entry. The version bump is not - itself a release: no tag, signed artifact, SBOM/provenance bundle, or support - policy exists yet ([GAP-011](#operator-gap-register)). -3. **Driver p.16 `std`-family restorations continue on protected main:** the - Driver et al. (2017) SDE discrete-time recovery suite drained through - #231/#232 was extended by `T0MEANSstd` (#262) and `T0VARstd` (#265); the - remaining `std`-family restorations stay open as #267/#268/#270/#271/#272. +- Rasch remains distinct from generic 1PL; formulation-qualified 2PLM–5PLM, MIRT, ideal-point/GGUM, testlet/rater/facet/generalized-mixed identity is preserved. +- A nominal unit identifier is not repeated-measures evidence. Stable `Between` known truth is unit-level with canonical `occasion_index = 0`; `Within` retains actual `(unit, occasion)` identity. +- Row arrival order is not scientific evidence. Fixed admitted observations must produce bit-identical results under permutation wherever the deterministic CPU `f64` contract claims it. +- Mean signed bias and bias SE are Validation Evidence measures. `n=2` and proved `n=3` identities remain inherited from GAP-092–110. For exact represented residuals with `n=4..=16`, GAP-111–125 admit `SE(mean)^2 = Σ_{i Wide256 O(n) -> pairwise fail-closed fallback` telemetry. A correct numerator alone does not prove which resource path ran. +- Represented-input characterization `5a19b6334487b43fb630abba7e487d7cf4c49960` makes the wider numerator route reachable rather than synthetic-only. At `n=4096`, represented residual classes `{0,1,2^53}` have exact residual construction and exact distinct pairwise subtractions `{1,2^53,2^53-1}`; common dyadic shift is zero; narrow products overflow; Wide256 recovers exact 119-bit pair numerator `664_289_479_338_799_435_974_172_876_300_357_631`; unreduced denominator is `68_702_699_520`. +- Exact-midpoint characterization `a8423173188fa53a26a16d3afdafeb76e114cc1d` shows a second width boundary at represented `n=2050`. The exact pair numerator `332_306_998_946_228_931_332_463_617_650_984_961` is 118 bits and recoverable by Wide256; denominator `8_610_922_500` remains below `2^53`. The normal seed `0x4296998e1aff78de` requires 136-bit exact candidate-square operands and 140-bit upward-midpoint operands. +- `aab9fe9115cee97225f2aa81e54a55ceafb23336` demonstrates an exponent-safe exact comparison for that boundary: keep each operand as a `Wide256` mantissa plus signed dyadic exponent, compare top-bit positions first, then aligned significand bits. It reproduces target > candidate square and target < upward midpoint without materializing `2^k`, and covers extreme exponent metadata `-2148/-2149` and `2046/2047`. This proves bounded algorithm feasibility, not production admission. +- Historical-cutoff admission occurs before duplicate-identity checks. Future-unavailable evidence cannot change an earlier run's conflicts, counts, or terminal state. +- Supported temporal estimators require state/trajectory and claimed-structure recovery, bias/RMSE, interval coverage, convergence, uncertainty calibration, reproducibility, and leakage-safe rolling-origin evidence. Scientific failures are never hidden with skip/xfail/source rewriting/coverage exclusions. -### Queue-consolidation progress (GAP-012) — COMPLETE (issue #175 closed) +## Current Validation Evidence repair and resource finding -The main non-draft pull-request queue reached **zero** at 2026-08-25T02:30Z and -issue [#175](https://github.com/ContextualWisdomLab/TEPP/issues/175) is CLOSED. -All previously queued slices landed on protected main through: +#488 exact head `c682aa22b9e4c0f76e21544b9763fec3de607d92` inherits the GAP-045–124 source/test/fixture/contract lineage and GAP-125's sixteen-observation repair. GAP-125 RED `5da82b2d651706c191ca191c6c077d916cbfda25` → repair `a509ae9e46c8ffc2cc3ef4f0e904774ad2516e1f` advances only the bounded proof to `n=4..=16`. -1. the hourly scheduler (independent merges of ~40 PRs); -2. batch integration vehicle [#215](https://github.com/ContextualWisdomLab/TEPP/pull/215) (31 folded green slices with per-slice merge-commit provenance); and -3. individual rebase-and-admin-merge passes for the remainder, including the - psychometric recovery stack drained through vehicles - [#231](https://github.com/ContextualWisdomLab/TEPP/pull/231)/[#232](https://github.com/ContextualWisdomLab/TEPP/pull/232), - coverage repair [#219](https://github.com/ContextualWisdomLab/TEPP/pull/219) - (merged 2026-08-25T03:17Z), terminal-result contract - [#157](https://github.com/ContextualWisdomLab/TEPP/pull/157) (merged - 2026-08-25T02:53Z), posterior network estimator - [#230](https://github.com/ContextualWisdomLab/TEPP/pull/230) (merged - 2026-08-25T06:24Z), and network-repair/version-alignment - [#239](https://github.com/ContextualWisdomLab/TEPP/pull/239). +Issue #491 retains the exactly represented `n=17` fixture whose 136 exact pair squares sum to `92_549_865_125_191_410_206`; denominator `4_624`; gcd `2`; reduced radicand `46_274_932_562_595_705_103/2_312`. Current fallback returns `0x41a0_dd77_9ac3_8e98`; exact-rational evaluation gives adjacent `0x41a0_dd77_9ac3_8e99`. -The residual open PRs are new forward work (register refresh #273, release cut, -API anchor contract, coverage completion, event-intelligence fold, and the -`std`-family psychometric restorations #267/#268/#270/#271/#272), not backlog. +Resource arithmetic remains separated from scientific admission. Exact pair records are 120 at `n=16`, 136 at `n=17`, 2,096,128 at `n=2,048`, and 4,997,541 at `n=3,162`. For canonical aligned diameter `D=2^53`, normalized narrow O(n) checked intermediate envelope `n²D²` fits through `n=2,047`, exact pair-square numerator extremum `floor(n²/4)D²` fits through `n=4,095`, and unreduced denominator `n²(n-1)` stays at or below `2^53` through `n=208,064`. Production uses the GCD-reduced denominator, so none is a universal refusal count. -## Snapshot open pull-request evidence +The current causal sequence is now numerator width → exact-rounding width → exponent-safe comparison feasibility. The two-limb comparator characterization eliminates the need to materialize huge power-of-two factors, but production `bias_se.rs` still uses bounded `u128` products. Promotion therefore requires integrating that primitive into authoritative candidate stepping, adjacent-midpoint comparison, and exact tie-to-even semantics, then demonstrating represented-input equivalence against the pairwise authority. -The following exact-head register was fetched live from GitHub at -2026-08-27T07:35:00Z against protected main `c7cf34b8`. Review decisions, -required Checks, and mergeability remain volatile; the live GitHub API -supersedes this snapshot. `draft=false` is not approval, mergeability, or a -passing-check claim. Re-read the full SHA, current review decision, required -Checks, and branch rules immediately before every mutation. +Hosted Rust Foundation runs established the stale local-cron contract and five missing integration-test crate docs. Repairs `1f765a7430b3263afb7e436efdf6d3f14dd433c9` and `aefefba5982579e46e8c3ff33d64c99ea7a6bafc` document those tests without suppression. Foundation cron repair remains #492 rather than a duplicated #488 change. -| PR | Exact current head | Draft | Base | Title | -| #272 | `eff029c809d2e3227c8fb31e42348464268ce511` | false | main | feat(psychometric): restore Driver p.16 TIPREDVARstd v/v=1 on main | -| #271 | `6033582cb060f3ad7b32a4f9ece16d642727393e` | false | main | feat(psychometric): restore Driver p.16 MANIFESTVARstd θ/θ=1 on main | -| #270 | `b4b51f135eb653b4b39241da4a64b89dd7abfc73` | false | main | feat(psychometric): restore Driver p.16 MANIFESTTRAITVARstd ψ/ψ=1 on main | -|---:|---|:---:|---|---| +Pinned Rust 1.98.0 formatter run `34009378472` on predecessor `1f765a...` completed with artifact `9982621569`, digest `sha256:3594e30cec832e1d230c0966ef3853d189ae764b36ef1c2f0df36584329fee49`. That predecessor artifact is not current-head GREEN. Current #488 exact-head runs are `34014176851` Rust Foundation, `34014176838` Documentation, `34014176905` CodeQL, `34014176883` Security, and `34014176853` Semgrep; all are non-terminal at this snapshot. +No Rust 1.98.0 release-mode resource CSV, allocator/RSS record, applicable buyer-path p95, exact-head hosted GREEN, or qualifying independent review is claimed. Canonical `docs/TRACEABILITY.md` still needs a direct #491 resource-route row. +## Gap register +| ID | Gap / state | Current closure evidence | +| --- | --- | --- | +| GAP-001–044 | Existing product/domain/DDD/release and Longitudinal gaps; mixed/inherited | Exact histories remain in ancestry, surviving landing vehicles, ADRs/tests, and research/TRACEABILITY. | +| GAP-045–091 | Validation Evidence bias, RMSE/SE, Monte Carlo, Wilson, matching, acceptance, provenance/serde/projection repairs; verification pending | Exact source/tests/research remain inherited on #488; protected-main integration still requires current-head gates/review. | +| GAP-092–110 | Represented residual subtraction, translated-moment, rational-scale, anchor, three-level and subnormal correctness sequence; verification pending | Exact RED→repair lineages and public contracts remain inherited on #488. | +| GAP-111–125 | Exact pair-distance/midpoint proof introduced and extended through `n=16`; verification pending | GAP-125 RED `5da82b2d...` → repair `a509ae9e...`; production bounded proof remains `n=4..=16`. | +| #491 | Hard sample-count cutoff is an unmeasured resource budget; open | Canonical normalization, Wide256 numerator route, product-width theorem, represented `n=4096` reachability, represented `n=2050` exact-rounding width boundary, and exponent-safe two-limb ordering characterization are executable/documented. Authoritative comparator integration, tie-to-even/end-to-end equivalence, current-head GREEN/review, measured CPU/RSS, and canonical TRACEABILITY matrix indexing remain. | +| #492 | Central hourly admission tests remained stale/incomplete after #490; verification pending | Repairs through `794ba9e6...` remove the cron assertion and structurally validate `on:`. Rust Foundation and Documentation are exact-head GREEN; security/static-analysis gates and qualifying approval remain. | +## Release gate - - -Note on #241: the #239 squash-merge landed through its pre-fix head, so #241 -cherry-picks the final coverage-and-semantics commit (dead singleton-guard -removal in `network_analysis::consensus`, unreachable let-else replacement in -`evidence_core::image_unit`) onto current main. Until #241 merges, protected -main carries those two dead-branch semantics points; they are test debt, not a -weakened 100% gate. - -Review decisions, required Checks, and mergeability remain volatile; re-read -them immediately before every mutation. This snapshot is not merge authorization -and does not treat queued or passing Checks as shipped protected-main behavior. - -## Authority and derivation - -| Concern | Canonical authority | Constraint | -|---|---|---| -| Product outcomes | [`docs/product/prd-v0.4-approved.md`](product/prd-v0.4-approved.md) | Defines the release product, users, visual surfaces, scientific claims, and eight delivery phases. | -| Technical/runtime requirements | [`docs/TRD.md`](TRD.md) | Requires independently usable Rust boundaries, CPU `f64` authority, temporal eligibility, realistic validation, and warning-free release evidence. | -| Architecture and service boundaries | [`ARCHITECTURE.md`](../ARCHITECTURE.md), [`docs/UML.md`](UML.md), [`docs/API_CONTRACT.md`](API_CONTRACT.md) | Separates evidence, measurement, compute, psychometrics, event intelligence, interpretation, artifacts, and visual analytics. | -| Data authority | [`docs/ERD.md`](ERD.md), [`docs/TRACEABILITY.md`](TRACEABILITY.md), [`docs/adr/0013-bitemporal-persistence-reproducibility-and-split-authority.md`](adr/0013-bitemporal-persistence-reproducibility-and-split-authority.md) | Requires normalized persistence, six-clock eligibility, relation-aware splits, immutable provenance, and reproducible artifacts. | -| Scientific claim promotion | [`docs/adr/0014-scientific-claim-promotion-and-release-evidence.md`](adr/0014-scientific-claim-promotion-and-release-evidence.md), [`docs/TEST_STRATEGY.md`](TEST_STRATEGY.md) | Requires production-code recovery, uncertainty, parity, exact-head checks, and independent review before promotion. | -| LLM authority | [`docs/adr/0010-adaptive-llm-orchestration.md`](adr/0010-adaptive-llm-orchestration.md), [`docs/LLM_ORCHESTRATION.md`](LLM_ORCHESTRATION.md) | LLMs may propose and verify interpretations; deterministic/statistical gates remain authoritative. | -| Privacy/security/assurance | [`docs/PRIVACY_DATA_GOVERNANCE.md`](PRIVACY_DATA_GOVERNANCE.md), [`SECURITY.md`](../SECURITY.md), [`docs/THREAT_MODEL.md`](THREAT_MODEL.md), [`docs/COMPLIANCE_READINESS.md`](COMPLIANCE_READINESS.md) | Preserves legitimate PII utility through purpose-bound access while prohibiting credential/source leakage and unsupported certification claims. | -| Research | [`docs/research/standards-and-literature.md`](research/standards-and-literature.md) | Method and standards claims require current authoritative sources and APA 7 traceability. | -| Live delivery | [open PRs](https://github.com/ContextualWisdomLab/TEPP/pulls?q=is%3Apr+is%3Aopen), [open issues](https://github.com/ContextualWisdomLab/TEPP/issues?q=is%3Aissue+is%3Aopen) | Live GitHub state supersedes this time-stamped queue snapshot. | - -## Protected-main as-built baseline - -Protected `main` contains 58 unique Rust crate boundaries in the current -workspace manifest (as of `c7cf34b8`). The `members` and `default-members` -arrays enumerate the same crate set for distinct Cargo commands; the -unique-crate count is the authoritative modularity measure. -The core boundaries include: - -```text -evidence_core -temporal_core -event_core -relation_graph -membership_core -persistence_postgres -corpus_split -tepp_simulation -validation_core -tepp_api -topic_measurement -network_analysis -psychometric_core -analysis_engine -interpretation_gateway -compute_backend -mlx_native_receipt -``` - -The traceability ledger records meaningful protected-main implementation in -immutable evidence, six clocks and interval reasoning, forward transitions, -event mention/instance separation, weighted multiple membership, cutoff-safe -splits, validation metrics, simulations, PostgreSQL slices, versioned API/export -contracts, orchestration routing, privacy authorization, release-evidence -generation, the CPU topic-measurement reference estimator, the repaired -posterior network estimator (#230 + #239), the Driver et al. (2017) SDE -recovery suite (#231/#232) and its `T0MEANSstd`/`T0VARstd` restorations -(#262/#265), the deterministic analysis-run execution engine, the loopback -interpretation gateway, the provider-owned analysis-run status/read HTTP -exchange (#266), the macOS-native MLX CPU receipt probe -(`mlx_native_receipt`), and VRAM-policy compute types. - -Protected `main` does **not** yet establish the complete approved product. In -particular, it does not contain the full multilingual semantic pipeline beyond -the first span slice, full Bayesian candidate-`K` topic fitting, a composed -longitudinal ESEM/DSEM estimation engine, a calibrated TDT/CHRONOS workflow, -repeated Leiden consensus clustering with buyer-facing exports, real accelerator -kernels with hardware parity, an executed contextual-orchestrator interpreter, -the coordinated visual workspace, or a supported multi-tenant release. - -## Operator-gap register - -| ID | Operator-visible gap | Maturity | Delivery status | Protected-main authority | Current delivery authority | Current head SHA | Closure evidence | -|---|---|---|---|---|---|---|---| -| GAP-001 | Submission produces a durable accepted receipt, and the deterministic terminal-result lifecycle is now implemented-main. | `implemented-main` | closed on protected main | `340087494b0a` lineage merged through [PR #157](https://github.com/ContextualWisdomLab/TEPP/pull/157) (merged 2026-08-25T02:53Z); [#156](https://github.com/ContextualWisdomLab/TEPP/issues/156) CLOSED | — | — | Exact request/result/snapshot/cutoff/model/profile binding, typed terminal failures, deterministic retrieval, and cutoff-safe execution are protected-main behavior as of the #157 merge. | -| GAP-002 | LineageWeave and other modular consumers can rely on the complete protected-main HTTP evidence/result boundary. | `partial` | consumer hardening remains | Terminal-result lifecycle implemented-main via #157; versioned API contract intact | [#156](https://github.com/ContextualWisdomLab/TEPP/issues/156) (closed) / [PR #155](https://github.com/ContextualWisdomLab/TEPP/pull/155) (merged) | — | Remaining work is consumer-side adoption evidence and any versioned-contract drift discovered during integration; core boundary is no longer the gap it was. | -| GAP-003A | Immutable evidence cannot yet be submitted to a durable validation run that produces operator-usable scientific acceptance evidence. | `accepted-target` | product-completion | `e65cd66` (validation metrics are library-level only) | [#166](https://github.com/ContextualWisdomLab/TEPP/issues/166) | `—` (issue program; no current implementation PR) | Compose/CLI/API execution must bind immutable evidence, cutoffs, model configuration, validation metrics, and reproducibility manifests to one idempotent run. | -| GAP-003B | Scientific result artifacts cannot yet be persisted, restarted, and recovered as one supported operator workflow. | `accepted-target` | product-completion | `e65cd66` (persistence contracts lack E2E recovery) | [#166](https://github.com/ContextualWisdomLab/TEPP/issues/166) | `—` (issue program; no current implementation PR) | Durable storage, migration/rollback, restart/recovery, artifact digest verification, and terminal retrieval must pass against a real Compose deployment. | -| GAP-003C | The persistence slice classifies concurrent-write SQLSTATEs, but has no measured hot-partition detection, routing, or mitigation for tenant/result workloads. | `accepted-target` | product-completion | `e65cd66` (conflict classification only; no measured partition control) | [#166](https://github.com/ContextualWisdomLab/TEPP/issues/166) | `—` (issue program; no current implementation PR) | A real Compose/PostgreSQL workload identifies hot keys and partition skew, applies bounded tenant/time or result routing without weakening 3NF or temporal authority, and proves conflict rate, latency, recovery, and migration/rollback behavior under load. | -| GAP-004 | The central shared-latent temporal/relational topic estimator is absent. | `partial` | product vertical | CPU `f64` TRSL-TM reference estimator with ALR/ILR coordinates and refusal gates is implemented-main (v0.2.0 `topic_measurement`); fitted candidate-`K` scoring present | [#167](https://github.com/ContextualWisdomLab/TEPP/issues/167) | — | GPU, method effects, full Bayesian sampling, and topic birth/split/merge remain. This is not full #167 closure. | -| GAP-005 | Real multilingual documents are not yet transformed into validated exact-span semantic units and versioned shared concepts. | `partial` | product vertical | `e65cd66` lineage (semantic_core exact-span units and language-profile validation are implemented-main as the first slice from [PR #201](https://github.com/ContextualWisdomLab/TEPP/pull/201)) | [#168](https://github.com/ContextualWisdomLab/TEPP/issues/168) CLOSED COMPLETED 2026-08-24; residual evidence tracked under product completion (#166/#169) | `—` | Remaining evidence beyond the closed first slice: concept alignment, Unicode/layout/language-tailored processing, unknown-concept review, multilingual calibration/invariance, image-position evidence, and prompt-injection tests. | -| GAP-006 | Posterior topic measurements cannot yet be fitted through a complete cross-classified longitudinal ESEM/DSEM engine. | `partial` | product vertical | Psychometric recovery stack drained onto protected main through integration vehicles [#231](https://github.com/ContextualWisdomLab/TEPP/pull/231)/[#232](https://github.com/ContextualWisdomLab/TEPP/pull/232) (both merged 2026-08-25T06:2xZ): Driver et al. (2017) SDE discrete-time recovery suite with standardised-parameter families and true-parameter RMSE tests is implemented-main (`psychometric_core`) | [#169](https://github.com/ContextualWisdomLab/TEPP/issues/169) | — | Remaining: joint plausible-value uncertainty wiring, full invariance evidence, irregular event-time fitting at production scale, multiple-membership integration with posterior coordinates, and end-to-end composition under #166/#167. Recovery primitives alone are not the ESEM/DSEM engine. | -| GAP-007 | TDT detection/tracking and CHRONOS schema/forecast/temporal reasoning remain isolated bounded gates rather than one calibrated product workflow. | `accepted-target` | product vertical | `e65cd66` (event/time primitives only) | [#170](https://github.com/ContextualWisdomLab/TEPP/issues/170) / [PR #70](https://github.com/ContextualWisdomLab/TEPP/pull/70) | `7a1f33aa68c1` | Span-grounded mentions, calibrated TDT metrics, schema/forecast hypothesis states, interval consistency, known-truth recovery, persistence, and exports. | -| GAP-008 | GPU support is policy-only; no production estimator kernel has real hardware parity or declared VRAM evidence. | `accepted-target` | product vertical | `e65cd66` (VRAM policy only) | [#171](https://github.com/ContextualWisdomLab/TEPP/issues/171) / [PR #51](https://github.com/ContextualWisdomLab/TEPP/pull/51) | `1801501c4d7c` | Real CUDA/portable backend execution, CPU parity, streamed memory, bounded OOM/fallback, hardware profiles, telemetry, and no skipped-support claim. | -| GAP-009 | Topic association and cluster outputs lacked posterior-valid estimation, uncertainty, edge stability, and consensus communities. | `partial` (estimator core + repairs landed; Leiden consensus + buyer workflow remain) | product vertical | `a69eb3e2` (posterior log-ratio edge estimator merged from [PR #230](https://github.com/ContextualWisdomLab/TEPP/pull/230)) advanced by [#239](https://github.com/ContextualWisdomLab/TEPP/pull/239) (`c482ccea`): exact two-sided Fisher z-transform p-values driving Benjamini–Hochberg admission (Benjamini & Hochberg, 1995), percentile-bootstrap credible intervals and selection fractions (Efron, 1979), fail-closed guard ordering for non-finite correlations and short samples, negative-effect edges excluded from the whole consensus perturbation pipeline, explicit validated `edge_drop_probability`, bounds-safe admission helpers | [#172](https://github.com/ContextualWisdomLab/TEPP/issues/172) | — (#241 carries two dead-guard removals) | Remaining closure evidence: repeated Leiden consensus replacing the union-find stand-in (Traag et al., 2019), known-truth network/cluster recovery at production scale, and reproducible exports wired into the end-to-end run (#166). | -| GAP-010 | Operators lack coordinated accessible visual analytics and exact-value export workflows. | `accepted-target` | product vertical | `e65cd66` (no visual workspace) | [#173](https://github.com/ContextualWisdomLab/TEPP/issues/173) | `—` (Figma work not started) | Real Figma File ID in ADR, Storybook/design tokens, ten PRD views, exact-value tables, accessible interaction/print/PDF states, provenance, and source-consistent exports. | -| GAP-011 | TEPP is not yet an operable multi-tenant service or supported release. | `accepted-target` | product vertical | `e65cd66` (library contracts only) | [#174](https://github.com/ContextualWisdomLab/TEPP/issues/174) | `—` (issue program; no current implementation PR) | Durable queue/storage, OIDC/RLS/purpose controls, OpenTelemetry/SLOs, load/recovery, migrations, signed release/SBOM/provenance, assurance evidence, and support policy. | -| GAP-012 | The 71-PR queue obscured authority, repeatedly staled exact-head evidence, and fragmented product boundaries. | `implemented-main` (consolidation complete) | closed | `c7cf34b8` (#239 merged 2026-08-25T09:23Z; #266 merged 2026-08-26T12:40Z); [#175](https://github.com/ContextualWisdomLab/TEPP/issues/175) CLOSED; queue drained from 58 through #215, the hourly scheduler, vehicles #231/#232, and individual passes | — | — | Residual open queue is forward work (register refresh #273, event-intelligence fold #269, `std`-family psychometric restorations #267/#268/#270/#271/#272); no backlog remains. Exact-head discipline stays enforced by this register's refresh rule. | -| GAP-013 | Evidence-grounded LLM interpretation is routed but not executed and validated as a production interpreter/verifier port. | `partial` | active integration | `e65cd66` lineage (routing and refusal contracts implemented-main; loopback interpretation POSTs landed via #92/#107) | [#176](https://github.com/ContextualWisdomLab/TEPP/issues/176), [PR #69](https://github.com/ContextualWisdomLab/TEPP/pull/69), [PR #165](https://github.com/ContextualWisdomLab/TEPP/pull/165) | `8e4a3ca9cc80` / `34083c3f5d66` | Contextual-orchestrator execution, evidence citations, verifier refusals, comparable-budget ablations, provider eligibility/fallback, abstention, live/offline contract tests, and no numerical-authority escalation. | -| GAP-014 | README/TRD and some PR descriptions lag protected-main and live queue reality. | `partial` | documentation drift | Documentation synchronized to `c7cf34b8` through register refreshes including this file (#273) | [#175](https://github.com/ContextualWisdomLab/TEPP/issues/175) (closed) | — | Remaining: reconcile README/TRD crate counts to 58, retire CHANGELOG `[Unreleased]` bullets superseded by the v0.2.0 entry, and keep ADR maturity current. | -| GAP-015 | There was no canonical live product/operator-gap register tied to documentation validation. | `implemented-main` (register + validator); this refresh is the live maintenance slice | register refresh | `c7cf34b8` (register and validator are implemented-main; this snapshot refresh keeps the volatile queue current) | [PR #164](https://github.com/ContextualWisdomLab/TEPP/pull/164) is the merged authority; this refresh is [#273](https://github.com/ContextualWisdomLab/TEPP/pull/273) | `7f6c8a5a4351b4a8d0cfa5b7d2eaadfae71c7a9a` | Land each refresh after exact-head checks and independent review, then regenerate it whenever protected-main or the live queue changes. Only one refresh authority lands per queue state. | -| GAP-016 | Hourly PR maintenance used an older central scheduler revision whose per-repository sweep budgets could amplify the queued review workload. | `active-PR` | operability hardening | `e65cd66` (caller pin before central budget hardening) | [PR #177](https://github.com/ContextualWisdomLab/TEPP/pull/177) | `580d45206536` | The change pins a verified central revision immutably; closure still requires exact-head hosted Checks, resolved threads, and independent review. With the queue near zero the urgency is low but the slice remains unlanded. | -| GAP-017 | Accepted analysis runs have a terminal DTO and cutoff-safe execution on protected main after #157 merged. | `implemented-main` | closed on protected main | [PR #157](https://github.com/ContextualWisdomLab/TEPP/pull/157) merged 2026-08-25T02:53Z carrying the terminal result contract and folded cutoff-safe execution from closed stacked PR #178 | [#156](https://github.com/ContextualWisdomLab/TEPP/issues/156) (closed) / [#166](https://github.com/ContextualWisdomLab/TEPP/issues/166) | — | Exact availability cutoff, snapshot binding, multiple-membership preservation, digest integrity, redacted no-eligible failure, and realistic end-to-end tests are protected-main behavior; remaining E2E composition work belongs to #166. | -| GAP-018 | Coverage debt: the #219 repair landed, and #239 added 27 exact branch cases, leaving two dead-guard semantics points queued on [#241](https://github.com/ContextualWisdomLab/TEPP/pull/241). | `active-PR` | coverage completion | `5c8599442e85` lineage + #219 (merged 2026-08-25T03:17Z) + #239 (`c482ccea`): gates enforce 100% unique production arms; remaining items are dead-branch removals in `network_analysis::consensus` and `evidence_core::image_unit` | [PR #241](https://github.com/ContextualWisdomLab/TEPP/pull/241) | `a12e48c1e61b` | Merge #241 after exact-head Checks plus independent review so protected main carries the final semantics cleanup; two provably-dead singleton guards and an unreachable let-else are the last known items. | - -## Product-completion issue register - -| Issue | Product vertical | Depends on / constrains | -|---:|---|---| -| [#156](https://github.com/ContextualWisdomLab/TEPP/issues/156) **CLOSED** | Completed analysis-run result contract | Landed on protected main through PR #157 (merged 2026-08-25T02:53Z). | -| [#166](https://github.com/ContextualWisdomLab/TEPP/issues/166) | Executable end-to-end analysis run, recovery, and hot-partition readiness | Integrates all scientific/service verticals; cannot substitute placeholders or hide write skew behind an unmeasured queue. | -| [#167](https://github.com/ContextualWisdomLab/TEPP/issues/167) | Shared-latent temporal topic CPU estimator | Numerical foundation for K selection, networks, psychometrics, interpretation, and product E2E; CPU reference landed, full estimator remains. | -| [#168](https://github.com/ContextualWisdomLab/TEPP/issues/168) **CLOSED** | Multilingual semantic units and concept dictionary | Closed COMPLETED 2026-08-24; first-slice span units are implemented-main, remaining invariance/calibration evidence tracks product completion elsewhere. | -| [#169](https://github.com/ContextualWisdomLab/TEPP/issues/169) | Multilevel longitudinal ESEM/DSEM | Consumes posterior topic coordinates and membership/time contracts; recovery stack landed via #231/#232, engine composition remains. | -| [#170](https://github.com/ContextualWisdomLab/TEPP/issues/170) | TDT/CHRONOS event intelligence | Consumes evidence/time/event contracts and supplies calibrated event artifacts; span-grounding fold queued as draft #233. | -| [#171](https://github.com/ContextualWisdomLab/TEPP/issues/171) | Real GPU compute and parity | Accelerates production estimators only after CPU authority is stable. | -| [#172](https://github.com/ContextualWisdomLab/TEPP/issues/172) | Posterior network and consensus clustering | Estimator core plus #239 repairs landed; Leiden consensus and buyer workflow remain. | -| [#173](https://github.com/ContextualWisdomLab/TEPP/issues/173) | Accessible visual analytics and exports | Starts after stable API/artifact contracts; requires Figma and Storybook evidence. | -| [#174](https://github.com/ContextualWisdomLab/TEPP/issues/174) | Commercial deployment/release/support | Wraps a scientifically complete product without weakening gates; v0.2.0 version alignment (#239) is a prerequisite slice, not closure. | -| [#175](https://github.com/ContextualWisdomLab/TEPP/issues/175) **CLOSED** | PR queue and delivery consolidation | Queue consolidation completed at near-zero; issue closed after the residual queue drained through #239. | -| [#176](https://github.com/ContextualWisdomLab/TEPP/issues/176) | Contextual-orchestrator interpreter/verifier | Consumes validated artifacts and cannot promote scientific truth. | - -## Priority pull-request queue - -This table lists every open pull request at snapshot time. The pull request's -live page is authoritative because its head can change after this file is -committed. - -| PR | Current delivery role | Required next action | -|---:|---|---| -| [#273](https://github.com/ContextualWisdomLab/TEPP/pull/273) | Live gap-baseline refresh to protected `c7cf34b8` (GAP-015 maintenance slice) | Exact-head Required Checks must pass on the current head plus independent review before merge; re-dispatch superseded exact-head evidence. | -| [#272](https://github.com/ContextualWisdomLab/TEPP/pull/272) | Driver p.16 `TIPREDVARstd` restore (GAP-006 recovery family) | Exact-head Required Checks must pass on the current head plus independent review before merge; re-dispatch superseded exact-head evidence. | -| [#271](https://github.com/ContextualWisdomLab/TEPP/pull/271) | Driver p.16 `MANIFESTVARstd` restore (GAP-006 recovery family) | Exact-head Required Checks must pass on the current head plus independent review before merge; re-dispatch superseded exact-head evidence. | -| [#270](https://github.com/ContextualWisdomLab/TEPP/pull/270) | Driver p.16 `MANIFESTTRAITVARstd` restore (GAP-006 recovery family) | Exact-head Required Checks must pass on the current head plus independent review before merge; re-dispatch superseded exact-head evidence. | -| [#269](https://github.com/ContextualWisdomLab/TEPP/pull/269) | Calibrated workflow composition: fold TDT detection and CHRONOS schema/forecast reasoning into one versioned product workflow (GAP-007) | Exact-head Required Checks must pass on the current head plus independent review before merge; re-dispatch superseded exact-head evidence. | -| [#268](https://github.com/ContextualWisdomLab/TEPP/pull/268) | Driver p.16 `TRAITVARstd` restore (GAP-006 recovery family) | Exact-head Required Checks must pass on the current head plus independent review before merge; re-dispatch superseded exact-head evidence. | -| [#267](https://github.com/ContextualWisdomLab/TEPP/pull/267) | Driver p.16 `asymDIFFUSIONstd` restore (GAP-006 recovery family) | Exact-head Required Checks must pass on the current head plus independent review before merge; re-dispatch superseded exact-head evidence. | -## Delivery sequence - -The dependency-aware product order is (✓ = landed on protected main): - -1. ✓ **Consolidate delivery authority:** #175 closed; PR #164 merged; queue drained through #239. -2. ✓ **Finish live result contracts:** #156/#157 merged; the LineageWeave consumer parent #155 is implemented-main. -3. ✓ **Build validated multilingual evidence (first slice):** #168 closed COMPLETED 2026-08-24 with span units implemented-main from #201; remaining alignment/invariance evidence tracks product completion under #166/#169. -4. **Build the CPU topic estimator:** #167 — reference estimator landed, full Bayesian/candidate-K fitting remains. -5. **Build event intelligence and posterior networks:** #170 and #172 — network estimator core plus #239 repairs landed; Leiden consensus, buyer workflow, and event-intelligence calibration remain; the calibration compositional fold is open (#269). -6. **Build the posterior-aware longitudinal psychometric engine:** #169 — recovery stack landed via #231/#232 plus #262/#265; remaining Driver p.16 `std`-family restorations are open as #267/#268/#270/#271/#272, and engine composition remains. -7. **Accelerate real kernels with parity:** #171. -8. **Complete the durable end-to-end run:** #166 — terminal-result lifecycle and analysis-run execution engine are implemented-main; full E2E validation remains. -9. **Execute and validate interpretation:** #176. -10. **Design and implement the operator workspace:** #173. -11. **Productionize and release:** #174 — v0.2.0 version alignment landed (#239); tagged cut remains pending. - -Stacking is appropriate where public contracts make dependencies explicit. -Stacking is not a reason to leave multiple unexplained implementation authorities -or stale draft predecessors open. - -## Definition of product complete - -TEPP is not complete until one released version proves all of the following on -the same protected source lineage: - -- a documented user can install, authenticate, ingest, run, inspect, export, and - recover the product without repository-internal intervention; -- immutable source evidence, six clocks, relation/membership structure, cutoff, - splits, model/config, backend, seeds, and artifacts are reproducible; -- the shared-latent topic estimator and longitudinal psychometric model recover - declared known truth with pre-registered RMSE, bias, coverage, convergence, - calibration, and error-rate gates; -- declared language profiles have span/concept/alignment/invariance evidence; -- event intelligence, topic networks, and clusters have known-truth and - uncertainty/stability evidence; -- accelerator claims use real hardware and match the CPU scientific reference; -- LLM interpretation cites allowed evidence, rejects unsupported claims, and - abstains when evidence or policy is insufficient; -- every visual value has an accessible exact-value and provenance path; -- tenant, purpose, identity, retention, security, migration, backup/restore, - observability, capacity, rollback, SBOM, provenance, and support evidence pass; -- production statement coverage, branch coverage, and public documentation are - 100% for shipped TEPP code; -- current-head CI, security, supply-chain, scientific, and independent review - gates pass with no unresolved release blocker; -- version, CHANGELOG, signed artifacts, and release notes match the protected - source and make no unsupported certification, causality, language, GPU, or - valuation claim; -- the release-blocking PR and issue queues are zero. - -A `200억 달러` bar remains a prioritization heuristic. It is not a valuation -result and cannot replace operator adoption, predictive/construct validity, -operational reliability, proprietary advantage, revenue, retention, or -independent diligence evidence. - -## Architecture, data, and assurance constraints - -- Rust owns production mathematical and psychometric arithmetic. -- CPU `f64` is the numerical reference; parallelism is bounded and GPU work must - prove real-hardware parity. -- Event, assertion, document, system, availability, and knowledge-cutoff clocks - remain distinct. -- Cross-classified and weighted multiple membership prevents atomistic - pseudo-replication. -- Topic proportions remain compositional; valid latent/log-ratio coordinates - feed ESEM and network analysis. -- Database objects use descriptive two-or-more-word `snake_case`, third-normal - form where applicable, explicit tenant/temporal/provenance authority. Hot - partition readiness is a separate acceptance gate: measure skew first, then - mitigate it without denormalizing authority tables or changing temporal - semantics. -- Documents, web/search results, connector data, and LLM output are untrusted. -- Purpose-bound access and protected identity mappings preserve PII utility - without broadcasting or blanket masking. -- External products integrate through versioned API/event/artifact contracts, - never direct application-table access. -- CSAP/SOC 2/ISO/NIST alignment is readiness evidence, not certification. -- Every method/standard decision updates APA 7 traceability and source-to-test - traceability in the same reviewed change. - -## Refresh rule - -Refresh this file when any of the following changes materially: - -- protected-main SHA or package version; -- open PR/draft/issue counts; -- a priority PR head/base/review/check/merge state; -- an issue or operator-gap acceptance boundary; -- a capability's implementation maturity; -- the dependency/landing order; -- a release, deprecation, replacement, Figma file, or standards/research basis. - -Keep this file operator-oriented. The volatile per-PR classification lives in -this register's snapshot tables (issue #175 is closed; no separate artifact is -required). Never rewrite an active-PR -capability as protected-main before merge and exact-head verification. +TEPP currently has no GitHub release. Release is permitted only after a coherent vertical reaches protected main with exact protected-head CI/security evidence, scientific/recovery acceptance, reproducible package/build artifacts with SBOM and provenance, validated migrations/upgrade/rollback/recovery where applicable, consistent version metadata and current CHANGELOG/TRACEABILITY/operator baseline, accessibility/operability evidence for user-facing components, no unresolved scientific/privacy/security/supply-chain blockers, and released integration contracts where deployment depends on them. Queued/pending/startup-failed/skipped or predecessor-head evidence is not GREEN. diff --git a/docs/research/rubin-total-variance.md b/docs/research/rubin-total-variance.md index aa8ff6749..be70a5584 100644 --- a/docs/research/rubin-total-variance.md +++ b/docs/research/rubin-total-variance.md @@ -6,7 +6,7 @@ Adds Rubin combining for complete-data OLS loadings across posterior indicator d ## Claim boundary -`T_m = \bar U_m + (1+1/m)B_m` is the complete-data combining rule. This slice does **not** implement Mislevy plausible values. The 1991 *Psychometrika* paper was not opened in this cycle (Unpaywall/OpenAlex/Semantic Scholar/archive.org 2026-08-18T03:07Z: closed; ETS landing page is HTML; ERIC ED334221 is Singer & Willett, 1991). Do not cite that paper as having been read. +`T_m = \bar U_m + (1+1/m)B_m` is the complete-data combining rule. This slice does **not** implement Mislevy plausible values. The 1991 *Psychometrika* paper was not opened in this cycle (Unpaywall/OpenAlex 2026-09-01T10:22Z: still closed, `is_oa: false`, 0 OA locations; ETS landing page is HTML; ERIC ED334221 is Singer & Willett, 1991). Do not cite that paper as having been read. ## Authoritative sources diff --git a/docs/research/standards-and-literature.md b/docs/research/standards-and-literature.md index 8ce0ecc77..e2d555306 100644 --- a/docs/research/standards-and-literature.md +++ b/docs/research/standards-and-literature.md @@ -47,9 +47,9 @@ Browne, W. J., Goldstein, H., & Rasbash, J. (2001). Multiple membership multiple Jones, K. (1991). Specifying and estimating multi-level models for geographical research. *Transactions of the Institute of British Geographers, 16*(2), 148–160. https://doi.org/10.2307/622612 -TEPP applies these sources to construct definition, score interpretation, reliability, validity evidence, uncertainty, consequences, longitudinal invariance, ESEM cross-loadings, and DSEM. Topic outputs are treated as fallible indicators or components only after their construct role is evaluated. Reflective, formative, and network classes remain distinct (Bollen & Lennox, 1991). Complete-data OLS loadings across posterior indicator draws are combined with Rubin (1996) \(T_m\); the arithmetic-mean helper remains a point estimate. Mislevy (1991, *Psychometrika, 56*, 177–196, DOI 10.1007/bf02294457) remains unread (Unpaywall/OpenAlex/Semantic Scholar 2026-08-18T03:07Z: closed). The 1988 ETS RR-88-45 / DTIC ADA200179 technical report of the same title was opened 2026-08-17T12:04Z from archive.org; it is not the 1991 journal article and is not used as Mislevy plausible-value authority. Temporal precedence is not causal identification (Holland, 1986). Within/between OLS follows Enders and Tofighi (2007), Curran and Bauer (2011), and Hamaker et al. (2015). Enders and Tofighi (2007, Table 2, pp. 124–127; PDF opened 2026-08-17) show that the CWC cluster-mean coefficient is the contextual effect (`between − within`), not the between-cluster effect. Curran and Bauer (2011, pp. 607–608) reject person-mean subtraction on a raw autoregressive series as the lagged within-person residual; already-centered irregular residuals use the Voelkle et al. (2012, Eq. 7) / Driver et al. (2017, Eq. 3) scalar map. Discrete lags from unequal event intervals are remapped through that log-rate (Voelkle et al., 2012, ZORA accepted manuscript re-opened 2026-08-17T13:13Z) and are not pooled. Driver, Oud, and Voelkle (2017, Eq. 3 and p. 4) write \(A_{\Delta t}=\operatorname{expm}(A\Delta t)\) and restate the discrete intercept as a function of \(A\) and \(\Delta t\). A binary64 underflow of \(\exp(a\Delta t)\) to `+0` is refused because discrete auto-effects are strictly positive. The discrete effect of a constant predictor is Voelkle et al. (2012, Eq. 12; ZORA accepted manuscript re-opened 2026-08-17T14:20Z, Introducing Intercepts, manuscript p. 20), evaluated as \(a_{yx}(\operatorname{expm1}(z)/a_{xx})\) with \(z=a_{xx}\Delta t\) so a finite result is not lost when \(z\) overflows to \(-\infty\) or when \(a_{yx}\Delta t\) overflows, and in log space when `expm1(z)` overflows at a finite \(z\); a zero continuous effect is exactly zero; an overflowing \(a_{yx}/a_{xx}\) rewrite term fails closed; the first-order product is the underflow limit of that equation, not the general constant-predictor discrete effect. The discrete effect of a time-varying predictor with matched sampling and constancy intervals is Voelkle et al. (2012, Eq. 14; manuscript p. 21): \(b^{*}_{y.x}(\Delta t)=a_{yx}\Delta t\). That product is not Eq. 12. Unmatched intervals fail closed (Oud & Jansen, 2000, unread). The exact scalar discrete process noise is Driver, Oud, and Voelkle (2017, Eq. 3; JSS PDF re-opened 2026-08-18T14:04Z, p. 4): \(Q_{\Delta t}=0.5 q(\operatorname{expm1}(z)/a)\) with \(z=2(a\Delta t)\) for \(a\neq 0\) and \(q=GG^{\top}\ge 0\); do not form \(2a\) first; \(a=0\) recovers \(q\Delta t\); an overflowing rewrite scale \(0.5 q/a\) fails closed. This is not a Kalman filter. Driver, Oud, and Voelkle (2017, Eq. 3; JSS PDF re-opened 2026-08-18T14:04Z) write the same discrete intercept as \(A^{-1}[e^{A\Delta t}-I]\xi\). The lagged covariance is \(\mathrm{e}^{a\Delta t}p\) and the unconditional variance is \(\mathrm{e}^{2a\Delta t}p+Q_{\Delta t}\) (Driver et al., 2017, Eq. 3–4, pp. 4–5); a zero diffusion whose \(2(a\Delta t)\) overflows to \(+\infty\) fails closed. The stationary within-subject variance is the \(\Delta t\to\infty\) limit of Eq. 4: \(-q/(2a)\) for stable \(a<0\) (JSS p. 16 `asymDIFFUSION`; §4.3; PDF re-opened 2026-08-18T18:03Z). Finite-interval \(Q_{\Delta t}\) is not that limit. Trait-plus-state variance is \(\mathrm{trait}+\mathrm{state}\) and lagged covariance is \(\mathrm{trait}+\mathrm{e}^{a\Delta t}p\) (Driver et al., 2017, §4.3, p. 9; JSS PDF re-opened 2026-08-18T21:07Z). Trait variance is not process noise and not `asymDIFFUSION`. The first-occasion map `τ + λ μ_0` is not `E(y_t)`. The contemporaneous `TDPREDEFFECT` impulse is `m x` (Driver et al., 2017, Eq. 3 fourth summand; Table 2; §7.2; JSS PDF re-opened 2026-08-20T07:10Z). `TDPREDEFFECT` is not `CINT`. `M x` is not `A^{-1}[e^{A Δt} − I] B z` and is not Voelkle et al. (2012, Eq. 14). Metric/weak invariance does not license latent-mean comparison. Putnick and Bornstein (2016, PMC author manuscript PMC5145197 opened 2026-08-19T22:15Z) require scalar invariance before latent-mean comparison and state that residual invariance is not a prerequisite. Two-observation OLS residual variance is identically `0` and is not strict. Meredith (1993) remains unread (Unpaywall/OpenAlex 2026-08-25T11:32Z: `is_oa: false`; Springer `content/pdf` is a 3038-byte HTML stub; Cambridge Core DOI 10.1007/BF02294825 remains a closed product page). Vandenberg and Lance (2000) remains unread. Mislevy (1991, *Psychometrika, 56*, 177–196, DOI 10.1007/bf02294457) remains unread (Unpaywall/OpenAlex 2026-08-25T11:32Z: `is_oa: false`; Springer `content/pdf` is a 3038-byte HTML stub). ERIC ED334221 is Singer and Willett (1991), not the 1991 journal article. ERIC ED333032 is Mislevy, Sheehan, and Wingersky (1990), ETS RR-90-17-ONR, not the 1991 journal article. Oud and Jansen (2000) remains unread (Unpaywall/OpenAlex 2026-08-18T21:07Z: closed). +TEPP applies these sources to construct definition, score interpretation, reliability, validity evidence, uncertainty, consequences, longitudinal invariance, ESEM cross-loadings, and DSEM. Topic outputs are treated as fallible indicators or components only after their construct role is evaluated. Reflective, formative, and network classes remain distinct (Bollen & Lennox, 1991). Complete-data OLS loadings across posterior indicator draws are combined with Rubin (1996) \(T_m\); the arithmetic-mean helper remains a point estimate. Mislevy (1991, *Psychometrika, 56*, 177–196, DOI 10.1007/bf02294457) remains unread (Unpaywall/OpenAlex/Semantic Scholar 2026-09-01T10:22Z: still closed, `is_oa: false`, 0 OA locations). The 1988 ETS RR-88-45 / DTIC ADA200179 technical report of the same title was opened 2026-08-17T12:04Z from archive.org; it is not the 1991 journal article and is not used as Mislevy plausible-value authority. Temporal precedence is not causal identification (Holland, 1986). Within/between OLS follows Enders and Tofighi (2007), Curran and Bauer (2011), and Hamaker et al. (2015). Enders and Tofighi (2007, Table 2, pp. 124–127; PDF opened 2026-08-17) show that the CWC cluster-mean coefficient is the contextual effect (`between − within`), not the between-cluster effect. Curran and Bauer (2011, pp. 607–608) reject person-mean subtraction on a raw autoregressive series as the lagged within-person residual; already-centered irregular residuals use the Voelkle et al. (2012, Eq. 7) / Driver et al. (2017, Eq. 3) scalar map. Discrete lags from unequal event intervals are remapped through that log-rate (Voelkle et al., 2012, ZORA accepted manuscript re-opened 2026-08-17T13:13Z) and are not pooled. Driver, Oud, and Voelkle (2017, Eq. 3 and p. 4) write \(A_{\Delta t}=\operatorname{expm}(A\Delta t)\) and restate the discrete intercept as a function of \(A\) and \(\Delta t\). A binary64 underflow of \(\exp(a\Delta t)\) to `+0` is refused because discrete auto-effects are strictly positive. The discrete effect of a constant predictor is Voelkle et al. (2012, Eq. 12; ZORA accepted manuscript re-opened 2026-08-17T14:20Z, Introducing Intercepts, manuscript p. 20), evaluated as \(a_{yx}(\operatorname{expm1}(z)/a_{xx})\) with \(z=a_{xx}\Delta t\) so a finite result is not lost when \(z\) overflows to \(-\infty\) or when \(a_{yx}\Delta t\) overflows, and in log space when `expm1(z)` overflows at a finite \(z\); a zero continuous effect is exactly zero; an overflowing \(a_{yx}/a_{xx}\) rewrite term fails closed; the first-order product is the underflow limit of that equation, not the general constant-predictor discrete effect. The discrete effect of a time-varying predictor with matched sampling and constancy intervals is Voelkle et al. (2012, Eq. 14; manuscript p. 21): \(b^{*}_{y.x}(\Delta t)=a_{yx}\Delta t\). That product is not Eq. 12. Unmatched intervals fail closed (Oud & Jansen, 2000, unread). The exact scalar discrete process noise is Driver, Oud, and Voelkle (2017, Eq. 3; JSS PDF re-opened 2026-08-18T14:04Z, p. 4): \(Q_{\Delta t}=0.5 q(\operatorname{expm1}(z)/a)\) with \(z=2(a\Delta t)\) for \(a\neq 0\) and \(q=GG^{\top}\ge 0\); do not form \(2a\) first; \(a=0\) recovers \(q\Delta t\); an overflowing rewrite scale \(0.5 q/a\) fails closed. This is not a Kalman filter. Driver, Oud, and Voelkle (2017, Eq. 3; JSS PDF re-opened 2026-08-18T14:04Z) write the same discrete intercept as \(A^{-1}[e^{A\Delta t}-I]\xi\). The lagged covariance is \(\mathrm{e}^{a\Delta t}p\) and the unconditional variance is \(\mathrm{e}^{2a\Delta t}p+Q_{\Delta t}\) (Driver et al., 2017, Eq. 3–4, pp. 4–5); a zero diffusion whose \(2(a\Delta t)\) overflows to \(+\infty\) fails closed. The stationary within-subject variance is the \(\Delta t\to\infty\) limit of Eq. 4: \(-q/(2a)\) for stable \(a<0\) (JSS p. 16 `asymDIFFUSION`; §4.3; PDF re-opened 2026-08-18T18:03Z). Finite-interval \(Q_{\Delta t}\) is not that limit. Trait-plus-state variance is \(\mathrm{trait}+\mathrm{state}\) and lagged covariance is \(\mathrm{trait}+\mathrm{e}^{a\Delta t}p\) (Driver et al., 2017, §4.3, p. 9; JSS PDF re-opened 2026-08-18T21:07Z). Trait variance is not process noise and not `asymDIFFUSION`. The first-occasion map `τ + λ μ_0` is not `E(y_t)`. The contemporaneous `TDPREDEFFECT` impulse is `m x` (Driver et al., 2017, Eq. 3 fourth summand; Table 2; §7.2; JSS PDF re-opened 2026-08-20T07:10Z). `TDPREDEFFECT` is not `CINT`. `M x` is not `A^{-1}[e^{A Δt} − I] B z` and is not Voelkle et al. (2012, Eq. 14). Metric/weak invariance does not license latent-mean comparison. Putnick and Bornstein (2016, PMC author manuscript PMC5145197 opened 2026-08-19T22:15Z) require scalar invariance before latent-mean comparison and state that residual invariance is not a prerequisite. Two-observation OLS residual variance is identically `0` and is not strict. Meredith (1993) remains unread (Unpaywall/OpenAlex 2026-09-01T10:22Z: `is_oa: false`, 0 OA locations; Springer `content/pdf` historically an HTML stub; Cambridge Core DOI 10.1007/BF02294825 remains a closed product page). Vandenberg and Lance (2000) remains unread. Mislevy (1991, *Psychometrika, 56*, 177–196, DOI 10.1007/bf02294457) remains unread (Unpaywall/OpenAlex 2026-09-01T10:22Z: `is_oa: false`, 0 OA locations; Springer `content/pdf` historically an HTML stub). ERIC ED334221 is Singer and Willett (1991), not the 1991 journal article. ERIC ED333032 is Mislevy, Sheehan, and Wingersky (1990), ETS RR-90-17-ONR, not the 1991 journal article. Oud and Jansen (2000) remains unread (Unpaywall/OpenAlex 2026-08-18T21:07Z: closed). -For Meredith (1993), the Cambridge Core original-paper page and abstract were opened on 2026-08-21; Unpaywall, Springer `content/pdf`, OpenAlex, Semantic Scholar, and Cambridge Core PDF lookup were re-tried 2026-08-25T11:32Z and remain closed. The earlier `remains unread` note means that the full text was not available, not that the authoritative record was unverified. +For Meredith (1993), the Cambridge Core original-paper page and abstract were opened on 2026-08-21; Unpaywall, Springer `content/pdf`, OpenAlex, Semantic Scholar, archive.org, and Cambridge Core PDF lookup were re-tried 2026-09-01T10:22Z and remain closed. The earlier `remains unread` note means that the full text was not available, not that the authoritative record was unverified. ## Numerical precision, memory-aware computation, and causal identification diff --git a/docs/research/strong-invariance-latent-means.md b/docs/research/strong-invariance-latent-means.md index ac8402b82..983fd802f 100644 --- a/docs/research/strong-invariance-latent-means.md +++ b/docs/research/strong-invariance-latent-means.md @@ -9,44 +9,47 @@ This slice does **not** import the unpublished `measurement_invariance` crate on ## Claim boundary - `#84` `metric` licenses shared **metric** meaning. It does **not** license latent means. -- `#84` `scalar` is the strong/scalar status (equal loading and intercept). That status licenses latent means. -- Strict (also equal residual variance) also licenses latent means. Residual invariance is **not** required for those means. -- Two-observation series have no residual degrees of freedom. OLS residual variance is then identically `0` and is not an estimated residual. Those series cap at strong/scalar and still license means. +- `#84` `scalar` is the strong/scalar status (equal loading and intercept). This implementation permits latent-mean recovery at that status. +- Strict additionally requires equal residual variance and also permits latent-mean recovery. +- This document does **not** claim from primary evidence that residual/strict invariance is universally unnecessary for every latent-mean comparison. The local gate simply does not add residual equality as a further requirement once its strong/scalar loading-and-intercept contract is satisfied. That narrower implementation policy is grounded in the factor-mean model and strong/scalar boundary described below; the stronger “residual invariance is not required” wording is treated only as secondary-literature context until a primary source is verified directly. +- Two-observation series have no residual degrees of freedom. OLS residual variance is then identically `0` and is not an estimated residual. Those series cap at strong/scalar; the local OLS implementation may recover the mean difference only after its loading/intercept equality conditions pass. - This is two-group OLS, not MGCFA, not partial invariance, and not alignment optimization. -- The weak/strong/strict labels remain conventional labels here. Meredith (1993) is the primary source for the hierarchy; its Cambridge Core original-paper page and abstract were opened, but its full-text PDF was not. Unpaywall, OpenAlex, Semantic Scholar, and Springer `content/pdf` were re-tried 2026-08-25T11:32Z and remain closed (`is_oa: false`, 0 locations; Springer returns a 3038-byte HTML stub). Putnick and Bornstein (2016) cite Meredith for residual invariance as part of *full factorial invariance*; that specific claim is not a reading of Meredith's full text. +- The weak/strong/strict labels remain conventional labels here. Meredith (1993) is the primary source for the hierarchy; its Cambridge Core original-paper page and abstract were opened, but its full-text PDF was not. Unpaywall, OpenAlex, Semantic Scholar, archive.org, and Springer `content/pdf` were re-tried 2026-09-01T10:22Z and remain closed (`is_oa: false`, 0 locations; Springer historically returns an HTML stub). No claim in this document relies on text from an unread Meredith full paper. ## Authoritative sources used for the mean gate Meredith, W. (1993). Measurement invariance, factor analysis and factorial invariance. *Psychometrika, 58*(4), 525–543. https://doi.org/10.1007/BF02294825 -The original-paper record and abstract were opened on the Cambridge Core page on 2026-08-21. Meredith defines weak measurement invariance, strong factorial invariance, and strict factorial invariance and relates factorial invariance to group differences. This is the primary source for the hierarchy used by this gate; the implementation deliberately reports the narrower local `strong`/`strict` labels rather than claiming a full multiple-group CFA. +The original-paper record and abstract were opened on the Cambridge Core page on 2026-08-21. Meredith defines weak measurement invariance, strong factorial invariance, and strict factorial invariance and relates factorial invariance to group differences. This is the primary source for the hierarchy used by this gate; the implementation deliberately reports the narrower local `strong`/`strict` labels rather than claiming a full multiple-group CFA. Because the full paper was not opened, this document does not attribute a stronger residual-invariance exception to Meredith. Sörbom, D. (1974). A general method for studying differences in factor means and factor structure between groups. *British Journal of Mathematical and Statistical Psychology, 27*(2), 229–239. https://doi.org/10.1111/j.2044-8317.1974.tb00543.x The original article record and abstract were opened on the Wiley Online Library page on 2026-08-21. Sörbom's primary model estimates factor means, loadings, and unique variances jointly from group observed means, variances, and covariances while allowing factorial-invariance constraints. It is the direct source for the factor-mean comparison target. The formula implemented here is the scalar two-group OLS reduction obtained by subtracting the observed-mean equation under equal loading and intercept; the source is not being presented as stating this crate-specific OLS formula. -Putnick, D. L., & Bornstein, M. H. (2016). Measurement invariance conventions and reporting: The state of the art and future directions for psychological research. *Developmental Review, 41*, 71–90. https://doi.org/10.1016/j.dr.2016.06.004 - -PMC author manuscript (PMC5145197) opened 2026-08-19T22:15Z from https://pmc.ncbi.nlm.nih.gov/articles/PMC5145197/. The NIHMS PDF endpoints returned HTML/500 on this cycle; the PMC HTML full text is the opened copy. - -Putnick and Bornstein write that measurement invariance is a prerequisite to comparing group means. Metric invariance is equivalence of item loadings: each item contributes to the latent construct to a similar degree across groups. Scalar invariance is equivalence of item intercepts after metric: “mean differences in the latent construct capture all mean differences in the shared variance of the items.” After those steps, “the researcher is free to compare group means on the latent factors.” Residual invariance “is not a prerequisite for testing mean differences because the residuals are not part of the latent factor” (they cite Vandenberg & Lance, 2000, unread). Configural, metric, and scalar “are required prior to group mean comparisons.” This crate’s `#84` `metric` / `scalar` split follows that terminology. The executable map remains two-group OLS, not their multiple-group CFA. - Steenkamp, J.-B. E. M., & Baumgartner, H. (1998). Assessing measurement invariance in cross-national consumer research. *Journal of Consumer Research, 25*(1), 78–90. https://doi.org/10.1086/209528 -The Oxford Academic article page and abstract were opened 2026-08-20. Steenkamp and Baumgartner connect sequential measurement-invariance requirements to when comparisons of construct means are meaningful and illustrate the procedure with multisample factor models. This is the primary source for the gate's comparison-purpose boundary; the implementation remains a narrower two-group OLS contract. +The Oxford Academic article page and abstract were opened 2026-08-20. Steenkamp and Baumgartner connect sequential measurement-invariance requirements to when comparisons of construct means are meaningful and illustrate the procedure with multisample factor models. This is a primary source for the comparison-purpose boundary used here; the implementation remains a narrower two-group OLS contract. Baumgartner, H., & Steenkamp, J.-B. E. M. (1998). Multi-group latent variable models for varying numbers of items and factors with cross-national and longitudinal applications. *Marketing Letters, 9*, 21–35. https://doi.org/10.1023/A:1007911903032 The Springer Nature article page and abstract were opened 2026-08-20. Its simulation and empirical study concerns estimates of differences between latent means. In this repository, subtracting the two-group model \(y=ν+λ f+e\) under equal loading and intercept gives \((\bar y_c-\bar y_r)/\lambda\); that algebra is an explicit derivation of this OLS slice, not a claim that the source states the same implementation formula. +## Secondary context, not primary authority for the exception + +Putnick, D. L., & Bornstein, M. H. (2016). Measurement invariance conventions and reporting: The state of the art and future directions for psychological research. *Developmental Review, 41*, 71–90. https://doi.org/10.1016/j.dr.2016.06.004 + +PMC author manuscript (PMC5145197) opened 2026-08-19T22:15Z. Putnick and Bornstein summarize scalar invariance as the point after which latent-factor means are commonly compared and state that residual invariance is not a prerequisite, citing Vandenberg and Lance (2000). That statement is useful secondary context but is **not** used here as primary evidence for a universal residual-invariance exception because the cited primary/underlying source was not verified directly in this run. + +Vandenberg, R. J., & Lance, C. E. (2000). A review and synthesis of the measurement invariance literature: Suggestions, practices, and recommendations for organizational research. *Organizational Research Methods, 3*(1), 4–70. https://doi.org/10.1177/109442810031002 + +This source remains unread in the current evidence set and therefore does not establish a scientific claim in this document. + Opened sources that constrain the surrounding longitudinal/invariance stance: Asparouhov, T., & Muthén, B. (2009). Exploratory structural equation modeling. *Structural Equation Modeling: A Multidisciplinary Journal, 16*(3), 397–438. https://doi.org/10.1080/10705510903008204 Hamaker, E. L., Kuiper, R. M., & Grasman, R. P. P. P. (2015). A critique of the cross-lagged panel model. *Psychological Methods, 20*(1), 102–116. https://doi.org/10.1037/a0038889 -Vandenberg, R. J., & Lance, C. E. (2000). A review and synthesis of the measurement invariance literature: Suggestions, practices, and recommendations for organizational research. *Organizational Research Methods, 3*(1), 4–70. https://doi.org/10.1177/109442810031002 (cited by Putnick & Bornstein, 2016, for residual invariance not being required for latent means; PDF not opened). - ## Formula notes Per group, \(y=\nu+\lambda f+e\) is fit by OLS. Status is: @@ -56,13 +59,13 @@ Per group, \(y=\nu+\lambda f+e\) is fit by OLS. Status is: - strong when loadings and intercepts match and residual variances differ, or when residual degrees of freedom are absent; - strict when both groups have residual degrees of freedom and loadings, intercepts, and residual variances match. -The latent-mean difference is \((\bar y_c-\bar y_r)/\lambda\) with \(\lambda\) the midpoint of the two loadings, and only after strong or strict. Meredith (1993) supplies the invariance hierarchy and Sörbom (1974) supplies the factor-mean comparison model; the displayed expression is the explicitly stated scalar OLS derivation for this implementation. +The latent-mean difference is \((\bar y_c-\bar y_r)/\lambda\) with \(\lambda\) the midpoint of the two loadings, and the local implementation evaluates it only after strong or strict. Meredith (1993) supplies the invariance hierarchy, Sörbom (1974) supplies the factor-mean comparison model, and Steenkamp and Baumgartner (1998) provide primary comparison-purpose context. The displayed expression is the explicitly stated scalar OLS derivation for this implementation. -The formula follows by subtracting the group means of \(y=\nu+\lambda f+e\) after the equal-loading/equal-intercept restrictions have been accepted; the cited multi-group latent-mean study supplies the comparison target, while this document records the narrower OLS derivation. +The formula follows by subtracting the group means of \(y=\nu+\lambda f+e\) after the equal-loading/equal-intercept restrictions have been accepted. This implementation policy does not assert that residual equality is scientifically irrelevant in every design; any broader exception requires separately verified primary evidence. ## Verification - strong/strict series recover a known mean difference with computed RMSE; - metric-only (equal loading, shifted intercept) and configural series return `StrongInvarianceRequired`; -- two-observation series with matching loading and intercept classify as strong, not strict, and still recover the known mean difference; -- `#84` wire-name tests: `metric` licenses shared metric meaning and refuses means; `scalar` is strong and licenses means; local `strict` is not a `#84` wire name. +- two-observation series with matching loading and intercept classify as strong, not strict, and exercise the local strong-gate recovery path; +- `#84` wire-name tests: `metric` licenses shared metric meaning and refuses means; `scalar` maps to the local strong gate; local `strict` is not a `#84` wire name. diff --git a/docs/research/temporal-dependence-models.md b/docs/research/temporal-dependence-models.md new file mode 100644 index 000000000..e87e35410 --- /dev/null +++ b/docs/research/temporal-dependence-models.md @@ -0,0 +1,69 @@ +# Temporal dependence model research authority + +This document is the canonical primary-research register for the LSIRM, MLSIRM, and DLSJM dependence families referenced by TEPP's temporal-composition architecture. It establishes what the cited studies support and, equally importantly, what they do not establish. Repository promotion policy is labeled separately and does not masquerade as a result of the cited papers. + +## Scope + +TEPP does not treat a published static dependence family as evidence for every possible response-family × generalized-mixed × dependence × temporal-state combination. The named studies support their stated model families. A novel temporal coupling remains `research_candidate` until the combined generative/state equation, identification and longitudinal comparability, Rust estimator, data-support conditions, and known-truth recovery are explicit and verified. That promotion status is **TEPP policy under ADR 0014 and ADR 0011**, not a claim that the three cited papers prescribe TEPP's release process. + +The reusable static/generalized-mixed/dependence specification and numerical kernel owner is `ContextualWisdomLab/fast-mlsirm`. TEPP owns temporal/event composition, including event-or-valid time, assertion time, document time, system time, available time, knowledge cutoff, irregular intervals, time-varying membership/covariates, longitudinal comparability, and temporal recovery. Repository ownership is an architectural decision under ADR 0011, not a conclusion of the psychometric papers. + +## LSIRM — primary evidence and extension boundary + +Jeon et al. (2021) introduce a latent-space item response model in which residual person–item interactions are represented through person and item positions and their latent-space relationship. For TEPP this supports the existence and interpretation of a residual person–item interaction geometry. It does not establish that known testlets, raters, item families, hierarchy, cross-classification, multiple membership, or omitted covariates should be absorbed by that geometry (Jeon et al., 2021). + +The cited study is static and does not establish a TEPP temporal state equation. Accordingly, requiring an explicit temporal state model, cross-occasion identification/alignment, uncertainty propagation, and temporal known-truth recovery before a new longitudinal LSIRM is promoted is **TEPP scientific-promotion policy** governed by ADR 0014. These are prerequisites for TEPP to make a longitudinal claim; they are not presented as requirements printed by Jeon et al. (2021). + +## MLSIRM — primary evidence and extension boundary + +Kang and Jeon (2025) develop a multidimensional latent-space item-response formulation and discuss conditional dependence in that multidimensional setting. In TEPP terminology, MLSIRM refers to that multidimensional-main-effect latent-space extension; the acronym is not redefined to mean “multilevel LSIRM” (Kang & Jeon, 2025). Multilevel, cross-classified, and multiple-membership structure is represented separately in TEPP's generalized-mixed specification by architecture policy. + +Preserving the exact base response formulation, multidimensional loading/trait structure, and person/item interaction geometry follows the need not to change the model being attributed to Kang and Jeon (2025). Requiring a declared temporal identification/alignment procedure, longitudinal invariance evidence, and recovery before interpreting cross-time trajectories is **TEPP extension and claim-promotion policy** under ADR 0014; the 2025 paper is not cited as a longitudinal MLSIRM validation study. + +## DLSJM — primary evidence and extension boundary + +Jin and Jeon (2019) provide the canonical baseline for the doubly latent-space joint model of local item dependence and local person dependence. DLSJM keeps the item-dependence and person-dependence spaces distinct; it is not an alias for LSIRM person–item interaction geometry (Jin & Jeon, 2019). + +TEPP therefore preserves separate item-space and person-space parameter/state identities when it creates a temporal DLSJM research candidate. The cited DLSJM is not itself evidence for a longitudinal DLSJM state process. Requiring explicit cross-occasion coordinate alignment and, when clusters are interpreted, label alignment before comparing maps is **TEPP temporal-extension policy** designed to prevent raw non-identified coordinate maps from being treated as longitudinal evidence. A primary longitudinal DLSJM source must be added here before those extension-specific procedures are attributed to published research. + +## Scientific evidence carried from the primary families + +The following requirements concern fidelity to the cited static families rather than TEPP release governance: + +- an LSIRM attribution must retain the residual person–item latent-space interaction structure supported by Jeon et al. (2021); +- an MLSIRM attribution must retain the multidimensional latent-space response formulation supported by Kang and Jeon (2025); +- a DLSJM attribution must keep local item-dependence and local person-dependence spaces distinct as in Jin and Jeon (2019); +- novel response-family, generalized-mixed, or temporal couplings must be labeled as extensions rather than described as if they appeared in those papers. + +## TEPP promotion and recovery policy + +The following is repository policy governed by ADR 0014 (scientific claim promotion), ADR 0011 (service/model ownership), ADR 0002 (temporal semantics), and the approved PRD. It is intentionally stronger and broader than what any one cited dependence paper establishes. + +For an LSIRM/MLSIRM/DLSJM **temporal** candidate to be classified `supported`, TEPP requires: + +- exact base response and generalized-mixed formulation; +- exact dependence formulation and parameter blocks; +- explicit temporal generative/state equation and six-clock role semantics; +- identified longitudinal comparison procedure, including map alignment when the representation is only identifiable up to transformations; +- implemented estimator owned by the canonical repository; +- leakage-safe recovery that separates event-or-valid time from available time and enforces the analysis knowledge cutoff; +- model-appropriate known-truth recovery with RMSE, bias, interval/credible-interval coverage, convergence, and uncertainty reporting for the parameters actually claimed; +- known-truth recovery of any claimed temporal ordering, transition ordering, dependency graph, branch graph, or cluster-transition structure; a candidate cannot be `supported` for a structural claim whose structure is not recoverable in simulation; +- longitudinal measurement-invariance evidence sufficient for every cross-time measurement or comparison claim actually made; invariance is not limited to multilingual or source-drift claims; +- irregular-gap, delayed/retrospective-record, missing-occasion, and changing-membership cases when the temporal formulation permits them; +- language/source drift tests when multilingual/source invariance is part of the claim; +- CPU `f64` reference evidence and CPU/GPU parity only when an accelerator implementation is claimed; a skipped or unexecuted GPU path is not evidence; +- Monte Carlo uncertainty for simulation summaries rather than an arbitrary replication pass percentage; +- primary-source traceability for established model components and explicit `research_candidate` labeling for novel couplings. + +Structural acceptance is claim-scoped: if a candidate claims only parameter recovery it is not automatically authorized to claim recovered temporal order, dependency topology, branching, clustering, or longitudinal invariance. Conversely, any such structural claim makes its corresponding known-truth recovery evidence mandatory before promotion. + +These items are acceptance evidence for a TEPP claim. They should not be cited as findings of Jeon et al. (2021), Jin and Jeon (2019), or Kang and Jeon (2025) unless a specific item is explicitly supported by the relevant paper. Auto-expansion only materializes a candidate contract; it does not satisfy TEPP's promotion conditions. + +## APA 7 references + +Jeon, M., Jin, I. H., Schweinberger, M., & Baugh, S. (2021). Mapping unobserved item–respondent interactions: A latent space item response model with interaction map. *Psychometrika, 86*(2), 378–403. https://doi.org/10.1007/s11336-021-09762-5 + +Jin, I. H., & Jeon, M. (2019). A doubly latent space joint model for local item and person dependence in the analysis of item response data. *Psychometrika, 84*(1), 236–260. https://doi.org/10.1007/s11336-018-9630-0 + +Kang, I., & Jeon, M. (2025). Multidimensional latent space item response models: A note on the relativity of conditional dependence. *Psychometrika, 90*(2), 799–826. https://doi.org/10.1017/psy.2025.5 diff --git a/scripts/validate_documentation.py b/scripts/validate_documentation.py index 7b7364c94..f2f47684f 100644 --- a/scripts/validate_documentation.py +++ b/scripts/validate_documentation.py @@ -9,6 +9,9 @@ ROOT = Path(__file__).resolve().parents[1] PRODUCT_TECHNICAL_GAP_BASELINE = "docs/product-technical-gap-baseline.md" +DOMAIN_CONTEXT_MAP = "docs/architecture/domain-context-map.md" +TEMPORAL_DEPENDENCE_COMPOSITION = "docs/architecture/temporal-dependence-composition.md" +TEMPORAL_DEPENDENCE_RESEARCH = "docs/research/temporal-dependence-models.md" REQUIRED_FILES = ( "DOCUMENTATION.md", @@ -49,9 +52,12 @@ "docs/adr/0022-deterministic-analysis-run-execution.md", "docs/product/prd-v0.4-approved.md", PRODUCT_TECHNICAL_GAP_BASELINE, + DOMAIN_CONTEXT_MAP, + TEMPORAL_DEPENDENCE_COMPOSITION, "docs/roadmaps/2026-08-05-tepp-delivery-roadmap.md", "docs/superpowers/plans/2026-08-05-temporal-event-foundation.md", "docs/research/standards-and-literature.md", + TEMPORAL_DEPENDENCE_RESEARCH, ) PLACEHOLDER_PATTERNS = ( @@ -74,9 +80,13 @@ ) INVENTORY_ROW = re.compile( r"^\|\s*#(?P\d+)\s*\|\s*`(?P[0-9a-f]{40})`\s*\|\s*" - r"(?Ptrue|false)\s*\|", - re.MULTILINE, + r"(?Ptrue|false)\s*\|\s*(?P[^|]+?)\s*\|\s*" + r"(?P[^|]+?)\s*\|\s*$" ) +PRIORITY_INVENTORY_HEADING = "## Current priority open pull-request evidence" +LEVEL_TWO_HEADING = re.compile(r"^##\s+", re.MULTILINE) +PRIORITY_HEADER_ROW = re.compile(r"^\|\s*PR\s*\|", re.IGNORECASE) +PRIORITY_SEPARATOR_ROW = re.compile(r"^\|(?:\s*:?-+:?\s*\|)+\s*$") OPEN_PR_COUNT = re.compile( r"\|\s*Open pull requests\s*\|\s*\*\*(?P\d+)\*\*" ) @@ -94,15 +104,23 @@ r"\b(?:but|however|yet|although|though)\b", re.IGNORECASE ) QUEUED_CHECKS_SENTENCE_BREAK = re.compile(r"[.;!?\n]") -ADR_TABLE_ROW = re.compile(r"^\|\s*\[(?P\d{4})\]", re.MULTILINE) +ADR_STATUS_VALUES = "Accepted|Proposed|Superseded|Rejected" +ADR_MATURITY_VALUES = ( + "implemented-main|active-PR|partial|accepted-target|research-only|out-of-scope" +) +ADR_TABLE_ROW = re.compile( + rf'^\|\s*\[(?P\d{{4}})\]\((?P[^)\s]+)(?:\s+"[^"]*")?\)\s*\|' + rf"\s*[^|]+\|\s*(?P{ADR_STATUS_VALUES})\s*\|" + rf"\s*(?P{ADR_MATURITY_VALUES})\s*\|", + re.MULTILINE, +) ADR_FILE_NAME = re.compile(r"^(?P\d{4})-[a-z0-9-]+\.md$") ADR_DECISION_STATUS = re.compile( - r"^\*\*Decision status:\*\*\s*(Accepted|Proposed|Superseded|Rejected)\b", + rf"^\*\*Decision status:\*\*\s*({ADR_STATUS_VALUES})\b", re.MULTILINE, ) ADR_IMPLEMENTATION_STATUS = re.compile( - r"^\*\*Implementation maturity:\*\*\s*" - r"(implemented-main|active-PR|partial|accepted-target|research-only|out-of-scope)\b", + rf"^\*\*Implementation maturity:\*\*\s*({ADR_MATURITY_VALUES})\b", re.MULTILINE, ) ADR_REQUIRED_HEADINGS = ( @@ -157,6 +175,8 @@ "docs/DOCUMENTATION_ASSESSMENT.md", "docs/TRD.md", "ARCHITECTURE.md", + DOMAIN_CONTEXT_MAP, + TEMPORAL_DEPENDENCE_COMPOSITION, "docs/API_CONTRACT.md", "docs/UML.md", "docs/ERD.md", @@ -173,6 +193,7 @@ "docs/roadmaps/2026-08-05-tepp-delivery-roadmap.md", "docs/superpowers/plans/2026-08-05-temporal-event-foundation.md", "docs/research/standards-and-literature.md", + TEMPORAL_DEPENDENCE_RESEARCH, "GOVERNANCE.md", "AGENTS.md", "CLAUDE.md", @@ -379,8 +400,43 @@ def _promotion_is_denied(text: str, claim: re.Match[str]) -> bool: return False +def _priority_inventory_section(text: str) -> str: + """Return only the canonical priority-inventory section from the gap register.""" + + heading = re.search( + rf"^{re.escape(PRIORITY_INVENTORY_HEADING)}[ \t]*$", + text, + re.MULTILINE, + ) + if heading is None: + return "" + section_start = heading.end() + next_heading = LEVEL_TWO_HEADING.search(text, section_start) + section_end = next_heading.start() if next_heading is not None else len(text) + return text[section_start:section_end] + + +def _priority_inventory_rows(section: str) -> tuple[list[re.Match[str]], list[str]]: + """Parse every Markdown table data row in the priority inventory fail-closed.""" + + inventory: list[re.Match[str]] = [] + malformed: list[str] = [] + for raw_line in section.splitlines(): + line = raw_line.strip() + if not line.startswith("|"): + continue + if PRIORITY_HEADER_ROW.match(line) or PRIORITY_SEPARATOR_ROW.fullmatch(line): + continue + match = INVENTORY_ROW.fullmatch(line) + if match is None: + malformed.append(line) + else: + inventory.append(match) + return inventory, malformed + + def validate_product_technical_gap_baseline(root: Path = ROOT) -> None: - """Require a dated live gap register that does not promote queued Checks.""" + """Require a dated live gap register with an honest priority PR inventory.""" path = root / PRODUCT_TECHNICAL_GAP_BASELINE if not path.is_file(): @@ -402,16 +458,24 @@ def validate_product_technical_gap_baseline(root: Path = ROOT) -> None: for match in QUEUED_CHECKS_AS_SHIPPED.finditer(text) ): failures.append("gap baseline treats queued Checks as implemented-main") - inventory = list(INVENTORY_ROW.finditer(text)) + priority_inventory = _priority_inventory_section(text) + inventory, malformed_rows = _priority_inventory_rows(priority_inventory) + if malformed_rows: + failures.extend( + f"malformed priority inventory row: {row}" for row in malformed_rows + ) + inventory_numbers = [match.group("number") for match in inventory] if not inventory: failures.append("gap baseline open-PR inventory has no exact-head rows") + elif len(inventory_numbers) != len(set(inventory_numbers)): + failures.append("gap baseline priority inventory contains duplicate PR rows") count_match = OPEN_PR_COUNT.search(text) if count_match is None: failures.append("gap baseline lacks an open pull-request count") - elif count_match.group("count") != str(len(inventory)): + elif int(count_match.group("count")) < len(inventory): failures.append( "gap baseline open-PR count " - f"{count_match.group('count')} does not match inventory " + f"{count_match.group('count')} is smaller than priority inventory " f"{len(inventory)}" ) if failures: @@ -419,21 +483,47 @@ def validate_product_technical_gap_baseline(root: Path = ROOT) -> None: def validate_adr_graph() -> None: - """Require every numbered ADR to be indexed and carry unambiguous authority metadata.""" + """Require every numbered ADR to have one repository-wide identity and authority.""" adr_root = ROOT / "docs" / "adr" adr_index = (adr_root / "README.md").read_text(encoding="utf-8") - indexed_numbers = { - match.group("number") for match in ADR_TABLE_ROW.finditer(adr_index) - } + index_rows = list(ADR_TABLE_ROW.finditer(adr_index)) + indexed_number_list = [match.group("number") for match in index_rows] + duplicate_index_numbers = sorted( + number + for number in set(indexed_number_list) + if indexed_number_list.count(number) > 1 + ) + if duplicate_index_numbers: + raise AssertionError( + f"duplicate ADR index identity: {duplicate_index_numbers}" + ) - adr_files: dict[str, Path] = {} + indexed_targets = [match.group("target") for match in index_rows] + duplicate_targets = sorted( + target for target in set(indexed_targets) if indexed_targets.count(target) > 1 + ) + if duplicate_targets: + raise AssertionError(f"duplicate ADR index target: {duplicate_targets}") + + indexed_numbers = set(indexed_number_list) + index_by_number = {match.group("number"): match for match in index_rows} + adr_paths_by_number: dict[str, list[Path]] = {} for path in sorted(adr_root.glob("[0-9][0-9][0-9][0-9]-*.md")): match = ADR_FILE_NAME.fullmatch(path.name) if not match: raise AssertionError(f"invalid ADR filename: {path.relative_to(ROOT)}") - adr_files[match.group("number")] = path + adr_paths_by_number.setdefault(match.group("number"), []).append(path) + + duplicate_file_numbers = sorted( + number for number, paths in adr_paths_by_number.items() if len(paths) > 1 + ) + if duplicate_file_numbers: + raise AssertionError( + f"duplicate ADR file identity: {duplicate_file_numbers}" + ) + adr_files = {number: paths[0] for number, paths in adr_paths_by_number.items()} file_numbers = set(adr_files) if indexed_numbers != file_numbers: raise AssertionError( @@ -442,13 +532,57 @@ def validate_adr_graph() -> None: f"file_only={sorted(file_numbers - indexed_numbers)}" ) + for row in index_rows: + number = row.group("number") + target = row.group("target") + target_name = Path(target).name + target_match = ADR_FILE_NAME.fullmatch(target_name) + if ( + "/" in target + or "\\" in target + or target_match is None + or target_match.group("number") != number + ): + raise AssertionError( + f"ADR index target identity mismatch: {number} -> {target!r}" + ) + canonical_target = adr_files[number].name + if target != canonical_target: + raise AssertionError( + f"ADR index target mismatch: {number} -> {target!r}; " + f"expected {canonical_target!r}" + ) + failures: list[str] = [] for number, path in adr_files.items(): text = path.read_text(encoding="utf-8") - if ADR_DECISION_STATUS.search(text) is None: + decision_matches = list(ADR_DECISION_STATUS.finditer(text)) + maturity_matches = list(ADR_IMPLEMENTATION_STATUS.finditer(text)) + if not decision_matches: failures.append(f"ADR {number} lacks a valid Decision status") - if ADR_IMPLEMENTATION_STATUS.search(text) is None: + elif len(decision_matches) > 1: + failures.append(f"ADR {number} has multiple Decision status authorities") + if not maturity_matches: failures.append(f"ADR {number} lacks a valid Implementation maturity") + elif len(maturity_matches) > 1: + failures.append(f"ADR {number} has multiple Implementation maturity authorities") + + index_row = index_by_number[number] + if decision_matches: + canonical_decision = decision_matches[0].group(1) + if index_row.group("decision") != canonical_decision: + failures.append( + f"ADR index decision-status mismatch for {number}: " + f"index={index_row.group('decision')} file={canonical_decision}" + ) + if maturity_matches: + canonical_maturity = maturity_matches[0].group(1) + if index_row.group("maturity") != canonical_maturity: + failures.append( + f"ADR index maturity mismatch for {number}: " + f"index={index_row.group('maturity')} file={canonical_maturity}" + ) + if "**Supersedes:**" not in text and "**Supersession:**" not in text: failures.append(f"ADR {number} lacks explicit supersession metadata") for heading in ADR_REQUIRED_HEADINGS: diff --git a/tests/quality/test_adr_identity_uniqueness.py b/tests/quality/test_adr_identity_uniqueness.py new file mode 100644 index 000000000..1c18878f2 --- /dev/null +++ b/tests/quality/test_adr_identity_uniqueness.py @@ -0,0 +1,228 @@ +"""Regression tests for repository-wide ADR identity and authority consistency.""" + +from __future__ import annotations + +import tempfile +import unittest +from pathlib import Path +from unittest import mock + +from scripts import validate_documentation as docs + + +ADR_BODY = """# ADR {number} — Test decision + +**Decision status:** Accepted +**Implementation maturity:** partial +**Supersession:** None. + +## Context + +Context. + +## Decision + +Decision. + +## Alternatives considered + +Alternative. + +## Consequences + +Consequence. + +## Verification + +Verification. + +## Rollback + +Rollback. +""" + + +class AdrIdentityUniquenessTests(unittest.TestCase): + """Reject branch-local reuse, misdirection, or split ADR authority metadata.""" + + def _root( + self, + index_rows: str, + files: dict[str, str], + bodies: dict[str, str] | None = None, + ) -> Path: + temporary = tempfile.TemporaryDirectory() + self.addCleanup(temporary.cleanup) + root = Path(temporary.name) + adr_root = root / "docs" / "adr" + adr_root.mkdir(parents=True) + (adr_root / "README.md").write_text( + "| ADR | Decision | Decision status | Implementation maturity | Clarification |\n" + "|---|---|---|---|---|\n" + + index_rows, + encoding="utf-8", + ) + for name, number in files.items(): + body = (bodies or {}).get(name, ADR_BODY.format(number=number)) + (adr_root / name).write_text(body, encoding="utf-8") + return root + + def test_duplicate_index_rows_fail(self) -> None: + """Two index rows may not claim the same ADR number.""" + + root = self._root( + "| [0001](0001-one.md) | One | Accepted | partial | first |\n" + "| [0001](0001-one.md) | One again | Accepted | partial | duplicate |\n", + {"0001-one.md": "0001"}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "duplicate ADR index identity"): + docs.validate_adr_graph() + + def test_duplicate_numbered_files_fail(self) -> None: + """Two numbered root ADR files may not share one repository-wide identity.""" + + root = self._root( + "| [0001](0001-one.md) | One | Accepted | partial | canonical |\n", + {"0001-one.md": "0001", "0001-two.md": "0001"}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "duplicate ADR file identity"): + docs.validate_adr_graph() + + def test_mismatched_index_link_identity_fails(self) -> None: + """Displayed ADR identity must match the linked numbered filename.""" + + root = self._root( + "| [0001](0002-two.md) | One mislabeled | Accepted | partial | bad link |\n" + "| [0002](0001-one.md) | Two mislabeled | Accepted | partial | bad link |\n", + {"0001-one.md": "0001", "0002-two.md": "0002"}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "ADR index target identity mismatch"): + docs.validate_adr_graph() + + def test_duplicate_index_targets_fail(self) -> None: + """Two index identities may not resolve to the same canonical ADR target.""" + + root = self._root( + "| [0001](0001-one.md) | One | Accepted | partial | canonical |\n" + "| [0002](0001-one.md) | Two | Accepted | partial | duplicate target |\n", + {"0001-one.md": "0001", "0002-two.md": "0002"}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "duplicate ADR index target"): + docs.validate_adr_graph() + + def test_titled_duplicate_index_rows_fail(self) -> None: + """Markdown link titles may not hide a duplicate ADR identity.""" + + root = self._root( + '| [0001](0001-one.md "canonical") | One | Accepted | partial | first |\n' + '| [0001](0001-one.md "duplicate") | One again | Accepted | partial | duplicate |\n', + {"0001-one.md": "0001"}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "duplicate ADR index identity"): + docs.validate_adr_graph() + + def test_index_maturity_must_match_canonical_adr(self) -> None: + """The index cannot advertise a different implementation maturity.""" + + root = self._root( + "| [0001](0001-one.md) | One | Accepted | active-PR | drift |\n", + {"0001-one.md": "0001"}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "ADR index maturity mismatch"): + docs.validate_adr_graph() + + def test_index_decision_status_must_match_canonical_adr(self) -> None: + """Accepted/proposed authority may not diverge between file and index.""" + + root = self._root( + "| [0001](0001-one.md) | One | Proposed | partial | drift |\n", + {"0001-one.md": "0001"}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "ADR index decision-status mismatch"): + docs.validate_adr_graph() + + def test_duplicate_maturity_metadata_fails(self) -> None: + """An ADR has exactly one canonical implementation-maturity declaration.""" + + body = ADR_BODY.format(number="0001").replace( + "**Implementation maturity:** partial", + "**Implementation maturity:** partial\n**Implementation maturity:** active-PR", + ) + root = self._root( + "| [0001](0001-one.md) | One | Accepted | partial | canonical |\n", + {"0001-one.md": "0001"}, + {"0001-one.md": body}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "multiple Implementation maturity"): + docs.validate_adr_graph() + + def test_identical_duplicate_maturity_metadata_fails(self) -> None: + """Repeating the same maturity is still competing canonical authority.""" + + body = ADR_BODY.format(number="0001").replace( + "**Implementation maturity:** partial", + "**Implementation maturity:** partial\n**Implementation maturity:** partial", + ) + root = self._root( + "| [0001](0001-one.md) | One | Accepted | partial | canonical |\n", + {"0001-one.md": "0001"}, + {"0001-one.md": body}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "multiple Implementation maturity"): + docs.validate_adr_graph() + + def test_duplicate_decision_status_metadata_fails(self) -> None: + """An ADR has exactly one canonical decision-status declaration.""" + + body = ADR_BODY.format(number="0001").replace( + "**Decision status:** Accepted", + "**Decision status:** Accepted\n**Decision status:** Proposed", + ) + root = self._root( + "| [0001](0001-one.md) | One | Accepted | partial | canonical |\n", + {"0001-one.md": "0001"}, + {"0001-one.md": body}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "multiple Decision status"): + docs.validate_adr_graph() + + def test_identical_duplicate_decision_status_metadata_fails(self) -> None: + """Repeating the same Decision status is still competing authority.""" + + body = ADR_BODY.format(number="0001").replace( + "**Decision status:** Accepted", + "**Decision status:** Accepted\n**Decision status:** Accepted", + ) + root = self._root( + "| [0001](0001-one.md) | One | Accepted | partial | canonical |\n", + {"0001-one.md": "0001"}, + {"0001-one.md": body}, + ) + with mock.patch.object(docs, "ROOT", root): + with self.assertRaisesRegex(AssertionError, "multiple Decision status"): + docs.validate_adr_graph() + + def test_canonical_index_targets_pass(self) -> None: + """Each displayed identity may link to its unique root ADR file.""" + + root = self._root( + "| [0001](0001-one.md) | One | Accepted | partial | canonical |\n" + "| [0002](0002-two.md) | Two | Accepted | partial | canonical |\n", + {"0001-one.md": "0001", "0002-two.md": "0002"}, + ) + with mock.patch.object(docs, "ROOT", root): + docs.validate_adr_graph() + + +if __name__ == "__main__": # pragma: no cover + unittest.main() diff --git a/tests/quality/test_gap_inventory_heading.py b/tests/quality/test_gap_inventory_heading.py new file mode 100644 index 000000000..131edab4a --- /dev/null +++ b/tests/quality/test_gap_inventory_heading.py @@ -0,0 +1,94 @@ +"""Regression tests for exact priority-inventory heading recognition.""" + +from __future__ import annotations + +import tempfile +import unittest +from pathlib import Path + +from scripts import validate_documentation as docs + + +BASE = """# Product and Technical Gap Baseline + +**Snapshot:** 2026-09-01T10:49:02Z +**Protected-main evidence:** `1bc02f580cf48e1d39da239f0e818453437c31c3` + +## Snapshot facts + +| Signal | Snapshot evidence | Delivery implication | +|---|---:|---| +| Open pull requests | **139** | Queue only. | + +{heading} + +| PR | Exact current head | Draft | Base | Title | +|---:|---|:---:|---|---| +| #441 | `6f483224b3a03e8237c6f4f098a8b0e85e0a91f5` | false | main | repair | +{extra_rows} + +## Operator-gap register + +| ID | Closure evidence | +|---|---| +| GAP-001 | Closure evidence exists. | +""" + + +class PriorityInventoryHeadingTests(unittest.TestCase): + """Require the canonical level-two heading and every inventory row to be valid.""" + + def _write(self, heading: str, extra_rows: str = "") -> Path: + temporary = tempfile.TemporaryDirectory() + self.addCleanup(temporary.cleanup) + root = Path(temporary.name) + path = root / docs.PRODUCT_TECHNICAL_GAP_BASELINE + path.parent.mkdir(parents=True) + path.write_text( + BASE.format(heading=heading, extra_rows=extra_rows), encoding="utf-8" + ) + return root + + def test_exact_level_two_heading_passes(self) -> None: + """The canonical priority-inventory heading is accepted.""" + + root = self._write("## Current priority open pull-request evidence") + docs.validate_product_technical_gap_baseline(root) + + def test_level_three_near_match_fails(self) -> None: + """A level-three heading cannot masquerade as the canonical inventory.""" + + root = self._write("### Current priority open pull-request evidence") + with self.assertRaisesRegex(AssertionError, "no exact-head rows"): + docs.validate_product_technical_gap_baseline(root) + + def test_suffixed_level_two_near_match_fails(self) -> None: + """A suffixed level-two heading is not the canonical inventory authority.""" + + root = self._write("## Current priority open pull-request evidence (historical)") + with self.assertRaisesRegex(AssertionError, "no exact-head rows"): + docs.validate_product_technical_gap_baseline(root) + + def test_malformed_priority_row_fails_even_with_valid_sibling(self) -> None: + """A malformed data row cannot disappear from an otherwise valid inventory.""" + + root = self._write( + "## Current priority open pull-request evidence", + "| #442 | `deadbeef` | maybe | main | malformed |", + ) + with self.assertRaisesRegex(AssertionError, "malformed priority inventory row"): + docs.validate_product_technical_gap_baseline(root) + + def test_missing_priority_columns_fail_even_with_valid_sibling(self) -> None: + """Missing cells in one data row are an integrity failure, not an omission.""" + + root = self._write( + "## Current priority open pull-request evidence", + "| #442 | `0123456789012345678901234567890123456789` | true |", + ) + with self.assertRaisesRegex(AssertionError, "malformed priority inventory row"): + docs.validate_product_technical_gap_baseline(root) + + +if __name__ == "__main__": # pragma: no cover + unittest.main() diff --git a/tests/quality/test_prepare_agent_pr_message.py b/tests/quality/test_prepare_agent_pr_message.py index cccc0cc37..dd7aeaa46 100644 --- a/tests/quality/test_prepare_agent_pr_message.py +++ b/tests/quality/test_prepare_agent_pr_message.py @@ -4,7 +4,6 @@ import os import stat -import sys import tempfile import unittest import unittest.mock @@ -288,15 +287,8 @@ def test_module_entrypoint_invokes_main(self) -> None: str(body), ], ): - loaded_module = sys.modules.pop("scripts.prepare_agent_pr_message", None) - try: - with self.assertRaises(SystemExit) as raised: - runpy.run_module( - "scripts.prepare_agent_pr_message", run_name="__main__" - ) - finally: - if loaded_module is not None: - sys.modules["scripts.prepare_agent_pr_message"] = loaded_module + with self.assertRaises(SystemExit) as raised: + runpy.run_module("scripts.prepare_agent_pr_message", run_name="__main__") self.assertEqual(raised.exception.code, 0) def test_read_without_nofollow_flag_when_unavailable(self) -> None: diff --git a/tests/quality/test_priority_inventory_fail_closed.py b/tests/quality/test_priority_inventory_fail_closed.py new file mode 100644 index 000000000..638f17260 --- /dev/null +++ b/tests/quality/test_priority_inventory_fail_closed.py @@ -0,0 +1,78 @@ +"""Fail-closed regressions for the operator priority pull-request inventory.""" + +from __future__ import annotations + +import tempfile +import unittest +from pathlib import Path + +from scripts import validate_documentation as docs + + +VALID_SHA = "c45be17a9dbce95ef81cee230e9d128abc7160ac" +VALID_HEAD = "a" * 40 + + +def baseline_with_rows(*rows: str) -> str: + """Build the minimum valid register around caller-supplied priority rows.""" + + return ( + "# Product and Technical Gap Baseline\n\n" + "**Snapshot:** 2026-09-02T00:00:00Z\n" + f"**Protected-main evidence:** `{VALID_SHA}`\n\n" + "## Snapshot facts\n\n" + "| Signal | Snapshot evidence | Delivery implication |\n" + "|---|---:|---|\n" + "| Open pull requests | **2** | Queue only. |\n\n" + "## Current priority open pull-request evidence\n\n" + "| PR | Exact current head | Draft | Base | Title |\n" + "|---:|---|:---:|---|---|\n" + + "".join(rows) + + "\n## Operator-gap register\n\n" + "| ID | Closure evidence |\n" + "|---|---|\n" + "| GAP-015 | Exact-head evidence required. |\n" + ) + + +class PriorityInventoryFailClosedTests(unittest.TestCase): + """Reject malformed rows even when another priority row parses successfully.""" + + def test_valid_row_cannot_hide_malformed_head_row(self) -> None: + """Every data row under the canonical priority heading must parse exactly.""" + + fixture = baseline_with_rows( + f"| #164 | `{VALID_HEAD}` | false | main | valid |\n", + "| #165 | `not-a-40-character-sha` | false | main | malformed |\n", + ) + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + path = root / docs.PRODUCT_TECHNICAL_GAP_BASELINE + path.parent.mkdir(parents=True) + path.write_text(fixture, encoding="utf-8") + with self.assertRaisesRegex( + AssertionError, "malformed priority inventory row" + ): + docs.validate_product_technical_gap_baseline(root) + + def test_valid_row_cannot_hide_invalid_draft_or_missing_columns(self) -> None: + """Invalid enums and truncated Markdown rows are also malformed inventory data.""" + + fixture = baseline_with_rows( + f"| #164 | `{VALID_HEAD}` | false | main | valid |\n", + f"| #165 | `{VALID_HEAD}` | maybe | main | invalid draft |\n", + f"| #166 | `{VALID_HEAD}` | true | main |\n", + ) + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + path = root / docs.PRODUCT_TECHNICAL_GAP_BASELINE + path.parent.mkdir(parents=True) + path.write_text(fixture, encoding="utf-8") + with self.assertRaisesRegex( + AssertionError, "malformed priority inventory row" + ): + docs.validate_product_technical_gap_baseline(root) + + +if __name__ == "__main__": # pragma: no cover + unittest.main() diff --git a/tests/quality/test_product_technical_gap_baseline.py b/tests/quality/test_product_technical_gap_baseline.py index a65421534..d27d33403 100644 --- a/tests/quality/test_product_technical_gap_baseline.py +++ b/tests/quality/test_product_technical_gap_baseline.py @@ -26,7 +26,7 @@ def valid_baseline(*, count: int = 1, extra: str = "") -> str: "| Signal | Snapshot evidence | Delivery implication |\n" "|---|---:|---|\n" f"| Open pull requests | **{count}** | Queue only. |\n\n" - "## Current open pull-request evidence\n\n" + "## Current priority open pull-request evidence\n\n" "| PR | Exact current head | Draft | Base | Title |\n" "|---:|---|:---:|---|---|\n" f"| #164 | `{VALID_HEAD}` | false | main | docs |\n\n" @@ -52,7 +52,7 @@ def test_baseline_is_required_and_mapped(self) -> None: self.assertIn(f"]({BASELINE_PATH})", documentation) def test_live_repository_baseline_is_structurally_valid(self) -> None: - """The committed register carries a dated SHA-bound inventory.""" + """The committed register carries a dated SHA-bound priority inventory.""" docs.validate_required_files(REPOSITORY_ROOT) docs.validate_documentation_map(REPOSITORY_ROOT) @@ -81,7 +81,7 @@ def test_map_without_baseline_link_fails(self) -> None: docs.validate_documentation_map(root) def test_valid_fixture_passes_structure_validator(self) -> None: - """A dated exact-head register with matching count is accepted.""" + """A dated exact-head register with a priority inventory is accepted.""" with tempfile.TemporaryDirectory() as temporary: root = Path(temporary) @@ -107,15 +107,62 @@ def test_missing_snapshot_sha_closure_or_inventory_fails(self) -> None: with self.assertRaisesRegex(AssertionError, "exact-head"): docs.validate_product_technical_gap_baseline(root) - def test_inventory_count_mismatch_fails(self) -> None: - """Declared open-PR count must match exact-head inventory rows.""" + def test_queue_total_may_exceed_priority_inventory(self) -> None: + """A large live queue need not be duplicated row-for-row in the operator register.""" with tempfile.TemporaryDirectory() as temporary: root = Path(temporary) path = root / BASELINE_PATH path.parent.mkdir(parents=True) path.write_text(valid_baseline(count=94), encoding="utf-8") - with self.assertRaisesRegex(AssertionError, "does not match inventory"): + docs.validate_product_technical_gap_baseline(root) + + def test_queue_total_smaller_than_priority_inventory_fails(self) -> None: + """The declared live queue cannot be smaller than its exact-head subset.""" + + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + path = root / BASELINE_PATH + path.parent.mkdir(parents=True) + path.write_text(valid_baseline(count=0), encoding="utf-8") + with self.assertRaisesRegex(AssertionError, "smaller than priority inventory"): + docs.validate_product_technical_gap_baseline(root) + + def test_same_pr_in_unrelated_exact_head_table_is_allowed(self) -> None: + """Only duplicates inside the priority inventory are classification errors.""" + + supporting_row = ( + "\n## Historical evidence\n\n" + "| PR | Exact current head | Draft | Base | Note |\n" + "|---:|---|:---:|---|---|\n" + f"| #164 | `{VALID_HEAD}` | false | main | historical |\n" + ) + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + path = root / BASELINE_PATH + path.parent.mkdir(parents=True) + path.write_text( + valid_baseline(count=94, extra=supporting_row), + encoding="utf-8", + ) + docs.validate_product_technical_gap_baseline(root) + + def test_duplicate_priority_inventory_row_fails(self) -> None: + """A priority PR may appear at most once inside the priority inventory.""" + + duplicate_row = f"| #164 | `{VALID_HEAD}` | false | main | docs duplicate |\n" + marker = "\n## Operator-gap register\n" + fixture = valid_baseline(count=94).replace( + marker, + f"{duplicate_row}{marker}", + 1, + ) + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + path = root / BASELINE_PATH + path.parent.mkdir(parents=True) + path.write_text(fixture, encoding="utf-8") + with self.assertRaisesRegex(AssertionError, "duplicate PR rows"): docs.validate_product_technical_gap_baseline(root) def test_queued_checks_as_implemented_main_fails(self) -> None: @@ -234,4 +281,4 @@ def test_adversative_severed_negation_still_fails(self) -> None: if __name__ == "__main__": # pragma: no cover - unittest.main() + unittest.main() \ No newline at end of file diff --git a/tests/quality/test_workflow_queue_hygiene.py b/tests/quality/test_workflow_queue_hygiene.py deleted file mode 100644 index 431687af5..000000000 --- a/tests/quality/test_workflow_queue_hygiene.py +++ /dev/null @@ -1,67 +0,0 @@ -"""Queue-isolation contracts for repository-local GitHub Actions.""" - -from pathlib import Path -import unittest - - -WORKFLOW_DIRECTORY = Path(".github/workflows") - - -class WorkflowQueueHygieneTests(unittest.TestCase): - """Keep local validation isolated by repository and pull request.""" - - def test_pull_request_workflows_cancel_only_older_same_pr_runs(self) -> None: - """CI groups include workflow, repository, and PR identity.""" - - expected_groups = { - "ci.yml": ( - "tepp-rust-foundation-${{ github.repository }}-" - "${{ github.event.pull_request.number || github.run_id }}" - ), - "docs-quality.yml": ( - "docs-quality-${{ github.repository }}-" - "${{ github.event.pull_request.number || github.run_id }}" - ), - } - for workflow_name, expected_group in expected_groups.items(): - workflow = (WORKFLOW_DIRECTORY / workflow_name).read_text(encoding="utf-8") - self.assertIn(f"group: {expected_group}", workflow) - self.assertIn( - "cancel-in-progress: ${{ github.event_name == 'pull_request' }}", - workflow, - ) - - def test_central_scheduler_replaces_local_hourly_caller(self) -> None: - """A local timer must not duplicate central PR scheduling.""" - - self.assertFalse((WORKFLOW_DIRECTORY / "hourly-pr-maintenance.yml").exists()) - - def test_documentation_workflow_does_not_duplicate_crate_ci(self) -> None: - """Crate changes already run documentation contracts in Rust CI.""" - - workflow = (WORKFLOW_DIRECTORY / "docs-quality.yml").read_text( - encoding="utf-8" - ) - self.assertNotIn(' - "crates/**"', workflow) - - def test_rust_ci_reuses_one_runner_for_both_coverage_reports(self) -> None: - """Coverage keeps both gates while avoiding a second runner boot.""" - - workflow = (WORKFLOW_DIRECTORY / "ci.yml").read_text(encoding="utf-8") - self.assertIn(" production-coverage:\n", workflow) - self.assertNotIn(" line-coverage:\n", workflow) - self.assertNotIn(" branch-coverage:\n", workflow) - self.assertIn("id: line-report", workflow) - self.assertIn("id: branch-report", workflow) - self.assertIn("if: ${{ !cancelled() }}", workflow) - self.assertNotIn( - "cargo check --workspace --all-targets --all-features", workflow - ) - self.assertIn( - "cargo clippy --workspace --all-targets --all-features -- -D warnings", - workflow, - ) - - -if __name__ == "__main__": # pragma: no cover - unittest.main()