MOPC-App/docs/unified-architecture-redesign/13-open-questions-and-gover...

17 KiB

Open Questions & Governance

Overview

This document tracks all design decisions — resolved and remaining — and defines the governance process for the redesign. Resolved decisions are numbered for reference. Remaining questions are prioritized (P1 = must resolve before implementation, P2 = can resolve during implementation).


Resolved Decisions

# Decision Resolution Resolved By
1 Winner count per category Top N (configurable, default 3). All projects ranked within category. Podium UI for top 3. Cross-category comparison view. User Q&A
2 Score model for final winners Jury 3 live scores only for final winner determination. All-jury composite rankings available in reports/analytics. Configurable between "Jury 3 only" and "Jury 3 + audience blend" per competition. User Q&A
3 Cross-jury visibility Fully independent during active evaluation — no cross-jury score visibility. During Live Finals (R7) and Deliberation (R8), prior jury scores/feedback/notes visible to Jury 3 if admin enables (showPriorJuryData toggle). All cross-jury data available in reports section for internal analytics. User Q&A
4 Confirmation model Deliberation IS the confirmation — no separate WinnerProposal → jury sign-off → admin approval. Deliberation voting serves as jury agreement. Replaces "all jury agree + admin approval" from original flow spec. User Q&A
5 Deliberation modes Two admin-configurable modes: SINGLE_WINNER_VOTE (each juror picks one winner) and FULL_RANKING (ordinal 1st, 2nd, 3rd... aggregated via Borda count). User Q&A
6 Deliberation scope Separate per category (Startup and Concept deliberations are independent sessions). No deliberation for special awards — awards decided by their own jury/judge mechanism. User Q&A
7 Tie-breaking Multiple methods supported: runoff vote (new vote with tied projects only), admin tie-break (admin decides between tied), admin override (override entire result). All configurable per deliberation session. User Q&A
8 Post-deliberation flow Admin reviews final deliberation result → locks → ResultLock snapshot created. Unlock requires super-admin with mandatory reason. User Q&A
9 Soft-cap buffer Default +10 over the soft cap. Configurable per JuryGroup via softCapBuffer field. User Q&A
10 Startup/concept ratio Suggestive bias only (not deterministic). Disclosed to judges. Judges see a note like "You have been assigned primarily Startup projects based on your preference." User Q&A
11 Mode A pull-out Admin-confirmed (routingConfirmationMode: ADMIN_CONFIRMED). Admin must review and approve which projects are pulled from the main pool into the award pool. User Q&A
12 File promotion authority Team lead and admin can promote mentor workspace files to official submissions. Mentor can promote IF admin enables it per competition. User Q&A
13 Invite pre-assignment Both modes supported: AssignmentIntent (intent at invite time, honored by algorithm) and direct admin assignment. User Q&A
14 Jury absence handling Quorum fallback with participant status types: REQUIRED, ABSENT_EXCUSED, REPLACED, REPLACEMENT_ACTIVE. Absent-excused don't count toward quorum. Admin can replace juror or mark as excused. User Q&A
15 Result unlock Super-admin only, mandatory reason. Creates ResultUnlockEvent with audit trail. User Q&A
16 Jury naming Custom labels per program. JuryGroup has a label field (e.g., "Jury 1", "Selection Panel", "Live Finals Jury"). User Q&A
17 Judge onboarding self-service Judges CAN adjust their cap and category ratio preference during onboarding. Admin-configurable toggle (allowOnboardingSelfService) to enable/disable per JuryGroup. Flow spec + Q&A
18 AI ranked shortlist AI generates recommended ranked shortlist per category at the end of EVERY evaluation round (Jury 1, Jury 2, and any award evaluation). Admin can always override. Flow spec + Q&A
19 Audience vote totals Shown to Jury 3 during deliberation phase. Configurable reveal timing (real-time, after jury vote, at deliberation). Flow spec + Q&A
20 Assignment intent lifecycle Full lifecycle tracking: PENDING → HONORED (algorithm matched) / OVERRIDDEN (admin changed) / EXPIRED (round closed) / CANCELLED (removed). All terminal states immutable. See 04-jury-groups-and-assignment-policy.md. Gap analysis
21 Submission bundle state REJECTED — Per-file tracking with SubmissionWindow enforcement is simpler than a formal SubmissionBundle entity. Completeness is derived from slot requirements vs. uploaded files. See Rejected Alternatives below. Gap analysis
22 Purpose keys for analytics Optional Round.purposeKey: String? for analytics grouping (e.g., "jury1_selection", "semifinal_docs"). NOT a new enum — purely semantic. RoundType + label is sufficient for routing; purposeKey is for cross-competition reporting only. Gap analysis
23 Enhanced audit with before/after state DecisionAuditLog.details JSON field already supports before/after state. Convention: include { before: {...}, after: {...} } structure for all override actions. No new DB fields needed — documented as convention. Gap analysis

Rejected Alternatives

Design concepts from the Codex architecture plan that were evaluated and rejected in favor of simpler approaches:

# Concept Source Rejection Rationale
R1 SubmissionBundle entity Codex docs Added complexity without benefit. Per-file tracking with SubmissionWindow + slot requirements achieves the same completeness tracking. Deriving bundle state from required slots - uploaded files is simpler than maintaining a separate state machine.
R2 FinalConfirmation as separate step Codex docs Merged into Deliberation per Decision #4. Deliberation voting IS the confirmation — a separate WinnerProposal → jury sign-off → admin approval flow added unnecessary ceremony. Admin reviews and locks the deliberation result directly.
R3 Purpose Keys as enum Codex docs Made optional String? instead of enum (Decision #22). A fixed enum would require schema migration for each new analytics category. Free-text purposeKey with conventional values is more flexible.
R4 Jury-Stage binding Codex docs JuryGroups are independent entities linked to rounds via roundId, not bound to stages. This allows a jury to be reused across competitions and rounds without schema changes.

Ambiguity Log

Design decisions where both approaches were viable. Documenting the trade-off for future reference:

# Ambiguity Decision Trade-Off
A1 Cap enforcement: strict vs. flexible 3-mode system (HARD/SOFT/NONE) More complex than binary on/off, but covers all real-world scenarios. SOFT mode with buffer is the common case.
A2 Cross-jury data visibility: always vs. configurable Configurable per round via showPriorJuryData Default OFF prevents bias, but some programs want continuity. Toggle gives admin control.
A3 Deliberation mode: single vs. dual Both modes supported (SINGLE_WINNER_VOTE / FULL_RANKING) Two code paths to maintain, but programs have genuinely different needs. Borda count for detailed ranking, simple vote for quick decisions.
A4 Document mutability: immutable vs. admin-replaceable Admin can replace with full provenance tracking Trades simplicity for flexibility. Provenance chain (replacedById, audit log) ensures accountability.

Remaining P1 Questions (Before UI/Router Refactor)

These must be resolved before starting Phase 5 (Admin Control Plane + Participant UX):

P1-1: Mentoring Scope

Question: Is mentoring available only to finalists, or configurable to include semi-finalists?

Options:

  • A) Finalists only (simplest, matches current flow)
  • B) Configurable via MentoringConfig.eligibility enum: FINALISTS_ONLY | SEMIFINALISTS_AND_ABOVE | CONFIGURABLE

Impact: Affects who sees the "Request Mentor" toggle and when mentor assignment runs.

Current leaning: The MentoringConfig already has an eligibility field with options. Implement B for flexibility.


P1-2: Document Mutability After Lock

Question: Can admins replace locked (read-only) submissions from prior rounds?

Options:

  • A) No — once a round's docs are locked, they're immutable for everyone
  • B) Yes — admin can replace with full provenance (sourceType: ADMIN_REPLACEMENT)

Impact: Affects document lifecycle rules and audit requirements.

Current leaning: B — admin override everywhere is a guiding principle. Provenance tracking ensures accountability.


P1-3: Audience Reveal Timing

Question: Are audience vote totals visible to Jury 3 in real time during the live event, or only when deliberation begins?

Options:

  • A) Real-time (jury sees audience votes as they come in)
  • B) After jury vote (jury submits their scores first, then audience results revealed)
  • C) At deliberation start (audience results shown when deliberation session opens)
  • D) Configurable via LiveFinalConfig.audienceRevealTiming

Impact: Affects whether audience votes can bias Jury 3 scoring.

Current leaning: D — make it configurable. Default to C (at deliberation start) to prevent audience bias on jury scores.


Remaining P2 Questions (Can Resolve During Implementation)

P2-1: Reporting Visibility

Question: Are per-jury compliance reports (assignment coverage, evaluation completion, etc.) visible to all program admins or super-admin only?

Impact: Affects report page access control.


P2-2: Override Transparency

Question: Which override details are visible to jury users? For example, if admin overrides a judge's assignment, does the judge see "Admin assigned this project to you" or just the project appearing?

Impact: Affects jury dashboard messaging.


P2-3: Notification Triggers

Question: What exact round transitions trigger applicant email notifications? (e.g., "You've advanced to the semi-finals", "Your submission window is open", "You've been selected as a finalist")

Impact: Affects notification service configuration.


P2-4: CSV Bulk Invite

Question: What columns should the CSV bulk invite format include? Current thinking: name, email, role, juryGroupLabel, roundLabel, preAssignmentMode (INTENT | DIRECT), maxProjects, categoryBias.

Impact: Affects invite import service.


Delivery Governance

Weekly Architecture Sync

  • Who: Backend lead, frontend lead, product owner, ops
  • When: Weekly, 30 minutes
  • Agenda: Phase progress, blockers, upcoming decisions, contract drift review

Phase Gate Reviews

Each phase completion triggers a review:

  1. Deliverables checklist reviewed
  2. Release gate criteria verified (see 12-observability-and-release-gates.md)
  3. Test results reviewed
  4. Any outstanding P1 questions flagged
  5. Sign-off from architecture owner and product owner

No Silent Contract Drift

After Phase 0 (Contract Freeze), any change to the following requires explicit review:

Change Type Approval Required
Prisma model addition or field change Architecture owner
Zod config schema modification Architecture owner
RoundType enum change Architecture owner + product owner
tRPC procedure signature change Architecture owner
Assignment policy behavior change Architecture owner + product owner
New feature flag addition Architecture owner

Changes are NOT blocked — they require documentation (what changed, why, impact) and sign-off.

Evidence Package Template

Each phase gate review includes:

Phase [X] Evidence Package
- Date: YYYY-MM-DD
- Phase: [name]
- Status: PASS / CONDITIONAL PASS / FAIL

Deliverables:
- [ ] [deliverable 1] — status, link to PR/commit
- [ ] [deliverable 2] — status

Test Results:
- Unit: X/X passing
- Integration: X/X passing
- E2E: X/X passing

Release Gate: [A/B/C/D/E/F]
- [ ] Criterion 1 — status
- [ ] Criterion 2 — status

Open Items:
- [any blockers or deferred items]

Sign-off:
- Architecture: [name] [date]
- Product: [name] [date]

Reference Monaco 2026 Configuration

A concrete example showing how the Monaco 2026 competition would be configured in the redesigned system:

competition:
  name: "Monaco Ocean Protection Challenge 2026"
  programId: "monaco-opc-2026"
  status: DRAFT

