سجلات القرارات · ADR-010
ADR-010: Authority comes from roles, never from balances; RETIRED is terminal
Only an account with STATUS_ROLE can change a lot's status or metadata; holding units grants no authority, and once a lot is RETIRED (255) no one can revive it.
- معرّف المستند
- ADR-010
- التاريخ
- 2026-09-21
- المصدر
- docs/adr/ADR-010.md
| Field | Value |
|---|---|
| ID | ADR-010 |
| Subject area | Access control |
| Status | Accepted |
| Date | 2026-09-21 |
| Owners | A-REX Contributors |
| Related requirements | FR-10 (SDD §3) |
| Supersedes / superseded by | — |
Context
The earlier design let any holder of a single unit change a lot's lifecycle state, including to terminal states. In a lot held by many parties, that let a minority holder retire everyone else's goods. Status changes in agriculture are made by accountable institutions: a warehouse accepting delivery, an inspector condemning a lot, a registry cancelling a receipt.
Issue
Who may change a lot's status and metadata, and which status changes are irreversible?
Assumptions
- Lots commonly have many holders.
- Status changes correspond to acts of identifiable institutions.
Constraints
- No authority may derive from token balances.
Alternatives considered
| Alternative | For | Against | Outcome |
|---|---|---|---|
| Any holder | No administration | A one-unit holder can retire a lot held by others | Rejected |
| Vote of holders weighted by balance | Democratic | Complex, slow, open to griefing | Rejected |
A role (STATUS_ROLE) with RETIRED terminal | Clear accountability; simple | The role holder can act on lots held by others | Accepted |
Decision
setBatchStatus and setBatchMetadata require STATUS_ROLE. Status 255 (RETIRED) cannot be changed again; a retired lot cannot be minted, transferred or transformed, and can still be burned so that delivered or destroyed goods leave the supply.
Argument
Tying status to a role makes every change attributable to an institution through an event with a reason, which is what disputes and audits require. A terminal state gives integrators one invariant they can rely on.
Consequences
Positive
- A minority holder cannot touch the lot's state.
- RETIRED is a guarantee indexers and marketplaces can rely on.
Negative
- The role holder can retire lots held by others; this power must be disclosed to holders.
Obligations it creates
- Assign
STATUS_ROLEto an accountable institution and document when it acts. - Every change emits
BatchStatusChangedwith a reason.
Implementation and evidence
| What | Where |
|---|---|
| Implementation | ARexToken.setBatchStatus, _update (retired check) |
| Tests | test/standard/ARexToken.test.js: status is changed by STATUS_ROLE only, and RETIRED is terminal, retired batches cannot be transferred but can be burned |
| Invariant | test/standard/Invariants.test.js: RETIRED never changes |