fix(longitudinal): reject reused Commons observation identities - #262
seonghobae wants to merge 8 commits into
Conversation
📝 WalkthroughWalkthrough
Changes관측 레코드 식별자 충돌
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This PR adds a localized validation for reused observation identities while preserving replay behavior. Only minor test-strengthening and documentation follow-up remain, with no actionable merge-blocking risk identified. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
Fixed the current-head Runtime CI formatting failure with a minimal formatting-only commit.
This is validation evidence, not an approval. The required remote checks must complete for the new exact head. |
|
Additional local validation on exact code after the formatting commit: |
|
@opencode-agent Please review only exact head |
|
Reconciled exact head
This is validation evidence, not approval. |
|
@opencode-agent Please review only exact head |
|
@opencode-agent Current-base correction: protected main is exact head 503a4e6. Please review only PR #262 head 31df209 against that current protected main; the PR metadata may still show the older ancestor base 5544149. Do not transfer conclusions from superseded heads or stale-base reviews. |
Preserve the #262 longitudinal observation identity guard and its focused traceability/test evidence on top of current protected main. The #258 Rust toolchain-refresh paths are disjoint, so this reconciliation retains both change sets without force-pushing or changing longitudinal behavior beyond the existing PR delta.
|
@opencode-agent Current-head correction: PR #262 is now at exact head 8cd3ae2 after a concurrent branch update. Please review only this current head against protected main 503a4e6; ignore earlier review requests for superseded heads and do not require a force push. |
Why
Protected
maintreatsobservation_record_refas the opaque Commons identity of one immutable longitudinal observation, but the in-memoryLongitudinalObservationSetonly enforces uniqueness of the Gyeot source tuple(enrollment_ref, source_system_ref, source_observation_ref). Two distinct source observations can therefore reuse the same Commons record identity and both be accepted. That contradicts the identity contract and the PostgreSQL persistence slice in #248, whereobservation_record_refis a unique persisted record identity.What
observation_record_ref.IdempotencyConflict.ObservationIdentityConflicterror so operators can distinguish a Commons identity collision from a source idempotency conflict.TDD lineage
2fc3a36b779895d1be2e972bcfa27b44f1964520adds a contract that references the missing identity-conflict behavior and therefore cannot compile on the protected-main implementation.a2fe87dad1ffa429d79aa9ebb5c488688693ea28adds the narrow domain guard and operator-facing error.Compatibility with #248
#248 does not modify
src/longitudinal_observation.rsor this focused contract file. Its PostgreSQL schema already treatsobservation_record_refas the persisted observation identity. This PR closes the in-memory/domain mismatch without copying persistence or TEPP/Gyeot responsibilities.Required evidence before merge
Do not merge until the unchanged exact head passes live Runtime CI, exact line/branch coverage, rustfmt/clippy/rustdoc, security/SAST/SBOM/provenance, zero valid unresolved findings, and qualifying independent non-author review. Never self-approve.
Summary by CodeRabbit