asf-tooling commented on issue #1230:
URL:
https://github.com/apache/tooling-trusted-releases/issues/1230#issuecomment-4409638678
<!-- gofannon-issue-triage-bot v2 -->
**Automated triage** — analyzed at `main@2da7807a`
**Type:** `new_feature` • **Classification:** `actionable` •
**Confidence:** `low`
**Application domain(s):** `voting`
### Summary
Issue #1230 requests a new 'contingent approvals vote system for arbitrary
vote topics,' with the example of opting in to a Tooling audit agent. @sbp
confirmed this was decided in a meeting. The current voting system is entirely
release-centric—all vote casting, tallying, initiation, and resolution code
assumes a release (project_key + version_key) context. This feature would
require new models, routes, writers, and potentially task types to support
votes on arbitrary topics with conditional/contingent logic. The issue body
provides minimal specification, making implementation details highly uncertain.
### Where this lives in the code today
#### `atr/models/tabulate.py` — `Vote, VoteStatus, VoteEmail, VoteDetails`
(lines 25-36)
_extension point_
The core vote value and status enums are generic and could be reused for
arbitrary topic votes.
```python
class Vote(enum.Enum):
YES = "Yes"
NO = "No"
ABSTAIN = "-"
UNKNOWN = "?"
class VoteStatus(enum.Enum):
BINDING = "Binding"
COMMITTER = "Committer"
CONTRIBUTOR = "Contributor"
UNKNOWN = "Unknown"
```
#### `atr/storage/writers/vote.py` — `FoundationCommitter.cast_trusted`
(lines 65-74)
_currently does this_
Current trusted vote casting is tightly coupled to releases (requires
project_key, version_key, release phase checks). A new writer would be needed
for arbitrary topic votes.
```python
async def cast_trusted( # noqa: C901
self,
project_key: safe.ProjectKey,
version_key: safe.VersionKey,
choice: sql.VoteChoice,
comment: str,
fullname: str,
expected_vote_seq: int | None = None,
expected_vote_mode: sql.VoteMode | None = None,
) -> tuple[list[str], str]:
```
#### `atr/tabulate.py` — `binding_vote_passes` (lines 47-48)
_extension point_
The basic vote-passing logic (3 binding +1s, more +1 than -1) could be
reused for arbitrary topic votes.
```python
def binding_vote_passes(binding_plus_one: int, binding_minus_one: int) ->
bool:
return (binding_plus_one >= 3) and (binding_plus_one > binding_minus_one)
```
#### `atr/tasks/vote.py` — `initiate` (lines 195-206)
_currently does this_
Vote initiation is release-specific. A parallel task type and initiation
flow would be needed for arbitrary topic votes.
```python
@checks.with_model(args.Initiate)
async def initiate(task_args: args.Initiate) -> results.Results | None:
"""Initiate a vote for a release."""
try:
return await _initiate_core_logic(task_args)
except VoteInitiationError as e:
log.error(f"Vote initiation failed: {e}")
raise
except Exception as e:
log.exception(f"Unexpected error during vote initiation: {e}")
raise
```
#### `atr/post/vote.py` — `selected_post` (lines 31-38)
_currently does this_
The POST handler for vote casting routes via project_key/version_key,
binding the entire flow to releases.
```python
@post.typed
async def selected_post( # noqa: C901
session: web.Committer,
_vote: Literal["vote"],
project_key: safe.ProjectKey,
version_key: safe.VersionKey,
cast_vote_form: shared.vote.CastVoteForm,
) -> web.WerkzeugResponse:
```
### Where new code would go
- `atr/models/sql.py` — after existing vote-related models (BallotPaper,
VoteChoice, VoteMode)
New SQL models needed: ApprovalTopic (arbitrary vote subject with
contingency conditions), ApprovalBallot (votes cast on topics),
ApprovalContingency (conditions that must be met for approval to take effect).
- `atr/storage/writers/approval.py` — new file
New writer module for creating topics, casting approval votes, and
resolving contingent approvals.
- `atr/get/approval.py` — new file
GET routes for viewing approval topics, their status, and casting
interface.
- `atr/post/approval.py` — new file
POST routes for creating topics and casting contingent approval votes.
- `atr/tasks/approval.py` — new file
Background tasks for approval vote lifecycle (e.g., checking contingency
conditions, notifications).
### Proposed approach
This feature requires building a parallel voting subsystem that is decoupled
from releases. The key architectural decisions are: (1) What constitutes an
'arbitrary vote topic' — likely a new SQLModel table with fields like topic
description, committee scope, contingency conditions, and status. (2) What
'contingent' means — likely votes that only take effect when specified
conditions are met (e.g., 'I approve X if Y also passes'). (3) Authorization
model — who can create topics, who has binding votes.
Given the minimal specification in the issue, the implementation should
start with a design document or RFC specifying: the data model for topics and
contingencies, the UI flow, the vote counting rules (do contingent votes count
toward the 3-binding threshold only when conditions are met?), and integration
points with existing committee membership. The existing `binding_vote_passes`
logic and `Vote`/`VoteStatus` enums can likely be reused, but the storage
layer, routes, and task infrastructure need to be built fresh.
### Open questions
- What exactly does 'contingent' mean in this context — votes conditional on
other votes passing, or votes conditional on external conditions?
- What authorization model applies — can any committer create a vote topic,
or only PMC members?
- Is this committee-scoped (per-project) or foundation-wide?
- What is the 'Tooling audit agent' mentioned as the motivating example, and
what conditions would its opt-in be contingent upon?
- Should this reuse the existing trusted vote / email vote infrastructure,
or be a standalone system?
- Is there a design document or meeting notes from the meeting @sbp
referenced that would clarify requirements?
### Files examined
- `atr/tabulate.py`
- `atr/models/tabulate.py`
- `atr/post/vote.py`
- `atr/storage/writers/vote.py`
- `atr/tasks/vote.py`
- `atr/get/vote.py`
- `atr/get/voting.py`
- `atr/post/resolve.py`
---
*Draft from a triage agent. A human reviewer should validate before merging
any change. The agent did not run tests or verify diffs apply.*
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]