Skip to content

Conversation

@vcarl
Copy link
Member

@vcarl vcarl commented Dec 10, 2025

  • Add a "require majority" button that removes the the automatic execution vote threshold, and instead executes the resolution with a plurality of votes.
  • Slow down resolution timer. Starting at 24hr is too fast, too few votes to get it down to immediate execution.
    • Extend the vote lifespan, defaulting to 36 hours.
    • Shorten per-vote acceleration, from 8hr to 4hr. This means after 4 votes, the default behavior will execute after 36hr - (4vote * 4hr) = 20hr
  • Add a second-tier "escalate" that requires a minimum time after escalation, then executes the majority vote.
  • Post result as a new message, forward it to #mod-log
  • Disable voting when resolution is executed, but keep buttons.

vcarl and others added 8 commits December 17, 2025 13:55
- simple (default): Early resolution when any option hits quorum (3 votes)
- majority: No early resolution; voting stays open until timeout, plurality wins

Changes:
- Add voting_strategy column to escalations table
- Add shouldTriggerEarlyResolution() to check strategy before triggering
- Update handlers to set strategy based on escalation level (0=simple, 1+=majority)
- Update UI to show strategy-specific status and hide "Require majority" when active
- Simplify escalationResolver since both strategies resolve identically on timeout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents Discord API mocking challenges, time-dependent behavior,
multi-actor workflows, and proposes solutions including pure logic
extraction and time abstraction.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update test expectations for the new timeout formula:
max(0, 36 - 4 * (voteCount - 1))

- 0 votes = 40h (was 24h)
- 1 vote = 36h (was 16h)
- 2 votes = 32h (was 8h)
- 3 votes = 28h (was 0h)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All these were implicitly testing the same voting logic, but with various layers of indirection in pulling out the output. Not helpful, not worth keeping
Replace dynamic timeout calculation on every poll with a stored
scheduled_for timestamp. The column is updated whenever votes change,
making the resolver query a simple indexed lookup instead of requiring
vote tallies for every pending escalation.

- Add migration with backfill for existing pending escalations
- Add calculateScheduledFor, updateScheduledFor, getDueEscalations
- Update vote/escalate handlers to persist new scheduled time
- Simplify resolver to query due escalations directly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Simplify function signatures by passing the escalation object instead
of individual fields. This makes the code cleaner and allows direct
use of scheduled_for for Discord timestamps instead of recalculating.

- buildVoteMessageContent now takes (modRoleId, escalation, tally, votingStrategy)
- buildConfirmedMessageContent now takes (escalation, resolution, tally)
- Update all call sites in handlers.ts
- Update tests with mock escalation helper

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add getDisabledButtons helper to disable vote buttons on resolution
- Handle edge case where user left server or deleted account
- Forward resolution notices to mod log channel
- Clean up resolution message format with consistent timestamp display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vcarl
Copy link
Member Author

vcarl commented Dec 19, 2025

Screenshot 2025-12-19 at 11 52 04 AM

yayy

@vcarl vcarl marked this pull request as ready for review December 20, 2025 15:32
@vcarl vcarl requested a review from Copilot December 20, 2025 15:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request enhances the escalation voting system with improved timing, majority voting support, better resolution notifications, and optimized scheduling. The changes introduce a database-backed scheduled resolution time that updates dynamically as votes are cast, and adds a two-tier voting system (simple vs majority).

Key changes:

  • Added scheduled_for column to track computed resolution timestamps, eliminating the need to recalculate on every poll
  • Extended default voting period from 24hr to 36hr with slower acceleration (4hr per vote instead of 8hr)
  • Implemented majority voting strategy that requires timeout before execution (no early resolution)
  • Added resolution result messages that forward to mod-log channel
  • Disabled voting buttons after resolution while keeping them visible

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
migrations/20251217145416_add_scheduled_for.ts Adds scheduled_for column to store precomputed resolution timestamps and backfills existing escalations
migrations/20251209140659_add_voting_strategy.ts Adds voting_strategy column to support simple vs majority voting modes
app/models/escalationVotes.server.ts Adds calculateScheduledFor, updateScheduledFor, getDueEscalations, and updateEscalationStrategy functions; updates createEscalation to set initial scheduled time
app/helpers/modResponse.ts Defines voting strategy constants and types
app/helpers/escalationVotes.ts Updates timeout formula from 24 - 8*voteCount to 36 - 4*voteCount for slower acceleration
app/helpers/escalationVotes.test.ts Updates test cases to reflect new timeout formula
app/db.d.ts Adds scheduled_for and voting_strategy columns to Escalations type definition
app/commands/escalate/voting.ts Adds shouldTriggerEarlyResolution function to handle strategy-based early resolution logic
app/commands/escalate/strings.ts Updates message builders to accept Escalation objects, display strategy-specific status messages, and show "Require majority vote" button conditionally
app/commands/escalate/strings.test.ts Adds createMockEscalation helper and updates tests for new function signatures
app/commands/escalate/handlers.ts Updates vote handler to recalculate scheduled_for after votes; implements re-escalation for majority voting; uses new strategy-aware resolution logic
app/discord/escalationResolver.ts Adds getDisabledButtons function; updates resolution to use getDueEscalations, post result messages, forward to mod-log, and handle user-gone scenarios
notes/*.md Documentation for scheduling refactor, voting strategy implementation, and testing challenges

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +24 to +25
// Formula: timeout = max(0, 36 - 4 * (voteCount - 1))
// 0 votes = 40h, 1 vote = 36h, 2 votes = 32h, 3 votes = 28h
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

The comment on line 24 describes the formula as max(0, 36 - 4 * (voteCount - 1)) and claims "0 votes = 40h", but the actual implementation uses max(0, 36 - 4 * voteCount) which gives "0 votes = 36h". This comment is incorrect and should be updated to match the implementation.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

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

fair but meh

@github-actions
Copy link

github-actions bot commented Dec 20, 2025

Preview environment removed

The preview for this PR has been cleaned up.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@github-actions
Copy link

github-actions bot commented Dec 20, 2025

✅ E2E Tests Passed

3 passed

View Report · View Run

Tested against: https://214.euno-staging.reactiflux.com

@vcarl vcarl merged commit 8a0e9ee into main Dec 20, 2025
6 checks passed
@vcarl vcarl deleted the vc-fix-votes branch December 20, 2025 16:23
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