Versioned property-graph schema for agentic decision structures (dg/v1) — spec, validator, and generators
Project description
dg — decision-graph spec
DRAFT — pre-1.0. Schema is settled in shape; the JSON spec format is a first-iteration draft and will likely refine before stable release.
dg is a versioned property-graph schema for representing decision structures — the choices, actions, and communications an AI agent (or human, or hybrid system) makes during a workflow run. It's designed to be the canonical target for mapping any decision-making data, including OpenTelemetry agent traces, into
- Contntext graph (Neo4j or any property-graph database)
- Analytics-ready tabular data (Arrow / Parquet) for ML training pipelines, RL, and agentic research.
The spec exists as a machine-readable JSON document (spec.json) plus a human-readable design rationale (design.md). The JSON spec is intended to drive auto-generators in consumer libraries — Arrow schema generation, Cypher constraint / index / upsert templates, validation tooling, etc.
What's in this repo
| File | Purpose |
|---|---|
spec.json |
Canonical machine-readable schema. Property types, node definitions (with labels, upsert keys, indexes, properties, inheritance), relationship definitions (with from/to, cardinality, edge properties). |
design.md |
Full design rationale — locked decisions and the why behind them, layering, identity rules, namespacing contract, provenance contract, mapping from OpenTelemetry agent-trace formats, considered-and-rejected alternatives, open questions. |
arrows.json |
Supplementary Arrows.app-importable JSON for visual editing. Renders the schema as a property-graph diagram. Open at arrows.app and paste contents. |
Why three artifacts
- spec.json is what tooling consumes. Auto-generators read it; validators check instances against it.
- design.md is what humans read to understand why the schema looks the way it does. New consumers should start here.
- arrows.json is what humans use to see the schema as a diagram and to propose edits visually. Re-export from Arrows back into this file when changes are accepted.
The three should stay in sync — if you change one, update the others.
Layers at a glance
┌────────────────────────┐
│ Evaluation layer │ scores, judgments — produced
│ (:Evaluation) │ separately from the workflow
└────────────┬───────────┘
│ EVALUATES
▼
┌─────────────────┐ FOR_TASK ┌───────────────────────┐
│ Reference layer │◄─────────────│ Execution layer │
│ (resolve down) │ │ (UUIDs / OTel ids) │
│ Task, Actor, │ │ WorkflowExecution, │
│ Tool, Resource │ │ StepExecution │
│ (incl. :Model) │ │ (:ToolCall :Reasoning │
│ Session │ │ :Message) │
└─────────────────┘ └────────────────────────┘
- Reference layer — natural keys, MERGE on upsert. Same
gpt-4o-minieverywhere; sameTool {service_name, name, version}across all workflows. Resolves down across runs. - Execution layer — IDs derived from OTel
trace_id/span_idwhen sourced from OTel (so re-ingestion is idempotent); UUIDs otherwise. Per-run state with timestamps, status, errors, provenance. Edges to the reference layer carry per-call data (token counts, model identity, tool args). - Evaluation layer — independent provenance,
EVALUATESback into the execution layer. Produced by separate eval pipelines (LLM judges, human review batches, automated tests).
See design.md for the full reference.
Consuming the spec
The intended pattern is for downstream libraries to:
- Read
spec.json(pin to a tagged version) - Generate Arrow schemas from the node + relationship definitions
- Generate Cypher
CREATE CONSTRAINT/CREATE INDEX/ parameterizedMERGEupsert templates per node label and edge type - Validate instance documents against the spec
The reference implementation is otela, which will produce dg/v1 instance data from OTel agent traces.
Installing
pip install --pre decision-graph
# or with uv:
uv add --prerelease=allow decision-graph
The --pre flag is needed while dg/v1 is in alpha (1a0, 1a1, ...). Once v1 ships stable, drop it.
The package ships with the bundled dg/v1 spec accessible as decision_graph.SPEC_PATH (a pathlib.Path) and decision_graph.load_spec() (a parsed dict). It has no runtime dependencies.
Validating an instance
A dg-instance JSON document is a single file with nodes and relationships arrays:
{
"spec": "dg",
"spec_version": "v1",
"nodes": [
{"id": "n1", "labels": ["Tool"], "properties": {"service_name": "...", "name": "...", "version": "..."}}
],
"relationships": [
{"type": "CALLS_TOOL", "from_id": "tool-call-1", "to_id": "n1", "properties": {}}
]
}
The instance-level node id is an opaque handle used for relationship endpoint resolution within the file. The spec's properties.id (where present) is a separate concept — the natural identity used for upsert into a graph DB.
Validate against the bundled spec:
python -m decision_graph.validator path/to/instance.json
Or programmatically:
import decision_graph
from decision_graph.validator import SpecModel, validate
spec = SpecModel(decision_graph.load_spec())
errors = validate(instance_dict, spec)
for err in errors:
print(err)
The validator checks structural shape, property types and constraints (enums, minLength, minimum, format=json, nullable), edge endpoint type matching (via extends chains so an :Actor:Agent is accepted where :Actor is required), dangling endpoint detection, and upsert-key uniqueness grouped by upsert root (an Agent and a Human with the same (service_name, name, version) will collide under the abstract Actor constraint, matching the Cypher-generation intent).
To validate against a spec on disk (e.g., a different version):
python -m decision_graph.validator path/to/instance.json --spec path/to/spec.json
Versions
| Version | Status | Tag | Notes |
|---|---|---|---|
v1 |
DRAFT (alpha) | v1a0 |
Initial pre-release. Three layers (reference / execution / evaluation), Actor-centric execution, OTel-derived idempotency. |
The package's major version tracks the schema version: alpha releases of dg/v1 are tagged v1a0, v1a1, ...; the stable dg/v1 release is v1; the next schema generation goes to v2a0, then v2. The main branch reflects the in-progress next release. For a stable consumable spec, install a tagged release from PyPI or pin to a tag.
Status and stability
dg/v1 is DRAFT in alpha. The schema shape is settled (locked decisions in design.md); what's still in flux is the JSON spec format itself — spec.json is a first iteration of a JSON-Schema-flavored DDL with custom extensions for graph-DDL concerns (extends, upsert_key, indexes, $arrow). The format (meta.format_version: "0.1") is expected to refine before v1 is tagged stable.
Once a version is tagged stable, its spec.json is immutable at that tag. Iteration during alpha happens via pre-release tags (v1a0, v1a1, ...); subsequent schema generations get a new version (v2a0, v2, ...).
Contributing
This is an early project. The way to contribute right now is to open an issue describing a real-world OTel trace shape, ML use case, or graph-query pattern that the current schema doesn't support cleanly. Concrete examples beat abstract proposals.
When the schema does change, the version's design.md "Changes from previous version" section captures the diff with rationale; the GitHub Release notes summarize.
License
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 decision_graph-1a0.tar.gz.
File metadata
- Download URL: decision_graph-1a0.tar.gz
- Upload date:
- Size: 35.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39a5463f074cb90293716a7bd5eebf4271a2983523c3b59adc3d65795aa577fe
|
|
| MD5 |
6fc4420fff85565c7fe0d83723273efc
|
|
| BLAKE2b-256 |
b8004e5fefb5bec7533d699f5ab75ba077fbe7fafebdfebd721e56856782568d
|
Provenance
The following attestation bundles were made for decision_graph-1a0.tar.gz:
Publisher:
release.yml on decision-graph/decision-graph
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
decision_graph-1a0.tar.gz -
Subject digest:
39a5463f074cb90293716a7bd5eebf4271a2983523c3b59adc3d65795aa577fe - Sigstore transparency entry: 1463349802
- Sigstore integration time:
-
Permalink:
decision-graph/decision-graph@25a511ca1700f467b55df2105c9594b2b20320e2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/decision-graph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@25a511ca1700f467b55df2105c9594b2b20320e2 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file decision_graph-1a0-py3-none-any.whl.
File metadata
- Download URL: decision_graph-1a0-py3-none-any.whl
- Upload date:
- Size: 20.1 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 |
e4279b6593ad4ab2ca8e29cfb52b674485589f28625cb776695bd43764b298e6
|
|
| MD5 |
43395f04eb4dd899492ce25a03f34ef0
|
|
| BLAKE2b-256 |
86671187e59607d0097f8811b2818b859aeb6f1ae41afc7365920cfc62d58428
|
Provenance
The following attestation bundles were made for decision_graph-1a0-py3-none-any.whl:
Publisher:
release.yml on decision-graph/decision-graph
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
decision_graph-1a0-py3-none-any.whl -
Subject digest:
e4279b6593ad4ab2ca8e29cfb52b674485589f28625cb776695bd43764b298e6 - Sigstore transparency entry: 1463349873
- Sigstore integration time:
-
Permalink:
decision-graph/decision-graph@25a511ca1700f467b55df2105c9594b2b20320e2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/decision-graph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@25a511ca1700f467b55df2105c9594b2b20320e2 -
Trigger Event:
workflow_dispatch
-
Statement type: