Metadata-Version: 2.4
Name: activegraph
Version: 1.12.0
Summary: An event-sourced reactive graph runtime for long-running, auditable, agentic systems.
Author: Active Graph contributors
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/yoheinakajima/activegraph
Project-URL: Documentation, https://docs.activegraph.ai/
Project-URL: Repository, https://github.com/yoheinakajima/activegraph
Project-URL: Changelog, https://docs.activegraph.ai/about/changelog/
Project-URL: Issues, https://github.com/yoheinakajima/activegraph/issues
Keywords: graph,agents,event-sourcing,runtime
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Development Status :: 3 - Alpha
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: click<9,>=8
Requires-Dist: pydantic>=2
Provides-Extra: llm
Requires-Dist: anthropic>=0.40; extra == "llm"
Requires-Dist: openai>=1.0; extra == "llm"
Requires-Dist: tiktoken>=0.7; extra == "llm"
Requires-Dist: pydantic>=2; extra == "llm"
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.40; extra == "anthropic"
Requires-Dist: pydantic>=2; extra == "anthropic"
Provides-Extra: openai
Requires-Dist: openai>=1.0; extra == "openai"
Requires-Dist: tiktoken>=0.7; extra == "openai"
Requires-Dist: pydantic>=2; extra == "openai"
Provides-Extra: sqlite
Provides-Extra: postgres
Requires-Dist: psycopg[binary]<4,>=3.1; extra == "postgres"
Provides-Extra: falkordb
Requires-Dist: falkordb>=1.0; extra == "falkordb"
Provides-Extra: falkordb-embedded
Requires-Dist: falkordblite>=0.10; extra == "falkordb-embedded"
Provides-Extra: prometheus
Requires-Dist: prometheus_client>=0.20; extra == "prometheus"
Provides-Extra: opentelemetry
Requires-Dist: opentelemetry-api>=1.25; extra == "opentelemetry"
Requires-Dist: opentelemetry-sdk>=1.25; extra == "opentelemetry"
Provides-Extra: all
Requires-Dist: anthropic>=0.40; extra == "all"
Requires-Dist: openai>=1.0; extra == "all"
Requires-Dist: tiktoken>=0.7; extra == "all"
Requires-Dist: pydantic>=2; extra == "all"
Requires-Dist: psycopg[binary]<4,>=3.1; extra == "all"
Requires-Dist: prometheus_client>=0.20; extra == "all"
Requires-Dist: opentelemetry-api>=1.25; extra == "all"
Requires-Dist: opentelemetry-sdk>=1.25; extra == "all"
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pydantic>=2; extra == "dev"
Requires-Dist: prometheus_client>=0.20; extra == "dev"
Requires-Dist: psycopg[binary]<4,>=3.1; extra == "dev"
Requires-Dist: opentelemetry-api>=1.25; extra == "dev"
Requires-Dist: opentelemetry-sdk>=1.25; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.6; extra == "docs"
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
Requires-Dist: mkdocs-llmstxt>=0.2; extra == "docs"
Dynamic: license-file

# Active Graph

> The graph is the world. Behaviors are physics. The trace is the proof.

