Audit logs and action gates for safer AI agents.
Project description
Problem Frame Gate
Problem Frame Gate is a Python library and CLI for finite, proof-carrying audit checks around AI decision frames and external action gates. It implements the audit-calculus concepts in:
Takahashi, K. (2026). Problemogenesis Theory: A Finite Proof-Carrying Audit Calculus for Problem-Frame Activation. Zenodo. https://doi.org/10.5281/zenodo.20913669
The package is strict by default. A log is not considered safe unless a finite manifest declares writer authority, protected action constructors, capacities, certificate families, risk modes, and gate bundle policy.
Install
uv sync --all-extras
uv run pytest
From PyPI:
pip install problem-frame-gate
pfg init-manifest > horizon.json
Safe Quickstart
Create a strict manifest:
pfg init-manifest > horizon.json
Validate and fold a log. The repository contains complete copy-paste JSON
fixtures in docs/examples/:
pfg validate-schema horizon docs/examples/horizon.json
pfg validate-schema log docs/examples/log.json
pfg verify-log --horizon docs/examples/horizon.json docs/examples/log.json
pfg fold --horizon docs/examples/horizon.json docs/examples/log.json
Check an action gate and emit the atomic bundle:
pfg validate-schema gate-request docs/examples/gate-request.json
pfg check-gate --horizon docs/examples/horizon.json --bundle docs/examples/gate-request.json docs/examples/log.json
The generated bundle contains exactly five protected rows:
GateCheckOutboxClaimUseCapConsumeResourceRiskClose
Each row must be written by the executor writer and committed in one atomic
group. A standalone OutboxClaim is rejected.
For a new project, copy the three JSON files from docs/examples/, then change
the writer ids, certificate issuers, frame id, action name, risk id, and resource
ids to match your deployment.
Python Example
from problem_frame_gate import (
Envelope,
EnvelopeClass,
ExecutorGate,
GateRequest,
Horizon,
RiskClaimRecord,
RiskRouteWitness,
digest_json,
)
horizon = Horizon.strict_default(agent_writers=("agent",))
def env(eid: str, commit: int, kind: str, **payload: object) -> Envelope:
return Envelope(eid, eid, "0", commit, "agent", "agent", 1, EnvelopeClass.NORMAL, {"kind": kind, **payload})
family_check = {
"accepted": True,
"checker": "example-certificate-family-v1",
"transcript_digest": digest_json({"checker": "example-certificate-family-v1", "accepted": True}),
"dependency_digest": digest_json({"dependencies": [], "source_ids": []}),
"revocation_frontier": [],
"checked_at": 2,
"assumption": "CertificateFamilyChecker",
}
log = [
env("e0", 0, "Frame", frame_id="p1", scope="lab", goal="test anomaly",
evidence_ids=["u1"], actions=["run-check"], acceptance=["review"], risk_ids=["r1"]),
env("e1", 1, "Evidence", evidence_id="u1", digest="sha256:source"),
env("e2", 2, "Issue", cert_id="c-risk", family="risk", issuer="agent",
expires_at=99, family_check=family_check),
env("e3", 3, "Activated", frame_id="p1"),
env("e4", 4, "RiskReg", hypothesis_id="h1", family="fixed"),
env("e5", 5, "RiskReserve", risk_id="r1", hypothesis_id="h1", frame_id="p1", eta="1/100"),
env("e6", 6, "RiskSpend", risk_id="r1", hypothesis_id="h1", frame_id="p1",
eta="1/100", mode="fixed", cert_id="c-risk"),
env("e7", 7, "ReserveResource", lease_id="lease1", token_id="tool", frame_id="p1"),
env("e8", 8, "MintCap", capability_id="cap1", frame_id="p1", action="run-check"),
env("e9", 9, "AuthorizeOutbox", outbox_id="out1", frame_id="p1", action="run-check"),
]
risk_claim = RiskClaimRecord(
claim_id="q1",
risk_id="r1",
hypothesis_id="h1",
mode="fixed",
cert_id="c-risk",
eta="1/100",
event_id="F1",
standardized_event_id="F1",
route_witness=RiskRouteWitness(
accepted=True,
checker="example-risk-route-v1",
transcript_digest=digest_json({"checker": "example-risk-route-v1", "mode": "fixed"}),
route="fixed",
),
)
request = GateRequest(
gate_id="gate1", bundle_id="bundle1", frame_id="p1", action="run-check",
outbox_id="out1", capability_id="cap1", lease_id="lease1",
risk_id="r1", hypothesis_id="h1", risk_mode="fixed", risk_cert_id="c-risk",
source_time=9, commit_time=10, risk_claim=risk_claim.to_json(), risk_alpha="1/50",
)
gate = ExecutorGate()
assert gate.check(horizon, log, request).ok
bundle = gate.create_bundle(horizon, log, request)
assert bundle.verify(horizon, log).ok
Security Boundary
The library proves finite audit consistency. It does not prove external truth, cryptographic collision resistance, statistical model validity, or physical effect. Those are explicit assumptions in checker results.
Strict certificates require a finite family-check record with a checker name, transcript digest, dependency digest, revocation frontier, and check time. Boolean certificate flags are treated as legacy assumptions and fail strict v1.0.0 checks.
There are two verification routes:
- JSON-only use relies on manifest-declared environment assumptions such as
CertificateFamilyCheckerandStatisticalModel. - Python deployments can register callable
CertificateFamilyandRiskModecheckers. The verifier reuses those registries when replaying embeddedGateChecktranscripts.
See docs/quickstart.md, docs/schema.md, docs/theory-mapping.md, and
docs/issue-codes.md for operational use.
Release
The canonical repository is https://github.com/kadubon/problem-frame-gate.
Versioned releases are published by GitHub Actions through PyPI Trusted
Publishing from .github/workflows/workflow.yml; no long-lived PyPI token is
required.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file problem_frame_gate-1.0.0.tar.gz.
File metadata
- Download URL: problem_frame_gate-1.0.0.tar.gz
- Upload date:
- Size: 80.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cb20e9e7fe90393cd95c757f458646dbad9940ed74f551620f29f2635a7756c
|
|
| MD5 |
48eccd4bd9c04a7db0f0592f00bb8068
|
|
| BLAKE2b-256 |
c9e40105ee4ab1ca7763f5b8e26d274cd33a3240202ac20ecbcb3a8c53a68de9
|
Provenance
The following attestation bundles were made for problem_frame_gate-1.0.0.tar.gz:
Publisher:
workflow.yml on kadubon/problem-frame-gate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
problem_frame_gate-1.0.0.tar.gz -
Subject digest:
8cb20e9e7fe90393cd95c757f458646dbad9940ed74f551620f29f2635a7756c - Sigstore transparency entry: 1965485979
- Sigstore integration time:
-
Permalink:
kadubon/problem-frame-gate@ded8d8e101759a329d44ef0d74446a0e2cfe7509 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/kadubon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@ded8d8e101759a329d44ef0d74446a0e2cfe7509 -
Trigger Event:
push
-
Statement type:
File details
Details for the file problem_frame_gate-1.0.0-py3-none-any.whl.
File metadata
- Download URL: problem_frame_gate-1.0.0-py3-none-any.whl
- Upload date:
- Size: 59.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87b202f1cb8caba24137389375445dc026226970010ca107c74eaddcd17f5e48
|
|
| MD5 |
24a76247422adb521b333c4a212dc6e8
|
|
| BLAKE2b-256 |
fc7a3786c9b49cac171fe67f0fe09ce04fbfc0d707454024788cda23b746a5ee
|
Provenance
The following attestation bundles were made for problem_frame_gate-1.0.0-py3-none-any.whl:
Publisher:
workflow.yml on kadubon/problem-frame-gate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
problem_frame_gate-1.0.0-py3-none-any.whl -
Subject digest:
87b202f1cb8caba24137389375445dc026226970010ca107c74eaddcd17f5e48 - Sigstore transparency entry: 1965486137
- Sigstore integration time:
-
Permalink:
kadubon/problem-frame-gate@ded8d8e101759a329d44ef0d74446a0e2cfe7509 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/kadubon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@ded8d8e101759a329d44ef0d74446a0e2cfe7509 -
Trigger Event:
push
-
Statement type: