Skip to content

fix(backend): validate Display start_at must not exceed expires_at in Announcement ($25 bounty proposal) - #21510

Closed
aiwithrajan wants to merge 1 commit into
BasedHardware:mainfrom
aiwithrajan:fix/announcement-display-bounds
Closed

aiwithrajan wants to merge 1 commit into
BasedHardware:mainfrom
aiwithrajan:fix/announcement-display-bounds

Conversation

@aiwithrajan

@aiwithrajan aiwithrajan commented Oct 14, 2026 •

Copy link
Copy Markdown

Description

Validates that Display in backend/models/announcement.py enforces start_at <= expires_at.
Currently, Display normalizes start_at and expires_at to UTC but lacks bounds validation. If start_at is after expires_at, an inverted display window is accepted, which causes temporal schedule anomalies. Furthermore, Announcement.from_dict uses _optional_submodel(Display, display_data) to guard against malformed display configurations; with bounds validation in place, documents with inverted display timestamps are safely caught as ValidationError and dropped rather than causing schedule corruption.

This change:

  1. Adds a model_validator to Display to ensure start_at <= expires_at when both timestamps are specified.
  2. Adds unit tests in backend/tests/unit/test_announcement_display_bounds.py covering valid bounds, equal timestamps, one-sided bounds, ValidationError on inverted dates, and graceful sub-document dropping in Announcement.from_dict.

Test Plan

  • Run unit tests:
    PYTHONPATH=backend python3 backend/tests/unit/test_announcement_display_bounds.py
    Result: 5/5 tests passed in 0.008s.

View guided diff

@Git-on-my-level

Copy link
Copy Markdown
Member

Thanks @aiwithrajan — reviewed and verified. backend/models/announcement.py: the new model_validator(mode="after") on Display only fires when both start_at and expires_at are set and start_at > expires_at, and it runs after _normalize_display_datetimes, so the comparison is always on UTC-normalized values (no naive/aware pitfalls). Inverted display sub-documents read through Announcement.from_dict are caught by the existing _optional_submodel guard and dropped, which matches how this model already tolerates malformed sub-documents (bad enum, bad type, bad datetime) so one bad document can't 500 the announcements list. backend/tests/unit/test_announcement_display_bounds.py: good coverage — valid bounds, equal timestamps, one-sided bounds, the ValidationError message, and the from_dict drop path. I ran this suite plus the sibling announcement suites locally: all green. One behavior note for the record rather than a change request: any stored document that already has an inverted display window will now have its display sub-document dropped and fall back to get_effective_display's unbounded default (show immediately, no expiry) instead of a broken-but-bounded window. That seems like the right default and is consistent with the model's existing malformed-subdoc policy, but maintainers should be aware legacy docs with inverted windows change visible behavior. Nice, tight contribution.


by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with need human response.

@Git-on-my-level Git-on-my-level added positive-signal Automation verified a genuine fix/quality contribution backend Backend Task (python) labels Oct 14, 2026
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Hey @aiwithrajan 👋

Thank you so much for taking the time to contribute to Omi! We truly appreciate you putting in the effort to submit this pull request.

After careful review, we've decided not to merge this particular PR. Please don't take this personally — we genuinely try to merge as many contributions as possible, but sometimes we have to make tough calls based on:

  • Project standards — Ensuring consistency across the codebase
  • User needs — Making sure changes align with what our users need
  • Code best practices — Maintaining code quality and maintainability
  • Project direction — Keeping aligned with our product principles and locked invariants

Before your next PR, please skim:

  • PRODUCT.md — product north star
  • Product invariants — locked rules (shared chat, memory tiers, agent control plane, integrations, brand)

If this was declined for direction or taste, maintainers should cite an invariant ID or open a proposed one — ask if that citation is missing.

Your contribution is still valuable to us, and we'd love to see you contribute again in the future! If you'd like feedback on how to improve this PR or want to discuss alternative approaches, please don't hesitate to reach out.

Thank you for being part of the Omi community!

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

Labels

backend Backend Task (python) positive-signal Automation verified a genuine fix/quality contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants