Skip to main content

hypabolic-trajectory

Normalize coding-agent session transcripts into deterministic, versioned Trajectory contracts. Independent native Python 3.11+ runtime of the Hypabolic Trajectory product — same wire contracts and shared conformance suite as .NET, TypeScript, and Rust. No FFI to other language runtimes.

PyPI name hypabolic-trajectory (org Hypabolic)
Import root hypabolic_trajectory
Requires-Python >=3.11
Normalizer contract 0.2.0 (identity-stable; embedded in canonical output)
Wire package version WIRE_PACKAGE_VERSION — tip pin "0.1.0" (must match peer runtimes + goldens on the same tag; not auto-bound to package SemVer)
License MIT

Published vs tree: NuGet / npm / crates 0.1.0 already ship without AHP. The first public PyPI cut of this package ships on the next synchronized multi-registry tag (with tip sources including AHP Shape A). Until that tag, install from this monorepo (editable) or wait for the tag.


Package map

Dist / extra Import Role
hypabolic-trajectory (core wheel) hypabolic_trajectory Normalize, project (including pure project_otel_genai), listing, bundled contracts + runtime-capabilities.json, and hypabolic_trajectory.otel (SpanSetSink / emit_to, no SDK)
hypabolic-trajectory[otel] same hypabolic_trajectory.otel Optional OpenTelemetry SDK sink helpers + opentelemetry-* deps only. Does not gate pure projection or emit_to with a pure sink.
Conformance runner not published python/tools/trajectory_conformance — stdin/stdout protocol v1 for conformance/verify.py
Sample CLI not published python/samples/trajectory_cli — browse/list/show (no console script)

Cross-ecosystem map (same product):

Ecosystem Core Optional
.NET Hypabolic.Trajectory .OpenTelemetry, .Testing
TypeScript @hypabolic/trajectory @hypabolic/trajectory-node, @hypabolic/trajectory-otel
Rust hypabolic-trajectory hypabolic-trajectory-opentelemetry
Python hypabolic-trajectory [otel] SDK sinks only

Install

# After first public tag (replace with the tag SemVer):
pip install hypabolic-trajectory==<tag-semver>
pip install 'hypabolic-trajectory[otel]==<tag-semver>'   # optional SDK sinks

# From this monorepo (development):
python -m pip install -e './python[dev]'

The published wheel has no console scripts. The conformance runner and sample CLI are monorepo-only.

Sample CLI (unpublished)

# After editable install of the core package:
PYTHONPATH=python/samples python -m trajectory_cli list --source pi
PYTHONPATH=python/samples python -m trajectory_cli show \
  --source pi \
  --path conformance/cases/pi/tool-calls/input.jsonl
PYTHONPATH=python/samples python -m trajectory_cli browse

See samples/trajectory_cli/README.md.


Supported public imports (semver-stable)

Only these paths are supported:

  1. Package root hypabolic_trajectory — names in root __all__
  2. hypabolic_trajectory.ir — multi-project IR surface (ir.__all__)
  3. hypabolic_trajectory.otel — always importable from the core wheel

Any other module path (api, engine, normalize, sources, …) is unsupported and may break without notice.

from hypabolic_trajectory import (
    # free functions
    normalize_to_ir,
    normalize_to_letta,
    normalize_to_canonical,
    normalize_to_hypabolic,
    project_letta,
    project_canonical,
    project_hypabolic,
    project_openai,
    project_minimal_jsonl,
    project_otel_genai,
    list_trajectories,
    serialize_projection,
    canonical_json,
    # engine
    TrajectoryEngine,
    # request / errors
    NormalizeRequest,
    SourceContext,
    NormalizeOptions,
    Bounds,
    Filters,
    TrajectoryError,
    Diagnostic,
    TrajectorySource,
    # versions
    NORMALIZER_CONTRACT_VERSION,  # "0.2.0"
    WIRE_PACKAGE_VERSION,         # tip "0.1.0" until coordinated bump
    PACKAGE_VERSION,
    __version__,
)
from hypabolic_trajectory.ir import TrajectoryIR  # also re-exported at root
from hypabolic_trajectory.otel import SpanSetSink, emit_to

OTEL import matrix

Import / call Without opentelemetry-* With [otel] extra
from hypabolic_trajectory import project_otel_genai Succeeds Succeeds
from hypabolic_trajectory.otel import SpanSetSink, emit_to Succeeds Succeeds
emit_to(pure_sink, ir) pure project + sink.emit; no SDK Same
Concrete SDK helper symbols (if shipped) ImportError with install hint Succeeds when deps present
Whole hypabolic_trajectory.otel package Always in the core wheel Same

Quick usage

from pathlib import Path
from hypabolic_trajectory import (
    NormalizeRequest,
    TrajectorySource,
    list_trajectories,
    normalize_to_ir,
    project_hypabolic,
    project_letta,
    project_otel_genai,
    serialize_projection,
    TrajectoryEngine,
)

# Listing always takes an explicit root (no home default in library APIs).
page = list_trajectories(
    source=TrajectorySource.CLAUDE_CODE,
    root=Path.home() / ".claude" / "projects",
    limit=20,
)
session = page.items[0]

transcript = Path(session.path).read_bytes()
request = NormalizeRequest(
    source=TrajectorySource.CLAUDE_CODE,
    transcript=transcript,
)

ir = normalize_to_ir(request)
hypabolic = project_hypabolic(ir)
messages = project_letta(ir)
spans = project_otel_genai(ir)  # pure; no OTEL SDK required

# Product JSON emit (shared Trajectory string-escape; never stdlib json.dumps
# for identity/product schemas):
wire = serialize_projection(hypabolic)

# Engine (tip matrix including pure otel); free functions ignore engine mutations.
engine = TrajectoryEngine.create_default()
out = engine.project(ir, "hypabolic-trajectory-v1")

Filters (normalize options)

NormalizeOptions.filters controls content inclusion during normalization:

Field Values Default Effect
filters.tool_results "include" | "omit" "include" When "omit", tool-result record bodies are dropped while structure/diagnostics remain policy-correct

Bounds (options.bounds.tool_arguments / tool_results) cap argument/result character lengths with documented truncation strategies. Domain validation of options runs at free-function / engine entry (DTO construction does not raise TrajectoryError).

from hypabolic_trajectory import (
    Filters,
    NormalizeOptions,
    NormalizeRequest,
    TrajectorySource,
    normalize_to_ir,
)

request = NormalizeRequest(
    source=TrajectorySource.PI,
    transcript=b"...",
    options=NormalizeOptions(filters=Filters(tool_results="omit")),
)
ir = normalize_to_ir(request)

Dual timestamps

Source adapters and the normalizer preserve dual timing when present (never fabricated):

Clock Field Role
Millisecond timestamp_ms (int) Filled / synthesized body clock used for public message, canonical, Hypabolic, and jsonl-minimal timestamps
Precise timestamp_precise (str, optional) Source-native high-resolution string when present; copied onto IR records and model invocations

Public timestamp formats (filled timestamp_ms only — never source_timestamp_ms):

Surface Format
Message / canonical / Hypabolic yyyy-MM-ddTHH:mm:ss.fffZ
Listing updated_at Z form
jsonl-minimal yyyy-MM-ddTHH:mm:ss.fff+00:00 (three fractional digits; omit key when filled ms is absent)
OTEL span bounds precise as-is; else ms → seven-digit pad (Z0000+00:00)

Identity formulas and string escape

Authority: contracts/spec/identity.md, contracts/spec/canonical-json.md, and peer goldens. Digests are 64 lowercase hex.

Product field Formula
Hypabolic trajectory_id sha256(utf8(compact_json([source_wire_name, group_id])))
Model-invocation id sha256(utf8(compact_json([group_id, identity, "model-invocation"])))
Model-invocation absolute offset checked decoded.source_offset + base_byte_offset (signed int64; overflow → invalid_input)
segment.partial config.partial or base_byte_offset != 0

Trajectory string-escape (shared by canonical_json, serialize_projection, and each project_minimal_jsonl line):

  1. Walk the string as UTF-16 code units.
  2. Short escapes for ", \\, \b, \t, \n, \f, \r.
  3. \uXXXX four uppercase hex for U+0000–001F, U+E000–F8FF, U+2028, U+2029, and surrogates; else UTF-8.
  4. Do not escape solidus /; no Unicode normalization; no BOM.

Only identity hashing sorts object keys by UTF-16 code unit order via canonical_json. Product serialize_projection preserves insertion order.


Capabilities and sources

Advertised surface is the tip matrix in python/runtime-capabilities.json (must equal contracts/compatibility.json and peer TS/Rust manifests at ship):

  • Sources: pi, claude-code, codex, openclaw, hermes, ahp (Shape A offline ChatState snapshot; listing Phase 3 stub)
  • Outputs: letta-trajectory-v1, letta-canonical-v1, hypabolic-trajectory-v1, openai-chat-messages, jsonl-minimal, otel-genai-spans-v1
  • Capabilities: normalize, normalize-partial, list-explicit-root, typed-diagnostics, typed-fatal-errors, deterministic-rerun
  • Slice: ML13 (historical id; AHP is a post-0.1.0 source addition on tip)

Do not treat IMPLEMENTED_SOURCES as a registry claim — the capabilities file is authoritative for CI and advertising.


Conformance (filtered runner argv)

Protocol v1 runner (unpublished): python/tools/trajectory_conformance.

# Editable install + unit tests
python -m pip install -e './python[dev]'
python -m pytest python/tests -q

# Tip suite (unfiltered verify defaults to compatibility tip set):
python conformance/verify.py --repository-root . -- \
  env PYTHONPATH=python/src:python/tools python -m trajectory_conformance

# Progressive / filtered argv from claimed capabilities (fail-closed when ⊂ tip):
python conformance/verify.py --repository-root . \
  $(python tools/conformance_argv_from_capabilities.py --repository-root .) \
  -- \
  env PYTHONPATH=python/src:python/tools python -m trajectory_conformance

# Manual filters while iterating:
python conformance/verify.py --repository-root . \
  --source pi --operation normalize-letta --operation normalize-canonical -- \
  env PYTHONPATH=python/src:python/tools python -m trajectory_conformance

When claimed sources/outputs are a proper subset of tip, CI must pass explicit --source / --operation filters (generator: tools/conformance_argv_from_capabilities.py). Never run unfiltered verify while claimed ⊂ tip.

Identity baseline:

sha256sum --check conformance/identity-baseline.sha256

Version pins

Symbol / field Value / rule
NORMALIZER_CONTRACT_VERSION "0.2.0" — wire identity contract
WIRE_PACKAGE_VERSION "0.1.0" tip pin until all runtimes + goldens move together
PACKAGE_VERSION / __version__ From installed dist metadata (stamp-synced with root VERSION)
Canonical normalizer_version Contract version 0.2.0 (never package SemVer)
Hypabolic normalizer.version WIRE_PACKAGE_VERSION
OTEL instrumentation_version WIRE_PACKAGE_VERSION

Development

From the monorepo root:

python -m pip install -e './python[dev]'
python -m pytest python/tests -q

Implementation authority: docs/python-implementation-spec.md, contracts/, and conformance/. Status: docs/python-impl-status.md.

License

MIT — Copyright 2026 Hypabolic

Release files for hypabolic-trajectory 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hypabolic-trajectory 0.1.2
File Size Uploaded
hypabolic_trajectory-0.1.2.tar.gz 80.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hypabolic-trajectory 0.1.2
File Interpreter ABI Platform
hypabolic_trajectory-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 197.6 kB

Release files / hypabolic_trajectory-0.1.2.tar.gz

Download URL hypabolic_trajectory-0.1.2.tar.gz
Size 80.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ab2e9f2d5e6bb67e6adcac4c568fec6f574759239739a7f4b40e6f2535f26716
BLAKE2b-256 checksum
How to use checksums
c2ba362d0ece25978406bf023e080d915137134ba447957a44c757d92e6de3c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.

Transparency log

Release files / hypabolic_trajectory-0.1.2-py3-none-any.whl

Download URL hypabolic_trajectory-0.1.2-py3-none-any.whl
Size 117.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
495405a2e631815347748a3bdc3220a1b4e383f1c767a008ae4f5c5e95c49ad1
BLAKE2b-256 checksum
How to use checksums
ae3e0eee76265e0539e37931536929ec9352c2ce35e5897f039f1aad294b00cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.4

2 release files

0.1.3

2 release files

This release

0.1.2 This release

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page