Canonical source for hard constraints, forbidden shortcuts, and weaver-spec compliance. Referenced from
AGENTS.md. Consult before any change that could weaken security guarantees.
agent-kernel must conform to weaver-spec invariants. All three are equally critical — there is no priority ordering.
| Invariant | Requirement | Where enforced |
|---|---|---|
| I-01 | Every tool output must pass through a context boundary before reaching the LLM | Firewall.transform() in firewall/transform.py |
| I-02 | Every execution must be authorized and auditable (CapabilityToken validated before execution; TraceEvent recorded after) | HMACTokenProvider.verify() + TraceStore.record() in kernel.py; PolicyEngine.evaluate() at grant time in grant_capability() |
| I-06 | Tokens must bind principal + capability + constraints; no reuse across principals | HMACTokenProvider.verify() in tokens.py |
Budget enforcement (size, depth, field count via
Budgetsinfirewall/budgets.py) is an implementation constraint that strengthens I-01. It has no separate invariant number in weaver-spec.
These constraints are non-negotiable. Violating any one silently degrades security.
-
Never bypass the Firewall.
RawResult → Frametransformation is mandatory. Raw driver output must never reach the LLM (except via adminrawmode, which the Firewall itself controls). -
Never skip token verification before invocation.
Kernel.invoke()always callsverify()first. Removing or short-circuiting this check defeats confused-deputy prevention. -
Never allow non-admin principals to get
rawresponse mode. The Firewall downgradesrawtosummaryfor non-admin principals. Any code path that bypasses this check leaks unbounded, unredacted data. -
Never store secrets in token payloads. Tokens are HMAC-signed but not encrypted. Payload contents are readable by anyone who holds the token.
-
Never log or print secret key material. The
AGENT_KERNEL_SECRETand any derived keys must stay out of logs, error messages, and traces. -
Never add dependencies without justification. The dependency list is intentionally minimal (
httpxonly). Every new dependency expands the attack surface. -
Never register duplicate capability IDs. The registry raises
CapabilityAlreadyRegistered. Duplicates cause ambiguous routing and policy enforcement.
These are subtle correctness hazards where the code is correct today but a careless change introduces a silent bypass.
DefaultPolicyEngine.evaluate() processes rules sequentially. Adding a new "allow"
rule before sensitivity/justification checks can silently bypass them. Always add
new rules after existing sensitivity checks, or verify that the new rule's
position does not short-circuit downstream checks.
evaluate() only checks SensitivityTag values it knows about. Adding a new tag to
the SensitivityTag enum without a corresponding rule in evaluate() means the new
tag is silently ignored — capabilities tagged with it pass policy without constraint.
Rule: When adding a SensitivityTag, always add a matching policy rule and test.
| Safe | Unsafe |
|---|---|
Refactoring driver internals without changing the Driver Protocol |
Changing the Driver Protocol (breaks downstream implementors) |
| Adding a new response mode to the Firewall | Removing the Firewall step from invoke() |
| Adding a new policy rule after existing checks | Adding a policy rule before sensitivity checks |
| Adding error subclasses | Raising bare ValueError/KeyError to callers |
- A weaver-spec invariant is added, changed, or reinterpreted.
- A new "never do" constraint is discovered through review or incident.
- A new security-critical ordering trap is identified.