Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
33 changes: 33 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!--
SPDX-FileCopyrightText: 2026 Sequent Tech Inc <legal@sequentech.io>
SPDX-License-Identifier: AGPL-3.0-only
-->

# Copilot Code Review Instructions

Review this repository as election software, not a generic web app. Prioritize findings that can change counted ballots, voter eligibility, auditability, tenant isolation, permissions, privacy, or backwards compatibility. Prefer correctness and security issues over style comments.

Detailed review rules are intentionally split into files under .github/instructions so GitHub.com Copilot code review can apply more specific guidance while staying within the 4000-character per-file limit.

## System Mindset

- Treat changes in packages/windmill, packages/sequent-core, packages/harvest, packages/immu-board, packages/keycloak-extensions, packages/voting-portal, packages/admin-portal, and beyond/packages/ballot-audit as high risk.
- Review for election-system invariants: outcome correctness, deterministic behavior, reproducible audits, tenant isolation, voter privacy, and safe failure modes.
- Flag bugs that can silently drop ballots, count stale or duplicate ballots, mis-handle area rules, widen eligibility, expose voter-linked data, or make two code paths disagree about the same election state.
- Be suspicious of best-effort parsing, skipped records, silent fallbacks, lossy transforms, non-deterministic ordering, retry logic, and special cases for one client. In this system those are often integrity bugs, not harmless implementation details.

## High-Priority Review Areas

- Ballot selection and counting: verify that latest valid ballot semantics, deduplication rules, and area scoping stay consistent across tally, statistics, exports, receipts, and audits.
- Authorization and tenancy: verify server-side enforcement, correct Keycloak and Hasura scoping, and no cross-tenant or cross-event data exposure.
- Election state transitions: review open or closed voting logic, eligibility checks, revote rules, ceremony steps, and admin-only actions as security-sensitive.
- Cryptography and auditability: flag any weakening of proof, signature, hash, encryption, randomness, immutable-log, or canonical serialization checks.
- Compatibility and data flow: review imports, exports, migrations, generated GraphQL types, and persisted payloads for backwards compatibility and deterministic semantics.
- Frontend correctness matters when it changes security or election behavior: contest state, permission-gated actions, public documents, and HTML or rich-text rendering must remain correct and sanitized.

## Product and Tests

- Flag client-specific behavior that is not generalized. Prefer composable policies and enums over booleans when more modes are likely.
- Expect targeted tests for changes to tally, cast_vote, revotes, permissions, state transitions, migrations, import or export, or cryptographic validation.
- Strong tests cover revotes, multi-area behavior, deterministic ballot selection, authorization failures, wrong-tenant access, invalid input, and backwards compatibility with existing election data.
- If no material integrity, security, privacy, or compatibility issue is present, prefer no finding over low-value style commentary.
18 changes: 18 additions & 0 deletions .github/instructions/auth-tenancy.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
applyTo: "packages/harvest/**/*.rs,packages/keycloak-extensions/**/*.java,packages/admin-portal/**/*.ts,packages/admin-portal/**/*.tsx,packages/voting-portal/**/*.ts,packages/voting-portal/**/*.tsx,packages/ui-core/**/*.ts,packages/ui-core/**/*.tsx,packages/ui-essentials/**/*.ts,packages/ui-essentials/**/*.tsx,hasura/metadata/**/*.yaml,hasura/migrations/**/*.sql"
---
<!--
SPDX-FileCopyrightText: 2026 Sequent Tech Inc <legal@sequentech.io>
SPDX-License-Identifier: AGPL-3.0-only
-->

# Authorization And Tenant Boundary Review

- Prioritize tenant isolation, election-event isolation, and authorization correctness over UI polish or code style.
- Check that server-side access control remains enforced. Hiding a button or route in the frontend is not sufficient protection.
- Review Keycloak and Hasura changes for privilege escalation, missing role checks, cross-tenant reads or writes, and accidental widening of default permissions.
- For admin and voting portals, verify admin-only actions remain protected, contest state stays accurate, and tenant or event identifiers in routes, storage, document URLs, and API variables cannot leak data across tenants.
- Rich text or HTML must stay sanitized through existing safe paths. Flag new raw HTML rendering or changes that bypass sanitization.
- For user, role, and permission changes, verify compatibility with the default tenant template and existing realms.
- For logs, exports, or public document access, check that voter-linked or tenant-linked data is not exposed to broader audiences.
- Expect tests for authorization failures, wrong-tenant access, sanitized rich text, and permission-gated frontend states.
18 changes: 18 additions & 0 deletions .github/instructions/crypto-audit.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
applyTo: "packages/sequent-core/**/*.rs,packages/braid/**/*.rs,packages/strand/**/*.rs,packages/immu-board/**/*.rs,packages/windmill/src/services/insert_cast_vote.rs,packages/windmill/src/services/reports/**/*.rs"
---
<!--
SPDX-FileCopyrightText: 2026 Sequent Tech Inc <legal@sequentech.io>
SPDX-License-Identifier: AGPL-3.0-only
-->

# Crypto And Audit Review

- Review changes here as cryptographic and audit critical, not as routine refactors.
- Flag any weakening of proof, signature, hash, encryption, randomness, key-handling, or canonical serialization checks.
- Do not allow validation bypasses for malformed ballots, invalid proofs, mismatched hashes, bad signatures, or parse failures that should stop processing.
- Verify native and WASM code paths preserve the same ballot semantics and verification behavior.
- Receipt, bulletin-board, export, and audit outputs must remain reproducible and traceable to the same ballot content and hashes.
- For changes to audit logging or bulletin-board storage, check immutability assumptions, ordering assumptions, and whether retries can duplicate or hide evidence.
- Backwards compatibility matters: older election events, stored payloads, and serialized objects must still verify or fail in a controlled, explicit way.
- Expect negative tests for invalid proofs, signature failures, malformed ciphertexts, mismatched hashes, replay or retry scenarios, and serialization round trips.
17 changes: 17 additions & 0 deletions .github/instructions/schema-io.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
applyTo: "hasura/migrations/**/*.sql,hasura/metadata/**/*.yaml,packages/windmill/src/services/import/**/*.rs,packages/windmill/src/services/export/**/*.rs,packages/sequent-core/**/*.rs,packages/admin-portal/src/types/**/*.ts,packages/voting-portal/src/types/**/*.ts"
---
<!--
SPDX-FileCopyrightText: 2026 Sequent Tech Inc <legal@sequentech.io>
SPDX-License-Identifier: AGPL-3.0-only
-->

# Schema Import Export Review

- Review schema, migration, import, and export changes for backwards compatibility with existing election events and generated GraphQL types.
- New fields should usually be optional or have safe defaults. Flag changes that make old data, fixtures, or previously exported packages unreadable.
- Hasura metadata, migrations, and generated types must stay in sync. Flag manual schema drift and missing regeneration steps.
- Changes to CSV, JSON, or report export formats must preserve stable identifiers, deterministic ordering where required, and documented semantics.
- For tally and results import or export, verify the same latest-ballot and multi-area semantics used by the backend counting paths.
- For migrations, look for irreversible or unsafe transformations, silent truncation, and changes that can break tenant isolation or permission checks.
- Expect tests or fixtures that cover old event data, invalid input, missing optional fields, and round trips through export then import.
19 changes: 19 additions & 0 deletions .github/instructions/tally.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
applyTo: "packages/windmill/src/services/cast_votes.rs,packages/windmill/src/services/insert_cast_vote.rs,packages/windmill/src/services/join.rs,packages/windmill/src/services/ceremonies/**/*.rs,packages/windmill/src/postgres/cast_vote.rs,beyond/packages/ballot-audit/**/*.rs,packages/step-cli/src/commands/duplicate_votes.rs"
---
<!--
SPDX-FileCopyrightText: 2026 Sequent Tech Inc <legal@sequentech.io>
SPDX-License-Identifier: AGPL-3.0-only
-->

# Tally And Ballot Selection Review

- Treat any change that influences which ballot is selected, exported, counted, duplicated, or audited as critical.
- For logic over sequent_backend.cast_vote, verify scoping by tenant_id, election_event_id, election_id, and area_id when the operation is area-specific.
- When PostgreSQL DISTINCT ON is used to choose one ballot per voter or area, ORDER BY must begin with the same grouping keys and then use deterministic recency. Flag stale-selection patterns such as ordering only by voter_id_string or using recency without a stable tie-breaker.
- If created_at can tie, require a stable tie-breaker such as id DESC. Otherwise the selected revote can change across runs.
- Latest valid ballot must win consistently across tally export, statistics, duplicate-vote tooling, receipts, and ballot-audit. Flag semantic drift between these paths.
- COUNT(DISTINCT voter_id_string) is not interchangeable with latest-per-voter or latest-per-voter-per-area semantics unless the election rules prove it.
- In revote checks, verify same-area and other-area handling, unlimited-revote behavior, and retry paths. Review whether failures can permit double voting or reject valid revotes.
- For CSV joins and exports, preserve sort and dedup preconditions. merge_join_csv assumes sorted input and currently skips malformed rows; flag changes that can silently drop or misalign ballots and voters.
- Expect tests for stale-ordering regressions, equal-timestamp tie handling, multi-area voters, revote limits, and consistency between tally and audit outputs.
18 changes: 11 additions & 7 deletions CLAUDE.md → AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# CLAUDE.md
# Agent Instructions

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This file provides repository guidance for AI coding agents working in this repository.

This is the canonical shared handbook for Claude, ChatGPT, GitHub Copilot coding agent, and similar tools.

For GitHub Copilot pull request reviews, review-specific guidance lives in `.github/copilot-instructions.md` and `.github/instructions/*.instructions.md`.

## Project Overview

Expand Down Expand Up @@ -110,10 +114,10 @@ reuse lint # Every file must have SPDX headers
## Important Conventions

- **REUSE license headers required on every file**:
```
// SPDX-FileCopyrightText: 2025 Sequent Tech Inc <legal@sequentech.io>
// SPDX-License-Identifier: AGPL-3.0-only
```
```
// SPDX-FileCopyrightText: 2025 Sequent Tech Inc <legal@sequentech.io>
// SPDX-License-Identifier: AGPL-3.0-only
```
- **Vendored Cargo dependencies**: `packages/vendor/` — Cargo.toml uses `[source.vendored-sources]`
- **Pinned crate**: `wasm-bindgen` 0.2.104 — do not change
- **Forked crate**: `celery` uses a custom fork (Findeton/rusty-celery)
Expand Down Expand Up @@ -188,4 +192,4 @@ Dev service URLs (inside dev container):
- MinIO: http://127.0.0.1:9001
- RabbitMQ: http://127.0.0.1:15672

**Dev container tips**: When editing Rust code in harvest, windmill, or sequent-core, check the pod logs to see if it compiles successfully — the services auto-rebuild on changes inside the dev container.
**Dev container tips**: When editing Rust code in harvest, windmill, or sequent-core, check the pod logs to see if it compiles successfully — the services auto-rebuild on changes inside the dev container.
2 changes: 1 addition & 1 deletion packages/windmill/src/services/cast_votes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub async fn find_area_ballots(
election_event_id = '{election_event_id}' AND
area_id = '{area_id}' AND
election_id = '{election_id}'
ORDER BY election_id, voter_id_string, created_at DESC
ORDER BY voter_id_string
"#
Comment on lines 77 to 87
);

Expand Down
Loading