[![PyPI](https://img.shields.io/pypi/v/activegraph)](https://pypi.org/project/activegraph/)
[![Python versions](https://img.shields.io/pypi/pyversions/activegraph)](https://pypi.org/project/activegraph/)
[![Tests](https://github.com/yoheinakajima/activegraph/actions/workflows/tests.yml/badge.svg)](https://github.com/yoheinakajima/activegraph/actions/workflows/tests.yml)
[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![arXiv](https://img.shields.io/badge/arXiv-2605.21997-b31b1b.svg)](https://arxiv.org/abs/2605.21997)

An event-sourced reactive graph runtime for long-running, auditable,
agentic systems. Behaviors react to a shared graph instead of talking
to each other. Every change is traceable. Every run is resumable,
forkable, and diff-able from its event log.

If chat-based agents are a group conversation, Active Graph is a
shared workspace where everyone can see what changed, who changed
it, and why.

> 🎥 **New:** [Watch the AI Engineer talk](https://www.youtube.com/watch?v=khVX_BUnEwU) —
> Active Graph introduced by its author in one sitting. The fastest
> way to get the mental model before you read further.

## Where everything lives

This repo is the runtime; the project is spread across a few sites,
papers, and sibling repos. Whether you are a person evaluating the
framework or an AI assistant gathering context, these are the
canonical entry points:

| Resource | What it is |
| --- | --- |
| [activegraph.ai](https://activegraph.ai/) | Project home — the pitch in one page |
| [The AI Engineer talk](https://www.youtube.com/watch?v=khVX_BUnEwU) | Video introduction from the author |
| [docs.activegraph.ai](https://docs.activegraph.ai/) | Full documentation: concepts, guides, cookbook, CLI + API reference, per-error catalog |
| [learn.activegraph.ai](https://learn.activegraph.ai/) | Interactive tutorials — refactor a familiar agent loop onto the runtime, one substitution at a time |
| [Blog](https://activegraph.ai/blog) | Release write-ups and research notes from the project |
| ["The Log is the Agent" (arXiv:2605.21997)](https://arxiv.org/abs/2605.21997) | The paper — the design argument for event-sourced agents |
| ["Regimes" (arXiv:2606.10241)](https://arxiv.org/abs/2606.10241) | Follow-up research paper; code at [yoheinakajima/regimes](https://github.com/yoheinakajima/regimes) |
| [activegraph-packs](https://github.com/yoheinakajima/activegraph-packs) | Open pack library: ~20 packs, demo bundles, a demo server, a React Inspector UI |
| [activegraph-lab](https://github.com/yoheinakajima/activegraph-lab) | Self-hosted research agent running on the runtime in production |
| [llms.txt](https://docs.activegraph.ai/llms.txt) · [llms-full.txt](https://docs.activegraph.ai/llms-full.txt) | Machine-readable docs for AI coding assistants |
| [Status](#status) · [CHANGELOG.md](CHANGELOG.md) | Where the project stands right now |

The [ecosystem](#the-ecosystem) and [research](#research) sections
below say more about each.

## Try it in 30 seconds

```bash
pip install activegraph
activegraph quickstart
```

The bundled Diligence pack runs against recorded fixtures: no API
key, no configuration, byte-deterministic output. You see what the
framework does before you read about how it does it.

Then walk the 10-minute tutorial:

```bash
activegraph quickstart --interactive
```

It scaffolds a behavior, runs it against the same fixtures, and ends
with the fork-and-diff workflow — the framework's most differentiated
capability.

## Install

```bash
pip install activegraph                    # core runtime + SQLite store + Diligence pack
pip install "activegraph[llm]"             # Anthropic + OpenAI providers
pip install "activegraph[anthropic]"       # Anthropic provider only
pip install "activegraph[openai]"          # OpenAI provider only (+ tiktoken)
pip install "activegraph[postgres]"        # Postgres-backed event store
pip install "activegraph[prometheus]"      # Prometheus metrics
pip install "activegraph[opentelemetry]"   # OpenTelemetry metrics
pip install "activegraph[all]"             # everything
```

Both LLM providers expose the same `LLMProvider` Protocol surface;
swap one for the other without touching `@llm_behavior` definitions.
The [LLM providers reference](https://docs.activegraph.ai/reference/llm-providers/)
covers the side-by-side surface, including tool use and provider-specific
token counting.

Python 3.11+. Two hard dependencies (`click` for the CLI, `pydantic`
for the pack format); persistence backends and provider integrations
are opt-in extras.

## What you get

- **Event-sourced graph runtime.** Objects + typed relations + an
  append-only event log. Every mutation is an event; the trace is the
  audit trail.
- **Reactive behaviors as first-class.** Function, class, LLM-backed,
  or attached to typed edges (the relation-behavior primitive — edges
  with logic). Subscriptions are event type + predicate + a Cypher
  subset for graph-shape patterns.
- **Fork-and-diff.** Branch any run at any event into an independent
  fork, configure it differently, and structurally diff the result
  against the parent. Cache replay means the shared prefix doesn't
  re-execute (no new LLM calls). Most agent frameworks can't do this.
- **Packs.** A pack bundles object types, behaviors, tools, prompts,
  and policies for a specific domain. The bundled
  [Diligence pack](activegraph/packs/diligence) is the reference:
  8 object types, 7 behaviors, 3 tools, recorded fixtures. The open
  [activegraph-packs](https://github.com/yoheinakajima/activegraph-packs)
  library is the multi-pack reference architecture.
- **Isolated event export.** `EventSink` streams accepted live events
  through a bounded per-sink worker without putting adapter I/O on the
  runtime hot path. `JSONLEventSink` is the first-party adapter; drops,
  queue depth, and failures are explicit in status and metrics, and
  normal replay never redelivers history.
- **Cooperative bounded drains.** Single-writer hosts keep reads
  responsive during large derived-work drains with
  `Runtime.run_quantum(max_queue_events=25, max_seconds=0.25)`. A
  yielded quantum never writes a false `runtime.idle`; repeated quanta
  are byte-identical to one `run_until_idle()` under the same
  deterministic inputs (CONTRACT v1.10 #3).
- **Per-error reference pages.** Every error message ends with a
  `More:` link to a page that explains when it fires, why, and how to
  fix it. Catalog at [docs.activegraph.ai/reference/errors](https://docs.activegraph.ai/reference/errors/).

## Concepts at a glance

The framework's twelve primitives, in roughly the order you meet them
when reading a trace. Each links to its concept page on the doc site;
read those when you want depth on one piece.

- **Graph** — objects and typed relations forming the world the
  framework reasons about. The graph is a projection of the event log;
  every mutation is an event. [→ concepts/graph](https://docs.activegraph.ai/concepts/graph/)
- **Events** — the append-only history. Every behavior fires in
  response to events and produces more events; the trace is the
  ordered log of all of them. [→ concepts/events](https://docs.activegraph.ai/concepts/events/)
- **Behaviors** — the unit of reactive code. Function, class, or
  LLM-backed; declares what events it subscribes to and what it
  produces. The determinism contract is per-behavior. [→ concepts/behaviors](https://docs.activegraph.ai/concepts/behaviors/)
- **Relations** — typed edges between objects, with their own
  behaviors. The relation-behavior primitive — coordination logic on
  the edge, not on either endpoint — is uncommon in other agent
  frameworks. [→ concepts/relations](https://docs.activegraph.ai/concepts/relations/)
- **Patches** — proposed mutations with optimistic concurrency.
  Behaviors propose patches; the runtime applies or rejects them;
  rejections are events in their own right. [→ concepts/patches](https://docs.activegraph.ai/concepts/patches/)
- **Views** — scoped reads of the graph for behavior context. Type
  filters, depth filters, recent-event windows. Views are how
  pattern-driven behaviors see only what they need to. [→ concepts/views](https://docs.activegraph.ai/concepts/views/)
- **Frames** — bounded contexts for a run. Goal, constraints, budget,
  and the registered behaviors for this frame. A run can have one
  frame or many. [→ concepts/frames](https://docs.activegraph.ai/concepts/frames/)
- **Policies** — approval and gating for behavior capabilities. Which
  behaviors can call which tools, which mutations require human
  approval, what the runtime refuses. [→ concepts/policies](https://docs.activegraph.ai/concepts/policies/)
- **Patterns** — the Cypher subset for pattern subscriptions. Beyond
  event-type + predicate, behaviors can subscribe to graph shapes
  (claim-cited-by-evidence, task-blocks-task, …) with `NOT EXISTS`
  and temporal predicates. [→ concepts/patterns](https://docs.activegraph.ai/concepts/patterns/)
- **Replay** — re-execute a run from its event log. Strict mode
  re-fires every behavior and fails on divergence; permissive mode
  reconstructs state without re-firing. The LLM replay cache is what
  makes fork cheap. [→ concepts/replay](https://docs.activegraph.ai/concepts/replay/)
- **Forking** — branch any run at any event into an independent
  fork; structurally diff the fork against the parent. The framework's
  mechanism for hypothesis testing on agentic systems. [→ concepts/forking](https://docs.activegraph.ai/concepts/forking/)
- **Failure model** — a behavior failure is a `behavior.failed`
  event, not an exception. The audit trail captures failures as
  first-class history. Exceptions live at runtime entry points only.
  [→ concepts/failure-model](https://docs.activegraph.ai/concepts/failure-model/)

## The type system at a glance

What's fixed and what's yours. The framework speaks a small vocabulary
of event types — the verbs of what happened. The nouns and edges of
your domain are strings you choose.

**Event types — fixed.** The runtime emits these; the trace, replay,
and observability surfaces all key off them.

- **Lifecycle:** `goal.created`, `runtime.idle`, `runtime.budget_exhausted`
- **Graph:** `object.created`, `object.removed`, `relation.created`, `relation.removed`
- **Behaviors:** `behavior.scheduled`, `behavior.started`, `behavior.completed`, `behavior.failed`, `relation_behavior.started`
- **Patterns:** `pattern.matched`
- **LLM:** `llm.requested`, `llm.responded`
- **Tools:** `tool.requested`, `tool.responded`
- **Patches:** `patch.proposed`, `patch.applied`, `patch.rejected`
- **Approvals:** `approval.proposed`, `approval.granted`
- **Packs:** `pack.loaded`

Behaviors can also emit custom event types — any string. The
`task.completed` signal in the example below is one: an
application-level event the `unblock` relation behavior subscribes
to, flowing through the same log alongside the framework's own.

**Object and relation types — yours.** Any string works. There is no
central schema, no registration step, no enum to extend.
`graph.add_object("claim", {...})` creates a `claim` because you said
`claim`; `graph.add_relation(a, b, "depends_on")` makes a
`depends_on` edge because you said `depends_on`. Packs can attach
optional Pydantic validation per type; absent a pack, the data passes
through unchanged. The Diligence pack's object types (`claim`,
`evidence`, `risk`, `memo`, …) and relation types (`supports`,
`contradicts`, `references`, …) are an example ontology, not framework
base types — you design your own for your domain.

**Patch states — fixed.** `proposed` → `applied` | `rejected`. Three
values, two of them terminal.

The full model — composition, ontology design guidance, the Diligence
pack as a worked example — lives at
[→ concepts/type-system](https://docs.activegraph.ai/concepts/type-system/).

## A small example

The relation-behavior primitive — coordination logic on the edge,
not on either endpoint:

```python
from activegraph import Graph, Runtime, behavior, relation_behavior

graph = Graph()
runtime = Runtime(graph, budget={"max_events": 200, "max_seconds": 60})

@behavior(name="planner", on=["goal.created"])
def planner(event, graph, ctx):
    research = graph.add_object("task", {"title": "Research", "status": "open"})
    memo = graph.add_object("task", {"title": "Draft memo", "status": "blocked"})
    graph.add_relation(research.id, memo.id, "depends_on")

@behavior(name="researcher", on=["object.created"], where={"object.type": "task"})
def researcher(event, graph, ctx):
    task = event.payload["object"]
    if task["data"]["status"] != "open" or "Research" not in task["data"]["title"]:
        return
    graph.add_object("claim", {"text": "Market early but growing.", "confidence": 0.7})
    graph.emit("task.completed", {"task_id": task["id"]})

@relation_behavior(name="unblock", relation_type="depends_on", on=["task.completed"])
def unblock(relation, event, graph, ctx):
    if event.payload["task_id"] == relation.source:
        graph.patch_object(relation.target, {"status": "open"})

runtime.run_goal("Evaluate this startup idea")
runtime.print_trace()
```

The `unblock` relation behavior fires only for events touching one of
its edge endpoints. The conceptual deep-dive on edges-with-logic is
in [`docs/concepts/relations.md`](https://docs.activegraph.ai/concepts/relations/).

## Documentation

- **[docs.activegraph.ai](https://docs.activegraph.ai/)** — full doc site:
  concepts, guides, cookbook, CLI reference, API reference, the
  per-error catalog.
- **[10-minute tutorial](https://docs.activegraph.ai/quickstart/)** — install
  to a working custom behavior, including fork-and-diff.
- **[learn.activegraph.ai](https://learn.activegraph.ai/)** — interactive
  tutorials in the browser: start from the familiar LLM agent loop,
  watch where it breaks, and rebuild it on the runtime one
  substitution at a time.
- **AI coding assistants** — the docs are machine-readable at
  [docs.activegraph.ai/llms.txt](https://docs.activegraph.ai/llms.txt)
  (structured index) and
  [docs.activegraph.ai/llms-full.txt](https://docs.activegraph.ai/llms-full.txt)
  (concatenated full content), generated from the same source markdown
  as the rendered site. Built for AI agents evaluating the framework
  via Claude Code, Cursor, Replit, and similar tooling. The
  [ecosystem repos](#the-ecosystem) are useful additional context to
  point an assistant at.
- **[CHANGELOG.md](CHANGELOG.md)** — every release, with per-version
  migration notes.
- **[CONTRACT.md](CONTRACT.md)** — locked design decisions, version
  by version. Useful when you want to know *why* something is the way
  it is.
- **[examples/](examples)** — runnable end-to-end demos:
  [`diligence_real_run.py`](examples/diligence_real_run.py),
  [`resume_and_fork.py`](examples/resume_and_fork.py),
  [`llm_claim_extraction.py`](examples/llm_claim_extraction.py),
  [`diligence_with_tools.py`](examples/diligence_with_tools.py),
  [`operate_a_run.py`](examples/operate_a_run.py),
  [`babyagi.py`](examples/babyagi.py) — BabyAGI's autonomous agent loop,
  rebuilt as three reactive behaviors over a shared graph.

## The ecosystem

Active Graph is one repo in a small open-source constellation. The
siblings are where the runtime gets exercised for real — and they are
good additional context to hand an AI assistant alongside this repo.

- **[activegraph-packs](https://github.com/yoheinakajima/activegraph-packs)** —
  the open pack library: ~20 packs spanning infrastructure
  (tool gateway, secrets, memory, identity), communication adapters
  (Telegram, WhatsApp, email), and domain verticals (research,
  codebase, team ops, meetings), plus composed demo bundles, a Python
  demo server, and a React Inspector UI. The reference architecture
  for multi-pack assistants with no central orchestrator —
  coordination emerges through events on the shared graph.
- **[activegraph-lab](https://github.com/yoheinakajima/activegraph-lab)** —
  a self-hosted autonomous research agent, built as a layered pack on
  activegraph-packs, whose mission is growing activegraph.ai's
  evidence base. It crawls, proposes claims and branches, and drafts
  posts behind human approval gates; the research notes on the
  [blog](https://activegraph.ai/blog) are its published output, each
  carrying an evidence-linked provenance trail. It is also the
  runtime's longest-running production soak, and its findings feed
  back into the hardening milestones in [Status](#status).
- **[regimes](https://github.com/yoheinakajima/regimes)** — research
  code for the [Regimes paper](https://arxiv.org/abs/2606.10241): an
  autonomous evaluation-improvement loop that diagnoses failing runs
  into a failure-regime taxonomy, routes the dominant regime to the
  pipeline seam that can address it, and promotes repairs only through
  static, sandbox, in-sample, and held-out gates — running natively on
  the runtime, with every step recorded as an event.
- **FalkorDB graph store** — the first external `GraphStore` backend
  (native edges, Cypher push-down), contributed by
  [@dudizimber](https://github.com/dudizimber). See the
  [FalkorDB guide](https://docs.activegraph.ai/guides/using-falkordb/)
  and [FalkorDB's write-up](https://www.falkordb.com/blog/beyond-in-memory-graphs/).

## Research

- **[The Log is the Agent: Event-Sourced Reactive Graphs for Auditable, Forkable Agentic Systems](https://arxiv.org/abs/2605.21997)**
  (Nakajima, 2026 — arXiv:2605.21997). The design argument behind this
  runtime: invert the usual agent framework so the append-only log is
  the source of truth and the working graph a deterministic projection
  of it. Deterministic replay, cheap forking, and end-to-end lineage
  fall out of that inversion.
- **[Regimes: An Auditable, Held-Out-Gated Improvement Loop Demonstrated on LongMemEval with ActiveGraph](https://arxiv.org/abs/2606.10241)**
  (Nakajima, 2026 — arXiv:2606.10241). Follow-up research: controlled
  self-improvement as a first-class, replayable workflow instead of
  external scaffolding, demonstrated on the LongMemEval benchmark.
  Code: [yoheinakajima/regimes](https://github.com/yoheinakajima/regimes).
- **[The blog](https://activegraph.ai/blog)** — release write-ups and
  research notes, including posts drafted by the
  [lab agent](https://github.com/yoheinakajima/activegraph-lab) and
  published through human editorial gates, with per-claim provenance.
- **[The AI Engineer talk](https://www.youtube.com/watch?v=khVX_BUnEwU)** —
  the spoken version of the argument, from the author.

## What this is not

- Not a chat framework. If your problem fits in one conversation, use
  a chat framework.
- Not a workflow engine. Workflows model control flow. This models
  world state.
- Not a rules engine, exactly. Rules engines forward-chain over
  facts. This event-sources over a graph and supports LLM behaviors
  as first-class.
- Not a production graph database. The event log lives in SQLite
  (default) or Postgres behind the `EventStore` protocol; the
  materialized graph lives behind the `GraphStore` protocol —
  in-memory by default, or [FalkorDB](https://docs.activegraph.ai/guides/using-falkordb/)
  for a real, traversable graph backend. For a different
  high-throughput store, plug one in behind either protocol.
- Not magic. Bad behaviors produce bad graphs. The runtime makes the
  badness inspectable, not absent.

## Status

**v1.12.0** (2026-09). v1.0 shipped in May 2026 after a three-rc
external user-test gate per
[CONTRACT v1.0 #C4](CONTRACT.md#v10-c4-v10-ships-as-v10-rc1-first-time-user-gate-is-owned-externally);
the v1.1–v1.12 line followed, driven by a downstream self-modification
stack — the [activegraph-packs](https://github.com/yoheinakajima/activegraph-packs)
library and a governed fork→test→promote assistant — and hardened
against findings from [production deployments](#the-ecosystem) built
on the runtime. See [CHANGELOG.md](CHANGELOG.md) for the full
v0 → v1.12 history and per-version migration notes.

Major shipped milestones:

- **v1.12** — projection query planning (CONTRACT v1.12 #1–#4): object
  reads cross one structured `ObjectQuery` plan
  (`GraphStore.query_objects`), existence checks avoid full
  materialization, and optional `FalkorDBGraphStore(indexed_fields=...)`
  scalar indexes stay explicit projection configuration. Ships together
  with the staged v1.11 line below; there is no separate 1.11.0 release.
  Upgrades from 1.10.0 also get that line's integrity changes
  (`ConcurrentWriterError`, `InvalidPatchOperation`, detached events,
  single-writer runs).
- **v1.11** — (staged unreleased; ships with v1.12.0) trust-boundary
  integrity (CONTRACT v1.11 #1–#5): accepted events are canonical
  detached values and the authoritative append precedes projection; one
  writer per run; closed patch operations; name-based pack identifier
  ownership.
- **v1.10** — runtime legibility and cooperative hosts: opt-in
  context-read tracing (`Runtime(trace_context_reads=True)` — each
  behavior execution commits one batched `context.read` event
  recording what it looked at), reserved-field collisions fail loud
  with `ReservedFieldError`, and `Runtime.run_quantum` cooperative
  bounded drains. Default-configuration runs stay byte-identical.
- **v1.9** — the canonical action-class authority release: a single
  ceiling for what behaviors are allowed to do, explicit evaluation
  order, and an audit surface (CONTRACT v1.9 #1–#3). Published
  together with the staged v1.8 line below.
- **v1.8** — (staged unreleased; shipped with v1.9.0) isolated
  `EventSink` delivery; runtime-owned embedding record/replay;
  fail-closed direct `web_fetch`; deterministic wall-stop replay; and
  the provider-neutral `TrialExecutor` seam with the existing local
  subprocess as its honest, non-security-sandbox default; plus
  explicit, log-backed `dev.override` receipts bounded below
  governance authority.
- **v1.7** — subprocess trial-child hardening from downstream soaks:
  `extra_packs` for cross-pack interaction trials, the child's stderr
  captured into the trial report, code discovery made an explicit
  computed-`PYTHONPATH` channel (the env allow-list stays closed),
  `sandbox.preflight()`, and portable resource limits — `RLIMIT_AS`
  enforced on Linux, announced-off (not crashed) on macOS.
- **v1.6** — loader-side manifest validation as a warning tier at
  `load_pack` (structured, once per pack, never an error before 2.0);
  the fork-tail-removal promote invariant pinned as contract.
- **v1.5** — subprocess fork-trial isolation (`run_forked_trial`: a
  fresh-interpreter child against a fork, artifacts pinned by bundle
  hash) and compaction phase 1 (snapshot + archive tier + the
  retention pin set, never deletion).
- **v1.4** — the pack-manifest validator (`load_manifest`,
  `verify_surface`, content + bundle hashes), declarative
  `Pack.capabilities`, and `disable_pack` deregistration.
- **v1.3** — `promote`: apply a fork's net structural delta back to
  its parent, fail-closed on conflicts (the fork→test→promote loop);
  provider-compatibility hardening; traceback/DX surfacing; the
  `EmbeddingProvider` seam.
- **v1.2** — the `GraphStore` seam: the materialized projection
  becomes pluggable, with `FalkorDBGraphStore` (native edges, Cypher
  query push-down) as the first external backend, contributed by
  [@dudizimber](https://github.com/dudizimber); the test suite
  becomes a CI gate.
- **v1.1** — bounded LLM retries for transient provider failures,
  `inspect --memo` / `inspect --search`, `fork --set`, OpenAI
  tool-shape parity, `OpenTelemetryMetrics`, and the
  spec-vs-impl drift gates.
- **v1.0** — error hierarchy rewrite with per-error reference
  pages, doc site at [docs.activegraph.ai](https://docs.activegraph.ai/),
  `activegraph quickstart` command, mypy `--strict` and docstring
  coverage CI gates, wheel-completeness and deploy-verification CI
  gates.
- **v0.9** — pack format and the Diligence reference pack (8 object
  types, 7 behaviors, 3 tools, recorded fixtures).
- **v0.8** — operator surface: structured logging, Prometheus
  metrics, `runtime.status()`, full `activegraph` CLI,
  `PostgresEventStore`.
- **v0.7** — `@tool` decorator, Cypher-subset pattern subscriptions,
  temporal predicates.
- **v0.6** — `@llm_behavior` with structured output, frame-aware
  prompt construction, cost accounting.
- **v0.5** — full event-log persistence, save/load across processes,
  fork from any historical event, structural diff between runs.
- **v0** — core runtime: graph, behaviors, relation behaviors,
  patches with optimistic concurrency, views, frames, policies,
  budgets, the trace.

[ROADMAP.md](ROADMAP.md) preserves the v1.3-cycle plan as a dated
artifact (that line has since shipped — see its header note);
[CHANGELOG.md](CHANGELOG.md) is the authoritative record of what
landed. Unscheduled candidates live in
[FUTURE_IDEAS.md](FUTURE_IDEAS.md).

## License

Active Graph is licensed under the Apache License 2.0. See
[LICENSE](LICENSE) for the full text and [NOTICE](NOTICE) for
the attribution that downstream redistributors must preserve.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for the current contribution
policy and [TRIAGE.md](TRIAGE.md) for the invariant-first path from a report to
a decision, milestone, and `status: ready-for-pr`. The framework is in its
early public phase: issues are open, documentation PRs are welcome, and
non-trivial code changes pass through the issue-first discussion gate.

**Test discipline:** tests must remain deterministic. No live network
calls in CI. LLM and tool tests use recorded fixtures
(`RecordedLLMProvider`, `RecordedToolProvider`). If a contribution
adds a test that would only pass with a live API key or live HTTP,
it cannot land.

---

The graph is the world. Behaviors are physics. The trace is the proof.
