DOCS

Authority sources.

How authority is sealed into execution — keys, constitutions, and admission checks.

Authority Source Adapter Contract v1.0

Status: Stable

Version: 1.0.0

Last Updated: 2026-02-09

---

Purpose

This contract defines the responsibilities and prohibitions for any system that wishes to become an authority source for ZAK governance infrastructure.

This is not a feature specification.

This is not a recommendation.

This is a contract.

Violating this contract means you are not an authority source — you are something else.

---

Core Principle

> ZAK does not react to the world.

> It records the world so institutions can explain themselves later.

Every authority source must preserve this principle.

---

What an Authority Source Is

An authority source is a system that:

  • Emits signals about institutional state changes
  • Never interprets those signals
  • Never recommends actions
  • Never auto-applies behavior changes
  • Examples:

  • GitHub = code authority (what changed in version control)
  • Okta = identity authority (who can do what)
  • Jira = change authority (what was approved)
  • AWS = runtime authority (what's deployed where)
  • ---

    Adapter Responsibilities

    An authority source adapter MUST:

    1. Normalize Events

    Convert platform-specific events into GovernanceEvent schema.

    ``typescript

    export function normalize[Platform]Event(

    eventType: string,

    payload: any,

    eventId: string

    ): GovernanceEvent | null

    `

    Required:

  • Map to one of 4 event types: state_change, authority_change, artifact_change, signal
  • Preserve occurred_at timestamp from source
  • Store full raw_payload for audit
  • Return null for unsupported events (don't guess)
  • 2. Preserve Immutability

    Events are append-only.

    Required:

  • Never modify events after creation
  • Never delete events
  • Never "correct" historical events
  • 3. Maintain Idempotency

    Same event delivered twice = same result.

    Required:

  • Use platform's event ID as raw_event_id
  • Support deduplication via unique constraint
  • 4. Store Raw Payloads

    Original platform payload must be preserved.

    Required:

  • Store in raw_payload field (JSONB)
  • Never redact unless legally required
  • If redacted, document what was removed
  • ---

    Adapter Prohibitions

    An authority source adapter MUST NOT:

    1. Interpret Meaning

    Prohibited:

    `typescript

    // WRONG

    if (event.type === 'admin_role_granted') {

    return { ...event, recommended_action: 'tighten_constraints' };

    }

    `

    Allowed:

    `typescript

    // CORRECT

    return {

    source: 'okta',

    type: 'authority_change',

    event: { name: 'privilege.granted', severity: 'high' },

    // No recommendations. Just facts.

    };

    `

    Why: Interpretation is constitutional evaluation. That lives elsewhere.

    ---

    2. Make Decisions

    Prohibited:

    `typescript

    // WRONG

    if (severity === 'critical') {

    await applyEmergencyConstitution();

    }

    `

    Allowed:

    `typescript

    // CORRECT

    await storeGovernanceEvent(event);

    // Constitutional evaluator decides what to do (if anything)

    `

    Why: Adapters emit signals. Constitutions evaluate. Humans approve.

    ---

    3. Auto-Apply Behavior Changes

    Prohibited:

    `typescript

    // WRONG

    if (productionDatabaseDeleted) {

    await freezeAIBehavior(); // Automatic action

    }

    `

    Allowed:

    `typescript

    // CORRECT

    await emitGovernanceSignal({

    recommended_action: 'freeze_mode',

    requires_approval: true, // Human must approve

    });

    `

    Why: auto_apply: false is enforced at the type level, DB constraint, and code.

    ---

    4. Add Logic

    Prohibited:

    `typescript

    // WRONG

    if (isBusinessHours() && !isWeekend()) {

    // Different behavior based on time

    }

    `

    Allowed:

    `typescript

    // CORRECT

    // Emit event with timestamp. Constitutional rules can reference time if needed.

    `

    Why: Adapters are dumb. All logic lives in constitutional evaluation.

    ---

    5. Filter Events

    Prohibited:

    `typescript

    // WRONG

    if (event.priority === 'low') {

    return null; // Silently drop

    }

    `

    Allowed:

    `typescript

    // CORRECT

    // Emit all events. Constitutional rules decide what matters.

    return normalizeEvent(event);

    `

    Why: Filtering is a decision. Adapters don't decide.

    ---

    Example Mappings

    GitHub → GovernanceEvent

    | GitHub Event | Event Type | Subject Kind | Event Name |

    |--------------|-----------|--------------|------------|

    | repository (created) | state_change | repo | repository.created |

    | push | artifact_change | branch | push |

    | pull_request.opened | artifact_change | pr | pull_request.opened |

    | workflow_run.disabled | authority_change | workflow | workflow_run.disabled |

    Okta → GovernanceEvent

    | Okta Event | Event Type | Subject Kind | Event Name |

    |------------|-----------|--------------|------------|

    | user.account.privilege.grant | authority_change | identity | privilege.granted |

    | group.user_membership.add | authority_change | identity | group.added |

    | policy.lifecycle.update | authority_change | identity | policy.updated |

    Jira → GovernanceEvent

    | Jira Event | Event Type | Subject Kind | Event Name |

    |------------|-----------|--------------|------------|

    | jira:issue_created | state_change | ticket | issue.created |

    | jira:issue_updated (status) | state_change | ticket | issue.status_changed |

    | project_deleted | state_change | project | project.deleted |

    AWS → GovernanceEvent

    | AWS Event | Event Type | Subject Kind | Event Name |

    |-----------|-----------|--------------|------------|

    | CreateBucket | state_change | environment | bucket.created |

    | PutBucketPolicy | authority_change | environment | bucket_policy.updated |

    | AssumeRole | authority_change | identity | role.assumed |

    | DeleteDBInstance | state_change | environment | database.deleted |

    ---

    Webhook Handler Pattern

    Every authority source follows the same flow:

    `typescript

    export const handler: Handler = async (event: HandlerEvent) => {

    // 1. Parse platform webhook

    const payload = JSON.parse(event.body || '{}');

    const eventType = extractEventType(payload);

    const eventId = extractEventId(payload);

    // 2. Get organization (from installation mapping)

    const orgId = await getOrganizationId(payload);

    // 3. Normalize to GovernanceEvent

    const governanceEvent = normalize[Platform]Event(eventType, payload, eventId);

    if (!governanceEvent) {

    return { statusCode: 200, body: 'Ignored (unsupported event)' };

    }

    // 4. Store event (immutable, append-only)

    const storedEvent = await storeGovernanceEvent(orgId, governanceEvent);

    // 5. Evaluate constitutionally (centralized, not in adapter)

    const evaluation = await evaluateGovernanceEvent(governanceEvent, userTier);

    // 6. Store signals (if any matched rules)

    if (evaluation.recommended_actions.length > 0) {

    await storeGovernanceSignals(orgId, storedEvent.id, evaluation);

    }

    // 7. Mark processed

    await markEventProcessed(storedEvent.id);

    return { statusCode: 200, body: 'Event processed' };

    };

    `

    Critical: Steps 5-6 are never in the adapter. They live in shared infrastructure.

    ---

    Installation Table Pattern

    Every authority source has an installation table:

    `sql

    CREATE TABLE IF NOT EXISTS [platform]_installations (

    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,

    -- Platform-specific identifiers

    [platform]_org_id TEXT NOT NULL UNIQUE,

    [platform]_domain TEXT NOT NULL,

    -- Access credentials (encrypted)

    api_token_encrypted TEXT,

    webhook_secret_encrypted TEXT,

    -- Status

    status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'suspended', 'revoked')),

    installed_at TIMESTAMPTZ DEFAULT NOW(),

    created_at TIMESTAMPTZ DEFAULT NOW(),

    updated_at TIMESTAMPTZ DEFAULT NOW()

    );

    `

    Required:

  • Link to organization_id
  • Store encrypted credentials
  • Track installation status
  • Never store plaintext secrets
  • ---

    Governance Rules (Separate from Adapters)

    Governance rules live in governance-events.ts, not in adapters.

    `typescript

    export const GOVERNANCE_RESPONSE_RULES: GovernanceResponseRule[] = [

    {

    id: 'PRODUCTION_DATABASE_DELETED',

    name: 'Production Database Deleted',

    when: {

    source: 'aws',

    type: 'state_change',

    event_name: 'database.deleted',

    condition: 'event.severity === "high"',

    },

    then: {

    action: 'freeze_mode',

    reason: 'Production database deleted - freeze AI behavior',

    severity: 'critical',

    },

    auto_apply: false, // ALWAYS false

    requires_approval: true, // ALWAYS true

    expires_after_hours: 4,

    min_tier: 'enterprise',

    },

    ];

    `

    Critical: Rules reference events by source + event_name. Adapters never see rules.

    ---

    Testing Your Adapter

    1. Emit a Test Event

    `bash

    curl -X POST https://zak.example.com/api/[platform]-webhook \

    -H "Content-Type: application/json" \

    -d '{ /* platform event payload */ }'

    `

    2. Verify Storage

    Check that:

  • Event stored in governance_events table
  • raw_payload preserved
  • processed = false initially
  • 3. Verify No Auto-Apply

    Check that:

  • No automatic behavior changes occurred
  • If rules matched, signals created with response_status = 'pending'
  • responded_by IS NULL (requires human)
  • ---

    Checklist for New Authority Source

    Before claiming compliance with this contract:

  • [ ] Adapter is dumb (no logic, no decisions)
  • [ ] Events normalize to GovernanceEvent schema
  • [ ] Raw payloads preserved in raw_payload`
  • [ ] Webhook handler follows standard pattern
  • [ ] Installation table created
  • [ ] No auto-apply anywhere in code
  • [ ] No recommendations in adapter
  • [ ] No filtering of events
  • [ ] Constitutional evaluation is centralized (not in adapter)
  • [ ] Tested with real events
  • ---

    What Happens If You Violate This Contract

    If an adapter:

  • Makes decisions → It's not an authority source, it's a policy engine
  • Auto-applies → It's not governance, it's automation
  • Filters events → It's not a witness, it's an interpreter
  • Adds logic → It's not dumb, it's smart (and will drift)
  • Result: You are building something else. Not an authority source.

    ---

    Version History

  • v1.0.0 (2026-02-09) — Initial stable release
  • ---

    Contact

    Questions? Clarifications? Proposed changes?

  • Email: governance-spec@zakplatform.com
  • GitHub: https://github.com/harmonicfutures/zak-foundry/issues
  • ---

    License

    This contract is released under CC0 1.0 Universal (Public Domain).

    Anyone may implement, extend, or reference this contract without restriction.

    ---

    End of Contract