Skip to content

fix: repair the checks that fail on ovcs since the VoteSecure migration - #3901

Closed
ereslibre wants to merge 7 commits into
ovcsfrom
fix/meta-14260-ci/ovcs
Closed

ereslibre wants to merge 7 commits into
ovcsfrom
fix/meta-14260-ci/ovcs

Conversation

@ereslibre

@ereslibre ereslibre commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Parent issue: https://github.com/sequentech/meta/issues/14260

ovcs has failing checks since #3885 (VoteSecure migration) and #3883 (merge of main). Every PR against ovcs inherits them. This PR repairs them. Tests and tooling follow the current code; three changes touch the product: the Hasura output type loses a leftover field, publishing runs its ballot-style and custody check again, and the backend image gets a Chrome that starts with the renderer's flags.

What was failing and why

Check Cause Fix
Hasura metadata is consistent AuthorizeTallyCustodyOutput kept an outcome field of the removed enum RestorePrivateKeyOutcome, which makes every action inconsistent; Harvest returns no outcome and no client selects it Remove the leftover field
Core JavaScript boundary — WASM sequent-core/tests/wasm/wasm.rs imports the removed ed25519_dalek Sign with voting_crypto::signing, as the crate does
contracts (openwhisk, aws_lambda) orare, a proc-macro crate, depended on sequent-core, so sequent-core and braid were built twice and their rlibs overwrote each other sequent-core is a dev-dependency of orare; doc_renderer keeps its own
Run Windmill tests The migrated sign-key-ceremony and sign-tally-key roles carried the old labels; WBRAID_BOARD_DATABASE_URL named port 5432 while the job's PostgreSQL listens on 3322 Labels as the Admin Portal has them, in the migration, both realm templates and the docs; port 3322
admin-portal stories (1/3, 2/3, 3/3) SettingsTrustees, AdminWizard and StartStep stories were stale against the custody screens Stories follow the components
admin-portal production browser journeys (1/4, 3/4, 4/4) The /trustee smoke heading, the custody request's file name, the protocol of a new event, an unmocked ListTallyKeyRestoreState Journeys follow the application
Check frontend linting One journey file not formatted Prettier
journeys (backend E2E), Tooling: python:scripts-e2e A runner test built a Portal without VOTING_PORTAL_URL The test sets it, as its siblings do
Tooling: python:scripts-dev The Rust watch test expected the workers' old target directory It reads the service's CARGO_TARGET_DIR
Coverage tooling ruff on test_summary.py; three profiles lacked scope_exceptions, which the runner requires Formatted; the tables are declared
journeys (backend E2E), once past setup An imported publication is restored unpublished, but two journeys expected it published; one journey read the dropped cast_vote table; publishing no longer ran validate_published_ballot_styles (its only call was dropped), so a publication with a native joint key could be published before custody was confirmed; and Debian's Chromium 155 traps at startup with the renderer's --single-process, so the post-tally PDF task never finished and Windmill was killed at shutdown Journeys follow the import and the ballot box; the publication check is called again; on amd64 the backend image installs the Chrome headless shell that the unit tests pin
step-cli coverage A test unpacked the bundled runtime into the home cache, shared by the base and head measurements, so the head always looked behind The test has a home directory of its own and covers both paths
Committed WASM source freshness The committed sequent-core package did not match the sources Regenerated

Checks that stay red on this PR

windmill coverage — no decrease and wrap-map-err coverage — no decrease measure the base commit as well as the head, and the base's own Windmill tests fail, so the base cannot be measured. They pass for pull requests opened after this one is merged.

Two messaging tests assert wall-clock bounds and fail now and then on the runners, here and on the base measurement: postgres_messaging_rate_bucket::a_saturating_bulk_send_keeps_to_the_rate_and_leaves_the_reserve_to_codes (Windmill) and fake_provider::route_tests::adapters_send_and_check_through_the_routes_and_reports_reach_the_ledger (Harvest). access/approvals.spec.ts is flaky too. They are not changed here; a rerun passes.

Tests

Hasura consistency check, the Windmill test suite with the native board database, the WASM boundary test, the orare contract commands, the three story files, the journey spec files and the Python tooling tests were run locally.

🤖 Generated with Claude Code

- Hasura metadata: declare the RestorePrivateKeyOutcome enum that
  AuthorizeTallyCustodyOutput uses.
- sequent-core: the WASM boundary test signs with voting-crypto, as the
  crate does, instead of the removed ed25519-dalek.
- orare: sequent-core is a dev-dependency of the proc-macro crate, so
  sequent-core and braid are built once and their rlibs no longer collide.
- Windmill: the migrated sign-key-ceremony and sign-tally-key roles are
  described as the Admin Portal labels them; realm templates and docs
  follow. The test job reaches the native board database on the port its
  PostgreSQL service listens on.
- Admin Portal: the trustee, key ceremony and start step stories follow
  the custody screens. Journeys: the /trustee smoke, the custody request's
  file name, the WBRAID protocol of a new event and the tally list's key
  restore state for trustees. Prettier.
- Tooling: the Rust watch test reads the workers' target directory, the
  journey runner test sets the voting portal URL, ruff on the coverage
  summary test, and the voting-crypto, protocol-board and trustee coverage
  profiles declare their scope exceptions.
- The committed sequent-core WASM package is regenerated.

Parent issue: sequentech/meta#14260

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review: 2
  • release/10.0
  • feat/meta-12767/.*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: sequentech/step/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ae50009e-dac8-4111-ada6-e199b961581c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://docs.sequentech.io/docusaurus/pr-preview/pr-3901/

Built to branch doc-previews at 2026-10-13 23:51 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

ereslibre and others added 5 commits October 13, 2026 22:11
The test unpacked the bundled runtime into the home cache, which the
coverage job's two measurements share: the second one found the files and
covered the reuse path, so the head, measured first, always looked three
lines behind the base. The test now has its own cache and builds twice,
covering both paths in every run.

Parent issue: sequentech/meta#14260

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With a cache directory of its own the test no longer took the fallback
from XDG_CACHE_HOME to the home directory, which the base still covers.
It now runs with a home directory of its own and no XDG_CACHE_HOME.

Parent issue: sequentech/meta#14260

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ow the ballot box

- Windmill: update_publish_ballot calls validate_published_ballot_styles
  again. The VoteSecure migration added the custody check to that function
  and dropped its only call, so a publication with a native joint key
  could be published before the trustees confirmed custody, and the
  decoding and acclamation checks no longer ran at publish.
- Backend journeys: an imported publication is restored unpublished, as
  the import documents; the combined-contest journey reads the voter's
  stored votes from the voter status action, since Hasura has no cast_vote
  table.

Parent issue: sequentech/meta#14260

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hell

The PDF renderer starts Chrome with --single-process. Debian's Chromium,
now 155, traps at startup with that flag (0 of 6 starts in the image), so
in the development and backend journey stacks every PDF render retried
for minutes and the post-tally task never finished: Windmill was killed
at shutdown and the journeys' coverage step failed. On amd64 the image now
installs the Chrome headless shell 153.0.8010.36 that
.github/actions/setup-test-browser pins for the unit tests, ahead of
chromium on the PATH (6 of 6 starts).

Parent issue: sequentech/meta#14260

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The VoteSecure migration renamed RestorePrivateKeyOutput to
AuthorizeTallyCustodyOutput and removed the RestorePrivateKeyOutcome enum,
but left the type's outcome field. Declaring the enum again made the
metadata consistent and Hasura then refused Harvest's answer, which has no
outcome ("field outcome expected in webhook response"). No client selects
the field, so it is removed with the enum.

Parent issue: sequentech/meta#14260

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
send_bound_code delivers the code and marks the link CODE_SENT in a later
transaction. The test read the link as soon as the fake provider listed
the message, so on a slow runner it still found PENDING, which failed the
harvest coverage measurement of the head or of the base. It now waits for
the state, as it waits for the message.

Parent issue: sequentech/meta#14260

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ereslibre added a commit that referenced this pull request Oct 14, 2026
… Settings > Logs (VOTE-AUDIT) (#3900)

Parent issue: sequentech/meta#14259

Design package
[VOTE-AUDIT](https://project-1.sequent.sh/#package/VOTE-AUDIT). This PR
covers [SW-F-0364](https://project-1.sequent.sh/#requirement/SW-F-0364),
"Log all system activity from start to finish": activity that belongs to
no election event now has a signed log, shown in the Admin Portal.

## What changes

- **Tenant log.** Each tenant gets a log next to its election events'
logs, with a signing key of its own, in the electoral log's format
(signed statements in a Merkle log). It is a board of the electoral-log
server's base database, created with its key and a `TenantLogOpened`
entry the first time the tenant has something to record.
- **Sign-ins.** `custom-event-listener` recognizes the tenant realm and
sends its events with no election event (`KeycloakUserEvent`), leaving
out token housekeeping. The development realm and the COMELEC realm
template list the listener.
- **Administrator requests.** Harvest records the requests that belong
to no election event as `TenantAdminAction` entries: election events
(create, import, delete), staff accounts, roles and permissions,
tenants, the tenant's configuration, templates and country limits. An
entry holds the action, who asked, the outcome with its HTTP status and
what the request named, inside the signed statement. Denied and failed
requests are ERROR entries.
- **One writer.** Both producers enqueue on the electoral-log event
queue. The batch task routes an event without an election event to its
tenant's log instead of dead-lettering it.
- **Settings > Logs.** A new tab lists the tenant's log with filters and
details under Show More. It needs the new `tenant-logs-read` permission
and not `tenant-write`, so a read-only role opens Settings and sees only
Logs.
- **API.** Hasura action `listTenantLog`, Harvest route `POST
/tenant-log`.

- **Entries keep their own time.** A sign-in is stamped with the time
Keycloak saw it, a request with the time Harvest answered it, not with
the time the batch was stored.
- **Sent messages.** A message Keycloak sends to an account (a sign-in
code) is recorded as `MESSAGE_SENT`, without its text.

## Also in this PR: checks that were red on `ovcs`

`ovcs` has had failing checks since #3885 (VoteSecure migration) and
#3883. To get this PR green they are repaired here, in separate commits;
the same repairs alone are in #3901 (meta#14260). `windmill coverage`
and `wrap-map-err coverage` also measure the base commit, whose own
Windmill tests fail, so they stay red here until #3901 is merged into
`ovcs`:

- Hasura metadata: `AuthorizeTallyCustodyOutput` loses a leftover
`outcome` field of a removed enum, which made every action inconsistent.
- sequent-core: the WASM boundary test signs with `voting-crypto`
instead of the removed `ed25519-dalek`.
- orare: `sequent-core` is a dev-dependency of the proc-macro crate, so
`sequent-core` and `braid` are built once and their rlibs no longer
collide (the `contracts` jobs).
- Windmill: the migrated `sign-key-ceremony` and `sign-tally-key` roles
are described as the Admin Portal labels them; realm templates and docs
follow.
- Admin Portal: stale stories (trustees, key ceremony wizard, start
step) and journeys (custody request file name, WBRAID as the protocol of
a new event, the tally list's key restore state, the `/trustee` smoke),
and Prettier.
- Backend journeys: they follow the import (publications restored
unpublished) and the ballot box; publishing calls
`validate_published_ballot_styles` again, whose only call had been
dropped; on amd64 the backend image installs the pinned Chrome headless
shell, because Debian's Chromium 155 no longer starts with the PDF
renderer's `--single-process`.
- step-cli: a test no longer shares the home cache between the two
coverage measurements.
- Tooling: the Rust watch test, the journey runner test, ruff on the
coverage summary test, and the `scope_exceptions` of the voting-crypto,
protocol-board and trustee coverage profiles.

## Not in this PR

- Changes saved through Hasura without Harvest (the other Settings
tabs).
- Export, published checkpoints and the audit action for the tenant log.
- A transactional outbox: a request's entry is queued after the request
is answered.
- Keycloak admin events.

## Notes for review

- `StatementBody::TenantActivity` and the statement types
`TenantLogOpened` and `TenantAdminAction` are appended, so stored
entries keep decoding; the discriminant tests pin them.
- `GetElectoralLogBody.election_event_id` now defaults to empty, for the
tenant listing.
- `SettingsScreen` opens with `settings-menu` and either `tenant-write`
or `tenant-logs-read`; the existing tabs still need `tenant-write`.
- With the listener on the tenant realm, an Admin Portal sign-in
enqueues its event as a voter's does: under the default `fail-request`
policy it fails while the task-queue database is unreachable or not set
up.
- Existing tenants need the `tenant-logs-read` role and
`custom-event-listener` in their realm's event listeners;
`docs/.../13-electoral-log/04-tenant-log.md` says how. Nothing is
migrated.
- The committed sequent-core WASM package is regenerated (new
permission, realm template fingerprint).

## Tests

- electoral-log: statement head, wire bytes, signatures; tenant boards
in the base database.
- Windmill: entries, key creation against the migrated schema, board
opening, batch routing, listing.
- Harvest: the recorder and its fairing, real routes (refused role
deletion, voter versus staff deletion), the route's permission and the
route inventories.
- Keycloak listener: realm parsing and the events kept.
- sequent-core: the permission and the listener in both realm templates.
- Admin Portal: Jest (query builder, explanations), stories
(`SettingsLogs`, `SettingsScreen`), journeys
(`settings/access.spec.ts`).

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@ereslibre

ereslibre commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor Author

Superseded by #3900

@ereslibre ereslibre closed this Oct 14, 2026
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.

1 participant