Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions papers/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Published source packages: keep their bytes exactly as released, so each
# package manifest and SHA256SUMS still verifies after checkout.
* -text
16 changes: 16 additions & 0 deletions papers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Papers

LaTeX or Markdown source for the technical reports about this project. Each folder holds the
published `source.zip` of the version listed, unpacked and unchanged, so the build and the
reproduction steps in its own README work from here. The report page carries the built PDF,
citation files and every earlier version.

Paper text is licensed CC BY 4.0. Code inside a paper folder states its own license in that
folder; the rest of this repository keeps its existing license.

| Report | Version and date | Page | DOI |
|---|---|---|---|
| [From Agent Observability to Governance Evidence: A Privacy-Constrained Telemetry Contract](agentrust-telemetry/) | 2, 2026-10-01 | [page](https://agentrust-io.com/research/agentrust-telemetry/v2/) | [10.5281/zenodo.23091282](https://doi.org/10.5281/zenodo.23091282) |
| [Acceptance Before Export: A Bounded Evidence Contract for Governance Telemetry](telemetry-evidence-acceptance/) | 3, 2026-10-01 | [page](https://agentrust-io.com/research/telemetry-evidence-acceptance/v3/) | [10.5281/zenodo.23091285](https://doi.org/10.5281/zenodo.23091285) |

These sources previously lived in a private papers repository, which has been retired.
20 changes: 20 additions & 0 deletions papers/agentrust-telemetry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# From Agent Observability to Governance Evidence: A Privacy-Constrained Telemetry Contract

Technical report, version 2, October 1, 2026. Not peer reviewed. Patent Pending.
Version 2 corrects the statement that approval digests prevent an approval from being attached to
another action, which the reference finalizer does not check, and restores the bold type that
the version 1 build dropped. Results are unchanged.

Build: `tectonic paper.tex` (prepared with Tectonic 0.16.9; set SOURCE_DATE_EPOCH=1790812800
to reproduce the published PDF byte for byte).

Paper text is licensed CC BY 4.0: https://creativecommons.org/licenses/by/4.0/
Project code retains its existing project license; see https://github.com/agentrust-io/agentrust-telemetry.

This package contains the manuscript source and the rerun records. The evaluated code is
agentrust-telemetry 0.1.0-alpha.2, commit 29c13cfa4047a0f5784a90df63b22a3568453158.
`experiments/results/rerun-2026-09-27.txt` records the September 27 rerun and
`experiments/results/rerun-2026-10-01/` the October 1 audit rerun at that commit, a later
revision and main, with the probe scripts it used. It is not an independently replicated
reproduction package.
Current implementation guidance: https://agentrust-io.com/telemetry/
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
AgenTrust Telemetry software rerun, 2026-09-27
Repository: https://github.com/agentrust-io/agentrust-telemetry
Evaluated commit: 29c13cfa4047a0f5784a90df63b22a3568453158
(release 0.1.0-alpha.2, tag v0.1.0-alpha.2; main as of 2026-09-03; next main commit is dated 2026-09-05)
Source obtained with: git archive <commit> (no working-tree state)
Python: 3.12.10 on Windows 11
Install: pip install -e ".[test,otel]" resolved on 2026-09-27, then the TRACE
dependency pinned to the release current on 2026-09-03 and PyYAML added so
the two YAML repository gates run instead of skipping:
agentrust-trace==0.9.0 jsonschema==4.26.0 referencing==0.37.0 rfc8785==0.1.4
opentelemetry-api==1.45.0 opentelemetry-sdk==1.45.0 PyYAML==6.0.3 cbor2==5.9.0

## python -m unittest discover -s tests -v
Ran 111 tests
OK (111 passed, 0 skipped, 0 failed)
Per module: adapters 10, agt_adapter 4, agt_approval 6, agt_audit 4,
conformance 6, data_flow 4, evidence 11, otel_projectors 6, propagation 5,
reference_scenario 1, repository_gates 16, sdk 10, trace_adapter 9,
trace_adapter_refusals 10, usage 9

Same command with the dependency resolution of 2026-09-27 (agentrust-trace 0.11.0, no PyYAML):
Ran 111 tests: 108 passed, 2 skipped (PyYAML not installed), 1 failed
FAIL test_trace_adapter_refusals.test_a_failure_inside_official_signing_is_reported_as_one
cause: agentrust-trace 0.10.0 (published 2026-09-06) rejects a non-Ed25519
stand-in key ("key must be an Ed25519PrivateKey, got FailsWhenUsed");
the repository replaced the stand-in in commit 5d963d3 (2026-09-06).

## python conformance/runner/validate.py
PASS valid/action.json
PASS valid/approval.json
PASS valid/data-flow.json
PASS valid/evidence.json
PASS valid/policy-decision.json
PASS valid/usage.json
PASS invalid/action-without-digest.json
PASS invalid/aggregate-cost-without-rollup.json
PASS invalid/model-call-with-rollup.json
PASS invalid/numeric-timestamp.json
PASS invalid/raw-content.json
PASS invalid/usage-without-measurement.json
PASS invalid/zero-trace-id.json
13/13 expected verdicts (6 valid accepted, 7 invalid rejected); exit 0

## Repository contract checks
python tools/check_otel_compatibility.py
PASS OTel GenAI matrix covers 16 span attributes, 8 metrics, and 6 event families
(profile agentrust-otel-genai-compatibility-v1, captured 2026-08-18, upstream
open-telemetry/semantic-conventions-genai @ a685613a, status development)
python tools/check_typescript_schemas.py
PASS TypeScript schemas match normative bytes
python tools/check_schemas.py
PASS 8 bundled schemas match normative bytes
python tools/check_versions.py
PASS contract=0.1.0-alpha.2 python=0.1.0a2 npm_name=@agentrust-io/telemetry npm=0.1.0-alpha.2

## Boundary probes (scripted, against the evaluated source; probe script not part of the repository)
P1 durable callback returns False: EvidencePersistenceError raised; log projection calls=0; accepted entries=0
P2 log exporter raises after acceptance: accepted=True; entries=1;
projection_errors=['log projection failed: RuntimeError: exporter down']
P3 empty accumulator sealed: entries=0 completeness=complete
P4 callback commits externally then raises once, caller retries: external writes=2, local entries=1

## Post-evaluation regression tests run against the evaluated source
tests/test_trace_adapter_refusals.py copied from main c3515681 (fix merged 2026-09-25, PR #65)
Ran 14 tests: 3 failures, 1 error
FAIL test_an_event_edited_after_sealing_is_refused
FAIL test_a_dropped_entry_is_refused
FAIL test_a_substituted_chain_digest_is_refused
ERROR test_a_consistent_chain_over_a_malformed_event_is_refused
The evaluated finalizer signs snapshots whose entries no longer match the chain digest.

## Comparison: current main
Commit c3515681261fd0ab6e6aa38e20eb2f071aee7a20 (release 0.1.0-alpha.5), same Python,
dependencies resolved 2026-09-27 (agentrust-trace 0.11.0, PyYAML installed)
python -m unittest discover -s tests: Ran 128 tests, OK
conformance runner: 13/13 expected verdicts (same 13 fixtures)
check_otel_compatibility: 16 span attributes, 8 metrics, 6 event families

NOT RERUN: TypeScript test suite (npm run check); collector or backend interoperability;
performance. No hardware is involved in this evaluation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
AgenTrust Telemetry software rerun, 2026-10-01 (audit of technical report v1)
Repository: https://github.com/agentrust-io/agentrust-telemetry
Evaluated commit: 29c13cfa4047a0f5784a90df63b22a3568453158 (tag v0.1.0-alpha.2)
Later revision: c3515681261fd0ab6e6aa38e20eb2f071aee7a20 (release 0.1.0-alpha.5, 2026-09-26)
Current main: c86753cad6bbe9f00c5080489a12e0f94df34899 (2026-09-30; no src/ or
packages/typescript/src change since c351568)
Source obtained with: git archive <commit>; tar commit id checked (git get-tar-commit-id)
Python 3.12.10, Node v24.18.1, npm 11.16.0, Windows 11. Fresh virtual environments.

## Pinned commit, Python
Install: pip install -e ".[test,otel]" (resolved 2026-10-01: agentrust-trace 0.11.0,
opentelemetry 1.45.0), then agentrust-trace==0.9.0 PyYAML==6.0.3 cbor2==5.9.0
(dependencies-pinned.txt)
python -m unittest discover -s tests -v: Ran 111 tests, OK, 0 skipped (python-unittest-pinned.txt)
Same command before the TRACE pin and PyYAML (agentrust-trace 0.11.0):
Ran 111 tests, FAILED (failures=1, skipped=2)
FAIL test_trace_adapter_refusals.test_a_failure_inside_official_signing_is_reported_as_one
python conformance/runner/validate.py: 13 PASS (6 valid accepted, 7 invalid rejected), exit 0
python tools/check_otel_compatibility.py: PASS 16 span attributes, 8 metrics, 6 event families
python tools/check_typescript_schemas.py: PASS TypeScript schemas match normative bytes
python tools/check_schemas.py: PASS 8 bundled schemas match normative bytes
python tools/check_versions.py: PASS contract=0.1.0-alpha.2 python=0.1.0a2 npm=0.1.0-alpha.2

## Pinned commit, TypeScript (not rerun in the v1 report)
packages/typescript: npm ci (lockfile), npm run check (tsc build, tsx --test, npm pack --dry-run)
tests 41, pass 41, fail 0, skipped 0; pack dry run produced
agentrust-io-telemetry-0.1.0-alpha.2.tgz (typescript-check-pinned.txt)

## Boundary probes P1 to P4 (telemetry_probes.py, reconstructed from Section 6)
pin, later revision and current main give identical results (probes-output.txt):
P1 refused ack: EvidencePersistenceError raised; log projection calls=0; entries=0
P2 failing exporter: entries=1; projection_errors=['log projection failed: RuntimeError: exporter down']
P3 empty seal: entries=0 completeness=complete
P4 lost ack then retry: external writes=2; local entries=1

## Section 7 findings, rechecked (validation_probes.py and regression tests)
At the pin: 5000-deep nesting raises RecursionError; a non-string key raises
AttributeError; NaN and Infinity attributes pass validate() and are refused only
by the accumulator (EvidenceError); a durable callback that calls snapshot()
on the same thread deadlocks (no return in 5 s).
At c351568 and current main: all four cases return EventValidationError or succeed.
tests/test_trace_adapter_refusals.py from c351568 run against the pinned source:
Ran 14 tests, FAILED (failures=3, errors=1) (regression-tests-at-pin-python.txt)
The TypeScript regression test added by the same fix, appended to the pinned
test/trace-finalizer.test.ts: pass 5, fail 1, "Missing expected exception"
(regression-test-at-pin-typescript.txt). The TypeScript finalizer at the pin
also signs an edited, truncated or digest-substituted snapshot.

## Current main (c86753c), dependencies resolved 2026-10-01 plus PyYAML
python -m unittest discover -s tests: Ran 129 tests, OK (python-unittest-current-main.txt)
(128 at c351568; one repository-gate test added in #70)
conformance runner: 13/13; OTel matrix: 16 / 8 / 6; check_versions: 0.1.0-alpha.5
TypeScript npm run check: tests 42, pass 42 (typescript-check-current-main.txt)

## Not run
Collector or backend interoperability; performance; durable store; crash and restart.

## Approval to executed-action binding (approval_binding_probe.py, added by this audit)
Challenge decision, approval.requested and approval.approved bound to action digest b*64,
then action.executed carrying the same approval_id with digest b*64 or c*64, sealed
complete and finalized with agentrust-trace 0.11.0 (approval-binding-output.txt):
pin: same digest -> affirming; different digest -> affirming
main: same digest -> affirming; different digest -> affirming
The finalizer checks request-to-approval binding (including action_digest) but does not
compare the approved digest with the executed action's digest.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
== pin
executed action with same digest as approved: appraisal=affirming
executed action with different digest: appraisal=affirming
== main
executed action with same digest as approved: appraisal=affirming
executed action with different digest: appraisal=affirming
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Does TRACE finalization notice an executed action whose digest differs from the approved one?

Usage: python approval_binding_probe.py SOURCE_DIR (an agentrust-telemetry tree)
"""
import json, sys
from pathlib import Path
ROOT = Path(sys.argv[1]); sys.path.insert(0, str(ROOT / 'src'))
from agentrust_telemetry import EvidenceAccumulator, SchemaValidator, TraceConfiguration, finalize_trace
from agentrust_trace import generate_key
fx = lambda n: json.loads((ROOT / 'conformance/fixtures/valid' / n).read_text())
v = SchemaValidator(ROOT / 'spec/schema')
config = TraceConfiguration(subject='spiffe://example.test/agent/workflow', model_provider='example', model_id='m', model_version='1',
build_digest='sha256:' + 'b' * 64, build_slsa_level=1, origin_kind='self', origin_producer='example-runtime',
appraisal_verifier='https://example.test/verifier', classification_taxonomy='example.enterprise.v1',
classification_order=('public', 'internal', 'confidential', 'restricted'))
policy = fx('policy-decision.json'); policy['decision'] = 'challenge'
request = fx('approval.json'); request.update(event_type='approval.requested', event_id='018f0f7d-7a13-7cc2-8000-000000000010',
policy_event_id=policy['event_id'], chain_id='operators', chain_version='3', expires_at_unix_nano='1787080100000000000', time_unix_nano='1787079500000000000')
approval = fx('approval.json'); approval.update(event_type='approval.approved', policy_event_id=policy['event_id'], chain_id='operators',
chain_version='3', expires_at_unix_nano=request['expires_at_unix_nano'])
for label, digest in (('same digest as approved', 'b' * 64), ('different digest', 'c' * 64)):
action = fx('action.json'); action['action_digest'] = {'algorithm': 'sha256', 'value': digest}
acc = EvidenceAccumulator(policy['run_id'], v)
for e in (policy, request, approval, fx('data-flow.json'), action): acc.append(e)
rec = finalize_trace(acc.seal(completeness='complete'), config, signing_key=generate_key())
print(f'executed action with {label}: appraisal={rec["appraisal"]["status"]}')
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
agentrust-trace==0.11.0
annotated-types==0.8.0
arrow==1.4.0
attrs==26.1.0
cffi==2.1.1
cryptography==50.0.2
fqdn==1.6.0
idna==3.20
isoduration==20.11.0
jsonpointer==3.1.1
jsonschema==4.26.0
jsonschema-specifications==2025.9.1
opentelemetry-api==1.45.0
opentelemetry-sdk==1.45.0
opentelemetry-semantic-conventions==0.66b0
pycparser==3.0
pydantic==2.13.5
pydantic_core==2.46.5
python-dateutil==2.9.0.post0
PyYAML==6.0.3
referencing==0.37.0
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rfc3987==1.3.8
rfc8785==0.1.4
rpds-py==2026.6.3
six==1.17.0
typing-inspection==0.4.4
typing_extensions==4.16.0
tzdata==2026.4
uri-template==1.3.0
webcolors==25.10.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
agentrust-trace==0.9.0
annotated-types==0.8.0
arrow==1.4.0
attrs==26.1.0
cbor2==5.9.0
cffi==2.1.1
cryptography==50.0.2
fqdn==1.6.0
idna==3.20
isoduration==20.11.0
jsonpointer==3.1.1
jsonschema==4.26.0
jsonschema-specifications==2025.9.1
opentelemetry-api==1.45.0
opentelemetry-sdk==1.45.0
opentelemetry-semantic-conventions==0.66b0
pycparser==3.0
pydantic==2.13.5
pydantic_core==2.46.5
python-dateutil==2.9.0.post0
PyYAML==6.0.3
referencing==0.37.0
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rfc3987==1.3.8
rfc8785==0.1.4
rpds-py==2026.6.3
six==1.17.0
typing-inspection==0.4.4
typing_extensions==4.16.0
tzdata==2026.4
uri-template==1.3.0
webcolors==25.10.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
== pin
P1 refused ack: EvidencePersistenceError raised=True; log projection calls=0; accepted entries=0
P2 failing exporter: entries=1; projection_errors=['log projection failed: RuntimeError: exporter down']
P3 empty seal: entries=0 completeness=complete
P4 lost ack then retry: external writes=2; local entries=1
deep nesting (5000): RecursionError
non-string key: AttributeError
NaN attribute, validate: accepted
Infinity attribute, validate: accepted
NaN attribute, accumulator append: EvidenceError
callback re-entering snapshot(): deadlocked (no return in 5 s)
== later
P1 refused ack: EvidencePersistenceError raised=True; log projection calls=0; accepted entries=0
P2 failing exporter: entries=1; projection_errors=['log projection failed: RuntimeError: exporter down']
P3 empty seal: entries=0 completeness=complete
P4 lost ack then retry: external writes=2; local entries=1
deep nesting (5000): EventValidationError
non-string key: EventValidationError
NaN attribute, validate: EventValidationError
Infinity attribute, validate: EventValidationError
NaN attribute, accumulator append: EventValidationError
callback re-entering snapshot(): accepted
== main
P1 refused ack: EvidencePersistenceError raised=True; log projection calls=0; accepted entries=0
P2 failing exporter: entries=1; projection_errors=['log projection failed: RuntimeError: exporter down']
P3 empty seal: entries=0 completeness=complete
P4 lost ack then retry: external writes=2; local entries=1
deep nesting (5000): EventValidationError
non-string key: EventValidationError
NaN attribute, validate: EventValidationError
Infinity attribute, validate: EventValidationError
NaN attribute, accumulator append: EventValidationError
callback re-entering snapshot(): accepted
Loading
Loading