Kenshiki

Founding RFC

Deterministic Admissibility Gating and RAG Schema Compilation

How Kenshiki verifies that every regulatory obligation is satisfied by human-approved, version-current evidence — before the retrieval engine sees a single vector.

1,422 words · ~7 min

Status: Founding RFC — Approved Domain: High-Assurance AI Governance, Ingestion Pipeline, Admissibility Gate

1. Objective

To build a commercially viable, high-assurance retrieval architecture that enforces regulatory compliance as a deterministic engineering constraint before retrieval occurs. The system utilizes an Admissibility Engine backed by a relational PostgreSQL state cache. This engine dictates the obligations required for a query, verifies the presence of Human-In-The-Loop (HITL) approved document versions, handles version supersession cleanly, and fails closed with actionable remediation workflows if obligations are unmet.

Architectural Position

The Governed Intelligence Architecture defines a six-stage pipeline: Identity → Ingestion → Retrieval → Compilation → Inference → Audit. Admissibility gating occupies the boundary between Ingestion and Retrieval — it runs after ingestion produces SIRE-tagged, embedded evidence and before the retrieval engine queries the vector store. The pipeline position is:

IngestionAdmissibility GateRetrievalCompilation\text{Ingestion} \to \textbf{Admissibility Gate} \to \text{Retrieval} \to \text{Compilation}

The Admissibility Gate is independent of both the SIRE exclusion gate (which runs during retrieval, filtering chunks by Excluded terms) and the ReBAC authorization gate (which filters by caller-document relationships). All three gates must pass. No gate can override another. The system takes the intersection:

C=CadmissibleC¬excludedCauthorizedC' = C_{\text{admissible}} \cap C_{\neg\text{excluded}} \cap C_{\text{authorized}}

2. System Architecture

2.1 The Ontic Compliance Catalog (Proprietary Taxonomy)

Ontic Labs maintains a versioned, canonical JSON taxonomy mapping foundational frameworks (e.g., NIST AI RMF) to abstract enterprise obligations.

  • Structure: Control (NIST MAN.1.3) \to Obligation (req_incident_runbook).
  • Relationship to SIRE subjects: Each obligation maps to one or more SIRE subjects. A SOC 2 obligation maps to soc_2_trust_services_criteria; a cross-framework obligation (e.g., incident response) may map to multiple subjects. The Admissibility Gate resolves obligations independently of SIRE subject grouping — SIRE controls what evidence is, admissibility controls whether approved evidence exists.
  • Versioning: All admissibility evaluations record the active catalog_version in the Claim Ledger to ensure long-term auditability even as frameworks evolve.

2.2 Ingestion and Transactional HITL Approval

Documents are parsed via Docling, LLM-tagged for suggested obligations, and held in an inert state until a human compliance officer approves them.

Relationship to SIRE state transitions: The SIRE lifecycle defines PROPOSED → APPROVED → ACTIVE for identity metadata. The Admissibility Engine tracks a separate concern: evidence sufficiency. A document version may have SIRE state = ACTIVE (its identity is stamped) but is_admissible = false (a compliance officer has not yet approved it for obligation satisfaction). Both conditions must be true for the document’s chunks to enter the retrieval boundary.

Supersession Policy: When an officer approves dv+1d^{v+1} of a document, a single database transaction inserts dv+1d^{v+1} as is_admissible = true and updates dvd^v with superseded_at = now(). This ensures O(1)O(1) live checks while preserving the immutable historical record of what governed past system actions.

2.3 The Admissibility Gate (Pre-Flight Validation)

Vectors hold no compliance logic; they only contain a structural reference (document_version_id). The Admissibility Gate executes a strict, ordered validation loop (FGA → Postgres → Remediation) before the vector database is ever queried.

This gate is distinct from the SIRE exclusion gate defined in Algorithm 2 of the SIRE Identity System RFC:

GateRuns whenWhat it checksEnforcement mechanism
Admissibility GateBefore retrievalAre approved, current documents present for each required obligation?PostgreSQL obligation lookup
SIRE Exclusion GateDuring retrievalDoes chunk text contain out-of-scope terms from Excluded?Word-boundary match on chunk content
ReBAC Authorization GateDuring retrievalIs this caller authorized to access this document?OpenFGA relationship check

3. Data Model

All admissibility state lives in bare PostgreSQL.

3.1 The Obligations Schema

CREATE TABLE obligations (
    obligation_id VARCHAR PRIMARY KEY,
    control_id VARCHAR NOT NULL,
    description TEXT NOT NULL,
    min_documents INT DEFAULT 1 -- Supports cardinality (e.g., requires 2 policies)
);

The min_documents field enforces obligation cardinality: some obligations require n>1n > 1 approved documents to be considered satisfied (e.g., an incident response obligation may require both a policy document and a runbook).

3.2 The Admissibility Engine (Evidence State)

CREATE TABLE evidence_admissibility (
    document_version_id UUID PRIMARY KEY,
    organization_id UUID NOT NULL,
    obligation_id VARCHAR REFERENCES obligations(obligation_id),
    is_admissible BOOLEAN DEFAULT FALSE,
    approved_by VARCHAR,
    approved_at TIMESTAMPTZ,
    document_hash VARCHAR NOT NULL,
    supersedes_version_id UUID,          -- Links the chain of custody
    superseded_at TIMESTAMPTZ            -- Null if currently active
);

