Skip to content

feat(instrument): load exact published release on current main - #98

Closed
seonghobae wants to merge 2 commits into
mainfrom
feat/instrument-release-query-current-main-20260816
Closed

feat(instrument): load exact published release on current main#98
seonghobae wants to merge 2 commits into
mainfrom
feat/instrument-release-query-current-main-20260816

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Superseded by the locked session-start successor and dedicated recovery repair

Close this predecessor without merge.

Fresh evidence immediately before closure:

The three-file #98 diff has no remaining unique landing responsibility:

  1. Its load_published_instrument_release / PublishedInstrumentReleaseSnapshot / fail-closed persisted-manifest reconstruction and the full tests/postgres_instrument_release_query.rs acceptance 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 with SELECT … FOR UPDATE and composes it with persist-backed session start/reload HTTP.
  2. Its tests/postgres_recovery_invariants.rs claim_deadline_at seed-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.
  3. Exact-head reviews on feat(instrument): load exact published release on current main #98 already directed the load toward the locked start successor and the recovery fixture toward test(recovery): preserve inbox claim deadline evidence #177; they also identified stale rustdoc on feat(instrument): load exact published release on current main #98 that the feat(api): start and reload sessions over persist-backed HTTP #232 implementation no longer contains.

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.

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 80a88fef-64f6-4aa7-b708-313a3af7cb7d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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_release so 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/sessions remains #87 + #149 after #164 lands.

View PR

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

cursor Bot pushed a commit that referenced this pull request Aug 16, 2026
Keep the catalog family off protected main until an unchanged reviewed head is integrated, and keep it separate from #149, #150, and #98.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Processing consumption rows now require claim_deadline_at after #81.
Seed the wall-clock deadline and prove binary restore preserves it.

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

  1. The claim_deadline_at recovery seed/assert in tests/postgres_recovery_invariants.rs does 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.
  2. Do not merge this draft in parallel with #180. #164 cherry-picks this unlocked SELECT; #180 is the successor that locks stored publication_state in the same transaction as session insert.
  3. Load rustdoc at src/postgres_instrument_release.rs:318-319 claims some in-memory constructors normalize locale text. InstrumentReleaseManifest::new does the opposite: it rejects trimmed/aliased locale input and stores the exact spelling.
  4. Acceptance tests insert via raw SQL only. There is no persist_instrument_releaseload_published_instrument_release round-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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 UPDATE on stored publication_state in the same transaction as session insert. Prefer #180 over #164, #138, #98, and #196 for that path.
  • Recovery claim_deadline_at landing 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/sessions remains #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.

Open in Web View Automation 

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This claim_deadline_at seed belongs on dedicated recovery PR #177 (8a0db46), which also updates TRACEABILITY / QA-REC-01 / RISK / CHANGELOG. Do not land the #72 repair only through this instrument-load draft, and do not open a third recovery-deadline PR.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant