Registration
Live. Registrations land in the data bank the moment they are sent.
No signal?
Records queue on the device, encrypted, and replay when the network returns. Each carries a client-generated id, so a retry after a dropped response returns the existing record instead of creating a second one.
Duplicate found?
The record is quarantined and flagged, never silently dropped and never auto-rejected. A named human reviews it. The supporter is a real voter, and a machine does not get to decide they do not exist.
What a field agent records
One screen, designed for a low-end Android in bright sunlight. The agent picks the ward and the district, division, LGA and LCDA are derived and locked, so a record can never be misattributed to the wrong place.
Grassroots Voting DataBank
Module C · register, then collate
Register, then collate
Field agents capture supporters ward by ward, on phones, often with no signal. Every record lands against one of the 376 councillorship wards and one of the 57 local councils, and the collation below counts them live.
The register each councillor builds
Registration is done by councillors, ward by ward. Each councillor is the registrar for their own ward, and every voter record is attributed to the councillor who captured it, so nobody can register a voter into somebody else's ward and no voter can be claimed twice.
Voters database
Masked view. NIN and VIN are never rendered in full, in any export.| Name of councillor | Ward | Local Government | Voter’s name | NIN | VIN | Sex |
|---|---|---|---|---|---|---|
| No voter has been registered yet. Nothing is simulated here. This table has no rows because no councillor has captured a voter, and a platform that invents a register is worse than one that shows an empty one. The columns above are the real schema. | ||||||
How each column is handled
| Column | Source | Handling |
|---|---|---|
| Name of councillor | Derived from the ward | Attribution only. Set from the ward, never typed, so it cannot be spoofed. |
| Ward | Chosen by the registrar | Drives the whole hierarchy. Locked once the record is written. |
| Local Government | Derived from the ward | Never entered by hand. |
| Voter’s name | As written on the voter card | Stored in clear. Normalised for duplicate matching, never for display. |
| NIN | Voter | Envelope-encrypted under its own key. Hashed for de-duplication. Shown as the last four digits only. Unmasking needs a named permission and is written to the audit log. |
| VIN | Voter | Required on every supporter record (Forum decision, 14 Sep 2026), under its own key. Only a one-way hash is ever written, so the number cannot be read back — not by an administrator, and not by us. |
| Sex | Voter | Stored as declared. Reportable in aggregate only. |
Registers collation
The same slice is available at every level: state, senatorial district, division, LGA, LCDA, ward, and down to a single councillor or a single agent. The filters below compose, and every view is exportable.
Slice the register
Filters narrow within your scope. They can never widen it.Headline counts for this slice
By senatorial district
| District | LGAs | Councils | Wards | Registered |
|---|---|---|---|---|
| Lagos West | 10 | 28 | 185 | 0 |
| Lagos Central | 5 | 13 | 93 | 0 |
| Lagos East | 5 | 16 | 98 | 0 |
Verification funnel
Demographic breakdown
These panels are the reason the collation exists. Nothing is charted until there is a sample worth reading: any cell below the minimum is suppressed, and small samples are labelled so nobody over-reads noise.
Gender
No data yetAge bracket
No data yetReligion
Special-category data, suppressed below the minimum cell sizePer-council collation, Lagos West
Lagos West is shown because it is the largest district by voter population. Every council in the register is listed with its real ward count, so a coordinator can see exactly where a zero means "nothing captured" rather than "nothing planned".
| Local council | Type | Division | Wards | Registered | Target |
|---|---|---|---|---|---|
| Agbado-Oke Odo | LCDA | Ikeja | 7 | 0 | – |
| Agege | LGA | Ikeja | 7 | 0 | – |
| Ajeromi-Ifelodun | LGA | Badagry | 9 | 0 | – |
| Alimosho | LGA | Ikeja | 7 | 0 | – |
| Amuwo-Odofin | LGA | Badagry | 7 | 0 | – |
| Ayobo-Ipaja | LCDA | Ikeja | 5 | 0 | – |
| Badagry | LGA | Badagry | 10 | 0 | – |
| Badagry West | LCDA | Badagry | 5 | 0 | – |
| Egbe-Idimu | LCDA | Ikeja | 5 | 0 | – |
| Ejigbo | LCDA | Ikeja | 6 | 0 | – |
| Iba | LCDA | Badagry | 5 | 0 | – |
| Ifako-Ijaiye | LGA | Ikeja | 7 | 0 | – |
| Ifelodun | LCDA | Badagry | 7 | 0 | – |
| Igando-Ikotun | LCDA | Ikeja | 7 | 0 | – |
| Ikeja | LGA | Ikeja | 6 | 0 | – |
| Isolo | LCDA | Ikeja | 7 | 0 | – |
| Mosan-Okunola | LCDA | Ikeja | 5 | 0 | – |
| Mushin | LGA | Ikeja | 10 | 0 | – |
| Odi-Olowo / Ojuwoye | LCDA | Ikeja | 9 | 0 | – |
| Ojo | LGA | Badagry | 5 | 0 | – |
| Ojodu | LCDA | Ikeja | 6 | 0 | – |
| Ojokoro | LCDA | Ikeja | 7 | 0 | – |
| Olorunda | LCDA | Badagry | 5 | 0 | – |
| Onigbongbo | LCDA | Ikeja | 6 | 0 | – |
| Oriade | LCDA | Badagry | 7 | 0 | – |
| Orile Agege | LCDA | Ikeja | 6 | 0 | – |
| Oshodi-Isolo | LGA | Ikeja | 7 | 0 | – |
| Oto-Awori | LCDA | Badagry | 5 | 0 | – |
| Lagos West total | 185 | 0 | – |
The rules that make the collation trustworthy
Phone and VIN are stored only as keyed HMAC values, so a repeat attempt is detected without the register ever holding a searchable phone number.
Nothing is auto-rejected or auto-deleted. A flagged record goes to a review queue with the matched record shown beside it.
Each registration carries the agent who captured it and the ward it belongs to, and the agent is taken from the session, never from the form.
Rollups are maintained on write and recomputed nightly from source. A drift between the two raises an alert rather than being quietly tolerated.
Every export carries a stated reason, is watermarked with who requested it, expires, and is written to an append-only audit log.
A withdrawal removes the record from every count and every export, and the withdrawal itself is audited.