WEKID › Capability Blueprint › ASK reference blueprint

WEKID™ · Architecture Style Kit

WEKID™ — Govern intelligence before it governs you.

ASK (Architecture Style Kit) Master Context Manifest

Implementation Specification & Reference Blueprint · Version 1.3

Executive introduction · Reference blueprint · Audit checklist · NIST, SOC 2 and SOX control mapping

Wisdom · Experience · Knowledge · Information · DataVERSION 1.3 · 2026WEKID-STD-001 · The open standard

00 — Executive Introduction

From open standard to running code


The WEKID ASK (Architecture Style Kit) turns the WEKID standard into something an engineering team can deploy: a fail-closed runtime gate that sits between an AI system and the actions it wants to take, and lets those actions through only when the evidence supports them.

WEKID starts from one position: intelligent systems should not inherit authority because they show capability. Authority has to be earned from measured evidence, and it is always bounded by the consequences of the decision. The WEKID standard sets out that principle as normative requirements. This manifest, and the wekid-sdk 1.2 reference implementation it documents, show one way to enforce it in production, and how to evidence it inside the control frameworks your auditors already use.

Maturity sets the limit. Consequence sets the floor. Authority is what survives both.

The WEKID Framework

Where the ASK sits in the WEKID stack

WEKID is published in layers, from normative requirements down to working software. The ASK is the most concrete of them. It adds no new requirements; it applies the ones the layers above it already set.

LayerWhat it definesHow the ASK uses it
StandardWEKID-STD-001 v1.2 · STD-002 v1.1The normative core: epistemic maturity, the Trust Bridge, decision authority, gating, evaluator independence and conformance. STD-002 calibrates thresholds and gates by sector, and may tailor but never weaken the core.The source of every rule the gate enforces. Each evidence record is stamped WEKID-STD-001.
FrameworkTwo models, one Trust BridgeThe Epistemic Maturity Model (Data → Information → Knowledge → Experience → Wisdom) measures how mature knowledge is. The AI Decision Authority Model (AL-0 to AL-4) sets how much authority may be delegated. The Trust Bridge turns evidence into a ceiling on authority, never a grant.Each AI claim is mapped to one of the five layers and scored against live evidence.
Reference architectureMaturity builds up; authority is delegated downMaps each layer to enterprise systems, from logs and sensor records at Data to executive judgment at Wisdom, behind a Human Authority Boundary that is never delegated.Places the gate between AI-generated knowledge and the systems that act on it.
Capability blueprintWhat to build, sequenced by maturityReference capabilities in four tiers: Foundational, Runtime, Oversight and High-assurance, each buildable by a partner to sell or an enterprise for internal use.The ASK is a build pattern for the Runtime tier: AI Output Governance and Runtime Guardrails for Agentic AI.
Reference implementationGoverned Delivery PlatformWEKID’s own working implementation for software and AI delivery pipelines, published at demo.wekid.org.A complete, end-to-end example of the same principles applied to release decisions.
Implementation kitWEKID ASK v1.3 + wekid-sdk 1.2.0: this documentThe pip-installable runtime gate, its infrastructure and code patterns for one enforcement point, backed by an immutable evidence vault, with the audit checklist and control mappings to operate it. Written for engineers, auditors and AI coding assistants.You are here

What the gate does

Every AI output that would trigger an action passes through four steps. The first three follow the framework’s own assessment path of Parse, Score and Gate. The fourth makes every outcome auditable, so that the framework’s final step, Act, only ever happens on the record.

  1. 01ParseBreak the AI output into discrete, testable claims, each assigned to an epistemic layer.
  2. 02ScoreCheck each claim against live system evidence (database metadata, static analysis, CI results) rather than the model’s own confidence.
  3. 03GateDeny execution unless the evidence clears the threshold. A failed Data-layer claim blocks the action outright, however strong the rest of the case: gating, not averaging.
  4. 04CommitWrite every attempt, granted or denied, to a WORM evidence vault (S3 Object Lock in compliance mode) after the decision and before authority is returned. If the write fails, nothing runs.

Why it matters

  • Evidence, not assertion. Authority comes from what your systems measured, not from how fluent or confident the model sounds. A wise-sounding recommendation built on false data is still wrong.
  • Fail-closed by design. When evidence is missing, unclear, or comes from an unknown verifier, the answer is no.
  • Audit-ready from day one. Every decision leaves a fingerprinted, tamper-proof record that maps directly to NIST SP 800-53, the NIST AI RMF, SOC 2 and SOX IT general controls (Sections 06–07), and can be re-verified with wekid verify-record.
  • Built to extend. Teams register their own verifiers (telemetry, data-quality checks, test results) without changing the gate itself.

What changed in version 1.3

Version 1.2 enforced a binary allow-or-deny on the evidence side of the Trust Bridge. Version 1.3 documents the wekid-sdk 1.2.0 reference implementation, which implements the rest of WEKID-STD-001 v1.2:

  • Graded authority. Resolution to AL-0 through AL-4, including AL-2 staging for human release, AL-1 constrained grants for reversible, impact-capped actions, and AL-4 reservation to an accountable human.
  • The stakes floor. The evidence ceiling is resolved against the consequence of each decision, and every record states which limit bound the outcome.
  • The full Decision Matrix. All eight rows, evaluated in order, including Remediation Required, Approved with Monitoring and Oversight Decay.
  • Evidence provenance. Self-declared evidence caps authority at AL-2, and evaluators that are not independent of the agent count as self-declared.
  • Calibration profiles. One reviewable profile holds every threshold. It refuses any setting that would weaken the protected core, and each record carries its digest.
  • Fail-closed verifiers and commit. Placeholders and unknown verifiers fail, the registry is frozen after start-up, and no authority is granted without a committed record.