-- Optimized view for the Admissibility Gate hot-path
CREATE VIEW current_admissible_evidence AS
SELECT * FROM evidence_admissibility
WHERE is_admissible = true
  AND superseded_at IS NULL;

-- Index to support O(1) resolution
CREATE INDEX idx_active_evidence
ON evidence_admissibility(organization_id, obligation_id)
WHERE is_admissible = true AND superseded_at IS NULL;

3.3 The Claim Ledger

ALTER TABLE claim_ledger
ADD COLUMN admissibility_evaluations JSONB NOT NULL;
-- Payload: [{"catalog_version": "1.2", "obligation": "req_incident_runbook",
--            "satisfied_by_version": "uuid"}]

When the Admissibility Gate blocks a query, a Claim Ledger record is still written with output state = BLOCKED, the admissibility_evaluations array containing the unsatisfied obligations, and the remediation payload. This is consistent with the GIA’s audit invariant: a Claim Ledger record is persisted for every query, including blocked ones.

4. Admissibility Gate Runtime

The following defines the execution order for the governed query endpoint. The Admissibility Gate runs as the first validation step — before hybrid search, before the SIRE exclusion gate, before ReBAC authorization.

async function executeAdmissibilityGate(
    request: IncomingPrompt,
    orgId: string,
    operationContext: string
): Promise<AdmissibilityResult> {

    // Step 1: Resolve Applicability via OpenFGA
    // Determine which controls apply to this operation/org
    const requiredControls = await fgaClient.getRequiredControls(
        orgId, operationContext
    );

    if (requiredControls.length === 0) {
        return { isAdmissible: true, evaluations: [] };
    }

    // Step 2: Map Controls to Obligations (via Cached Ontic Catalog)
    const requiredObligations =
        await catalogCache.getObligationsForControls(requiredControls);
    let missingObligations = [];
    let passedEvaluations = [];

    // Step 3: Evaluate Evidence Existence (O(1) Postgres Check)
    for (const req of requiredObligations) {
        const query = `
            SELECT document_version_id
            FROM current_admissible_evidence
            WHERE organization_id = $1 AND obligation_id = $2
            LIMIT $3;
        `;
        const evidence = await db.query(
            query, [orgId, req.obligation_id, req.min_documents]
        );

        if (evidence.rowCount < req.min_documents) {
            missingObligations.push({
                obligation: req.obligation_id,
                control: req.control_id,
                description: req.description
            });
        } else {
            passedEvaluations.push({
                obligation: req.obligation_id,
                satisfied_by_versions:
                    evidence.rows.map(r => r.document_version_id)
            });
        }
    }

    // Step 4: Fail Closed with Remediation Payload
    if (missingObligations.length > 0) {
        throw new PreconditionFailedError(428, {
            error: "Admissibility Failed",
            message: "The requested operation requires compliance "
                   + "artifacts that are missing, unapproved, "
                   + "or superseded.",
            missing_obligations: missingObligations,
            remediation_url:
                `/compliance/remediate?org=${orgId}`
        });
    }

    // Step 5: Success — Return evaluations for Ledger
    return {
        isAdmissible: true,
        evaluations: passedEvaluations
    };
}

5. Determinism Guarantee

Given identical inputs (caller organization, operation context, obligation set, evidence admissibility state, OpenFGA graph), the Admissibility Gate always produces identical results. The gate is composed of three deterministic operations:

  1. Applicability resolution: A deterministic function of (organization, operation context, OpenFGA graph).
  2. Obligation mapping: A deterministic function of (required controls, catalog version).
  3. Evidence existence check: A deterministic function of (organization, obligation, evidence admissibility state).

No randomness. No model inference. No embedding similarity. The gate is a pure relational lookup with a fail-closed default.

6. Future Scope (V2+)

  • Scoped Applicability: V1 executes applicability at the organization_id level. V2 will introduce scope_type (e.g., department, system, user) to evidence_admissibility, allowing the Admissibility Gate to resolve specific policies for specific sub-tenants while falling back to org-wide baselines.
  • Cryptographic Attestations: Transition the HITL approval to generate a verifiable cryptographic signature of the document_hash using the organization’s private key, committing the actual signature to the Claim Ledger.

7. Invariants

  1. The Admissibility Gate runs before any vector retrieval. No chunks are fetched until all required obligations are satisfied.
  2. Admissibility, SIRE exclusion, and ReBAC authorization are independent gates. The system takes the intersection. No gate can override another.
  3. HITL approval is required for evidence to become admissible. Automated ingestion cannot set is_admissible = true.
  4. Version supersession is transactional: approving dv+1d^{v+1} and retiring dvd^v occur in a single database transaction.
  5. A document version with SIRE state = ACTIVE but is_admissible = false cannot enter the retrieval boundary.
  6. The Admissibility Gate fails closed. If the obligation lookup, the OpenFGA backend, or the PostgreSQL state cache is unavailable, the query is BLOCKED.
  7. Every admissibility evaluation — pass or block — is recorded in the Claim Ledger with the catalog_version active at query time.
  8. The current_admissible_evidence view guarantees O(1)O(1) resolution via partial index. No sequential scan of historical versions.
  9. Obligation cardinality is enforced: an obligation requiring nn documents is not satisfied by n1n - 1.
  10. The Admissibility Gate is deterministic: identical inputs always produce identical results.