Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
30d1122
Remove preprint release
haroldrubio Jan 15, 2026
fae13eb
Remove preprint process
haroldrubio Jan 15, 2026
7fe70c3
Change post submission process function
haroldrubio Jan 15, 2026
4d4c2fd
Change tests
haroldrubio Jan 15, 2026
07895a9
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Jan 15, 2026
6406213
Remove old test
haroldrubio Jan 15, 2026
55e4f45
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Mar 3, 2026
4aec93d
Merge branch 'master' into fix/arr-preprint-in-post
melisabok Mar 5, 2026
0ab123c
Parameterize post submission
haroldrubio Mar 10, 2026
9f1a738
Call venue invitation builder
haroldrubio Mar 10, 2026
b13b237
Duplicate Venue logic into ARR
haroldrubio Mar 10, 2026
da99720
Update process function
haroldrubio Mar 10, 2026
d3bfd13
Update tests
haroldrubio Mar 10, 2026
0572c67
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Mar 27, 2026
59cb630
Refactor source
haroldrubio Mar 27, 2026
9c7ea9a
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Mar 30, 2026
13a0fae
Fix level of nesting
haroldrubio Mar 30, 2026
5134dbf
Merge branch 'fix/arr-preprint-in-post' of https://github.com/openrev…
haroldrubio Mar 30, 2026
f05db47
Remove process function and fix explanation logic
haroldrubio Apr 3, 2026
811d2ca
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Apr 3, 2026
9e541c8
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Apr 3, 2026
3d3fc38
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Apr 3, 2026
a3456a8
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Apr 6, 2026
07723c3
Remove process function
haroldrubio Apr 7, 2026
1c40b6c
Update invitation schema
haroldrubio Apr 7, 2026
347724d
Move explanation of revisions assertions
haroldrubio Apr 7, 2026
1059204
Add back assertions
haroldrubio Apr 7, 2026
e2005b8
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Apr 8, 2026
f342066
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Apr 9, 2026
ee81cfd
Only keep custom source
haroldrubio Apr 9, 2026
a635ad7
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Apr 10, 2026
bbe439d
Merge branch 'master' into fix/arr-preprint-in-post
celestemartinez Apr 14, 2026
19ef4e4
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Apr 15, 2026
e4a6bf9
Merge branch 'master' into fix/arr-preprint-in-post
haroldrubio Apr 16, 2026
e54da3f
Merge branch 'master' into fix/arr-preprint-in-post
melisabok Apr 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion openreview/arr/arr.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,10 +489,35 @@ def create_submission_stage(self):
replacement=False,
invitation=invitation
)
self._patch_post_submission_invitation()
return stage_value

def create_post_submission_stage(self):
return self.venue.create_post_submission_stage()
self.venue.create_post_submission_stage()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what if you create the Post_Submission invitation here? or pass the process function path as a param?

self._patch_post_submission_invitation()

def _patch_post_submission_invitation(self):
post_submission_id = self.venue.get_post_submission_id()
inv = self.client.get_invitation(post_submission_id)

arr_script = self.invitation_builder.get_process_content('process/post_submission_process.py')

updated_date_processes = []
for dp in inv.date_processes:
updated_dp = dict(dp)
updated_dp['script'] = arr_script
updated_date_processes.append(updated_dp)

inv.date_processes = updated_date_processes

self.client.post_invitation_edit(
invitations=self.venue.get_meta_invitation_id(),
readers=[self.venue_id],
writers=[self.venue_id],
signatures=[self.venue_id],
replacement=False,
invitation=inv
)

def create_submission_revision_stage(self):
self.venue.submission_revision_stage = self.submission_revision_stage
Expand Down
75 changes: 0 additions & 75 deletions openreview/arr/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
arr_metareview_license_task,
arr_metareview_license_task_forum,
arr_metareview_rating_content,
hide_fields_from_public,
hide_fields,
arr_submitted_author_forum,
arr_submitted_author_content,
arr_delay_notification_content,
Expand Down Expand Up @@ -146,12 +144,6 @@ class ARRWorkflow(object):
"order": 14,
"required": False
},
"preprint_release_submission_date": {
"description": "When should submissions be copied over and the opt-in papers be revealed to the public? This should be done several hours (12+ hours) after the submission deadline.",
"value-regex": "^[0-9]{4}\\/([1-9]|0[1-9]|1[0-2])\\/([1-9]|0[1-9]|[1-2][0-9]|3[0-1])(\\s+)?((2[0-3]|[01][0-9]|[0-9]):[0-5][0-9])?(\\s+)?$",
"order": 15,
"required": False
},
"setup_sae_ae_assignment_date": {
"description": "When will both SAE and AE assignments be deployed? This must happen after both assignments are deployed to give SAEs access to the AE assignments.",
"value-regex": "^[0-9]{4}\\/([1-9]|0[1-9]|1[0-2])\\/([1-9]|0[1-9]|[1-2][0-9]|3[0-1])(\\s+)?((2[0-3]|[01][0-9]|[0-9]):[0-5][0-9])?(\\s+)?$",
Expand Down Expand Up @@ -408,64 +400,6 @@ class ARRWorkflow(object):
}


@staticmethod
def _build_preprint_release_edit(client, venue, builder, request_form):
venue_id = venue.id
submission_stage = venue.submission_stage

submission_id = submission_stage.get_submission_id(venue)

hidden_field_names = hide_fields_from_public
committee_members = venue.get_committee(number='${{4/id}/number}', with_authors=True)
note_content = { f: { 'readers': committee_members } for f in hidden_field_names}

# Always hide authors and authorids
author_readers = [venue_id, venue.get_authors_id(number='${{4/id}/number}')]
note_content['authors'] = { 'readers': author_readers }
note_content['authorids'] = { 'readers': author_readers }
for field in hide_fields:
note_content[field] = { 'readers': author_readers }

edit = {
'signatures': [venue_id],
'readers': [venue_id, venue.get_authors_id('${{2/note/id}/number}')],
'writers': [venue_id],
'note': {
'id': {
'param': {
'withInvitation': submission_id,
'optional': True
}
},
'odate': {
'param': {
'range': [ 0, 9999999999999 ],
'optional': True,
'deletable': True
}
},
'signatures': [ venue.get_authors_id('${{2/id}/number}') ],
'readers': ['everyone'],
'writers': [venue_id, venue.get_authors_id('${{2/id}/number}')],
}
}

note_content['_bibtex'] = {
'value': {
'param': {
'type': 'string',
'maxLength': 200000,
'input': 'textarea',
'optional': True
}
}
}

if note_content:
edit['note']['content'] = note_content

return {'edit': edit}