Remaining limits

  • Calibration defaults. Where the public framework leaves a number to calibration (for example the Wisdom and Experience floors, or high-risk capping at AL-2), the SDK ships documented defaults. No official WEKID-STD-002 sector profiles ship yet; review the defaults with your control owner.
  • Evaluator independence. Records capture evaluator identity and independence. Detecting correlated failure across evaluators, as WK-CORE-RFC-010 envisages, is on the roadmap.
  • Oversight telemetry. Human review rates are supplied by the caller. Computing them from override records is on the roadmap.
  • Live verifiers. The gate is only as good as the systems it checks. The example verifiers are illustrative and must be connected to your own platforms.

Conformance and use of the WEKID name

This kit implements the WEKID framework. Deploying it does not, by itself, make a system WEKID-conformant. Conformance is assessed against the current release of WEKID-STD-001 and every applicable companion standard, and a claim such as “WEKID-conformant” or “WEKID Certified” requires a trademark license from WEKID LLC. Describing a deployment as “based on the WEKID framework” or “implementing the Epistemic Maturity Model” needs no permission.

The wekid-sdk reference implementation is open source under the Apache License 2.0: anyone may use, modify and redistribute it, including commercially. The licence covers the code, not the WEKID™ name or marks; the trademark terms are set out in the SDK’s NOTICE file.

How to read this document

Executives & governance leadsThis introduction.
Enterprise & solution architectsSections 01–02: the architectural mandate and the compliance evidence vault.
Platform & application engineersSections 03–05: packaging, the verifier registry and gate engine, and API integration. The SDK ships INSTALL.md and docs/SDK_REFERENCE.md for every method.
Internal audit, risk & complianceSections 06–07: the audit checklist and the mapping to NIST, SOC 2 and SOX controls.
AI coding assistantsThe whole document, loaded as system context.

About this manifest

This single, self-contained reference file is the system context for Large Language Models (LLMs) and coding assistants (e.g., Cursor, Claude Projects, Custom GPTs). It sets out the architectural requirements, infrastructure blueprints, dependency set-up and code patterns needed to implement the WEKID-STD-001 v1.2 governance framework with the wekid-sdk 1.2.0 reference implementation. All code in Sections 02–05 is copied verbatim from the SDK source and covered by its test suite. The SDK is open source under the Apache License 2.0; the WEKID™ name and marks are not licensed by it.


01 — Overview

Architectural Mandate & Strategy


The WEKID ASK is a deterministic, fail-closed runtime gate for probabilistic AI outputs. No AI agent or system may execute downstream infrastructure changes, data operations or high-risk business logic without presenting verifiable evidence to the gate, and no authority is granted unless the decision has first been committed to the evidence vault.

The Runtime Lifecycle Execution

  1. 01ParseThe AI output is broken into isolated, testable Claims, each bound to one of the five epistemic layers (Data, Information, Knowledge, Experience, Wisdom) and to a verifier registered for that same layer.
  2. 02ScoreThe VerifierRegistry checks each claim against live systems and produces measured evidence. The five layers are scored over the evidence actually supplied; a layer with no evidence supports nothing. Self-declared evidence is labelled as such.
  3. 03GateThe Trust Bridge applies the Decision Matrix (first match governs) to set a maturity ceiling, consequence sets a stakes cap, and the Authority Level (AL-0 to AL-4) is whichever is more conservative.
  4. 04CommitEvery attempt, granted or denied, is fingerprinted and written to the WORM evidence vault after the decision and before authority is returned. If the write fails, the gate grants no authority.

Authority Levels

LevelMeaningIntegration behaviour
AL-3 AugmentedAutonomous within scope; human on the loopExecute (sample for review when enhanced_sampling is true)
AL-2 SupervisedAI proposes and stages; a human releases each actionStage; route record_id to the accountable human
AL-1 ConstrainedWhitelisted, reversible, impact-capped actions onlyExecute only reversible, in-cap actions
AL-0 No AuthorityInformational onlyDo not execute; re-plan from the governing triggers
AL-4 Human AuthorityReserved to an accountable human (from consequence, never maturity)Do not act; inform the human decision-maker

Decision Matrix (WEKID-STD-001 v1.2)

RowOutcomeConditionMaturity ceiling
1RejectedHard gate: fabrication, Data < 2, high-stakes judgment failure, failed Data-layer claim, policy hard gateAL-0
2Insufficient MaturityA layer without evidence, or Maturity Score < 50AL-0
3Oversight DecayEngagement gating active and the human loop not exercisedAt most AL-2
4ConstrainedAny layer < 3, or Wisdom / Experience below the profile floorAL-2
5Remediation RequiredMaturity Score 50–69, or a soft gate firedAL-1
6Approved with MonitoringMaturity Score 70–79, gate-freeAL-3 + enhanced sampling
7Approved for Autonomous UseMaturity Score ≥ 80, gate-freeAL-3
8Policy-ReservedSafety-critical, legally reserved, reserved decision class, or irreversible and high-riskAL-4

02 — AWS S3 Compliance Vault

Infrastructure Layer


Terraform Blueprint

The immutable evidence repository. Object Lock runs in COMPLIANCE mode, so no one, including the root user, can delete or alter a record during retention. Retention is a variable (default 2,555 days, about seven years); public access is blocked, the bucket accepts TLS only, and separate least-privilege policies are issued for the gate and for auditors. Variables and outputs are in variables.tf and outputs.tf.

infra/terraform/main.tf · HCL
# SPDX-License-Identifier: Apache-2.0
# Copyright 2025-2026 WEKID LLC
# WEKID evidence vault — S3 with Object Lock (COMPLIANCE mode).
#
# Changes from the ASK v1.2 manifest blueprint:
#   * retention is a variable (default 2555 days ≈ 7 years; the manifest's 365 days is
#     usually too short for SOX-relevant records — align with your retention schedule)
#   * public access fully blocked; TLS-only bucket policy; bucket-owner-enforced ownership
#   * optional SSE-KMS (customer-managed key) instead of SSE-S3
#   * separate least-privilege policies for the gate (append-only) and auditors (read-only)
#
# COMPLIANCE mode cannot be shortened or removed by anyone, including the root user, for the
# retention period. Test with a short retention in a sandbox account first.

terraform {
  required_version = ">= 1.5"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0"
    }
  }
}

provider "aws" {
  region = var.region
}

