# selfgraph First 30 Minutes Wiki > selfgraph is a minimal ActiveGraph agent that ingests its own source code, builds a capability graph from what it discovers, and proposes safe graph-native self-configuration patches validated by guardrails and tested in a forked sandbox before promotion to the live graph. This is a Grok-Wiki source-grounded repository wiki. Use the complete Markdown link when an agent needs the full repo context. ## Context Links - [Complete Markdown wiki](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393/llms-full.txt) - [Complete Markdown alias](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393.md) - [Human interactive wiki](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393) - [GitHub repository](https://github.com/yoheinakajima/activegraph-selfgraph) ## Repository - Repository: yoheinakajima/activegraph-selfgraph - Generated: 2026-05-22T06:05:25.981Z - Updated: 2026-05-22T06:49:13.181Z - Runtime: Claude Code - Format: First 30 Minutes - Pages: 8 ## Pages - [Start Here: What selfgraph Is and How to Read It](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393/pages/01-start-here-what-selfgraph-is-and-how-to-read-it.md): What this repo is, the mental model behind it, the key vocabulary (Capability, PatchProposal, guardrails, sandbox, promote), the fastest read order (README → cli.py → ingest/extract → propose → guardrails → sandbox), and the one constraint to keep in mind: the deterministic extractor is the contract, the LLM pass is optional and additive. - [Setup, CLI Commands & State Persistence](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393/pages/02-setup-cli-commands-state-persistence.md): How to install (pip install -r requirements.txt, no API key required), the six CLI commands (build, ask, propose, promote, chat, demo), how state persists to .selfgraph/graph.db via Runtime.load/persist_to, and when to delete graph.db to force a cold rebuild. - [ingest.py & extract.py — Building the Capability Graph](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393/pages/03-ingest.py-extract.py-building-the-capability-graph.md): How ingest.py walks the repo and introspects the activegraph module to produce File and Chunk objects (deduped on path + sha256), and how extract.py applies regex/heuristic patterns over those chunks to emit Capability, API, Behavior, ObjectType, Constraint, AuthorityRule, and RelationType nodes. Covers the deterministic vs. optional LLM-augment split and the SELFGRAPH_OBJECTTYPE_MATCH env flag (literal vs. relaxed) that controls which ObjectType regex fires. - [propose.py & query.py — Graph-Grounded Proposals and Answers](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393/pages/04-propose.py-query.py-graph-grounded-proposals-and-answers.md): How propose_patch_for composes a PatchProposal from extracted Behaviors, EventTypes, and ObjectTypes already in the graph (and the [FALLBACK] scaffold path when no matching Behavior is found), and how answer_question uses keyword-overlap retrieval over node data — not semantic search — to answer questions. Covers the node and relation types emitted by a proposal (PatchProposal, Evaluation, Policy, BehaviorBinding, Task) and the GROUNDED_IN / PATCH_PROPOSES relations. - [guardrails.py — Validation Rules and PatchProposal Lifecycle](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393/pages/05-guardrails.py-validation-rules-and-patchproposal-lifecycle.md): The allowed v1 change kinds (add_object, add_relation, add_policy, add_state_bucket, add_task, add_evaluation, bind_behavior), the substring banlist (_BANNED_TOKENS), the _PROTECTED_TYPES list blocking AuthorityRule/Capability mutation, and the draft → validated → applied (or rejected) state machine enforced at two call sites. Explains why cmd_promote re-runs validate_proposal with mutate_status=False before applying so a stale validated marker cannot bypass the check. - [sandbox.py — Fork, Diff, and Promote](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393/pages/06-sandbox.py-fork-diff-and-promote.md): How sandbox_apply forks the SQLite-backed Runtime via Runtime.fork(at_event=...) or falls back to a structural replay on an in-memory graph, applies changes, emits a synthetic smoke TestEvent so newly bound behaviors fire, diffs added_objects and added_relations, and conditionally promotes to the live graph when promote=True. Covers the real-fork vs. in-memory fallback distinction and the single comment in sandbox.py marking where a public projector entry point would live. - [Test Suite & Reproducibility Harness](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393/pages/07-test-suite-reproducibility-harness.md): What tests/test_smoke.py covers (accept path, banned-token injection, unknown-behavior binding, protected-type addition, disallowed change kind, promote lifecycle) and how the harness/ scripts (run_corpus.py, run_adversarial.py, run_future_event.py, extractor_recall.py, rollback_precondition.py, compare.py, report.py, invariants.py) regenerate the paper result files in harness/results/. Explains the LLM-free invariant enforced by the harness (ANTHROPIC_API_KEY must be unset) and the SELFGRAPH_OBJECTTYPE_MATCH=literal vs. relaxed condition that produces corpus.literal.jsonl vs. corpus.relaxed.jsonl. - [After 30 Minutes: What You Now Know and Where to Go Next](https://grok-wiki.com/public/wiki/yoheinakajima-activegraph-selfgraph-41747ef30393/pages/08-after-30-minutes-what-you-now-know-and-where-to-go-next.md): A closing map of what a reader should understand after this wiki — the full build→ask→propose→validate→sandbox→promote flow, the safety boundaries (no code authoring, no shell, no external I/O), and the key limitations to keep in mind (fallback scaffold, keyword-only retrieval, no multi-step planning, no UI). Suggests concrete next experiments: run demo.py, inspect graph.db with sqlite3, try a goal that triggers the FALLBACK branch, or add a new regex to extract.py and re-run the harness to verify the sha changes. ## Source Files - `harness/invariants.py` - `harness/reproduce.sh` - `harness/results/CANONICAL_SHAS.txt` - `harness/run_corpus.py` - `README.md` - `REPRODUCE.md` - `requirements.txt` - `selfgraph/__init__.py` - `selfgraph/__main__.py` - `selfgraph/cli.py` - `selfgraph/extract.py` - `selfgraph/guardrails.py` - `selfgraph/ingest.py` - `selfgraph/propose.py` - `selfgraph/query.py` - `selfgraph/sandbox.py` - `tests/test_harness.py` - `tests/test_smoke.py`