Parallect Research eXchange (.prx) format specification and bundle library
Project description
prx-spec
Reference implementation of the .prx file format — the open standard for packaging multi-provider AI research into portable, verifiable bundles.
A .prx file is a gzipped tar archive containing markdown reports, structured claims with typed categories, source registries, evidence graphs, W3C PROV-O provenance, and Ed25519 cryptographic attestations. Think of it as "a research paper in a zip file" that any tool can read, write, and verify.
Every file inside a bundle is human-readable text or JSON. You can tar -xzf a .prx and read it in any text editor.
What's in a bundle
prx_a1b2c3d4/
manifest.json # JSON-LD envelope (@context, @type: prov:Entity), content flags
query.md # The original research question
providers/
perplexity/
report.md # Full provider report
meta.json # Cost, tokens, response_hash, raw_response_size
gemini/report.md
openai/report.md
synthesis/
report.md # Unified synthesis across providers
claims.json # Extracted claims with claim_type + provider attribution
sources/
registry.json # Deduplicated, quality-scored sources
evidence/
graph.json # Claim-source graph
claim_relations.json # Claim-to-claim relations (supports / contradicts / refines)
provenance/
graph.jsonld # W3C PROV-O provenance graph
attestations/
<subject>.json # Optional per-file Ed25519 signatures
Install
pip install prx-spec
Or with uv:
uv add prx-spec
Requires Python 3.10+.
Usage
Read a bundle
from prx_spec import read_bundle
bundle = read_bundle("research.prx")
print(bundle.manifest.query)
print(bundle.manifest.providers_used)
for provider in bundle.providers:
print(f"{provider.name}: {len(provider.report_md)} chars")
if bundle.synthesis_md:
print(bundle.synthesis_md[:200])
Write a bundle
from prx_spec import BundleData, ProviderData, write_bundle
from prx_spec.models import Manifest, Producer
manifest = Manifest(
id="prx_a1b2c3d4",
query="What are the tradeoffs of consensus algorithms?",
created_at="2026-04-16T10:30:00Z",
producer=Producer(name="my-tool", version="0.1.0"),
providers_used=["perplexity", "gemini"],
has_synthesis=False,
has_claims=False,
has_sources=False,
has_evidence_graph=False,
has_follow_ons=False,
)
bundle = BundleData(
manifest=manifest,
query_md="# Research Query\n\nWhat are the tradeoffs of consensus algorithms?",
providers=[
ProviderData(name="perplexity", report_md="# Perplexity Report\n\n..."),
ProviderData(name="gemini", report_md="# Gemini Report\n\n..."),
],
)
write_bundle(bundle, "research.prx")
Validate a bundle
Three validation levels:
- L0 (structural) — valid archive, required files present
- L1 (manifest conformance) — providers listed in manifest match directories on disk
- L2 (cross-reference) — claims reference real providers, sources are internally consistent
from prx_spec import validate_archive, validate_bundle
# Validate a .prx file on disk
result = validate_archive("research.prx")
# Or validate an in-memory bundle
result = validate_bundle(bundle)
print(result.valid)
for level in result.levels:
status = "pass" if level.passed else "fail"
print(f"L{level.level}: {status}")
for error in level.errors:
print(f" error: {error}")
Sign and verify attestations
Ed25519 signatures for bundle provenance. Each attestation covers a specific subject (a manifest hash, a provider report hash, etc.) and carries a signer identity.
from prx_spec import generate_keypair, sign_attestation, verify_attestation
from prx_spec.models import Attestation, Signer, Subject
# Generate a signing keypair (once)
signing_key, verify_key, key_id = generate_keypair()
print(key_id) # prx_pub_a1b2c3d4e5f6...
# Build an attestation over a file's SHA-256 hash
attestation = Attestation(
type="bundle",
signer=Signer(type="researcher", key_id=key_id),
subject=Subject(file="manifest.json", sha256="abc123..."),
)
signed = sign_attestation(attestation, signing_key)
assert verify_attestation(signed, verify_key) is True
See docs/best-practices.md for the full attestation model, including response-hash chain-of-custody recommendations.
Merge and disagreement
Two bundles answering the same query can be merged. Providers, claims, sources, and evidence are deduplicated; claim-level conflicts are surfaced.
from prx_spec import merge_bundles, compute_disagreement
merged, stats = merge_bundles([bundle_a, bundle_b])
disagreement = compute_disagreement(merged)
print(f"Providers agreeing: {disagreement.consensus_count}")
print(f"Providers conflicting: {disagreement.conflict_count}")
Pydantic models
All format structures are Pydantic v2 models with full type annotations. Use them directly for custom tooling:
from prx_spec.models import (
Manifest, Producer, ProviderBreakdown,
Citation, ProviderMeta, TokenUsage,
BasicClaim, EnhancedClaim, ClaimsFile, FollowOn,
Source, SourcesRegistry,
EvidenceCluster, EvidenceClusters, EvidenceEdge, EvidenceGraph,
Attestation, Signer, Subject,
ContinuationEntry, Continuations,
MergeConflict, MergeResult, MergeStats,
)
Every model accepts x- prefixed extension keys via model_config = ConfigDict(extra="allow").
JSON Schemas
Pre-exported JSON Schemas live in schemas/v1/ for non-Python tools:
schemas/v1/
manifest.json
citations.json
provider-meta.json
claims.json
claim-relations.json
follow-ons.json
sources-registry.json
evidence-graph.json
evidence-clusters.json
continuations.json
attestation.json
context.jsonld # JSON-LD context for the @vocab/prov/schema/prx namespaces
Regenerate them from the Pydantic models:
from prx_spec.schemas import export_schemas
export_schemas()
Best practices
See docs/best-practices.md for recommended implementation patterns, including:
- Response hashing — hash raw provider responses at receipt time (SHA-256) and record them in
input_report_hashes. Since no AI provider signs text responses today, this is the strongest practical measure for establishing chain of custody. - Claim type classification — use the standardized taxonomy from
prx_spec.claim_typesfor consistent claim categorization. - Provenance graphs — include W3C PROV-O provenance graphs for full research lineage.
- Attestation signing — sign bundle attestations with Ed25519 for verifiable provenance.
Development
git clone https://github.com/parallect/prx-spec.git
cd prx-spec
uv sync --group dev
uv run pytest
uv run ruff check .
Contributing
Contributions welcome — bug reports, spec feedback, and implementations in other languages are all appreciated. For security reports, email security@parallect.ai.
License
MIT — see LICENSE.
Built by SecureCoders. The primary reference producer of .prx bundles is parallect, our open-source multi-provider research CLI. A hosted managed version is available at parallect.ai.
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 prx_spec-0.2.0.tar.gz.
File metadata
- Download URL: prx_spec-0.2.0.tar.gz
- Upload date:
- Size: 23.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7fdcd110057dd0e8114d01739d585e174bd7b1bd2bb4372dbca8960bd1aade4
|
|
| MD5 |
7f1288790c136f0b2b5051f1e2812558
|
|
| BLAKE2b-256 |
a2ec22534f9a323d7a32e2853aba22c7fab183b927844f8720a5c681d5cb73d7
|
Provenance
The following attestation bundles were made for prx_spec-0.2.0.tar.gz:
Publisher:
release.yml on parallect/prx-spec
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
prx_spec-0.2.0.tar.gz -
Subject digest:
c7fdcd110057dd0e8114d01739d585e174bd7b1bd2bb4372dbca8960bd1aade4 - Sigstore transparency entry: 1319403650
- Sigstore integration time:
-
Permalink:
parallect/prx-spec@63ca75daf169da7d75b01fb808cbdc22ffd9c66e -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/parallect
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@63ca75daf169da7d75b01fb808cbdc22ffd9c66e -
Trigger Event:
push
-
Statement type:
File details
Details for the file prx_spec-0.2.0-py3-none-any.whl.
File metadata
- Download URL: prx_spec-0.2.0-py3-none-any.whl
- Upload date:
- Size: 33.3 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 |
e18a55b90d1bf0e3c09eac08381a6d706dda4e9c70f77b278c1140714804053e
|
|
| MD5 |
e58a6283f43c9c1a5dbec2b913590800
|
|
| BLAKE2b-256 |
38c3a0c1f663f42ec95a3e9db01207c78422f8afc156bcf580678c18bb35d126
|
Provenance
The following attestation bundles were made for prx_spec-0.2.0-py3-none-any.whl:
Publisher:
release.yml on parallect/prx-spec
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
prx_spec-0.2.0-py3-none-any.whl -
Subject digest:
e18a55b90d1bf0e3c09eac08381a6d706dda4e9c70f77b278c1140714804053e - Sigstore transparency entry: 1319403730
- Sigstore integration time:
-
Permalink:
parallect/prx-spec@63ca75daf169da7d75b01fb808cbdc22ffd9c66e -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/parallect
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@63ca75daf169da7d75b01fb808cbdc22ffd9c66e -
Trigger Event:
push
-
Statement type: