Home Applications Proof Before Pay

Proof Before Pay

Community Project
This project is maintained by its author and is not officially supported by InterSystems. For technical support, please contact the project developer.
0
0 reviews
0
Awards
5
Views
0
IPM installs
0
Add to bundle
Details
Reviews
Issues
Videos (1)
Articles (1)
This app has a demo View
Seal an AI Hub agent’s observed and missing evidence before a synthetic payment effect, with authenticated review, a single-use permit and a verifiable receipt.

Proof Before Pay

Seal what an AI agent saw, what was missing and what it decided before an action.
The application runs on InterSystems IRIS AI Hub EAP build 154: native Interoperability
intake/process/operations, deterministic policy, scoped read-only tools, authenticated
Workflow review, a sealed approval, a single-use permit and one confirmed sandbox effect.
The review console detects edits to decision copies and shows the sealed evidence chain.
Model proposals are also checked against actual tool observations: invented/null references,
inconsistent money flags and missing evidence cannot silently close a case. Unsupported financial
actions go to a person; only duplicate refunds are executable in v1.

Simple cases use deterministic rules without a model call. When no rule matches, the
AI Hub agent reads the five scoped tools and proposes a decision; policy and the context
guard constrain it before sealing.

Audited v7 result, 1 November 2026

The current release adds the final v7 report
and its structured summary. The older
validation sections below retain their historical scope and failures.

In one pre-frozen informed set of 12 cases (four controls and eight residues),
the agent’s raw proposals were correct in 11/12, versus 7/12 for conservative
rules and 8/12 for the deterministic baseline. The frozen criterion was met:
at least two more correct raw decisions than both baselines, zero unsafe agent
decisions and all four controls correct. Effective results were 10/12, 7/12
and 8/12 respectively; correct autonomous closures were 5, 3 and 3. The r4 refund
was safely blocked because its exception label is outside the ledger contract;
its frozen eligible-effect label was an authoring error and remains counted against
the agent. In r8 the agent missed a required missing-evidence declaration. These
errors were not repaired by another run.

Claude independently remapped all 36 records and recomputed the identical score.
The result is descriptive evidence on these cases, not a blind sample, independent
human study, population estimate or general superiority claim. Estimated usage
cost was US$0.02566575, not a billing receipt. All effects were synthetic.

The basic authenticated viewer journey was checked through automated browser
navigation with Rafael signing in manually, including three cases, a tampered and
restored record copy, and queue access at 303/390/980/1100 pixels. Logout and recovery
code consumption were not run. Installation remained qualified on the owner’s
already loaded licensed build154 amd64 image under emulation on Apple Silicon,
not a fresh portal download or independent human install. The video 4.2.1 and
selected replay examples predate v7 and are not footage of that run. See the
article 5.3 for the development history and limitations.

What to inspect first

Use the judge path below to inspect these examples. Recorded proposals are replay,
not new inference; a proposed money flag is not a completed effect.

Example What it demonstrates Where to inspect
Completed synthetic refund A recorded agent route, authenticated test review, exact sealed approval, single-use permit and intact receipt. The viewer’s selected completed example; historical recorded integration.
pix-0006 R1 to R3 abstain. The recorded tape names the missing carrier signature despite a delivery scan. No money is proposed, so this route does not call Ledger.Stage. Local public fixture; recorded proposal and context guard. The UI explains the roles when its retained decision seal verifies intact.
pix-0008 / adversarial:* An unsupported withdrawal proposal, invented evidence or inconsistent flags are refused; the effective decision is a sealed escalation. Local recorded fixtures or cases generated by test_workflow.py; adversarial harness. Raw proposals are diagnostic, not authority.
Contained live proposal A malformed amount was misread by the model; the server refused the refund target and no effect occurred. Historical v5 report, also explained in the console. This is not a new inference or a quality estimate.

The store policy lists possible business requests; the v1 execution contract is narrower. Full or
partial refunds and withdrawal retries are not executable merely because they appear in that list.
They escalate rather than widening the contract. See the guard and
the synthetic ledger contract.

What this adds

Our contribution is a set of properties that hold together inside one native IRIS production, each
one checked by the validation evidence linked below:

  1. What the agent did not see is sealed as missing, as a first-class field of the record. Completing the record
    afterwards changes its commitment; the reviewer reads the gaps before the proposal. This is a local
    integrity check with the privileged-rewrite limit described below.
  2. The model never chooses where the money goes or which payment is returned. The destination is the
    store’s own record for the order and the refund target is derived on the server from the observed
    payments; the customer message, nested order destination fields and model prose do not override that stored
    test binding. This does not authenticate the original case data or a real bank destination. See
    recipient binding and the
    independent cohort.
  3. One sealed approval binds one single-use permit, which produces at most one test effect; a second
    attempt with the same permit is refused, also under concurrent sessions.
  4. Model decisions retain their actual tool outputs; rule decisions retain the inputs they read.
    The native Production messages carry the commitment, and the console reconstructs the retained evidence
    for inspection. Forensic replay does not rerun a model or guarantee the same future model response.
  5. The failures are published with their fixes: a policy miss in the baseline, an observability gap that
    failed a whole round, and a raw proposal on a malformed amount that the server contained.

Related work includes Google’s Agent Payments Protocol (AP2);
we do not claim to have invented proof-before-payment. The combination above, executed natively on IRIS with explicit ignorance
and published failures, is what we submit for review.

Status: the native workflow is tested in recorded mode and with real Gemini, OpenAI
and Anthropic models through OpenRouter in a private synthetic lab. Each model completed
one scenario with five native tool calls, authenticated test review, sealed approval and
one confirmed sandbox effect. This is an integration smoke test, not a model-quality ranking
or evidence for three-agent voting. A reviewer-note defect found during that trial was fixed
and covered by replay regression. Isolated cold installation, lifecycle and native IPM application
load/uninstall/local-package tests passed; scope and qualifications
include the separate fresh-volume IPM bootstrap result and limitations.
The 31 October reproduction
adds a qualified untraced USER IPM bootstrap, source-only package lifecycle and
scripted judge HTTP journey, cross-reviewed against the retained evidence. It used
the owner’s licensed cached build154 image under amd64 emulation on Apple Silicon;
it is not an independent human or authenticated browser-DOM walkthrough.
A final independent eight-case cohort was accepted on 28 October with one raw model failure contained by the
server (see the validation summary). The later twelve-case paired trial retains its
failed first-attempt instrumentation score alongside a separately admitted,
post-hoc technical repeat on the same known cases. That repeat observed three
autonomous residue closures for both G and deterministic triage D, so the required
autonomy gain was not demonstrated. Claude independently recomputed both scores byte for byte in C1236. G and D
closed different sets of three cases; the selected free-text failures were authored
with knowledge of D’s lexicon. See both readings and their limits
and the final descriptive report.
The recorded video predates both cohorts. Dedicated reviewer access is supplied
privately; the final package and submission remain pending. No bank settlement or independent
external anchor is claimed; local seals detect edits to a copy and do not protect against an administrator who
can rewrite the database, and an optional asynchronous anchor under independent custody is a declared roadmap
item without a date. See application design, validation, and
provider experiment.

Validation summary

The live integration evidence includes a legacy
duplicate_charge case where the agent proposed a refund and authenticated test review
produced one verified sandbox receipt. This establishes integration, not an advantage
over a deterministic solution. A later ten-case live challenge failed all four mandatory
financial positives: the agent could not observe the stored refund destination.
The tools now expose that case-bound value explicitly. The subsequent frozen live run
passed 14 protected outcomes: six mandatory positives each produced one intact synthetic
receipt, and eight negatives produced zero effects. Ten cases were post-fix regressions
and four were prospective controls. One raw proposal was still incorrect and was contained
by the core; this is not a claim of 14 correct model proposals or population-level accuracy.
Claude independently recomputed the results, and all ten supplied historical reviewer JSON
reports match our parsed originals. The failed result,
post-fix scope, and
independent review are retained together.

A final independent eight-case cohort (new trap types, written by the reviewer after all earlier results
were known, frozen and cross-checked by hash before any output) completed on 28 October: the three
mandatory financial positives each produced one intact synthetic receipt to the stored destination; the
five negatives produced no effect and remain pending for a person. One raw proposal was wrong: the model
reinterpreted a malformed order amount (“189.90”) as minor units and proposed a refund; the server-side
target derivation refused it and the sealed decision was an escalation with the refund target marked
missing. This is an informed adversarial set, not a blind sample or a population estimate; it establishes
nothing beyond these eight cases. See the independent cohort
and its cross-review.

Maintainer: Rafael Orlando Mendes.
Code developed with AI assistants under Rafael’s direction. License: MIT.
The vendor EAP image is separately licensed and is not distributed here.

Real IRIS console: deterministic duplicate refund with authenticated test review

Private synthetic lab: this case was decided by deterministic rule R1, followed by
authenticated test review. It shows 18990 minor units as 189.90 BRL; it is not a live
model decision or real settlement. The receipt view
shows the consumed permit and intact historical receipt. A separate
guard-refusal screen illustrates nonfinancial escalation.
The live agent-to-refund evidence is a different,
one-scenario integration test. None of these screenshots is the public viewer or the independent v5 cohort.

Judge path

Two paths exist with the prerequisites below. Times are not promised because the vendor image download,
license steps and an independent new-operator walkthrough were not measured.

Path A, no installation: the authenticated read-only viewer. Open
the dedicated judge viewer. It uses the application’s
sign-in form, not a browser credential prompt. Use the private access details supplied with your
invitation; the earlier viewer address uses separate credentials. Dedicated judge access has been
prepared and tested, but has not yet been released to judges or submitted to Open Exchange.
You can inspect three selected synthetic cases, the evidence the agent saw, missing information, the
sealed decision and approval, and an intact synthetic receipt. Use “Try to tamper” to edit a copy and
verify it: the verdict turns tampered; restoring the copy turns it intact. The stored record is unchanged.
The viewer cannot approve, create cases or call a model; those routes are refused by the gateway.
The selected delivery-conflict example retains its historical rejection, made by the instance owner
account during an automated synthetic test. Its role guide reads the
verified decision snapshot; the historical comparison links separate recorded-refund and live-v5
reports rather than presenting them as new executions.

