Decision records
Thirteen architecture decisions, each with its context, alternatives and accepted consequences.
An ADR records a decision that was genuinely contested — where a reasonable engineer would have chosen differently, and where the reasoning matters more than the outcome.
Each one has the same four sections:
| Context | What problem forced a choice |
| Decision | What was chosen |
| Alternatives | What was rejected, and why |
| Consequences | What this costs, stated plainly |
The last section is the one worth reading. A decision record that lists only benefits is marketing.
#The records
| Decision | |
|---|---|
| 0001 | Scope boundaries — what Veefore deliberately is not |
| 0002 | Two planes, one image |
| 0003 | A TypeScript policy IR, not OPA |
| 0004 | Refuse escalation rather than clamp it |
| 0005 | Per-agent key pairs, not API keys |
| 0006 | A signed snapshot that is never the decision |
| 0007 | Expiring typed evidence, not a reputation score |
| 0008 | Short-lived leases to the runtime, never to the agent |
| 0009 | Discovery and authorization as separate steps |
| 0010 | A2A through the gateway, not as a direct API |
| 0011 | Two independent isolation layers |
| 0012 | A keyed hash chain in PostgreSQL |
| 0013 | Stateless planes, forward-only migrations |
#The thread running through them
Most of these resolve the same way, for the same reason: prefer a guarantee that is structural over one that is configured.
- An agent belongs to one environment, so a staging identity cannot act in production. Not a rule — an absence.
- The broker runs after every refusal, so
BLOCKmeans the secret did not go out. - The SDK depends only on
types, so it is structurally incapable of deciding anything. - No table may have a
balancecolumn, so a wallet cannot be written without the audit noticing.
Configuration drifts. Structure does not.