Skip to content

Adds ability to have consequences to Events#75

Merged
bdc34 merged 8 commits into
developfrom
bdc34/SUBMISSION-5-add-consequences
Jun 12, 2026
Merged

Adds ability to have consequences to Events#75
bdc34 merged 8 commits into
developfrom
bdc34/SUBMISSION-5-add-consequences

Conversation

@bdc34

@bdc34 bdc34 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Add Event.consequences() for explicit follow-on events; auto-hold oversize on finalize

Replace the removed @bind/Rule/Callback choreography with an explicit,
traceable mechanism for events that imply other events.

Event base class (domain/event/base.py):

  • consequences(submission) -> List[Event]: follow-on events an event implies,
    given the post-projection state. Default returns none.
  • get_consequences(): wraps consequences() and enforces that every emitted
    type is declared in the new CONSEQUENCE_TYPES class attribute, so the static
    graph cannot silently rot.
  • CONSEQUENCE_TYPES: frozenset of event types an event may emit, declared
    statically so the type graph can be checked for cycles.

Save loop (implementations/legacy_implementation/init.py):

  • _save() now drives a work-queue instead of a flat loop. Consequences are
    applied and persisted in the same locked session/transaction, inserted at
    the front of the queue so a consequence applies to the state immediately
    after its parent.

First use case (domain/event/init.py):

  • FinalizeSubmission declares CONSEQUENCE_TYPES = {AddHold} and emits a
    SOURCE_OVERSIZE AddHold when the submission is oversize and unwaived.
    Status stays SUBMITTED; the derived is_on_hold property reports the hold
    (this model has no ON_HOLD status).

Tests:

  • test_consequences_graph.py: asserts the production consequence type-graph is
    acyclic (so chains always terminate) and that all declared types are Events.
    Includes a detector test with a self-referencing throwaway Event to prove
    find_cycle fires. Test-defined Event subclasses are excluded from the
    production enumeration since pydantic keeps them alive in subclasses().
  • test_finalize_oversize_hold.py (domain): unit-tests the oversize/normal/
    waiver branches of FinalizeSubmission.consequences().
  • test_finalize_oversize_hold.py (ui): end-to-end finalize of an oversize
    submission applies the hold and persists the AddHold in event history.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Update: This PR is/was stacked on #73 but that was merged to develop. So this is just a PR to merge to develop.

bdc34 and others added 2 commits June 9, 2026 17:03
Detect oversize submissions at file-upload time and persist the flag to the
classic arXiv_submissions.is_oversize column. The flag is a soft gate: the
submitter is warned but can still proceed. The auto-hold effect at finalize is
a later phase.

Adds policy module:
- submit_ce/domain/size_limits.py: SizeLimits (three per-archive limits,
  default 50 MB) and a pure check_sizes() decision function. Enforces the
  total and per-file uncompressed limits, matching legacy check_sizes;
  compressed limit defined but not enforced. OVERRIDE/MAXSIZE env escapes.
- ui/config.py: MAX_UNCOMPRESSED_TOTAL_KB / _PER_FILE_KB / _COMPRESSED_KB.

Adds detection in the file `Event`:
- Submission.is_oversize: flag set when files change.
- UploadArchive/UploadFiles/RemoveFiles evaluate the authoritative
  workspace against the limits in execute(), persist the result, and apply
  it in project() (deterministic on replay); RemoveAllFiles clears it.
- SubmitApi.get_size_limits() (defaults) + Flask override reading config,
  so the domain event reaches limits through the api boundary.
- upload controller flashes an oversize warning.

Adds submit 1.5 backward-compatible DB projection:
- update_from_submission writes arXiv_submissions.is_oversize; to_submission
  reads it back so rows round-trip.

Tests: size_limits unit tests, event detection tests, and UI/DB
persistence tests (column write + domain round-trip).

Co-Authored-By: Claude Opus 4.8 (1M context)
Adds auto-hold oversize on `FinalizeSubmission`

Event base class (domain/event/base.py):
- consequences(submission) -> List[Event]: follow-on events an event implies,
  given the post-projection state. Default returns none.
- get_consequences(): wraps consequences() and enforces that every emitted
  type is declared in the new CONSEQUENCE_TYPES class attribute, so the static
  graph cannot silently rot.
- CONSEQUENCE_TYPES: frozenset of event types an event may emit, declared
  statically so the type graph can be checked for cycles.

Save loop (implementations/legacy_implementation/__init__.py):
- `_save()` now drives a work-queue instead of a flat loop. Consequences are
  applied and persisted in the same locked session/transaction, inserted at
  the front of the queue so a consequence applies to the state immediately
  after its parent.

First use case (domain/event/__init__.py):
- FinalizeSubmission declares CONSEQUENCE_TYPES = {AddHold} and emits a
  SOURCE_OVERSIZE AddHold when the submission is oversize and unwaived.
  Status stays SUBMITTED; the derived is_on_hold property reports the hold
  (this model has no ON_HOLD status).

Tests:
- test_consequences_graph.py: asserts the production consequence type-graph is
  acyclic therefore chains always terminate and that all declared types are Events.
  Includes a detector test with a self-referencing throwaway Event to prove
  find_cycle fires.
- test_finalize_oversize_hold.py (domain): unit-tests the oversize/normal/
  waiver branches of FinalizeSubmission.consequences().
- test_finalize_oversize_hold.py (ui): end-to-end finalize of an oversize
  submission applies the hold and persists the AddHold in event history.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread submit_ce/domain/size_limits.py Outdated
limits: Optional[SizeLimits] = None) -> bool:
"""Return ``True`` if the submission exceeds any enforced limit."""
return bool(check_sizes(total_uncompressed, per_file_sizes,
primary_category, limits))

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 throws away all the well computed reasons.
Is there a way to incorporate the reasons in the message "flashed"?

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

Looks very good to me!!!

bdc34 added 4 commits June 12, 2026 14:12
- Moved default size limits to SIZE_LIMIT_POLICY for more visibility
- Changed to all bytes instead of kb
- Initial change to oversize message
- Saved `OversizeReason` instances on upload `Event`
- Changes check_sizes to not have a default `limits` to avoid incorrect use
- Changed UploadFiles and UploadArchive to only handle added files for size
  limit check.
- Updated tests.

Claude assisted
@bdc34 bdc34 merged commit c6c727f into develop Jun 12, 2026
1 check passed
@bdc34 bdc34 deleted the bdc34/SUBMISSION-5-add-consequences branch June 12, 2026 18:54
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