@zanii/gov
v0.1.1
Published
Public-sector algorithmic accountability: benefits, visas, fines, licences. A state decision with no governing rulebook cannot be constructed, and appealPack puts a court-ready, bilingual proof of what the algorithm did to you into the citizen's own hands
Readme
@zanii/gov
Public-sector algorithmic accountability — benefits, visas, fines, licences.
The state proves what its algorithm did to you — and you hold the proof.
No new cryptography. This is a preset over @zanii/decisions (completeness +
rule-consistency + committed factors), @zanii/subject (the citizen holds their own key and
their own verifiable slice), and the bilingual evidence discipline of @zanii/admissibility.
npm install @zanii/gov @zanii/decisions @zanii/subject @zanii/coreThe authority issues a decision
import { buildGovDecision } from '@zanii/gov';
const d = buildGovDecision({
citizenDid: citizen.did, authority: 'mohre.gov.ae',
kind: 'benefit.deny',
manifestHash: deployedRulesHash, // REQUIRED — no rulebook, no decision
outcome: { granted: false, reason_code: 'INCOME_THRESHOLD' },
factors: { income: 4200 }, // salt-committed at decision time
appealBy: 'P30D', // the statutory right, on the record
ts,
});
await zanii.record({ target: d.target, payload: d.payload, subjectTag: d.subjectTag });A state decision with no governing rulebook cannot be constructed. buildGovDecision
throws. That single constraint is the most important line of code in this package: an
unauditable state decision must not be issuable.
The citizen appeals — offline, holding their own proof
import { appealPack, renderAppealPackMarkdown, citizenTag } from '@zanii/gov';
const pack = await appealPack(citizenTag(me.did, 'mohre.gov.ae'), { authority: 'mohre.gov.ae' });
pack.verified; // every decision about me, verified offline
pack.rules.consistent; // did the rules change under me? (interleaved rulebooks are flagged)
pack.unruled; // decisions issued with NO governing rulebook — a process defect
writeFile('appeal.md', renderAppealPackMarkdown(pack, 'both')); // bilingual, for a judgeappealPack answers the two questions administrative law actually asks: was my record
complete and unaltered, and did the same rules decide everyone — or did they change
mid-process, and for whom?
Honest limits (in the rendered pack itself, not just here)
- It proves the process, never the justice. Same rules, complete record, committed inputs, appealable evidence. A discriminatory rule applied consistently is still discriminatory — but now it is visible, attributable, and admissible, which is what a court needs in order to act. The rendered pack states this in both languages; it is not optional boilerplate.
- A state could simply not stamp a decision. Omission, not forgery, is the attack. The citizen can detect the absence (their slice is incomplete — silence becomes visible), but duty-to-record is statutory, not protocol. We make the duty enforceable; we cannot create it.
- The subject tag is pseudonymous, not anonymous. The pack reveals no identity by itself, but a party who obtains the tag can see the decision pattern. For high-sensitivity programmes, consider a permissioned slice.
Changelog
- 0.1.0 — initial release:
buildGovDecision(rulebook required),citizenTag,appealPack/buildAppealPack,renderAppealPackMarkdown(bilingual),GOV_DECISION_KINDS.
License
Apache-2.0.
