# MakeJoy public poll operations

This document is the operator checklist for permanent numbered polls. Polls
0001 and 0002 are listed in the original `poll-registry.json`; Poll 0003 onward
are created through the authenticated MakeJoy Desk and exposed through the
count-free `/api/public-polls` directory. It is public so the lifecycle can be
reviewed alongside the poll charter and aggregate schema.

## Permanent records

- Assign IDs in order: `poll-0001`, `poll-0002`, and so on.
- Never reuse, renumber, or remove an ID after its poll has opened.
- Keep the numbered URL available after collection closes.
- Treat `poll-registry.json` as the original-round lifecycle record and the
  self-service poll definitions as the lifecycle record for Poll 0003 onward.
  Run `npm run validate:polls` before every hosted build.
- Do not inspect or publish running totals while a poll is open. Running totals
  can bias later responses.

## Lifecycle

Each poll moves forward through these states:

1. `draft` — the page may be reviewed, but collection is closed and all dates
   and publication links are null.
2. `open` — `openedOn` is set, the poll's collection variable is true, and no
   result or decision is claimed.
3. `closed` — collection is false, `closedOn` is set, and the cumulative totals
   are being audited.
4. `results-published` — the final aggregate file, limitations, and decision
   note are linked from the registry and permanent poll record.

The original rounds use independent collection controls:

- Poll 0001: `POLL_0001_COLLECTION_OPEN`
- Poll 0002: `POLL_0002_COLLECTION_OPEN`

Changing one control must not change the other poll.

Poll 0003 onward open and close through The Desk. Their server-stored lifecycle
status is the collection control; drafts and closed polls reject submissions.

## Open a poll

For Poll 0003 onward, use The Desk's Polls tab. Complete the publication gates
in `NETWORK-REVIEW.md`, save and review the private draft, then press **Publish
and open**. The Desk assigns the next permanent ID; there is no delete or
renumber action after publication.

For an original statically authored round:

1. Complete the publication gates in `NETWORK-REVIEW.md`.
2. Add the next sequential registry record with its stable page, API endpoint,
   charter, aggregate schema, and dedicated collection variable.
3. Build and test while its collection variable remains false.
4. Apply any required database migration and verify it with synthetic data
   before the real round opens; erase only that synthetic row.
5. Set `openedOn`, change the registry status to `open`, set only that poll's
   collection variable to true, rebuild, test, and deploy.

## Close and publish a poll

For Poll 0003 onward, enter the public decision note in The Desk and press
**Close poll and publish result**. The same operation stops new submissions and
makes only the final cumulative totals and decision note public.

For an original statically authored round:

1. Set only the closing poll's collection variable to false and deploy.
2. Verify its endpoint returns `503` while other open polls still accept valid
   requests.
3. Change its registry status to `closed` and set `closedOn`.
4. Query the single cumulative row once for the final audit. Never delete or
   rewrite real response totals.
5. Save the final aggregate totals in a versioned public file. Include the
   ballot total, skipped totals, option counts, collection dates, known
   limitations, and a statement that no individual ballots were stored.
6. Write a decision note. Explain what MakeJoy will do, what it will not infer
   from the poll, and any departure from the preference order.
7. Link both files in the registry, set `resultPublishedOn`, change the status
   to `results-published`, rebuild, test, and deploy.
8. Confirm the numbered page still works and shows the published record.

## Data boundary

The application stores one cumulative row per poll round. It rejects extra
fields, identity, demographics, free text, child-authored content, individual
ballots, timestamps, IP addresses, and user-agent data. Cloudflare necessarily
processes ordinary connection data to deliver and protect the site; MakeJoy
application code does not read or store it.
