Audicta

Architecture

The decision record, end to end.

Audicta's intellectual property is the structure of the decision record itself. The fields below — and the architectural properties that surround them — are what make a record audit-grade rather than a log file.

The audicta.pa.v1 schema

Every decision is a versioned JSON document. The schema is fixed at decision time and stamped into the record itself, so future readers always know which schema produced which record.

{
  "record_version": "audicta.pa.v1",
  "record_id": "rec_2026-04-25T14-22-08Z_a7f3c91e",
  "content_hash": "sha256:f4a2b9c1...",        // SHA of entire record minus this field

  "case": { ... },                              // immutable case attachment

  "agent_chain": [
    {
      "agent": "clinical_reviewer",
      "agent_version_hash": "sha256:c91a3...",  // exact prompt + skill.md hash
      "model": "claude-sonnet-4-20250514",
      "model_temperature": 0.0,
      "input_hash": "sha256:b2f1...",           // case + KB context hash
      "output": {
        "what":     "...",
        "why":      "...",
        "alternatives_considered": [ ... ],
        "tradeoff": "...",
        "confidence": 0.86,
        "scope_check": "...",
        "flagged_uncertainties": [ ... ],
        "citations": [
          { "source": "...", "kb_chunk_hash": "sha256:..." }
        ]
      }
    },
    ...
  ],

  "decision": {
    "verdict": "APPROVE",
    "verdict_basis": "...",
    "decided_at": "2026-04-25T14:22:08.412Z",
    "decided_by_chain": [ ... ]
  },

  "evaluation": {
    "evaluator_isolation_attestation": "...",
    "scores": { ... },
    "evaluator_local":  { "model": "qwen2.5-coder:7b", "scores": { ... } },
    "evaluator_cloud":  { "model": "claude-sonnet-4-...", "scores": { ... } },
    "convergence": { "max_dimension_divergence": 0.5, "convergent": true }
  },

  "provenance": {
    "kb_snapshot_hash":  "sha256:a1b2...",
    "agent_genome_hash": "sha256:91e3...",
    "audicta_version":   "0.4.0",
    "reproducible_with": "docker pull audicta/healthcare-imaging:0.4.0"
  }
}

Why each field exists

Every field below carries a specific audit-defensibility role. Removing any of them weakens the record's reproducibility or its independence from the system that produced it.

Field Audit-defensibility role
content_hash SHA-256 of the entire record minus this field. Tampering of any byte changes the hash. Stored externally where appropriate. The record self-attests to its own integrity.
agent_version_hash Hash of the exact prompt, skill file, temperature, and model name in effect at decision time. Even if the agent is later modified, the original record points to the original version. This is the contemporaneous-record property.
kb_chunk_hash Hash of the specific knowledge-base chunk an agent cited. If the KB is later updated, the original citation still points to the chunk version actually consulted at decision time.
scope_check Each agent's self-declaration of the scope it claimed authority over. If the record is later challenged in audit, the scope_check is the agent's own statement of what it claimed authority over — trivially comparable to what policy actually permits AI to decide.
evaluator_isolation_attestation Plain-text statement, provable from code, that the evaluator function literally could not see the case, the patient, the criteria, or the agents' reasoning code. Only the decision record. The architectural-isolation claim, made visible.
convergence Two independent LLMs scored the same record. Small divergence is the signal that the record itself is unambiguous — not that one model happened to like it.

Architectural isolation, proven by code

The evaluator-isolation claim is enforced at the type-checker level, not by policy or convention. The evaluator function's signature accepts a single typed input — a decision record — and rejects anything else at compile time.

from typing import NewType

DecisionRecordJSON = NewType("DecisionRecordJSON", dict)
# NewType makes this distinct from plain dict at the type-checker level.
# Cases, code, KB chunks are NOT DecisionRecordJSON — passing them is a type error.

def evaluate_pa_record(
    record: DecisionRecordJSON,
    dq_sub_weights: dict,
) -> EvaluationResult:
    """
    The signature carries the architectural claim:
    The only input is a DecisionRecordJSON. No case, no patient, no KB,
    no agent code. The evaluator cannot reason about the case;
    only about the record of how the case was reasoned about.
    """
    assert "record_version" in record, "Not a decision record"
    # ... rest of evaluation logic ...

In a live demonstration, the function signature is read out loud: this function takes one parameter: a decision record. Look — no patient, no case, no agent code. Compile-time enforced. The architectural-isolation claim, made visible.

Reproduction harness

Reproduction is the property that closes the audit loop. A previously written record can be replayed weeks or years later and produce the same scores it produced originally — even if the underlying agent has been modified in the meantime.

  1. 1. The agent versions in the record are pinned by their agent_version_hash.
  2. 2. The knowledge-base snapshot is pinned by kb_snapshot_hash.
  3. 3. The evaluator runs against the existing record JSON — not against the agents.
  4. 4. The recomputed scores are compared to the record's stored evaluation block.

Reproduction passes when, for every dimension, the recomputed score equals the archived score within tolerance. The record reproduces because the evaluator only ever needed the record.

The combination is the property

None of the fields above is novel individually. SHA-256 hashing isn't novel. Citations aren't novel. Bias-isolated evaluation isn't novel. Reproducibility tests aren't novel.

The combination — all of these properties, in a single record, written at decision time, designed to be reproduced years later under regulatory challenge — is the audit-defensibility claim Audicta makes.

That combination is what a compliance officer needs to see in five minutes and understand. After that, the rest of the conversation is about scope, not concept.