@staticmethod
def _extend_desk_reject_verification(client, venue, builder, request_form):
venue.invitation_builder.set_verification_flag_invitation()
Expand Down Expand Up @@ -600,15 +534,6 @@ def __init__(self, client_v2, venue, configuration_note, request_form_id, suppor
request_form = self.client.get_note(request_form_id)

self.workflow_stages = [
ARRStage(
type=ARRStage.Type.PROCESS_INVITATION,
required_fields=['preprint_release_submission_date'],
super_invitation_id=f"{self.venue_id}/-/Preprint_Release_{venue.submission_stage.name}",
stage_arguments={},
start_date=self.configuration_note.content.get('preprint_release_submission_date'),
process='process/preprint_release_submission_process.py',
build_edit=ARRWorkflow._build_preprint_release_edit
),
ARRStage(
type=ARRStage.Type.PROCESS_INVITATION,
required_fields=['setup_shared_data_date', 'previous_cycle'],
Expand Down
165 changes: 165 additions & 0 deletions openreview/arr/process/post_submission_process.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
def process(client, invitation):
Comment thread
haroldrubio marked this conversation as resolved.
Outdated
import datetime
import openreview
from openreview.stages.arr_content import hide_fields, hide_fields_from_public

domain = client.get_group(invitation.domain)
venue_id = domain.id
submission_venue_id = domain.content['submission_venue_id']['value']
venue_name = domain.content['title']['value']
meta_invitation_id = domain.content['meta_invitation_id']['value']
program_chairs_id = domain.content['program_chairs_id']['value']
submission_name = domain.content['submission_name']['value']
authors_name = domain.content['authors_name']['value']
reviewers_name = domain.content['reviewers_name']['value']
reviewers_submitted_name = domain.content['reviewers_submitted_name']['value']
area_chairs_name = domain.content['area_chairs_name']['value']
senior_area_chairs_name = domain.content['senior_area_chairs_name']['value']

now = openreview.tools.datetime_millis(datetime.datetime.now())
cdate = invitation.cdate

if cdate and cdate > now:
# invitation is in the future, do not process
print('invitation is not yet active', cdate)
return

client_v1 = openreview.Client(
baseurl=openreview.tools.get_base_urls(client)[0],
token=client.token
)

submissions = client.get_all_notes(content={'venueid': submission_venue_id})

def is_preprint(note):
return note.content.get('preprint', {}).get('value') == 'yes'

preprints = []
non_preprints = []
for note in submissions:
if is_preprint(note):
preprints.append(note)
else:
non_preprints.append(note)

print(f'Processing {len(non_preprints)} non-preprint submissions')
print(f'Processing {len(preprints)} preprint submissions')

def post_submission_edit(submission):
updated_note = openreview.api.Note(id=submission.id)
client.post_note_edit(
invitation=invitation.id,
note=updated_note,
signatures=[venue_id]
)

def get_paper_authors_group_id(number):
return f"{venue_id}/{submission_name}{number}/{authors_name}"

def get_committee_readers(number, include_authors=True):
readers = [
program_chairs_id,
f"{venue_id}/{submission_name}{number}/{senior_area_chairs_name}",
f"{venue_id}/{submission_name}{number}/{area_chairs_name}",
f"{venue_id}/{submission_name}{number}/{reviewers_name}"
]
if include_authors:
readers.append(get_paper_authors_group_id(number))
return readers

def get_explanation_of_revisions_readers(submission):
"""
Always replace current-cycle Reviewers with Reviewers/Submitted for this field

If previous_URL exists and author doesn't want new reviewers:
include previous-cycle Reviewers/Submitted
"""
readers = [
program_chairs_id,
f"{venue_id}/{submission_name}{submission.number}/{senior_area_chairs_name}",
f"{venue_id}/{submission_name}{submission.number}/{area_chairs_name}",
f"{venue_id}/{submission_name}{submission.number}/{reviewers_name}/{reviewers_submitted_name}",
get_paper_authors_group_id(submission.number)
]

paper_link = submission.content.get('previous_URL', {}).get('value')
wants_new_reviewers = submission.content.get('reassignment_request_reviewers', {}).get('value', '').startswith('Yes')

if paper_link and not wants_new_reviewers:
paper_forum = paper_link.split('?id=')[-1]
arr_submission_v1 = openreview.tools.get_note(client_v1, paper_forum)
if arr_submission_v1:
v1_domain = arr_submission_v1.invitation.split('/-/')[0]
readers.append(f"{v1_domain}/Paper{arr_submission_v1.number}/{reviewers_name}/{reviewers_submitted_name}")
arr_submission_v2 = openreview.tools.get_note(client, paper_forum)
if arr_submission_v2:
v2_domain = arr_submission_v2.domain
readers.append(f"{v2_domain}/{submission_name}{arr_submission_v2.number}/{reviewers_name}/{reviewers_submitted_name}")

return readers

def release_preprint_submission(submission):
authors_group_id = get_paper_authors_group_id(submission.number)
committee_readers = get_committee_readers(submission.number, include_authors=True)

# Build content with field-level readers
content = {}

# Authors and authorids are always readable only by venue and authors
venue_authors_readers = [venue_id, authors_group_id]
content['authors'] = {'readers': venue_authors_readers}
content['authorids'] = {'readers': venue_authors_readers}

for field in hide_fields:
content[field] = {'readers': venue_authors_readers}

# hide_fields_from_public -> committee_readers (with authors)
for field in hide_fields_from_public:
if field == 'explanation_of_revisions_PDF':
content[field] = {'readers': get_explanation_of_revisions_readers(submission)}
else:
content[field] = {'readers': committee_readers}

# Set _bibtex and odate only if not already set
if submission.odate is None:
content['_bibtex'] = {
'value': openreview.tools.generate_bibtex(
note=submission,
venue_fullname=venue_name,
year=str(datetime.datetime.now().year),
url_forum=submission.forum,
paper_status='under review',
anonymous=True
)
}

# Build the note edit
updated_note = openreview.api.Note(
id=submission.id,
readers=['everyone'],
content=content
)

# Set odate only if not already set
if submission.odate is None:
updated_note.odate = now

client.post_note_edit(
invitation=meta_invitation_id,
readers=[venue_id],
writers=[venue_id],
signatures=[venue_id],
note=updated_note
)

openreview.tools.concurrent_requests(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This seems to be two different types of post_submission invitations so I would try doing that:

  1. Post_Submission: post edits for all the submissions where preprint == No. This can be specified as a source parameter in the same invitation.
  2. Preprint_Post_Submission: post edits for all the submissions where preprint == Yes. This can be specified as the source parameter in the same invitation

@celestemartinez this is something that we discussed yesterday and this is a good case to support it.

  1. specify the source in the invitation.content
  2. process function get the submissions from the source
    3 apply the edits

post_submission_edit,
non_preprints,
desc='arr_post_submission_non_preprints'
)

openreview.tools.concurrent_requests(
release_preprint_submission,
preprints,
desc='arr_post_submission_preprints'
)
Loading