resource "aws_s3_bucket" "wekid_corpus" {
  bucket              = var.bucket_name
  object_lock_enabled = true
  tags                = merge(var.tags, { Framework = "WEKID-Governance", Compliance = "Immutable-Evidence-Logs" })
}

resource "aws_s3_bucket_ownership_controls" "wekid" {
  bucket = aws_s3_bucket.wekid_corpus.id
  rule {
    object_ownership = "BucketOwnerEnforced"
  }
}

resource "aws_s3_bucket_public_access_block" "wekid" {
  bucket                  = aws_s3_bucket.wekid_corpus.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_versioning" "wekid" {
  bucket = aws_s3_bucket.wekid_corpus.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_object_lock_configuration" "wekid" {
  bucket = aws_s3_bucket.wekid_corpus.id
  rule {
    default_retention {
      mode = "COMPLIANCE"
      days = var.retention_days
    }
  }
  depends_on = [aws_s3_bucket_versioning.wekid]
}

resource "aws_s3_bucket_server_side_encryption_configuration" "wekid" {
  bucket = aws_s3_bucket.wekid_corpus.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = var.kms_key_arn == "" ? "AES256" : "aws:kms"
      kms_master_key_id = var.kms_key_arn == "" ? null : var.kms_key_arn
    }
    bucket_key_enabled = var.kms_key_arn != ""
  }
}

data "aws_iam_policy_document" "bucket" {
  statement {
    sid       = "DenyInsecureTransport"
    effect    = "Deny"
    actions   = ["s3:*"]
    resources = [aws_s3_bucket.wekid_corpus.arn, "${aws_s3_bucket.wekid_corpus.arn}/*"]
    principals {
      type        = "*"
      identifiers = ["*"]
    }
    condition {
      test     = "Bool"
      variable = "aws:SecureTransport"
      values   = ["false"]
    }
  }
}

resource "aws_s3_bucket_policy" "wekid" {
  bucket     = aws_s3_bucket.wekid_corpus.id
  policy     = data.aws_iam_policy_document.bucket.json
  depends_on = [aws_s3_bucket_public_access_block.wekid]
}

# --- least-privilege policies ---------------------------------------------------------

data "aws_iam_policy_document" "gate_writer" {
  statement {
    sid       = "WekidAppendOnlyWrite"
    actions   = ["s3:PutObject", "s3:PutObjectRetention"]
    resources = ["${aws_s3_bucket.wekid_corpus.arn}/${var.prefix}*"]
  }
  dynamic "statement" {
    for_each = var.kms_key_arn == "" ? [] : [1]
    content {
      sid       = "WekidKmsEncrypt"
      actions   = ["kms:GenerateDataKey", "kms:Encrypt"]
      resources = [var.kms_key_arn]
    }
  }
}

data "aws_iam_policy_document" "gate_reader" {
  # Only needed if the gate serves /v1/records (record retrieval and overrides).
  statement {
    sid       = "WekidReadRecords"
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.wekid_corpus.arn}/${var.prefix}*"]
  }
  statement {
    sid       = "WekidListOverrides"
    actions   = ["s3:ListBucket"]
    resources = [aws_s3_bucket.wekid_corpus.arn]
    condition {
      test     = "StringLike"
      variable = "s3:prefix"
      values   = ["${var.prefix}overrides/*"]
    }
  }
  dynamic "statement" {
    for_each = var.kms_key_arn == "" ? [] : [1]
    content {
      sid       = "WekidKmsDecrypt"
      actions   = ["kms:Decrypt"]
      resources = [var.kms_key_arn]
    }
  }
}

data "aws_iam_policy_document" "auditor" {
  statement {
    sid       = "WekidAuditRead"
    actions   = ["s3:GetObject", "s3:GetObjectVersion", "s3:GetObjectRetention", "s3:GetObjectAttributes"]
    resources = ["${aws_s3_bucket.wekid_corpus.arn}/*"]
  }
  statement {
    sid = "WekidAuditList"
    actions = ["s3:ListBucket", "s3:ListBucketVersions", "s3:GetBucketObjectLockConfiguration",
    "s3:GetBucketVersioning", "s3:GetEncryptionConfiguration", "s3:GetBucketPolicy"]
    resources = [aws_s3_bucket.wekid_corpus.arn]
  }
  dynamic "statement" {
    for_each = var.kms_key_arn == "" ? [] : [1]
    content {
      sid       = "WekidKmsDecrypt"
      actions   = ["kms:Decrypt"]
      resources = [var.kms_key_arn]
    }
  }
}

resource "aws_iam_policy" "gate_writer" {
  name   = "${var.name_prefix}-gate-writer"
  policy = data.aws_iam_policy_document.gate_writer.json
}

resource "aws_iam_policy" "gate_reader" {
  name   = "${var.name_prefix}-gate-reader"
  policy = data.aws_iam_policy_document.gate_reader.json
}

resource "aws_iam_policy" "auditor" {
  name   = "${var.name_prefix}-auditor-readonly"
  policy = data.aws_iam_policy_document.auditor.json
}

IAM Security Profile — gate writer

The gate writes blind and append-only. It cannot read, delete or shorten retention.

infra/iam/gate-writer-policy.json · JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "WekidAppendOnlyWrite",
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:PutObjectRetention"],
      "Resource": "arn:aws:s3:::YOUR-WEKID-BUCKET/evidence/*"
    }
  ]
}

IAM Security Profile — auditor

A separate read-only role for internal audit (audit check 17).

infra/iam/auditor-readonly-policy.json · JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "WekidAuditRead",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:GetObjectVersion", "s3:GetObjectRetention", "s3:GetObjectAttributes"],
      "Resource": "arn:aws:s3:::YOUR-WEKID-BUCKET/*"
    },
    {
      "Sid": "WekidAuditList",
      "Effect": "Allow",
      "Action": ["s3:ListBucket", "s3:ListBucketVersions", "s3:GetBucketObjectLockConfiguration",
                 "s3:GetBucketVersioning", "s3:GetEncryptionConfiguration", "s3:GetBucketPolicy"],
      "Resource": "arn:aws:s3:::YOUR-WEKID-BUCKET"
    }
  ]
}

03 — pyproject.toml

Dependency Configuration


The SDK is a single pip-installable package. The core engine, gate, vaults, client and CLI use only the Python standard library; the HTTP service and S3 vault are optional extras. Install with pip install "wekid_sdk-1.2.0-py3-none-any.whl[server,aws]" and verify with wekid scenarios.

toml
[build-system]
requires = ["setuptools>=77", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "wekid-sdk"
version = "1.2.0"
description = "WEKID Architecture Style Kit (ASK) runtime gate and SDK — implements WEKID-STD-001 v1.2: five-layer scoring, the Trust Bridge, AI Decision Authority Levels AL-0..AL-4, and a WORM evidence vault."
readme = "README.md"
requires-python = ">=3.10"
license = "Apache-2.0"
license-files = ["LICENSE", "NOTICE"]
authors = [{ name = "WEKID LLC" }]
maintainers = [{ name = "James Madigan Judge" }]
keywords = ["wekid", "ai-governance", "trust-bridge", "authority-levels", "audit", "worm"]
classifiers = [
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Operating System :: OS Independent",
]
# The core engine, gate, vaults (memory/file), client and CLI use the standard library only.
dependencies = []

[project.optional-dependencies]
server = ["fastapi>=0.110", "uvicorn>=0.29", "pydantic>=2.6"]
aws = ["boto3>=1.28"]
test = ["httpx>=0.27", "fastapi>=0.110", "pydantic>=2.6"]
all = ["fastapi>=0.110", "uvicorn>=0.29", "pydantic>=2.6", "boto3>=1.28", "httpx>=0.27"]

[project.scripts]
wekid = "wekid.cli:main"

[project.urls]
Homepage = "https://wekid.org"
Framework = "https://wekid.org/framework.php"
Standards = "https://wekid.org/standards.php"
Blueprint = "https://wekid.org/blueprint/ask/index.php"

[tool.setuptools.packages.find]
where = ["src"]

[tool.setuptools.package-data]
wekid = ["data/*.json", "py.typed"]

04 — Python

Software Application Architecture


Module Map

ModuleResponsibility
models.pyData contract: AuthorityLevel, Outcome, Provenance, request and Determination types
calibration.pyCalibrationProfile; refuses any profile that would weaken the protected core
scoring.pyFive-layer scoring over supplied evidence; Maturity Score 0–100
bridge.pyGates, floors, Decision Matrix, provenance cap, stakes floor, authority resolution
verifiers.pyLayer-bound, fail-closed, freezable VerifierRegistry; built-in sql_safety
sqlsafety.pyStatic SQL safety checks
vault.pyMemoryVault, FileVault (hash-chained), S3ObjectLockVault (WORM)
gate.pyWekidGate: assess, permits, guard, governed, overrides
api.py / client.py / cli.pyHTTP service, zero-dependency client, wekid command

Modular System Verifiers

Each verifier checks one claim against a live system and returns measured evidence for one layer. Modules expose register(registry); the service loads them at start-up (WEKID_VERIFIER_MODULES) and then freezes the registry, so verifiers change only through a deployment. Unknown verifiers, errors and the manifest's original DB_METADATA_API and CI_BUILD_LOGS placeholders all fail closed.

examples/custom_verifiers.py · Python
# SPDX-License-Identifier: Apache-2.0
# Copyright 2025-2026 WEKID LLC
"""
examples/custom_verifiers.py — how to plug live systems into the gate.

Load it into the service with:

    WEKID_VERIFIER_MODULES=custom_verifiers  wekid serve      # module must be importable

The service calls ``register(registry)`` at start-up and then freezes the
registry, so verifiers can only change through a deployment (change control).

Each verifier returns measured evidence for ONE layer. Replace the stub
functions below with calls to your real systems.
"""

from __future__ import annotations

from wekid import Claim, VerifierRegistry, VerifierResult, http_health, metric_threshold


# --- Data layer: is the target database healthy and within limits? -----------
def _replica_lag_seconds(claim: Claim) -> float:
    # e.g. query CloudWatch / pg_stat_replication for the cluster named in the claim
    return 1.4


def _orders_db_metadata(content: str, claim: Claim) -> VerifierResult:
    lag = _replica_lag_seconds(claim)
    storage_used = 0.62  # e.g. from your metadata API
    if lag > 5.0 or storage_used > 0.85:
        return VerifierResult(False, 0.0, f"replica lag {lag}s / storage {storage_used:.0%} outside limits")
    # Per-component evidence (0-5) is better than a single score when you have it.
    return VerifierResult(True, 1.0, f"replica lag {lag}s, storage {storage_used:.0%}",
                          signals={"source_integrity": 4.8, "freshness": 4.6 if lag < 2 else 3.6,
                                   "anomaly_control": 4.5, "access_control": 4.7,
                                   "completeness": 4.5, "lineage": 4.4})


# --- Experience layer: has this change passed CI / staging before? -----------
def _ci_status(content: str, claim: Claim) -> VerifierResult:
    passed, total = 48, 50  # e.g. from your CI API for the change referenced in the claim
    rate = passed / total
    return VerifierResult(rate >= 0.95, rate, f"{passed}/{total} staging runs passed", score=round(rate * 5, 2))


def register(registry: VerifierRegistry) -> None:
    registry.register("orders_db_metadata", _orders_db_metadata, layer="data", owner="data-platform",
                      description="Orders cluster replica lag and storage headroom")
    registry.register("ci_pipeline_status", _ci_status, layer="experience", owner="platform-eng",
                      description="Staging pass rate for the change under review (>= 95%)")
    registry.register("payments_api_health", http_health("https://payments.internal/healthz", timeout=2.0),
                      layer="data", owner="payments", description="Payments API health endpoint returns 200")
    registry.register("error_budget", metric_threshold(lambda c: 0.31, "<", 0.8, "error budget burn"),
                      layer="experience", owner="sre", description="Error-budget burn below 80%")

Core Governance Interceptor: the Decision Matrix (src/wekid/bridge.py, excerpt)

Gates and floors are evaluated first, then the matrix rows in order. A high Maturity Score can never override a failure beneath it.

Python
# ---- Decision Matrix --------------------------------------------------
s = scores.maturity_score
sampling = False

def govern(ts: List[Trigger]) -> None:
    for t in ts:
        t.governing = True

if hard:
    outcome, ceiling = Outcome.REJECTED, AL.AL0
    govern(hard)
elif no_ceiling:
    outcome, ceiling = Outcome.INSUFFICIENT_MATURITY, AL.AL0
    govern(no_ceiling)
elif s < p.insufficient_below:
    outcome, ceiling = Outcome.INSUFFICIENT_MATURITY, AL.AL0
    t = Trigger("band:insufficient_maturity", "band", f"maturity score {s:.1f} < {p.insufficient_below:.0f}", True)
    other.append(t)
else:
    if floors:
        outcome, ceiling = Outcome.CONSTRAINED, AL.AL2
        govern(floors)
    elif s < p.remediation_below or soft:
        outcome, ceiling = Outcome.REMEDIATION_REQUIRED, AL.AL1
        if soft:
            govern(soft)
        if s < p.remediation_below:
            other.append(Trigger("band:remediation_required", "band",
                                 f"maturity score {s:.1f} in {p.insufficient_below:.0f}-{p.remediation_below - 1:.0f}",
                                 not soft))
    elif s < p.autonomous_from:
        outcome, ceiling, sampling = Outcome.APPROVED_WITH_MONITORING, AL.AL3, True
        other.append(Trigger("band:approved_with_monitoring", "band",
                             f"maturity score {s:.1f} in {p.remediation_below:.0f}-{p.autonomous_from - 1:.0f}", True))
    else:
        outcome, ceiling = Outcome.APPROVED_AUTONOMOUS, AL.AL3
    if req.oversight.decayed:
        outcome = Outcome.OVERSIGHT_DECAY
        ceiling = min(ceiling, AL.AL2)
        sampling = False
        other.append(Trigger("oversight:decay", "oversight",
                             "engagement gating active and the human loop is not demonstrably exercised", True))

# Self-declared evidence cannot support the upper tiers.
self_declared = [n for n, ls in L.items() if ls.provenance == Provenance.SELF_DECLARED]
if self_declared and ceiling > p.self_declared_ceiling:
    ceiling = p.self_declared_ceiling
    sampling = False
    other.append(Trigger("provenance:self_declared_cap", "provenance",
                         f"self-declared evidence ({', '.join(sorted(self_declared))}) caps the ceiling at "
                         f"{p.self_declared_ceiling.code}", True))
maturity_outcome = outcome

# ---- stakes floor (Model Two) ----------------------------------------
c = req.consequence
if c.risk_level not in p.stakes_cap_by_risk:
    raise InvalidRequest(f"consequence.risk_level '{c.risk_level}' not in {sorted(p.stakes_cap_by_risk)}")
reasons: List[str] = []
if c.safety_critical:
    reasons.append("safety-critical")
if c.legally_reserved:
    reasons.append("legally reserved")
if c.decision_class and c.decision_class in p.reserved_decision_classes:
    reasons.append(f"decision class '{c.decision_class}' reserved by policy")
if p.reserve_irreversible_high_risk and not c.reversible and c.risk_level == "high":
    reasons.append("irreversible and high-risk")
stakes: List[Trigger] = []
if reasons:
    cap = AL.AL4
    stakes.append(Trigger("stakes:policy_reserved", "stakes", "; ".join(reasons), True))
else:
    cap = p.stakes_cap_by_risk[c.risk_level]
    if cap < AL.AL3:
        stakes.append(Trigger(f"stakes:risk:{c.risk_level}", "stakes", f"{c.risk_level} risk caps at {cap.code}"))
    if not c.reversible and p.irreversible_cap < cap:
        cap = p.irreversible_cap
        stakes.append(Trigger("stakes:irreversible", "stakes", f"irreversible action caps at {cap.code}"))
    if policy:
        for cond, lvl in policy.caps.items():
            lvl = AL.parse(lvl)
            if _fired(cond, req, scores, p) and lvl < cap:
                cap = lvl
                stakes.append(Trigger(f"stakes:policy_cap:{cond}", "stakes", f"policy caps at {lvl.code}"))

# ---- resolution -------------------------------------------------------
if cap == AL.AL4:
    final, binding, outcome = AL.AL4, BindingLimit.POLICY_RESERVATION, Outcome.POLICY_RESERVED
    sampling = False
else:
    final = min(ceiling, cap)
    if ceiling < cap:
        binding = BindingLimit.MATURITY_CEILING
    elif cap < ceiling:
        binding = BindingLimit.STAKES_FLOOR
        sampling = False
        for t in stakes:
            t.governing = True
    else:
        binding = BindingLimit.BOTH
    outcome = maturity_outcome

Evidence Commit: S3 Object Lock (src/wekid/vault.py, excerpt)

Records are fingerprinted with SHA-256 over canonical JSON, uploaded with the integrity checksum that Object Lock requires, and optionally given a per-object COMPLIANCE retain-until date.

Python
    def commit(self, record: Dict[str, Any]) -> Dict[str, Any]:
        rec = dict(record)
        rec["fingerprint"] = compute_fingerprint(rec)
        body = json.dumps(rec, indent=2, sort_keys=True, ensure_ascii=False).encode("utf-8")
        params: Dict[str, Any] = {
            "Bucket": self.bucket,
            "Key": self._key(rec),
            "Body": body,
            "ContentType": "application/json",
            "ChecksumAlgorithm": "SHA256",
            "ChecksumSHA256": base64.b64encode(hashlib.sha256(body).digest()).decode("ascii"),
            "Metadata": {"wekid-fingerprint": rec["fingerprint"], "wekid-schema": EVIDENCE_SCHEMA},
        }
        if self.retention_days:
            params["ObjectLockMode"] = "COMPLIANCE"
            params["ObjectLockRetainUntilDate"] = utc_now() + _dt.timedelta(days=int(self.retention_days))
        if self.kms_key_id:
            params["ServerSideEncryption"] = "aws:kms"
            params["SSEKMSKeyId"] = self.kms_key_id
        try:
            self.client.put_object(**params)
        except Exception as e:
            raise EvidenceCommitError(f"S3 evidence write failed: {type(e).__name__}: {e}") from e
        rec["location"] = f"s3://{self.bucket}/{params['Key']}"
        return rec

Fail-Closed Gate (src/wekid/gate.py, excerpt)

The determination is committed before authority is returned; commit failures are retried and then raise EvidenceCommitError. permits() never grants authority to an uncommitted determination.

Python
    def _write(self, record: Dict[str, Any]) -> Dict[str, Any]:
        last: Optional[Exception] = None
        for attempt in range(self.commit_retries + 1):
            try:
                return self.vault.commit(record)
            except Exception as e:  # retry, then fail closed
                last = e
                log.error("evidence commit failed (attempt %d/%d): %s", attempt + 1, self.commit_retries + 1, e)
                if attempt < self.commit_retries:
                    time.sleep(self.retry_backoff_s * (2 ** attempt))
        raise EvidenceCommitError(f"evidence record {record.get('record_id')} not committed; "
                                  f"authority withheld: {last}") from last

    def _commit(self, req: AssessmentRequest, det: Determination, extra: Optional[Dict[str, Any]] = None) -> None:
        d = det.to_dict()
        for k in ("record_id", "committed", "fingerprint"):
            d.pop(k, None)
        body = {"request": request_to_dict(req, self.redact_content), "determination": d}
        if extra:
            body.update(extra)
        stored = self._write(self._envelope("determination", det.record_id, body))
        det.committed = True
        det.fingerprint = stored.get("fingerprint")

    # ------------------------------------------------------------------ enforcement
    def permits(self, det: Determination, action: Optional[ActionSpec] = None) -> bool:
        """Does this determination permit the action to run *now*, without a human?"""
        if not det.committed:
            return False
        al = det.authority_level
        if al == AuthorityLevel.AL3:
            return True
        if al == AuthorityLevel.AL1:
            if action is None or not action.reversible:
                return False
            if self.profile.al1_impact_cap and action.impact > self.profile.al1_impact_cap:
                return False
            if self.profile.al1_allowlist and action.name not in self.profile.al1_allowlist:
                return False
            return True
        return False  # AL-0 informational, AL-2 needs release, AL-4 reserved to a human

    def guard(self, req: AssessmentRequest, action: Optional[ActionSpec] = None) -> Determination:
        """Assess and raise unless the action may run now.

        Raises ``HumanReleaseRequired`` for AL-2 / AL-4 (stage it for a human),
        ``AuthorityDenied`` otherwise, ``EvidenceCommitError`` if the record
        could not be written.
        """
        det = self.assess(req)
        if self.permits(det, action):
            return det
        if det.authority_level in (AuthorityLevel.AL2, AuthorityLevel.AL4):
            raise HumanReleaseRequired(f"{det.authority_level.code}: human release required "
                                       f"(record {det.record_id})", det)
        raise AuthorityDenied(f"{det.authority_level.code} {det.outcome.value}: action not permitted "
                              f"(record {det.record_id})", det)

    def governed(self, build_request: Callable[..., AssessmentRequest],
                 action: Optional[Callable[..., ActionSpec]] = None):
        """Decorator: run the function only if the gate permits it.

            @gate.governed(lambda order_id, amount: make_request(order_id, amount),
                           action=lambda order_id, amount: ActionSpec("refund", True, amount))
            def refund(order_id, amount): ...
        """
        def deco(fn):
            @functools.wraps(fn)
            def wrapper(*args, **kwargs):
                req = build_request(*args, **kwargs)
                spec = action(*args, **kwargs) if action else None
                self.guard(req, spec)
                return fn(*args, **kwargs)
            return wrapper
        return deco

05 — FastAPI Integration

End-to-End Runtime Blueprint


The original Section 5 endpoint, rebuilt on the SDK (integrations/fastapi_governed_action.py). Verifiers are registered and frozen at start-up, every claim is bound to a verifier of its own layer, the decision is committed before anything executes, and the response distinguishes execute (200), staged for human release, denied (403) and evidence-not-committed (503).

Python
# SPDX-License-Identifier: Apache-2.0
# Copyright 2025-2026 WEKID LLC
"""
integrations/fastapi_governed_action.py — embed the gate in your own FastAPI service.

This is the ASK v1.2 manifest's Section 5 endpoint, rebuilt on the SDK:

* verifiers are registered at start-up and the registry is frozen;
* every claim is bound to a verifier of the same layer;
* the determination is committed to the evidence vault *after* the decision and
  *before* anything executes; a failed commit returns 503 and nothing runs;
* the response distinguishes 200 (execute), 202 (human release) and 403 (denied).

Run:  uvicorn fastapi_governed_action:app --app-dir integrations --port 8100
(needs: pip install 'wekid-sdk[server]'; set WEKID_VAULT=s3 + WEKID_CORPUS_BUCKET for WORM storage)
"""

from __future__ import annotations

import os
import sys

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "examples"))