Path B, private execution in recorded mode (no model key or paid inference). Requires the AI Hub
EAP build154 image from the vendor portal and the local-image setup described below. The default Compose
profile has no network; the optional console profile enables normal bridge networking and binds its
HTTP port only to loopback. The public viewer and this private IRIS authentication are separate.

  1. Load and tag the vendor image as described under “Start the isolated IRIS lab”, then run:

    docker compose up --build --detach --wait
    python3 scripts/test_iris.py
    python3 scripts/test_workflow.py
    python3 scripts/test_recipient.py
    

    The first test checks the actual compile/smoke markers and prints "compile_ok": true and "ok": true.
    The workflow test prints "ok": true with its measured native unit/E2E/adversarial counts; an IRIS
    session exiting zero alone is not enough. These tests use authenticated automated synthetic review,
    not a claim that the person running the command manually approved each case. Recipient tests cover
    one known-destination positive and absent/mismatched-destination zero-effect alternatives in recorded
    mode. Projection fixtures are rolled back; the recorded workflow cases remain in the private test lab.
    The workflow test creates unique suffixed case IDs, reported in its JSON result; use those IDs in the
    console. Search for adversarial: to inspect its three recorded proposals refused by the guard.
    FeedCases() alone feeds the original ten public fixtures; it does not create those adversarial cases.

  2. To exercise the HTTP workflow, opt into the private console profile:

    docker compose -f compose.yml -f compose.ui.yml up --build --detach --wait
    

    Privately configure PBP_TEST_BASE_URL=http://127.0.0.1:52773 and PBP_TEST_USER/PBP_TEST_PASSWORD.
    The HTTP test appends /pbp/api itself; do not include that suffix in the base URL. Use an existing
    private IRIS test login whose name begins with PBP, with the reviewer role and normal application
    access; no reviewer password is shipped. Run python3 tests/http_workflow.py to exercise authenticated
    review, one intact receipt, consumed permit, copy verification and refused/stale approval requests.
    This command reviews its own generated case automatically and performs synthetic effects only.

  3. If you need a new unreviewed case for an independently configured private console, use the same
    private environment and run python3 tests/http_workflow.py --seed. This only creates a fresh case and
    prints its id/commitment. It clones pix-0001 with unique payment references: a deterministic
    duplicate_payment/R1 case, not a live or recorded agent decision. Do not expect a case already closed
    by the full HTTP test to be approvable again. The raw local IRIS console uses the instance’s own access
    mechanism; the modern browser demonstration is Path A, which has no approval rights.

  4. To populate the ten public synthetic fixtures, run Do ##class(pbp.Setup).FeedCases() in a USER IRIS
    terminal. Installation and the bridge smoke alone do not feed them. pix-0009 has no stored destination:
    inspect its missing refund target and zero effect. pix-0005 is an amount_mismatch with a recorded agent
    proposal and five retained tool outputs; it escalates without money. These are public fixtures, not
    the private live benchmark. Repeated fixture ingestion is not a new benchmark or new approval.

Live inference (a real model deciding a duplicate charge that moves test money) needs your own provider key
and the compose.live.yml profile described below; it is a cost-bearing opt-in and is not part of this path.

IPM installation option

The repository includes module.xml and the hash-pinned requirements.txt. Use a
dedicated build154 instance with a functioning IPM installation; the vendor
image and SDK are obtained separately. Follow the operator guide.
Configure installs the application with Production stopped. The native module uses
six Python packages and per-app manager asset directories; the optional legacy
Solana library is outside this module. The native acceptance record
covers loaded classes, 48 recorded workflow checks, package generation, uninstall,
local archive reinstall and the original receipt in both SQL and the authoritative Ledger.
This is a local installation test, not a published registry release or a new model benchmark.
The 31 October independent follow-up
adds an untraced USER bootstrap on a fresh plain-vendor volume, all 38 declared
resources, 48 recorded checks, and package/uninstall/local-reinstall receipt continuity.
It ran under x64 emulation on Apple Silicon; the failed namespace and readiness
attempts remain recorded; the qualified final report separately records Claude’s review of the supplemental repair evidence.

Start the isolated IRIS lab

Prerequisites: Docker Engine with Compose v2; Python 3 on the host for the scripts/test_*.py
commands; x86-64 Linux (tested); enough capacity
for the approximately 6.8 GB unpacked vendor image, its archive/build overhead and 2 GiB of container RAM,
plus memory for Docker and the host. The independent run used a 3 GiB Docker daemon allocation.
The tested lab had at least 2.5 GB free after the base image had already been loaded.
The earlier 1.2 GiB container limit allowed worker OOM kills during the independent
recorded workflow run under amd64 emulation on Apple Silicon. The recorded tests and authenticated HTTP workflow subsequently
passed with a 2 GiB limit; the container supervisor alone had not detected the worker failure.
In a later cold boot under emulation, compilation and installation finished about three
minutes after container start. The default health grace period is 180 seconds; it still
reports healthy as soon as initialization and the checks succeed. The earlier shorter
grace produced a failed first compose up --wait followed by natural recovery in the
same container. That failed attempt is retained; no restart or health reset was used.

  1. Obtain the AI Hub Community build 154 archive from the
    official EAP portal, completing the
    vendor’s access and license steps yourself. Use the x64 archive
    iris-community-2026.3.0AI.154.0-docker.tar.gz. The
    contest instructions
    specify build 154. The downloaded image and any derived image must stay private.

  2. Load the archive locally and tag the loaded image:

    docker load --input /path/to/iris-community-2026.3.0AI.154.0-docker.tar.gz
    docker tag docker.iscinternal.com/docker-intersystems/intersystems/iris-community:2026.3.0AI.154.0 proof-before-pay/iris-eap:2026.3.0AI.154.0
    

    If build154 is already loaded under another local alias, Compose accepts it without an extra retag:
    IRIS_IMAGE=iris-community:2026.3.0AI.154.0 docker compose up --build --detach --wait.

    Inspect the loaded image before building:

    docker image inspect --format 'id={{.Id}} arch={{.Architecture}} os={{.Os}}' proof-before-pay/iris-eap:2026.3.0AI.154.0
    

    The validated x64 image has OCI manifest digest
    sha256:8fc1e5c64ed790aa263af05089d003a49bba272fb9c714e4823dd868aebff2a6
    and image configuration digest
    sha256:1d3d52bf15f4f69efb7b5d5e857382099694817132ed00aa989aa158adcedf74.
    Docker’s classic image store reports the configuration digest as .Id; the containerd
    image store used in our earlier lab reported the manifest digest. Both identify the
    verified image chain; a different store’s .Id alone does not imply different image contents.
    The original vendor archive used in the lab had SHA-256
    8b0daa63f279ef9f11fd2377ab9fcf5d5cc953e8141d000539d7eecceee39170.
    That archive hash applies to the original x64 kit, not to a private docker save re-export.
    The image must report arch=amd64 os=linux; keep the vendor archive and image private.

  3. From this repository:

    docker compose up --build --detach --wait
    python3 scripts/test_iris.py
    python3 scripts/test_ledger.py
    python3 scripts/test_workflow.py
    python3 scripts/test_pairguard.py
    python3 scripts/test_recipient.py
    

    Startup compiles the application recursively, loads synthetic policies/replay fixtures,
    installs reviewer permissions and starts the native Production. The health gate waits
    for installation as well as IRIS. Tests cover the real embedded-Python bridge, journaled
    ledger and concurrent sessions, native unit suites and the complete recorded workflow.
    The pairguard gate also races opposite refund targets and verifies that the rule and
    recorded-agent routes cannot refund both members of the same observed payment pair.
    A missing marker or failed assertion is a failure even if the IRIS terminal exits zero.
    Where the runtime exposes an oom_kill counter for this process’s own cgroup,
    readiness also fails
    after a kernel OOM kill in this container, even if the IRIS supervisor is still alive.
    This counter survives a worker’s death until the container is recreated; it does not
    identify the killed job. The helper checks the private v2 cgroup namespace or resolves
    the exact v1 self path, so a host/root counter cannot attribute another container’s
    OOM to this one. Coverage is established for v2 with a private cgroup namespace.
    On v1, a mount rooted at the container’s own cgroup may hide that self path; the
    check then reports unavailable rather than using an ambiguous root counter.
    Missing namespaces or older v1 counters are also reported as unavailable;
    the normal boot/IRIS checks still apply in those cases.
    Health status does not establish that every Production worker or the full workflow is
    functioning: the recorded workflow tests above provide that separate evidence.

  4. Stop with docker compose stop. docker compose down removes the container but
    preserves the named iris-state volume. Restart and recreation retain cases, approvals
    and receipts. docker compose down --volumes deliberately erases this lab data.

The service has no network, published port, wallet, model credential or paid inference.
Its working directory and IRIS databases must be writable. It uses the vendor’s
normal startup capabilities, dropping NET_RAW and MKNOD. The installer creates the PBPReview resource and PBPReviewer role and grants it
to existing users listed in PBP_REVIEWERS (default: the installing OS identity,
_SYSTEM,SuperUser,Admin). It creates no password or default public reviewer login.
Only explicitly trusted reviewers should be listed. Do not expose this lab publicly.

The x64 container was also exercised under emulation on Apple Silicon with the resource
allocation above. A native ARM64 installation is not validated. An ARM64 EAP kit is available from the vendor;
using it requires the matching local image and IRIS_PLATFORM=linux/arm64.
Do not compare that image with the x64 hash above.

Private review console

The default lab has no network. To opt into an authenticated console with a loopback-only
published port and normal bridge networking:

docker compose -f compose.yml -f compose.ui.yml up --build --detach --wait

Open http://127.0.0.1:52773/pbp/ui/ with a private IRIS reviewer login.
On a fresh volume, follow the reviewer setup recipe first:
the HTTP workflow needs PBPReviewer, %DB_USER, the specific
%Service_EmbeddedPython:USE resource, and membership in native pbp.Workflow.
This combination passed the independent authenticated HTTP test; it is not a proof of
minimum permissions for every installation. No model key is loaded by this profile.
Keep the operator-chosen password private; do not publish vendor default credentials.
The reviewer role includes SELECT on the synthetic projections and native Workflow task
lookup. The authenticated session, rather than a JSON operator field, supplies identity.

Feed the ten synthetic cases using the native runtime tests or pbp.Setup.FeedCases().
For an HTTP gate on this loopback URL set PBP_TEST_BASE_URL, PBP_TEST_USER and
PBP_TEST_PASSWORD privately, then run python3 tests/http_workflow.py. These tests
perform only synthetic sandbox effects. They require recorded mode and reject a public URL.

For explicitly authorized real inference, populate ignored private/providers.env and
add -f compose.live.yml. That profile enables outbound networking and loads credentials;
it is an intentional cost-bearing opt-in. Always specify the provider and model. See
provider scope and comparison. Never put keys in a Compose argument,
a command line, Git, a screenshot or a public image.

Test the language components

cd seal
npm ci
npm test
npm run typecheck
cd ..
python3 -m venv .venv
. .venv/bin/activate
python -m pip install --require-hashes -r requirements.lock
python -m pip install -r requirements-test.txt
python -I -B tests/offline_runner.py
python -m pytest -q python/tests
python scripts/check_source.py

GitHub Actions runs the TypeScript vectors/typecheck and Python suites. The vendor
EAP image is not available on public CI runners, so actual IRIS compile/bridge tests
run with scripts/test_iris.py in the local private-image lab. A green public workflow
alone does not establish an IRIS integration pass.

What is sealed

The salted SHA-256 commitment covers canonical JSON: inputs, tool outputs, explicit
missing evidence, policy, forbidden actions, decision and autonomy limits. An edited
decision or a dossier completed after sealing changes the commitment. The adapter
rejects personal data and bounded-input errors without returning offending values.
Witness.Seal creates a local commitment; Witness.VerifyLocal detects edits.
An intact local envelope stays pending until independent anchoring is verified.
This is an application-level integrity check against the stored commitment. A privileged
administrator who can replace the record, salt and commitment can rewrite local history;
protection from a compromised host or database administrator is not claimed. A rejected
model proposal remains a separately labelled, unsealed diagnostic; the effective escalation
and its input/tool evidence are sealed.

The validated agent operation uses one worker. Its current-case binding is held in a
process-private global, enforced by both the authorization policy and the tools, and cleared
after each run. Increasing parallelism requires separate validation; one-worker results are
not a scalability claim.

The original pbp_seal reference also contains chain and Solana helpers. Those are
not invoked by the runtime or tests, which do not sign or broadcast transactions.
The historical S0 fixture is public synthetic test evidence, not a new S1 anchor.

See provenance, runtime diagnosis,
validation, and the submission draft.
The contest bonus tracker now maps the official contest49
table to implementation evidence and pending deliverables. Published point values are not
points awarded to this application.

Made with
Install
zpm install proof-before-pay download archive
Version
0.1.0-beta.1
Category
AI Agents
Works with
InterSystems IRIS
First published
03 Nov, 2026
Last edited
03 Nov, 2026