rounds:
  - order: 1
    label: "Application Window"
    type: INTAKE
    config:
      deadlinePolicy: FLAG  # accept late with flag
      requiredDocSlots: ["executive_summary", "business_plan", "team_profile"]

  - order: 2
    label: "AI Eligibility Screening"
    type: FILTERING
    config:
      aiEnabled: true
      autoAdvanceEligible: false  # admin reviews before advancing

  - order: 3
    label: "Jury 1 — Semi-Finalist Selection"
    type: EVALUATION
    juryGroupId: jury-1
    config:
      scoringRubric: { criteria: [...], maxScore: 100 }
      requireFeedback: true
      generateAiShortlist: true

  - order: 4
    label: "Semi-Finalist Documents"
    type: SUBMISSION
    config:
      requiredDocSlots: ["updated_business_plan", "financial_projections", "impact_report"]
      lockPriorRoundDocs: true
      deadlinePolicy: HARD

  - order: 5
    label: "Jury 2 — Finalist Selection"
    type: EVALUATION
    juryGroupId: jury-2
    config:
      scoringRubric: { criteria: [...], maxScore: 100 }
      requireFeedback: true
      generateAiShortlist: true
      showPriorJuryData: false  # independent evaluation

  - order: 6
    label: "Finalist Mentoring"
    type: MENTORING
    config:
      eligibility: FINALISTS_ONLY
      requireMentorRequest: true
      assignmentMethod: MANUAL
      allowMentorPromotion: false

  - order: 7
    label: "Live Finals — Jury 3"
    type: LIVE_FINAL
    juryGroupId: jury-3
    config:
      audienceVotingEnabled: true
      audienceRevealTiming: AT_DELIBERATION
      audienceBlendWeight: 0  # jury only for scoring
      showPriorJuryData: true  # Jury 3 sees prior jury history
      scoringMode: CRITERIA_BASED
      presentationOrder: MANUAL

  - order: 8
    label: "Final Deliberation"
    type: DELIBERATION
    juryGroupId: jury-3
    config:
      mode: FULL_RANKING
      showCollectiveRankings: true
      tieBreakMethod: ADMIN_DECIDES
      topN: 3
      allowAdminOverride: true

juryGroups:
  - label: "Jury 1"
    defaultCapMode: SOFT
    defaultMaxProjects: 15
    softCapBuffer: 10
    allowOnboardingSelfService: true
    defaultCategoryBias: { STARTUP: 0.5, BUSINESS_CONCEPT: 0.5 }

  - label: "Jury 2"
    defaultCapMode: SOFT
    defaultMaxProjects: 10
    softCapBuffer: 10
    allowOnboardingSelfService: true

  - label: "Jury 3 — Live Finals"
    defaultCapMode: NONE  # all finalists reviewed
    allowOnboardingSelfService: false

specialAwards:
  - name: "Innovation Award"
    routingMode: STAY_IN_MAIN
    eligibilityMode: AI_SUGGESTED
    winnerDecisionMode: JURY_VOTE
    juryGroupLabel: "Innovation Award Panel"

  - name: "Ocean Impact Award"
    routingMode: SEPARATE_POOL
    pullOutBehavior: KEEP_IN_BOTH
    routingConfirmationMode: ADMIN_CONFIRMED
    eligibilityMode: AI_SUGGESTED
    winnerDecisionMode: SINGLE_JUDGE
    singleJudgeLabel: "Impact Award Chair"

submissionWindows:
  - label: "Round 1 Application Documents"
    roundOrder: 1
    requirements:
      - slotKey: "executive_summary"
        label: "Executive Summary"
        required: true
        acceptedTypes: ["application/pdf"]
      - slotKey: "business_plan"
        label: "Business Plan"
        required: true
        acceptedTypes: ["application/pdf"]
      - slotKey: "team_profile"
        label: "Team Profile"
        required: true
        acceptedTypes: ["application/pdf"]

  - label: "Round 2 Semi-Finalist Documents"
    roundOrder: 4
    requirements:
      - slotKey: "updated_business_plan"
        label: "Updated Business Plan"
        required: true
      - slotKey: "financial_projections"
        label: "Financial Projections"
        required: true
      - slotKey: "impact_report"
        label: "Environmental Impact Report"
        required: true

This configuration, when loaded into the system, would create the full Monaco 2026 competition with all 8 rounds, 3 main juries, 2 special awards, and 2 submission windows — ready for admin to set dates and invite jury members.