Skip to content

feat(analysis): bind template-copy identity refusals to an analysis-run profile - #416

Draft
seonghobae wants to merge 76 commits into
mainfrom
feat/copy-identity-analysis-run-gap-004
Draft

feat(analysis): bind template-copy identity refusals to an analysis-run profile#416
seonghobae wants to merge 76 commits into
mainfrom
feat/copy-identity-analysis-run-gap-004

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Consolidation status

landing_vehicle_candidate — Validation / Analysis Run simple-refusal/census landing vehicle tracked by #435. It is not a new bounded context. Folded profiles preserve domain refusal semantics and focused tests here; per-profile ADR numbers remain implementation lineage pending #437 repository-wide ADR normalization.

Fold lineage already preserved here: #473 inferred_status_v1, #430 location_membership_v1, #461 episode_membership_v1, #478 subevent_containment_v1, and #434 membership_target_v1. Those closed children are lineage into this Draft branch, not protected-main delivery.

Current exact branch head is 722affdd2c02d331bfba3816fbda799059cc1778 on protected main@a243f18da4a4ca8a8d068c39922537f1f8ed6ad0. History remains ordinary forward history; no rebase or force update is used.

Scientific and cross-profile contract repairs

AnalysisResultSummary.validation_status remains provider-authored validation status, not a domain inference claim. Folded profiles compare parsed KnowledgeCutoff::instant() values rather than timestamp text and keep domain inference_status separate from terminal validation_status == "validated".

The leakage invariant is explicit: evidence with AvailableTime > knowledge_cutoff must not enter the historical scientific census, duplicate/domain admission, counts, artifacts, or terminal scientific result. Duplicate identities among evidence actually available at the cutoff still fail closed. The engine-wide raw input cardinality guard remains an operational admission bound and is not weakened by this rule.

Current repair lineage:

  • copy_identity_v1: RED contract c89123d7c7165ec3acf2bffcd40676ea81f72c92 proves that a future-unavailable row reusing a visible document identity must not change a historical replay. Repair 745345544bd424cf410debab6d78a232638db8be excludes future rows before duplicate/domain admission and derives document_count from admitted identities. Exact coverage artifact from predecessor 93be3e043ddd21625d0b4aa67ba046bce8ef7621 also showed the post-validation to_json byte-limit branch uncovered. Because valid IDs are bounded to 256 UTF-8 bytes, the census is bounded by MAX_EVIDENCE_UNITS, and all other serialized fields are fixed/bounded, 9ee6d60ff4443d7e843e5b20c745a332dca6d097 adds a maximal-valid serialization proof and ced4b09dbbc1310c5c2503c787ae69815b4660e1 removes only that unreachable egress branch. The untrusted-input from_json 256 KiB cap remains fail-closed.
  • inferred_status_v1: 12bbcfbce7e3248f1237c601e99c7cf9426ffa57 removes a bounded, unreachable post-validation output-size branch while preserving the untrusted-input from_json cap; provider-result drift is checked through a directly testable fail-closed refusal guard.
  • location_membership_v1: 294f091cfb353e90267932da67289a65afc17cda stops discarding the two canonical location-refusal results and verifies the exact expected domain errors. It also proves the maximal valid canonical artifact remains below the input wire cap.
  • episode_membership_v1: RED b4a135ed0149b7020383f071edda6db9f5d3ff60 proves that a future-unavailable duplicate identity must not change a historical run; repair cb5d97cb159958ef259b2f2d97968fdd7830a1e3 moves availability admission before duplicate insertion. Exact predecessor coverage also left the post-validation output-size and unexpected-provider-error paths uncovered. 17b98449b391b178d8a777172536fceca4fc51d0 proves a maximal valid artifact remains below the 256 KiB wire cap, 21eda89ee8ce68a5ef35621676d0ab7cc72ad0b7 removes only that unreachable egress check while preserving from_json admission, and 03f6870c8b5cd201185cd7d53b503e3cea930121 moves the non-exhaustive provider-result fallback into a directly testable fail-closed classifier without weakening future-variant refusal.
  • subevent_containment_v1: RED 21d85de0793c1a386d693aefc42399d5d558d584 and repair 315de53a0f03de9d476ea578e47b43798a3a4deb apply the same cutoff-before-identity rule without weakening visible-duplicate refusal. Exact predecessor coverage likewise exposed an unreachable post-validation output-size branch and an unexercised provider-drift fallback. 7dad37591e8f220c95bc08227dfbb7b591b6a4a7 adds the maximal-valid wire-bound proof, b3a3edcc09f6cd25e2067308e83d71f29c6711f4 removes only the unreachable egress check while retaining the untrusted-input cap, and 722affdd2c02d331bfba3816fbda799059cc1778 makes the provider-drift fallback directly testable and fail-closed.
  • membership_target_v1: RED 66951df7d6c704e03edc7fd9b41a1857788034ca exposes that the profile called itself cutoff-safe while MembershipTargetDocument carried no availability provenance. Repair 5f3bd54f6aaf6bf01d95953f5ff5f74decd019df adds explicit AvailableTime, excludes future-unavailable rows before identity/domain admission, and makes document_count the admitted count rather than raw input length. 93be3e043ddd21625d0b4aa67ba046bce8ef7621 migrates the existing integration contract to explicit availability. Exact predecessor coverage also showed its post-validation output-size branch uncovered; 8ea980da36e73edde8a0512d8ea6710f17e34861 proves a maximal valid artifact stays below the 256 KiB wire cap and 441545fa9ea3d994a10f005329734fb249e98f5a removes only that unreachable egress check while preserving the inbound cap. There is no compatibility constructor that invents an availability timestamp.

