"Let the graph tend itself."
A Codex SDK playground for self-tending knowledge graphs.
Most Codex demos answer the polite little question:
"How do I start an agent from code?"
Tendril is poking at the weirder question:
"What if an agent thread is application state attached to a graph object?"
A new artifact arrives. A topic wakes up. Codex proposes a graph change. Proof checks try to be boring. A human approves or rejects. Only then does the graph mutate, with provenance attached like a tiny audit trail with opinions.
Think: knowledge graph + Codex threads + proof gates + operator review. Small for now. Suspiciously expandable later.
The interesting part of the Codex SDK is not "spawn a chatbot, but from your app." Useful, yes. World-endingly interesting, no.
The fun part is that Codex threads can become bounded software state:
- resumable work attached to a topic, edge, policy, or artifact
- scoped authority instead of one giant agent blob
- inspectable turns, tool calls, approvals, and outcomes
- reviewable proposals before mutation
- durable evidence for why the graph changed
Tendril's first runnable version uses the installed codex CLI through
codex exec, because that is what a Codex-ready clone already has. The deeper
architecture is pointed at Codex SDK and app-server concepts once graph objects
need richer thread lifecycles.
The Codex SDK is not just an automation interface for coding tasks. It is a runtime for bounded, resumable, inspectable agency. Tendril explores what happens when that agency is attached to domain objects instead of chat sessions.
The thesis:
Future apps will not just have agents bolted on. Some software objects will carry their own bounded agent work.
A knowledge graph is a nice little stress test because it already has topics, links, evidence, contradictions, authority boundaries, and endless temptation to grow into nonsense. Perfect laboratory. Slightly cursed. Very educational.
You need:
uv- an authenticated
codexCLI onPATH
Then:
uv sync --dev
codex --version
rm -rf .tendril1. Ingest a source artifact
ARTIFACT_ID=$(
uv run tendril ingest examples/artifacts/codex-thread-state.md \
| uv run python -c 'import json, sys; print(json.load(sys.stdin)["artifact_id"])'
)2. Let Codex propose graph changes
PROPOSAL_ID=$(
uv run tendril propose --artifact "$ARTIFACT_ID" \
| uv run python -c 'import json, sys; print(json.load(sys.stdin)["proposal_ids"][0])'
)3. Run proof, inspect the queue, approve, apply
uv run tendril proof --proposal "$PROPOSAL_ID"
uv run tendril queue
uv run tendril review \
--proposal "$PROPOSAL_ID" \
--decision accept \
--reason "sample artifact is grounded enough for the demo"
uv run tendril apply --proposal "$PROPOSAL_ID"4. Look at the receipts
uv run tendril casefile --proposal "$PROPOSAL_ID"
cat .tendril/graph.jsonWhat just happened?
- Ingest stored a source artifact in
.tendril/artifacts/. - Codex proposed graph growth from that artifact.
- Proof checked boring things like evidence, duplicates, and schema shape.
- Review recorded a human decision.
- Apply mutated
graph.jsononly after the proposal survived the gate. - Casefile pointed back to the raw artifact, proposal, proof, decision, and graph mutation records.
No silent graph mutation. No mystery meat autonomy. The tendrils have paperwork.
Tip: CI and deterministic local debugging can use
--runtime fake. The real default is Codex.
Tendril can also ingest a sourced research digest. The research can happen outside Tendril; the result enters the same proof/review/apply loop.
uv run tendril ingest \
--research-query "latest merger news about ExampleCo and SampleCorp" \
--finding "ExampleCo agreed to acquire SampleCorp for 4.2 billion dollars." \
--source "ExampleCo press release|https://example.com/news|2026-06-04" \
--caveat "Terms may change before closing."That digest becomes a normal artifact. Codex may propose graph changes from it, but the graph still does not change until proof and review say so.
artifact published
-> relevant topic wakes
-> Codex creates graph-change proposal
-> proof checks run
-> human accepts or rejects
-> accepted change is written with provenance
-> casefile explains what happened
The current store is intentionally boring:
.tendril/
artifacts/
proposals/
proofs/
decisions/
topics/
graph.json
proof-policy.json
Plain files are not glamorous. They are inspectable. Inspectable wins.
Topics and edges act like tiny custodians. A new artifact arrives, relevant topics wake up, and Codex proposes what should be added, connected, ignored, or reviewed.
The graph is not just queried. It reacts.
Autonomy needs an immune system.
Tendril checks for source grounding, duplicate claims, weak evidence, hallucinated links, topology drift, graph bloat, contradictions, and authority boundary weirdness.
The living layer gets to be imaginative. The proof layer gets to be boring. This is the correct division of labor.
Tendril can propose improvements to its own tending process:
"This source barely produces useful changes. Poll it less often."
or:
"This topic keeps proposing duplicate edges. Tighten its proof policy."
But it does not silently rewrite itself. Meta changes are proposals too, with evidence, blast radius, rollback path, proof, and human approval.
Default proposal generation uses Codex:
uv run tendril propose --artifact "$ARTIFACT_ID"Name it explicitly if you like being very clear:
uv run tendril propose --artifact "$ARTIFACT_ID" --runtime codexUse the deterministic test double when you want repeatability:
uv run tendril propose --artifact "$ARTIFACT_ID" --runtime fakeTopic runtime handles are inspectable:
uv run tendril topic show codex-runtime
uv run tendril topic bind-runtime codex-runtime \
--runtime codex \
--thread-id thr_123 \
--model gpt-5.4
uv run tendril topic clear-runtime codex-runtimeTendril currently has:
- artifact ingest
- Codex-backed proposal generation
- deterministic fake runtime for tests and CI
- persisted topic state
- governed edge proposals
- proof policy snapshots and schema checks
- bounded meta proposals
- operator queue and casefiles
- release hardening with CI, Ruff, and README demo coverage
- research digest ingest
Still tiny. Already enough to show the shape.
- Product requirements
- Architecture
- Decisions
- Implementation plan
- Codex runtime spike
- Topic state
- Edge tending
- Proof hardening
- Bounded meta layer
- Operator casefiles
- Release readiness
- Research digest ingest
- M0 goal prompt
- Mx sequential epic goal prompt
uv sync --dev --locked
uv run pytest
uv run ruff check .
git diff --checkIf codex is available, the live Codex runtime smoke test runs as part of the
suite. If not, that live smoke skips; deterministic tests still exercise the
proposal contract through fake.
