* fix(store): restore reuses prior approved verdict; admin detail surfaces content_quality
Live bug on agnes-development: entity 6ba2ee1d…'s v5 submission (third
restore of v1, byte-identical to v1/v2/v4/v6) landed `blocked_llm`
while the other identical-hash siblings landed `approved`. Anthropic
structured output is non-deterministic — same bytes flipped
`content_quality.verdict` pass↔fail across calls. Admin detail page
made the failure look mysterious: only security-findings table
rendered, so a content-quality-only block showed up as
"No findings — model verdict was clean".
Two fixes:
1. Restore endpoint reuses a prior `approved` submission's verdict
when the restored bundle hash matches an existing history entry
AND `reviewed_by_model` matches. Skips the LLM call, stamps the
new submission with the prior verdict + `reused_from_submission_id`
marker. Deterministic + saves Anthropic tokens. Gated on
schedule_async_llm so guardrails-off keeps its existing path.
2. Admin detail template now renders `content_quality.issues` in its
own table + adds an explicit "Blocked but no findings recorded"
notice for the transient-non-determinism case + surfaces the
reuse marker when present.
Reuse falls back to a real LLM call when:
- prior submission's reviewed_by_model doesn't match current (admin
upgraded tier Haiku → Sonnet → Opus)
- prior submission was guardrails-off (no reviewed_by_model)
- no history entry has matching hash
Tests:
- TestRestoreReusesApprovedVerdict::test_restore_of_approved_version_skips_llm_and_reuses_verdict
- TestRestoreReusesApprovedVerdict::test_restore_legacy_v1_falls_back_to_llm
* fix(store): admin detail v# by submission_id + version switcher
Three related fixes surfaced live by a user inspecting submission
47bbc1f5… on localhost where v# rendered as v1 even though current
was v10.
1. Admin queue + admin detail derive submission v# by submission_id
instead of hash. Pre-fix the loop matched first hash-equal entry
in version_history — always v1 when bundles were byte-identical
(which is the common case after the restore-reuse path). Two
call sites updated:
- `src/repositories/store_submissions.py:list_for_admin` (queue
v# column)
- `app/web/router.py:admin_store_submission_detail_page` (detail
page v# chip on each section header)
Same fix pattern as PR #330 for runner / override.
2. New version-switcher card on admin detail page lists every
submission linked to the entity with status + reviewed_by_model +
click-to-jump. Solves the user's secondary ask ("should be a way
to switch different versions on the submission detail").
3. Initial POST now backfills the v1 seed entry's submission_id
right after creating the v1 submission. The helper
`update_history_submission_id` existed but no production code
path called it — so v1 always had submission_id=None and every
"find v# for submission" lookup silently failed for v1.
171 tests green on touched surface.
* release: 0.54.24 — restore reuses prior approved verdict + admin detail content_quality + v# by submission_id (Codex/Live follow-up to #330/#331)
---------
Co-authored-by: ZdenekSrotyr <zdenek.srotyr@keboola.com>