The predecessor 93be3e043ddd21625d0b4aa67ba046bce8ef7621 Rust Foundation run exposed both the exact authored coverage deficit and a real cargo fmt --all -- --check RED in the newly added episode/subevent cutoff regressions and membership-target fixture. Ordinary forward formatting commits corrected only those rustfmt deltas before the later coverage-driven repairs; predecessor hosted receipts are not transferred to the current head.

#487 adds another scientific repair that must survive the fold: observed Allen relation classes are data, not run prerequisites. Its RED a2892b6ad4f632882f63da39eed2d4706ddf9213 and repair a64020152300232cb3214a66b45d97225b6d2b5b require sparse covered-only or contradiction-only censuses to report truthful zero class counts. Child head e07b2ff9f78ef456ff911b8643710af20921fe54 also changes ADR 0079 from premature Accepted branch authority to Proposed implementation lineage and removes its stale mixed-four-class eligibility claim. The eventual fold must inherit that corrected ADR semantics.

Profiles preserved on this head

  • copy_identity_v1: copy versus source identity/transition refusal, typed cutoff equality, cutoff-before-identity admission, bounded digest artifact.
  • inferred_status_v1: observed versus inferred remain distinct; inferred is neither observed evidence nor transition.
  • location_membership_v1: location remains distinct from entity identity and language channel; inspect remains recovery-metric-free.
  • episode_membership_v1: membership windows are checked against episode intervals with cutoff-safe admission; identity_recovery_rate stays library-side.
  • subevent_containment_v1: child intervals cannot escape parent intervals; TRACEABILITY excludes both containment_recovery_rate and identity_recovery_rate from inspect.
  • membership_target_v1: language/episode/template/department/opportunity-pool target kinds stay distinct from entity/project and carry explicit availability provenance.

Current fold children

#458 outcome_order_v1 at 08165e3b3c929b4ae77396689549f72723ff8ff5, #460 relation_absence_v1 at dfab4eab5ff733731e565a9348072b8dab2e4912, #482 role_contradiction_v1 at 506dbae236a4484301b704b6c6a05b20faf0fe69, #483 retrospective_edge_v1 at 847d96f913bb261803ac0bd751ad7e4f51324cee, #484 summarizes_edge_v1 at 9a1be78b5342ff65e3cf2aac1e9331c68943f246, #485 support_edge_v1 at f71591864efc2beff336ced7ef35d5a013305c36, and #487 prediction_contradiction_v1 at e07b2ff9f78ef456ff911b8643710af20921fe54 remain conflict-resolving fold children.

#484, #485, and #487 change the same shared Analysis Run integration surface as this vehicle (Cargo.lock, analysis_engine Cargo/lib, DOCUMENTATION.md, TRACEABILITY and ADR index). They remain non-destructively retargeted here; unique source/tests/doctoring must survive a real conflict-resolving fold. Closing a child without verified inheritance is not consolidation.

Coverage and current exact-head evidence

Predecessor coverage receipts never transfer to a new source head. At 93be3e043ddd21625d0b4aa67ba046bce8ef7621, exact coverage.lcov reported 17 authored production lines uncovered. Four post-validation egress size branches identified in that artifact have now been removed only after maximal-valid serialization proofs were added; the inbound 256 KiB from_json caps remain. Episode/subevent unexpected-provider outcomes are now explicit testable fail-closed contract guards rather than unexercised inline fallbacks. Current-head coverage must be regenerated before any lower uncovered-line count is claimed.

The current source head 722affdd2c02d331bfba3816fbda799059cc1778 must obtain its own Rust Foundation, Documentation Quality, Security Scan, Semgrep, and CodeQL receipts; predecessor GREEN/RED states are not transferred. This body does not claim GREEN or merge readiness.

A separate protected-main repository-contract failure remains outside this lane: tests/quality/test_hourly_nim_product_development.py:79 still expects repository-local cron: "47 * * * *", although protected main removed repository-local scheduling under #490. Canonical repair remains Draft #492 (794ba9e6...) and owns the central-admission/dispatch-only contract. This Analysis Run fold must not restore or duplicate the old workflow policy.

The predecessor Security Scan failure was confined to dependency-review: Trivy, OSV and Scorecard were GREEN while authenticated dependency-graph compare returned HTTP 403 and failed closed. That remains a central support/control-plane finding rather than demonstrated source vulnerability here; no leaf bypass or scanner suppression is permitted.

DDD boundary and merge gate

The Analysis Run application/Validation boundary owns request admission, cutoff-safe temporal composition, digest-bound result projection and claim refusals. Source-specific rule crates own domain vocabulary. Folding proceeds through shared admission/artifact invariants plus profile-specific adapters, not a flat model enum or technical god-module.

This vehicle remains Draft. Fold scope, DDD/docs, #492 prerequisite, exact current-head line/branch coverage, security control-plane availability, required checks, qualifying independent review, and conflict-resolving inheritance of active children must converge on one unchanged surviving head before Ready/merge. No self-approval, coverage exclusion, fail-open security change, force push, destructive rebase, routine admin bypass, no-op retrigger, or predecessor-head evidence transfer is allowed.

…un profile

