Skip to content

ALP Specification — Contracts

Version: 80.0.0 Status: Stable


1. Contracts Overview

mermaid
flowchart TD
    Contract[@contract] --> From[from entity]
    Contract --> To[to entity]
    Contract --> Requires[requires preconditions]
    Contract --> Allows[allows operations]
    Contract --> Denies[denies operations]
    Engine[ContractEngine] --> Check[check contractId]
    Check --> Satisfied[Satisfied]
    Check --> Violation[ContractViolation]
    Violation --> Deny[deny]
    Violation --> Warn[warn]
    Violation --> Log[log]

2. Overview

ALP v8.3.0 introduces contracts: declarative boundary objects that define which operations, fields, and data flows are permitted between two entities (agents, tasks, repos). Contracts make cross-agent and cross-repo handoffs explicit and auditable, replacing implicit trust with verifiable least-privilege rules.

Contracts are evaluated by ContractEngine at handoff points (task transfers, repo writes, swarm messages, MCP tool calls). A violation is a ContractViolation carrying the rule id, the actual value, and the allowed set.


2. The @contract Object

A @contract lives in .alp/contracts.alp (or any .alp file loaded by the workspace). It declares a single boundary.

FieldTypeRequiredDescription
idStringYesContract identifier
nameStringNoHuman-readable name
fromRefYesSource entity (agent, repo, or task)
toRefYesDestination entity
typeStringNoBoundary kind: api (default), data, tool, repo
requiresString[]NoPre-conditions that MUST be true for the handoff
allowsString[]NoOperations/fields explicitly permitted (allow-list)
deniesString[]NoOperations/fields explicitly blocked (deny-list)
on_violationStringNoAction: deny (default), warn, log

A contract is satisfied when:

  1. Every entry in requires evaluates to true.
  2. The operation is in allows (if allows is non-empty) and not in denies.

3. Contract Engine

3.1 Evaluation

function check(contract, context):
  for req in contract.requires:
    if not evaluate(req, context):
      return violation(req, context, "required condition not met")

  op = context.operation
  if contract.allows and op not in contract.allows:
    return violation(op, context, "not in allow-list")

  if op in contract.denies:
    return violation(op, context, "denied")

  return ok

3.2 on_violation modes

ModeBehavior
deny (default)Block the operation; return ContractViolation
warnLog a warning and allow the operation to proceed
logRecord the violation in .alp/.runtime/contract-violations.jsonl

4. Examples

alp
!alp-version: 80.0.0

@contract
  id: contract-repo-access
  name: "Frontend → Backend API boundary"
  from: -> agent-frontend
  to: -> agent-backend
  type: api
  requires:
    - auth.token valid
    - rate_limit < 100
  allows:
    - api.v1.users.read
    - api.v1.users.write
    - api.v1.orders.read
  denies:
    - api.v1.admin.*
    - api.v1.internal.*
  on_violation: deny

@contract
  id: contract-data-egress
  name: "No PII leaves the workspace"
  from: -> agent-any
  to: -> external
  type: data
  denies:
    - field.ssn
    - field.credit_card
    - field.password_hash
  on_violation: deny
typescript
const engine = new ContractEngine(contracts);
const result = engine.check(contractId, {
  operation: 'api.v1.users.read',
  auth: { token: validToken },
  rate_limit: 42,
});
if (!result.ok) {
  console.error('Blocked:', result.violation.rule, result.violation.reason);
}

5. Cross-Repo Handoff Contracts

When a task in repo A hands off to repo B, the handoff must be covered by a contract whose from is a task in repo A and to is a task in repo B.

The Loop Engine (spec/05) enforces this at the handoff stage:

stage 4: handoff
  for each outgoing reference:
    contract = find_contract(from=this_task, to=target_task)
    if contract:
      result = engine.check(contract.id, context)
      if not result.ok:
        abort_handoff(result.violation)
        if on_violation == 'deny': raise ContractViolationError

6. MCP Tool Boundary

MCP tool calls between agents are also subject to contracts:

agent A invokes tool X on agent B
  → ContractEngine checks any contract(from=A, to=B, type=tool)
  → Violation → deny/warn/log per on_violation

This gives spec/07 (MCP) a runtime enforcement layer without changing the transport protocol.