feat(instrument): load exact published release on current main - #98
feat(instrument): load exact published release on current main#98seonghobae wants to merge 2 commits into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
There was a problem hiding this comment.
Stale comment
Landing vehicle
No blocking defect found in the published-release load itself. Prefer #164 for the start-from-store path: it cherry-picks this load and composes
start_created_assessment_session_from_stored_releaseso a stale in-memory Published object cannot insert after the stored release is suspended.Do not merge this PR in parallel with #164. Independent last-push review is still required on #164. HTTP
POST /v1/sessionsremains #87 + #149 after #164 lands.Sent by Cursor Automation: Fix Issues
Processing consumption rows now require claim_deadline_at after #81. Seed the wall-clock deadline and prove binary restore preserves it.
seonghobae
left a comment
There was a problem hiding this comment.
Verdict: COMMENT
Reviewed exact HEAD 31116df9c65f73588183263a020500ca28cd2395 against base a7637351be8f0f90c12651d3bcafd959bc52ac81. CodeRabbit GitHub skipped this draft; coderabbit auth login --agent timed out here, so this is a direct HEAD read of the three-file diff. Do not treat this as approval. Independent last-push review is still required.
Blocking defects
None in load_published_instrument_release. The published-only load fails closed on non-canonical caller identity, exact locale mismatch, non-published state, and reconstruct-through-InstrumentReleaseManifest::new plus field-identity recheck. It does not recompute psychometric evidence.
Important
- The
claim_deadline_atrecovery seed/assert intests/postgres_recovery_invariants.rsdoes not belong on this instrument-load PR. Dedicated landing vehicle is #177 (8a0db46), which also updates TRACEABILITY / QA / RISK / CHANGELOG. This commit is a current-main CI unblock after #81; do not land recovery evidence only here, and do not open a third recovery-deadline PR. - Do not merge this draft in parallel with #180. #164 cherry-picks this unlocked
SELECT; #180 is the successor that locks storedpublication_statein the same transaction as session insert. - Load rustdoc at
src/postgres_instrument_release.rs:318-319claims some in-memory constructors normalize locale text.InstrumentReleaseManifest::newdoes the opposite: it rejects trimmed/aliased locale input and stores the exact spelling. - Acceptance tests insert via raw SQL only. There is no
persist_instrument_release→load_published_instrument_releaseround-trip. Column lists currently match; keep that gap on the start-from-store PR, not as a reason to widen this one.
Review questions
Does claim_deadline_at belong here? No. Keep it on dedicated recovery PR #177. #81 made processing rows require a non-null wall-clock deadline, so the old #72 fixture cannot insert. That is a recovery-acceptance repair, not published-release load.
Does load need READ COMMITTED like persist? No. Persist calls require_read_committed because insert-then-classify must observe a concurrent unique-key winner. Load is one SELECT ... WHERE release_ref = $1 on GenericClient. Isolation on that read does not close the suspend-after-load race; #180 must SELECT ... FOR UPDATE publication state in the same transaction as the session insert.
Does locale validation match the persisted contract? Yes. valid_exact_locale is locale.trim() == locale plus the same subtag grammar as instrument::valid_locale ([A-Za-z]{2,8}(-[A-Za-z0-9]{1,8})*). That matches InstrumentReleaseManifest::new and instrument_release_locale_format_check. Caller locale is not normalized. Stored locale is compared by exact string, then reconstructed; a constructor that trimmed or rewrote a field fails as InvalidStoredValue. en-us vs en-US is LocaleMismatch, not a silent fallback.
Next purchaser-facing product gap after this load exists: start a Created session from the stored Published locale-matched snapshot while locking publication_state in the same transaction (start_created_assessment_session_from_stored_release on #180). Until that lands, a stale in-memory Published object can still insert after the stored release is suspended. HTTP POST /v1/sessions remains #149 after #180. Catalog-from-store listing is #193 and is not the purchaser start path.
Prefer #180 for locked load+start. Prefer #177 for claim-deadline recovery. Keep this draft parked. Never self-approve.
| 'consumer_recovery_alpha', 'dependency_recovery_alpha', 'tenant_recovery_alpha', | ||
| 'event_dependency_alpha', 'consumption_recovery_alpha', 'effect_recovery_alpha', | ||
| 'processing', 7, 12000, 13000, NULL, NULL | ||
| 'processing', 7, 12000, 13000, clock_timestamp() + INTERVAL '1 hour', NULL, NULL |
There was a problem hiding this comment.
This claim_deadline_at seed is a recovery-acceptance repair after #81, not published-release load. Processing rows now require a non-null wall-clock deadline (integration_consumption_claim_deadline_shape), so the old #72 fixture cannot insert.
Do not land this on the instrument-query PR. Dedicated vehicle is #177 (8a0db46), which also records the schema-level vs ADR-0017 RPO/RTO distinction in TRACEABILITY / QA / RISK / CHANGELOG. Keep the exact source-vs-restored timestamp equality; do not weaken it to IS NOT NULL only.
| /// [`InstrumentReleaseManifest::new`] before they leave the persistence boundary, so | ||
| /// malformed or non-canonical persisted evidence fails closed instead of being served. | ||
| /// This boundary intentionally requires the caller's locale spelling to already be | ||
| /// canonical even though some in-memory constructors normalize locale text. It does |
There was a problem hiding this comment.
This rustdoc is wrong. InstrumentReleaseManifest::new does not normalize locale text: it rejects locale.trim() != locale and stores the exact spelling (src/instrument.rs around the valid_locale guard). The load path matches that persist contract (valid_exact_locale + exact stored-string compare + reconstruct identity recheck). Say that. Do not document a silent-normalization contrast that the in-memory constructor does not implement.
There was a problem hiding this comment.
Review (HEAD 31116df)
No blocking defect in load_published_instrument_release. The published-only load fails closed on non-canonical caller identity, exact locale mismatch, non-published state, and reconstruct-through-InstrumentReleaseManifest::new plus field-identity recheck. It does not recompute psychometric evidence.
Do not merge this draft.
Queue
- Start-from-store landing is #180 (
cca5192):SELECT … FOR UPDATEon storedpublication_statein the same transaction as session insert. Prefer #180 over #164, #138, #98, and #196 for that path. - Recovery
claim_deadline_atlanding is #177 (8a0db46). The second commit here duplicates that fixture repair without the docs/evidence binding. Keep #177; do not bury #72 evidence in this PR. - Catalog-from-store listing remains #193. Instrument catalog HTTP remains #165. In-process
POST /v1/sessionsremains #149 after #180.
Residuals
- Rustdoc claims in-memory constructors normalize locale text. They do not; they fail closed. See inline.
- Acceptance tests insert via raw SQL only. Persist→load round-trip belongs on the start-from-store PR, not a third load PR.
Purchaser next action
Keep this draft parked. After exact-head Runtime CI on #180 and an independent last-push review, start Created sessions with start_created_assessment_session_from_stored_release so a suspended stored release cannot insert. Then wire HTTP POST /v1/sessions (#149) to that locked helper. For restore of processing inbox rows, use #177.
Never self-approve. Independent last-push review is still required on #180 and #177.
Sent by Cursor Automation: Fix Issues
| /// [`InstrumentReleaseManifest::new`] before they leave the persistence boundary, so | ||
| /// malformed or non-canonical persisted evidence fails closed instead of being served. | ||
| /// This boundary intentionally requires the caller's locale spelling to already be | ||
| /// canonical even though some in-memory constructors normalize locale text. It does |
There was a problem hiding this comment.
This rustdoc says some in-memory constructors normalize locale text. InstrumentReleaseManifest::new and instrument::valid_locale reject trimmed or aliased tags and store the exact spelling. The load boundary is stricter only because it also rejects a caller locale that is not already canonical. Say that, instead of implying a silent normalize path exists.
| calibration_reference, norm_version_ref, narrative_version_ref, \ | ||
| consent_requirement_refs, intended_use_ref, limitations_ref, content_digest, \ | ||
| publication_state, created_at_unix_ms \ | ||
| FROM instrument_release WHERE release_ref = $1", |
There was a problem hiding this comment.
This is an unlocked SELECT by release_ref. Isolation on this read does not close the suspend-after-load race. Do not treat this draft as the start-from-store landing vehicle. Prefer #180, which locks stored publication_state in the same transaction as session insert.
| 'consumer_recovery_alpha', 'dependency_recovery_alpha', 'tenant_recovery_alpha', | ||
| 'event_dependency_alpha', 'consumption_recovery_alpha', 'effect_recovery_alpha', | ||
| 'processing', 7, 12000, 13000, NULL, NULL | ||
| 'processing', 7, 12000, 13000, clock_timestamp() + INTERVAL '1 hour', NULL, NULL |


Superseded by the locked session-start successor and dedicated recovery repair
Close this predecessor without merge.
Fresh evidence immediately before closure:
31116df9c65f73588183263a020500ca28cd2395main:a7637351be8f0f90c12651d3bcafd959bc52ac81c7b45145c9b693951fae498e0779d58cbe170f868a0db4611a684285185f9edadf086a1808444ab9The three-file #98 diff has no remaining unique landing responsibility:
load_published_instrument_release/PublishedInstrumentReleaseSnapshot/ fail-closed persisted-manifest reconstruction and the fulltests/postgres_instrument_release_query.rsacceptance suite are present on feat(api): start and reload sessions over persist-backed HTTP #232. feat(api): start and reload sessions over persist-backed HTTP #232 strengthens the load by locking the stored release withSELECT … FOR UPDATEand composes it with persist-backed session start/reload HTTP.tests/postgres_recovery_invariants.rsclaim_deadline_atseed-and-exact-restore assertion is the same recovery repair carried by test(recovery): preserve inbox claim deadline evidence #177, where the repository also binds that evidence to the recovery documentation/traceability lane.Do not transfer #98 checks or reviews to either successor. #232 and #177 remain Draft and must each satisfy their own unchanged exact-head CI/security/coverage/review gates before merge.