from wekid import (ActionSpec, AuthorityDenied, EvidenceCommitError, HumanReleaseRequired, VerifierRegistry,
                   WekidGate, vault_from_env)

import custom_verifiers  # your verifiers: register(registry)

registry = VerifierRegistry()
custom_verifiers.register(registry)
registry.freeze()
gate = WekidGate(registry=registry, vault=vault_from_env())

app = FastAPI(title="Governed actions")


class GovernedSQL(BaseModel):
    request_id: str
    sql_query: str
    cluster: str
    change_ref: str
    reviewed_wisdom: dict       # signals from your independent review step
    reviewed_information: dict  # signals from your grounding checks


def run_sql(sql: str) -> None:  # your executor
    print("EXECUTING:", sql)


@app.post("/api/v1/execute-governed-action")
def execute_action(body: GovernedSQL):
    request = gate.parse({
        "output": {"output_id": body.request_id, "output_type": "tool_call", "content": body.sql_query},
        "consequence": {"risk_level": "medium", "domain": "data_operations"},
        "claims": [
            {"claim_id": "C1", "layer": "knowledge", "verifier": "sql_safety", "content": body.sql_query},
            {"claim_id": "C2", "layer": "data", "verifier": "orders_db_metadata", "content": body.cluster},
            {"claim_id": "C3", "layer": "experience", "verifier": "ci_pipeline_status", "content": body.change_ref},
        ],
        "evidence": {
            "wisdom": {"provenance": "measured", "evaluator_id": "review-panel", "signals": body.reviewed_wisdom},
            "information": {"provenance": "measured", "evaluator_id": "grounding", "signals": body.reviewed_information},
        },
    })
    try:
        det = gate.guard(request, action=ActionSpec("sql_write", reversible=False))
    except EvidenceCommitError as e:
        raise HTTPException(status_code=503, detail=f"evidence not committed; nothing executed: {e}")
    except HumanReleaseRequired as e:
        return {"status": "STAGED", "authority_level": e.determination.authority_level.code,
                "record_id": e.determination.record_id}
    except AuthorityDenied as e:
        d = e.determination
        raise HTTPException(status_code=403, detail={
            "authority_level": d.authority_level.code, "outcome": d.outcome.value, "record_id": d.record_id,
            "governing_triggers": [t.code for t in d.triggers if t.governing]})
    run_sql(body.sql_query)
    return {"status": "EXECUTED", "authority_level": det.authority_level.code, "record_id": det.record_id}

Request Contract

The same JSON shape is accepted by WekidGate.assess(), the HTTP service, the client and wekid assess. Evidence for layers not covered by claims comes from measured sources such as grounding checks and independent review.

POST /v1/authorize · JSON
{
  "output": {
    "output_id": "SQL-7781",
    "output_type": "tool_call",
    "content": "UPDATE accounts SET status = 'closed' WHERE account_id = 4417"
  },
  "consequence": {
    "risk_level": "medium",
    "domain": "data_operations",
    "reversible": true
  },
  "claims": [
    {
      "claim_id": "C1",
      "layer": "knowledge",
      "verifier": "sql_safety",
      "content": "UPDATE accounts SET status = 'closed' WHERE account_id = 4417"
    },
    {
      "claim_id": "C2",
      "layer": "data",
      "verifier": "orders_db_metadata",
      "content": "accounts cluster"
    },
    {
      "claim_id": "C3",
      "layer": "experience",
      "verifier": "ci_pipeline_status",
      "content": "change 8812"
    }
  ],
  "evidence": {
    "information": {
      "provenance": "measured",
      "evaluator_id": "grounding-checker",
      "signals": {
        "context_accuracy": 4.3,
        "relevance": 4.4,
        "faithfulness": 4.2,
        "completeness": 4.0
      }
    },
    "wisdom": {
      "provenance": "measured",
      "evaluator_id": "ops-review-panel",
      "signals": {
        "authority_calibration": 4.2,
        "contextual_awareness": 4.1,
        "consequence_awareness": 4.3,
        "ethical_alignment": 4.6,
        "judgment_under_ambiguity": 4.0,
        "tradeoff_optimization": 4.0,
        "restraint_escalation": 4.2
      }
    }
  }
}

Determination (abridged)

Generated by running the request above through the SDK with the example verifiers. Enforce authority_level; never act when committed is false.

JSON
{
  "record_id": "wkd-20261025T141511Z-eca014903e49",
  "authority_level": "AL-3",
  "authority_title": "Augmented Authority",
  "outcome": "APPROVED_AUTONOMOUS",
  "maturity_ceiling": "AL-3",
  "stakes_cap": "AL-3",
  "binding_limit": "both",
  "maturity_score": 91.15,
  "enhanced_sampling": false,
  "committed": true,
  "fingerprint": "25edf01934941de9613e7c581474bea4a4f98ea80c5dea7336d2acae763a4ee6",
  "permissions": {
    "may_execute_autonomously": true,
    "requires_human_release": false,
    "constrained_only": false,
    "informational_only": false,
    "reserved_to_human": false
  },
  "claims": [
    {
      "claim_id": "C1",
      "verifier": "sql_safety",
      "valid": true,
      "reason": "UPDATE statement passed static safety checks"
    },
    {
      "claim_id": "C2",
      "verifier": "orders_db_metadata",
      "valid": true,
      "reason": "replica lag 1.4s, storage 62%"
    },
    {
      "claim_id": "C3",
      "verifier": "ci_pipeline_status",
      "valid": true,
      "reason": "48/50 staging runs passed"
    }
  ],
  "rationale": "Maturity score 91.2; matrix outcome APPROVED_AUTONOMOUS; maturity ceiling AL-3. Stakes cap AL-3. Authority AL-3 Augmented Authority (bound by both)."
}

Service Configuration

Set WEKID_VAULT=s3 with WEKID_CORPUS_BUCKET, WEKID_RETENTION_DAYS and optionally WEKID_KMS_KEY_ID for WORM storage; WEKID_API_KEYS for bearer authentication; WEKID_VERIFIER_MODULES to load verifiers; and WEKID_PROFILE for an approved calibration profile. Run with wekid serve or uvicorn wekid.api:app. Full installation steps and every method are in INSTALL.md and docs/SDK_REFERENCE.md.

06 — Audit Checklist

Audit Checklist


Use this checklist to test the gate and the evidence vault before relying on them, and at each audit cycle after that. Each check names the evidence to obtain and the controls it supports, so results can be filed directly against your existing control matrix. Control references are explained in Section 07.

A. Governance & ownership

B. Gate operation

C. Verifiers

D. Evidence vault

E. Access

F. Monitoring & response

07 — Control Integration

Mapping to NIST, SOC 2 and SOX