GAP-004 leftover / ADR 0058. Bind existing copy_identity refusals
(refuse_copy_as_source_identity, refuse_copy_as_transition) to cutoff-safe
copy_identity_v1. identity_recovery_rate stays library-side. Distinct from
simulation method-effect census (#415). Not GPU, not MCMC, and not topic
birth/split/merge.
@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 3 potential issues.

Devin Review

Comment thread crates/analysis_engine/src/copy_identity_artifact.rs
Comment thread crates/analysis_engine/src/copy_identity_artifact.rs
Comment thread crates/analysis_engine/src/copy_identity_artifact.rs

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

Devin Review

Comment thread crates/analysis_engine/src/copy_identity_artifact.rs Outdated
…profile

GAP-004 leftover / ADR 0066. Bind existing location_membership refusals
(refuse_location_as_entity_identity, refuse_location_as_language_channel)
to cutoff-safe location_membership_v1. identity_recovery_rate stays
library-side. Distinct from membership-posterior ICC (#398), copied-text
(#427), citation-edge (#426), and corpus-background (#422). Not GPU,
not MCMC, and not topic birth/split/merge.
…ofile

GAP-004 leftover / ADR 0069. Bind existing MembershipTargetKind and
refuse_collapsed_target to cutoff-safe membership_target_v1. Language,
episode, template, department, and opportunity-pool targets are not
entities; identity_recovery_rate stays library-side.
…rofile

GAP-004 leftover / ADR 0072. Bind existing EventWindow and
refuse_membership_outside_episode to cutoff-safe episode_membership_v1
(tepp.episode_membership.v1). Mixed contained/escaped census,
AvailableTime cutoff exclusion, and MAX_EVIDENCE_UNITS fail closed.
identity_recovery_rate stays library-side. Distinct from relation-absence,
outcome-order, membership-target, location-membership, and copy-identity.
GAP-004 leftover / ADR 0073. Bind existing EvidenceStatus,
refuse_inferred_as_observed, and refuse_inferred_as_transition to
cutoff-safe inferred_status_v1. Mixed observed/inferred corpora emit a
digest-bound census. identity_recovery_rate stays library-side.

Fixes #472.
Use the review-reproduced oversized compact artifact as RED evidence. Enforce the same MAX_EVIDENCE_UNITS invariant at artifact deserialization/serialization that execution already enforces, and add regression coverage for both directions.
Document the artifact-count invariant and exact-head landing procedure, and collapse the duplicated documentation map into one canonical index so the new doctoring entry cannot diverge between copies.

Copy link
Copy Markdown
Contributor Author

Coverage RCA / forward repair on current lane:

  • Predecessor exact head 12bbcfbce7e3248f1237c601e99c7cf9426ffa57 produced immutable line artifact 10320806351 (sha256:a427d17182301458fa58f72d48797a116c951995b7b2e8e63fec3b2848824008) and branch artifact 10320951161 (sha256:294db1ab56aaf857c80f9c33237dd3fb129c2bb5eaacbfc84e95f8c9c7c09356). The authored-line diagnostic still had location_membership_artifact.rs:135 uncovered; branch summary for that file was 48/50.
  • Source review confirmed the uncovered line was the post-validation to_json 256 KiB size refusal. run_id and snapshot_id are identifier-bounded and artifact cardinality is bounded by MAX_EVIDENCE_UNITS, so a valid canonical artifact cannot approach that untrusted-input limit. The from_json input cap remains fail-closed.
  • A second valid contract finding existed in the same adapter: LocationKind::Location called refuse_location_as_entity_identity and refuse_location_as_language_channel and discarded both results with let _ =, so provider-contract drift could silently become counted refusal evidence.
  • Forward commit 294f091cfb353e90267932da67289a65afc17cda removes only the unreachable post-validation output-size guard, adds a maximal-valid serialization proof, and replaces discarded domain results with require_refusal(actual, expected). The helper is directly tested for expected refusal, unexpected success, and wrong refusal error. from_json oversize refusal is unchanged.
  • Compare 12bbcfb... -> 294f091...: one file only, crates/analysis_engine/src/location_membership_artifact.rs, +66/-13. No force update, denominator change, skip/xfail, or provider/source copy.

Fresh exact-head workflows were admitted naturally (Rust Foundation CI 34767372762, Documentation 34767372749, Security 34767372763, Semgrep 34767372788, CodeQL 34767372754). Predecessor receipts do not transfer; keep Draft until the new head settles.

Copy link
Copy Markdown
Contributor Author

New scientific leakage finding and repair, after the location-refusal fix:

  • In episode_membership_artifact::census_assignments, duplicate identity admission still ran before AvailableTime <= knowledge_cutoff. That means future-unavailable evidence could change a historical run from success to DuplicateEvidence, violating the fold's stated cutoff invariant.
  • RED commit b4a135ed0149b7020383f071edda6db9f5d3ff60 adds episode_membership_cutoff_duplicate_contract.rs: the same visible two-assignment census is replayed with a future-unavailable row that reuses a visible assignment ID, and the historical artifact/terminal result must remain identical. The superseded RED workflows were cancelled when the causal fix followed; no cancelled run is treated as GREEN evidence.
  • Minimal repair cb5d97cb159958ef259b2f2d97968fdd7830a1e3 moves the availability test before insertion into seen. It does not relax duplicate rejection for evidence actually available at the cutoff.
  • Compare from the prior head 294f091... to cb5d97c...: two commits, one 93-line regression test file plus a 3-line-order source change (+3/-3) in episode_membership_artifact.rs. No force update or branch rewrite.

Fresh exact-head workflows are Rust Foundation CI 34767788674, Documentation 34767788695, Security 34767788697, Semgrep 34767788664, CodeQL 34767788673; all were queued/pending at the latest observation. Keep Draft and do not transfer predecessor receipts.

Copy link
Copy Markdown
Contributor Author

The leakage sweep found the same ordering defect in subevent_containment and a stronger provenance gap in membership_target; both are now forward-repaired on the same Draft lane.

  • Subevent RED 21d85de0793c1a386d693aefc42399d5d558d584 adds a historical-replay contract where a future-unavailable row reuses a visible assignment ID. Minimal fix 315de53a0f03de9d476ea578e47b43798a3a4deb moves availability admission ahead of duplicate identity insertion. Visible duplicates still fail closed.
  • Membership-target was calling itself cutoff-safe while MembershipTargetDocument carried no availability at all, so the executor could not enforce AvailableTime <= knowledge_cutoff. RED 66951df7d6c704e03edc7fd9b41a1857788034ca adds the same future-duplicate historical replay using the required explicit availability API.
  • Source repair 5f3bd54f6aaf6bf01d95953f5ff5f74decd019df adds AvailableTime to MembershipTargetDocument, excludes future-unavailable rows before duplicate/domain admission, and makes document_count the admitted count rather than raw input length. Existing execution fixtures were migrated at 93be3e043ddd21625d0b4aa67ba046bce8ef7621 to provide explicit availability.
  • PR-wide search now shows every MembershipTargetDocument::new call supplying availability; there is no compatibility constructor that silently invents an availability timestamp.

These repairs preserve the raw input resource bound (documents.len() <= MAX_EVIDENCE_UNITS) while making historical scientific counts and identity conflicts depend only on cutoff-admitted evidence. No source copy, denominator change, skip/xfail, or force update was used. Current exact head is 93be3e043ddd21625d0b4aa67ba046bce8ef7621; predecessor workflow receipts do not transfer.

Copy link
Copy Markdown
Contributor Author

Current-head repair update — exact head badf89e241943a1a0d9ee1405b73937f0c110eec.

The predecessor LCOV/branch RED left membership_target_v1 provider-drift and typed-kind fallback paths as coverage debt. This was not repaired by deleting fail-closed behavior or by constructing an impossible production fixture. The adapter now exposes three small private contract guards inside membership_target_artifact.rs:

  • require_target_refusal accepts only the canonical TargetKindCollapsed refusal and rejects unexpected Ok(()) or any other provider error;
  • require_target_identity accepts only same-kind Ok(()) and fails closed on provider errors;
  • typed_membership_target_kind maps the five non-persistence kinds into an internal closed classifier and explicitly rejects Entity/Project, removing the previously unexercisable nested branch from the execution loop without weakening the boundary.

Focused unit tests directly exercise canonical success/refusal, unexpected success, InvalidTargetPayload, and both persistence-kind rejection cases. The production refuse_collapsed_target calls remain owner-provided; no source copy or arithmetic change was introduced. Exact diff inspection confirms this commit changes only crates/analysis_engine/src/membership_target_artifact.rs.

Fresh current-head workflows were admitted as Rust Foundation 34773411080, Documentation Quality 34773411086, Security Scan 34773411057, Semgrep 34773411052, and CodeQL PR 34773411050; they are queued at this observation. No predecessor receipt is transferred and this Draft is not claimed GREEN/Ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant