Negative Capabilities
A negative capability answers a narrow question: is there an explicit reason this action must not occur?
DenySignal emits that fact. It does not authorize, block, or enforce.
Systems are easier to reason about when explicit denial is modeled separately from permission.
A denial fact can be queried directly. Permission still belongs to the application’s policy and enforcement layer.
Allow-based systems often encode logic like:
allowed = conditionA && conditionB && conditionC;
This can fail quietly when:
- State is missing
- Inputs are stale
- A new case is added but not wired everywhere
- Absence of information is interpreted as permission
A deny-first signal asks a narrower question:
- Is there an explicit denial fact present?
If the answer is yes, your application can decide how to react. If the answer is no, that means only that no denial fact is currently known.
- Not denied ≠ permitted
- Absence of a denial fact is not an allow-list
- Denial state is not authorization
- Returned state is application-evaluated
Negative capabilities preserve uncertainty instead of collapsing it into false confidence.
- Stale reads cause denial to persist longer than intended
- Missing writes make intended denial invisible
- Identifier mismatch returns the wrong subject or scope
- Operators forget to remove denial records
These are signal failures. Your application still owns the response.
DenySignal emits whether a denial fact exists at read time. It does not block execution.
Your application decides how to react to that fact: stop, degrade, escalate, ignore, record, or combine it with other signals.