The gate and the evidence vault are designed to be tested inside your existing audit programs, not as a separate AI regime. This section shows which control objectives each part of the ASK supports, so control owners can add it to their control matrix and auditors can reuse the evidence it produces.

Frameworks in scope

FrameworkWhat it coversWhere the ASK fits
NIST SP 800-53 Rev. 5Catalog of security and privacy controls for information systems.Audit logging, access enforcement, change control and integrity of the gate and vault.
NIST AI RMF 1.0 (AI 100-1)Voluntary framework for managing AI risk through four functions: Govern, Map, Measure and Manage.Human oversight, testing and production monitoring, and the ability to stop AI actions.
SOC 2 (AICPA Trust Services Criteria)Attestation over security, availability, processing integrity, confidentiality and privacy.Common Criteria CC1–CC8 and Processing Integrity PI1.
SOX §404 IT general controlsInternal control over financial reporting, typically assessed against COSO 2013 and audited under PCAOB AS 2201.In scope only where gated AI actions can change financially significant systems or data. The gate then acts as an ITGC over data operations and program changes.

Control mapping

Objective & ASK mechanismNIST SP 800-53NIST AI RMFSOC 2SOX / COSO
Governance & accountabilityGate policy tied to WEKID-STD-001; threshold and veto rules owned and approved.PM-9 · CA-6GOVERN 1.4 · GOVERN 2.1CC1.3 · CC5.3Entity-level controls · COSO P3, P12
Pre-execution authorizationNo AI action runs without a committed grant; denials return 403 and staged actions 202.AC-3 · CM-3 · CM-5MAP 3.5 · MANAGE 2.4CC6.1 · CC8.1ITGC: access to programs & data · program changes
Evidence-based verificationClaims checked against live verifiers, not model confidence.SI-10 · SA-11 · CA-7MEASURE 2.1 · 2.4 · 2.5CC4.1 · CC7.1 · PI1.3ITGC: program changes (testing) · COSO P11
Immutable audit trailWORM vault, Object Lock compliance mode, SHA-256 fingerprint, UTC timestamp.AU-2 · AU-3 · AU-5 · AU-8 · AU-9 · AU-10 · AU-11 · AU-12MEASURE 2.8CC7.2 · PI1.5ITGC: computer operations · audit trail retention
Least-privilege write pathApplication role may only write evidence; it cannot read, delete or change retention.AC-6 · AU-9(4)MAP 4.2CC6.1 · CC6.3ITGC: access to programs & data
Data protection at restServer-side encryption on the vault.SC-13 · SC-28—CC6.1Supporting control
Verifier change managementNew or changed verifiers deployed only through change control.CM-3 · CM-4 · CM-5MAP 4.2 · MEASURE 2.1CC8.1ITGC: program changes
Monitoring, incidents & overrideDenials reviewed; incidents escalated; the gate can be disabled only through a controlled process.AU-6 · CA-7 · IR-4 · IR-6MANAGE 4.1 · 4.3 · MEASURE 3.1CC4.2 · CC7.3 · CC7.4ITGC: computer operations · COSO P16, P17

SOX scoping

  • Scope test. If a gated AI action can create, change or delete data in a financially significant application (ERP, general ledger, consolidation, revenue) or change its infrastructure, add the gate to the ITGC inventory for that application.
  • Key-control candidates. The authorization gate is a preventive, automated control. The evidence vault is a detective control that lets auditors reperform decisions.
  • Testing approach. As an automated control, the gate can usually be tested by inspecting its configuration and a sample of transactions, provided the ITGCs over its code and configuration are effective.
  • Retention. The v1.2 blueprint’s 365-day default was likely too short for SOX-relevant records. Version 1.3 defaults to 2,555 days (about seven years); align it with your records retention schedule, by bucket default or per object.

v1.2 gaps and how v1.3 resolves them

The v1.2 blueprint code had gaps an auditor would raise. Version 1.3 resolves each of them in the SDK. Confirm the resolutions with the audit checklist rather than relying on this table.

v1.2 gapControls affectedResolution in v1.3
Default verifiers DB_METADATA_API and CI_BUILD_LOGS always returned valid.SA-11 · CC7.1 · MEASURE 2.5Registered as placeholders that fail closed; nothing approves by default.
The linter only checked for DROP DATABASE and DELETE FROM *.SI-10 · PI1.3sql_safety: allow-listed statement types, no stacked statements, WHERE enforced, tautologies and DDL refused, comments and literals stripped.
Claim layers did not match verifier layers.GOVERN 1.4 · CC5.3Verifiers are registered per layer and a mismatched claim is refused, so the Data-layer veto applies as designed.
The vault record was written before evaluate_gate, so it omitted the decision.AU-3 · PI1.5The record is committed after the decision, contains it, and is written before authority is returned.
A failed vault write had no defined handling.AU-5 · CC7.2Retries, then EvidenceCommitError (HTTP 503); no authority without a record.
Object Lock uploads need a checksum older boto3 releases did not send.AU-9A SHA-256 checksum is sent explicitly on every upload.
register() could replace a verifier at runtime.CM-5 · CC8.1The registry is frozen after start-up; replacing a verifier needs replace=True before freezing.
The pipeline score was compared against the per-claim threshold.GOVERN 1.4Removed. Claims gate through hard and soft gates; score bands come from layer evidence.
Allow-or-deny only; 365-day retention.MANAGE 2.4 · AU-11Full AL-0 to AL-4 resolution with stakes floor; retention defaults to 2,555 days.

References: NIST SP 800-53 Rev. 5; NIST AI 100-1 (AI RMF 1.0); AICPA 2017 Trust Services Criteria (revised points of focus, 2022); Sarbanes-Oxley Act §404; COSO Internal Control — Integrated Framework (2013); PCAOB AS 2201. Implementation: wekid-sdk 1.2.0. WEKID positioning drawn from wekid.org (Framework, Standards Catalogue, Capability Blueprint, Governed Delivery and Community pages), accessed 25 October 2026.

WEKID™ ASK · WEKID-STD-001The open standard© 2026 WEKID LLC. All rights reserved. WEKID™ is a trademark of WEKID LLC.