Skip to content

A Review close that would invert a fact's interval is refused - #1315

Merged
WaylandYang merged 2 commits into
deeplethe:devfrom
Aschenbath:feat/reject-inverted-review-closes-1294
Oct 19, 2026
Merged

WaylandYang merged 2 commits into
deeplethe:devfrom
Aschenbath:feat/reject-inverted-review-closes-1294

Conversation

@Aschenbath

Copy link
Copy Markdown
Contributor

Closing a Review fact before its start currently stores an inverted interval and removes the item from review. Reject these closes with HTTP 422 interval_inverted, and show the localized error in all three Review cards.

  • Check both endpoints at their own precision in close_superseded, after locking the live fact row and before any rewrite. This also covers a conflict closed at the new fact's start by default; close_stated and the ingestion callers stay unchanged.
  • Add English and Chinese error text and error toasts for fact, conflict, and violation decisions, making empty_state_span refusals visible too.
  • Exercise all three HTTP routes, default conflict closes, unchanged facts and open queues after refusals, and a successful retry with a later date normalized to its precision.

Validation on Linux x86_64 against local PostgreSQL 16 with pgvector and Poppler (UTOPIA_TEST_REQUIRE_DB=1, UTOPIA_TEST_REQUIRE_PDFTOTEXT=1), on dev 2bcc763:

  • cargo fmt --all --check and cargo clippy --workspace --all-targets -- -D warnings: passed.
  • cargo test --workspace: 1,622 passed, 0 failed, 6 existing opt-in tests ignored.
  • cargo test --workspace --bin utopia-server review_closes_refuse: failed before the fix (route returned 200 {"ok":true}) and passed after it.
  • web/: pnpm build passed, pnpm test 286/286 passed, node --test scripts/bench/lib.test.mjs 15/15 passed.

The commit is DCO signed off.

Closes #1294

Signed-off-by: Aschenbath <Aschenbath@users.noreply.github.com>
@WaylandYang WaylandYang changed the title fix: reject review closes that invert a fact's interval A Review close that would invert a fact's interval is refused Oct 19, 2026

@WaylandYang WaylandYang 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.

Thank you, Aschenbath, clean and well targeted. The check sits in close_superseded under the row lock, compares both ends after truncating them with the same truncate_to #1295 uses, and covers the conflict's default close at the new fact's start, while close_stated and the graph.rs callers stay untouched. The three cards now toast the localized refusal, which also brings today's silent empty_state_span to the surface, and the route test covers all three paths plus the default close, confirms nothing is written and the items stay in their queues, and that a later date still goes through.

Thanks also to @Maya-Kid for the report and the failing cases on #1294.

Merging.

@WaylandYang
WaylandYang merged commit 6ac9632 into deeplethe:dev Oct 19, 2026
6 checks passed
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.

2 participants