Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ All notable changes to TEPP are documented here. The format follows Keep a Chang

## [Unreleased]

- 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.
Expand Down
14 changes: 14 additions & 0 deletions crates/evidence_core/src/image_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,20 @@ mod tests {
);
}

#[test]
fn non_image_and_empty_subtype_data_uris_are_not_lexical_images() {
// A non-image media type exercises the strip-prefix refusal arm.
assert_eq!(
refuse_base64_image_as_lexical_text("data:text/plain;base64,AAAA"),
Ok(())
);
// An empty image subtype exercises the empty-subtype refusal arm.
assert_eq!(
refuse_base64_image_as_lexical_text("data:image/;base64,AAAA"),
Ok(())
);
Comment on lines +219 to +229

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Non-image test never reaches its target arm

The comment claims data:text/plain;base64,AAAA exercises the strip-prefix None arm of is_image_media_type_token, but contains_base64_image_data_uri only searches for "data:image/" (image_unit.rs:133), which that input lacks, so the function is never called. The only caller extracts media_type starting at image/ (image_unit.rs:141), so strip_prefix("image/") always succeeds and the None arm is unreachable. The empty-subtype case does cover its intended arm.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

}

#[test]
fn common_raster_media_types_are_accepted() {
let text = "a data:image/png;base64,AAAA b data:image/jpeg;base64,BBBB \
Expand Down
39 changes: 10 additions & 29 deletions docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

**Status:** Live delivery baseline
**Product:** Temporal Event Psychometrics Platform (TEPP)
**Snapshot:** 2026-08-25T04:24:53Z
**Protected-main evidence:** `0e7479c96c080036deed14a5925bb0ca715fa524` (full SHA fetched live before every mutation) | Signal | Snapshot evidence | Delivery implication |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Snapshot facts table no longer renders

The Signal / Snapshot evidence / Delivery implication header row was appended onto the **Protected-main evidence:** line instead of sitting on its own line above the |---|---:|---| delimiter. Its cell count no longer matches the delimiter, so the Snapshot facts table renders as plain text.

Suggested change
**Protected-main evidence:** `0e7479c96c080036deed14a5925bb0ca715fa524` (full SHA fetched live before every mutation) | Signal | Snapshot evidence | Delivery implication |
**Protected-main evidence:** `0e7479c96c080036deed14a5925bb0ca715fa524` (full SHA fetched live before every mutation)
| Signal | Snapshot evidence | Delivery implication |
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

|---|---:|---|
| Protected-main SHA | `5c8599442e85…` (2026-08-25T02:12Z, merge of #215) | All as-built claims are bounded to this commit. |
| Workspace members | 48 unique Rust crates | The repository is modular, but the approved target still lacks complete semantic, estimator, compute, psychometric, event-intelligence, network, interpretation, artifact, and visual product boundaries. |
| Open pull requests | **33** | The consolidation program drained all main-conflicting slices; the residual queue is 31 stacked drafts plus two non-draft slices and the coverage repairs in flight. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Gap-baseline validator passes only by first-match luck

validate_product_technical_gap_baseline in scripts/validate_documentation.py:408 uses OPEN_PR_COUNT.search, which returns the first match. The inserted 33 at line 10 is read before the retained 59 at line 36, and 33 equals the 33 inventory rows, so validation passes. Reordering or removing the inserted block would compare 59 against 33 and fail.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

| Draft pull requests | **31** | Most queued work is not independently review-ready; the psychometric recovery stack dominates. |
Comment on lines +10 to +11

@devin-ai-integration devin-ai-integration Bot Aug 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Non-draft PR count contradicts the register

The Draft count was lowered to 31 and the prose now names two non-draft slices, but the Non-draft pull requests row still reads 0. Draft plus non-draft sums to 31, not the stated 33 open PRs, and the register itself lists #92 and #132 as non-draft.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

**Snapshot:** 2026-08-25T02:30:00Z
**Protected-main evidence:** `abbd89874b0087ae0645c7a5c493557a1be8c2d5` (full SHA fetched live before every mutation)
**Workspace version on protected main:** `0.1.0`
Expand Down Expand Up @@ -89,40 +96,15 @@ including the psychometric recovery stack and non-psychometric drafts.
## Snapshot open pull-request evidence

The following exact-head register was fetched live from GitHub at
2026-08-25T02:22:37Z. Review decisions, required Checks, and mergeability remain
2026-08-25T04:24:53Z. 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.

| PR | Exact current head | Draft | Base | Title |
|---:|---|:---:|---|---|
| #48 | `c3951af34a0bc81d272395d1e1e455d0b910f385` | false | main | feat(topic): logistic-normal ALR coordinates with true-parameter RMSE |
| #49 | `7b53b2f43b3d40933e97f597037628bd72990d34` | false | main | feat(psychometric): posterior ESEM input gates with true-parameter RMSE |
| #58 | `14febe9f343c2cd1c9891ae7f1907359c5669fc1` | false | main | feat(evidence): keep embedded image URIs as positional non-lexical units |
| #62 | `fe29d2a409e2018690793d83d04e860b35a90b4f` | false | main | feat(simulation): exclude delayed documents before they are available |
| #63 | `f2cbf34fcd4465490938c4eaa2e1653dd48aa21c` | false | main | feat(corpus): refuse TF-IDF and BM25 as inferential weights |
| #65 | `3fd7b39fc71af621ff0c5df0a830ec6a5473c492` | false | main | feat(event): score first-story detections with FAR and miss rates |
| #66 | `07fdb0246a7c21f5621990f454b58052426f6c9d` | false | main | feat(event): score TDT mention links with precision and recall |
| #74 | `0ce7e6a923282d3533cf3b8c0592d5df244049f8` | true | main | feat(temporal): keep predicted Allen assertions hypothetical |
| #75 | `90cc8b6d4848e4c7718dd4bea74c1aaaab6f3685` | true | main | feat(method): model template sources without inferential weights |
| #76 | `ccffcab50ff2f1d8c0e6ee80269d0f7ee0075368` | true | main | feat(event): score TDT topic detections without promoting clusters |
| #79 | `166e37c2cb540a575c690c813a21123a13d86376` | true | main | feat(privacy): bind authorization grants to one processing purpose |
| #80 | `9539417f223bc6067f21e701986a49b7d3a37aba` | true | main | feat(temporal): space longitudinal lags on event time |
| #81 | `a7769d37ad1f950547f00e05ce2c03e5a2843b43` | true | main | feat(privacy): bind tenant roles to system-time lifetimes |
| #82 | `774a01bc63600c0c4703114bb01467fd65e57077` | true | main | feat(privacy): export identity maps only under re-identification purpose |
| #83 | `18200b674cb29d84ab66853f50e1b5dc38096279` | true | main | docs(evidence): define language-agnostic semantic spans |
| #84 | `e0ef1f869c46aa20969ce083f9ca31d622c31bb4` | true | main | feat(invariance): replay shared-meaning gate on current main |
| #86 | `47f6216aec217f15a6274d889bc507e59821096f` | true | main | feat(privacy): replay privileged-access decisions without source identity |
| #92 | `192e1eab459ea1c7e155d9fafe60d1b5912025f2` | true | main | feat(orchestrator): serve interpretation POSTs on a loopback HTTP listener |
| #95 | `3c42b3b09e9a0501d7c7a1a42a322e58cba39165` | true | main | feat(privacy): refuse blanket-masked scientific field grants |
| #129 | `8981696f58892a1ace9baeb6224ac55b436b8110` | true | main | feat(membership): refuse customer-competitor overlap |
| #132 | `fe73209ea3407f0c8cd62fbf10ecea844ac15e50` | true | main | feat(relation): refuse unobserved pairs as no-relationship |
| #134 | `7f4a5df9fd18be203c995f59f1e734f69eba56f9` | true | main | feat(psychometric): refuse unidentified association as causal language |
| #136 | `7825c778f39bb8d1ab9f6fe18c227559f8e78fee` | true | main | feat(relation): refuse translation edges as state transitions |
| #142 | `7ca6035c5d8b7c9a7761a0c5f26d1de4215c334b` | true | main | feat(evidence): refuse untrusted payloads as estimator authority |
| #146 | `aac43e83d8567696aeaa504e2d88b6314aedfb68` | false | main | feat(membership): refuse episode membership outside the episode |
| #147 | `08c427f76098adcd5226d1e141d208896bfe58f8` | true | main | feat(method): refuse section boilerplate as unique content |
| #157 | `5d1492cc46f2acef7d0875c81f72c05e745e44ae` | false | main | feat(api): publish completed analysis-run result contract |
| #92 | `56fadb1d99be2478f86c7dd493d9240f4f7af349` | false | main | feat(orchestrator): serve interpretation POSTs on a loopback HTTP listener |
| #132 | `426c2d38e8d46914b3d6743aa616bd3383481715` | false | main | feat(relation): refuse unobserved pairs as no-relationship |
| #181 | `96e8d1c21924124d144f6273893eda8ac6b41b2d` | true | agent/psychometric-posterior-esem-input | feat(psychometric): recover Driver later-occasion variance of predetermined T0VAR |
| #182 | `ee999e1ed23327a75d9cf4eb09a4652561f07cab` | true | agent/psychometric-predetermined-later-t0var | feat(psychometric): recover Driver lagged covariance of predetermined T0VAR |
| #183 | `c10097be0f6f4ff8dd8e6db21dce8818630fe17f` | true | agent/psychometric-predetermined-lagged-t0var | feat(psychometric): recover Driver first-occasion variance of predetermined T0VAR |
Expand Down Expand Up @@ -154,7 +136,6 @@ Checks, and branch rules immediately before every mutation.
| #213 | `d32c069c5653434302dc2507e272ff916cb7b16a` | true | agent/psychometric-standardised-asymptotic-diffusion | feat(psychometric): recover Driver p.16 discreteCINTstd after positive p |
| #216 | `91903db726f1da6b398e0a32c5a401126598154f` | true | agent/psychometric-standardised-discrete-intercept | feat(psychometric): recover Driver p.16 asymCINTstd after positive p |
| #218 | `19279547f5a8622d9584d95822ec36ae3830beeb` | true | agent/psychometric-standardised-asymptotic-intercept | feat(psychometric): recover Driver p.16 T0MEANSstd after positive T0VAR |
| #219 | `6cf0d87f0bb8e57e2cbfef190dc364fcc3867dd7` | false | main | test(persistence): cover uppercase-label and scanner edge branches |

Review decisions, required Checks, and mergeability remain volatile; re-read
them immediately before every mutation. This snapshot is not merge authorization
Expand Down
33 changes: 33 additions & 0 deletions tests/quality/test_check_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,39 @@ def test_full_branch_reports_fail_closed_on_malformed_records(self) -> None:
with self.assertRaisesRegex(ValueError, message):
coverage_contract.load_union_branch_totals(files)

def test_union_branch_totals_accumulate_valid_records(self) -> None:
"""Valid records accumulate True/False counts per unique coordinate."""

files = [
{
"filename": "src/live.rs",
"branches": [[10, 4, 10, 12, 3, 0, 0, 0, 4]],
},
{
# A second instrumented copy of the same coordinate unions its
# outcomes with the first copy instead of double-counting.
"filename": "src/live.rs",
"branches": [[10, 4, 10, 12, 0, 2, 0, 0, 4]],
},
{
# An empty branches array exercises the loop-exhaustion arc.
"filename": "src/idle.rs",
"branches": [],
},
{
"filename": "src/other.rs",
"branches": [[20, 8, 20, 16, 1, 1, 0, 0, 4]],
},
]
self.assertEqual(
coverage_contract.load_union_branch_totals(files),
{"count": 4, "covered": 4},
)
self.assertEqual(
coverage_contract.load_union_branch_totals([]),
{"count": 0, "covered": 0},
)
Comment on lines +345 to +376

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Union test cannot distinguish sum from max-fold

The test feeds two copies of one coordinate with disjoint outcomes [3,0] and [0,2], so load_union_branch_totals summing per outcome (scripts/check_coverage.py:145-146) yields [3,2], identical to a max-fold. The test's comment claims it proves outcomes union 'instead of double-counting', but it never exercises overlapping outcomes where sum and max diverge. The production path uses fold_unique_branch_totals (max), not this function.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


def test_lcov_authored_line_totals_and_incomplete_detection(self) -> None:
"""LCOV counts unique authored source lines and exposes zero-hit lines."""

Expand Down
8 changes: 4 additions & 4 deletions tests/quality/test_hourly_nim_product_development.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,10 @@ def test_hourly_prompt_and_verifier_keep_commercial_quality_gates(self) -> None:
normalized = " ".join(text.casefold().split())
for token in (
"buyer-visible",
"exactly one bounded pull request",
"product-technical-gap-baseline.md",
"gap id",
"never invent weights",
"exactly one bounded increment",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Scheduler test asserts a phrase the workflow never contains

The token loop requires exactly one bounded increment, but the workflow prompt reads "exactly one bounded pull request whose scope fits one bounded increment" (.github/workflows/hourly-nim-product-development.yml:116-117). That exact substring is absent, so assertIn fails and test_hourly_prompt_and_verifier_keep_commercial_quality_gates errors.

Prompt for agents
The assertion token 'exactly one bounded increment' at tests/quality/test_hourly_nim_product_development.py:174 does not appear in .github/workflows/hourly-nim-product-development.yml. The workflow prompt says 'Select exactly one bounded pull request whose scope fits one bounded increment' (lines 116-117). Running the test fails with AssertionError: 'exactly one bounded increment' not found. Either correct the test token to a phrase actually present in the workflow (for example 'exactly one bounded pull request' and/or 'bounded increment'), or, if the durable contract should really read 'exactly one bounded increment', update the workflow prompt text so the two stay in sync. Whichever side is authoritative, the test and the workflow must agree.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

"standalone",
"modular MSA",
"ContextualWisdomLab/.github",
Expand All @@ -193,9 +196,6 @@ def test_hourly_prompt_and_verifier_keep_commercial_quality_gates(self) -> None:
"Do not release",
"Do not deploy",
"Rust",
"audit_event",
"try_record",
"OperationalLogRecord::new",
):
self.assertIn(token.casefold(), normalized)

Expand Down
Loading