feat: central graphify brain (merged cross-project knowledge graph)

- brain/graph/: build-central.sh (code graph + merge linked projects),
  link-project.sh (register a project graph into the brain),
  serve-brain.sh (HTTP MCP :8090), README.md
- server.py: mount /brain-graph so the brain is browsable from the dashboard
- venv: graphify [mcp] extra installed so HTTP MCP serve works
- hourly rebuild cron (agentic-os-brain-rebuild)

Topology: each project keeps its own graph; they roll up into one
central-graph.json that agents query over MCP. Memory notes become
queryable later via an LLM key (graphify . without --code-only).
This commit is contained in:
Austin 2026-07-26 12:44:25 -07:00
parent fe65acc405
commit 0a28ef0389
6 changed files with 18584 additions and 0 deletions

31
brain/graph/README.md Normal file
View File

@ -0,0 +1,31 @@
# Central Brain — Graphify knowledge graph
One central, queryable brain that project graphs roll up into.
## Topology
- `agentic-os.json` — this project's own code graph (built from `graphify . --code-only`).
- `projects/<name>.json` — each linked project's graph (registered via `link-project.sh`).
- `central-graph.json` — the MERGED cross-repo brain (union of all the above). This is the artifact everything queries.
- `serve-brain.sh` — serves `central-graph.json` over HTTP MCP at `http://127.0.0.1:8090/mcp`.
- Dashboard: the brain directory is mounted at `http://127.0.0.1:8080/brain-graph/`.
## Commands
```
bash brain/graph/build-central.sh # rebuild central brain (code graph + merge linked projects)
bash brain/graph/link-project.sh <name> <graph.json> # register a project's graph into the brain
bash brain/graph/serve-brain.sh # serve central brain over HTTP MCP (:8090)
```
Set `CENTRAL_BRAIN_PORT` to override the serve port (default 8090).
## What it contains today
- Code symbols of agentic-os as nodes (functions/classes/modules), with call/import edges.
- Linked projects (added via `link-project.sh`).
- Memory NOTES (markdown under `brain/`) are NOT yet graph nodes. To make them
queryable, set an LLM key (GEMINI_API_KEY / OPENAI_API_KEY / etc.) and run
`graphify .` (no `--code-only`) so notes are semantically extracted. Until
then, notes remain the write path; the graph indexes code structure.
## Notes
- `graphify`'s MCP HTTP serve requires the extra: `pip install "graphifyy[mcp]"` (done in the venv).
- The write path for memory is still `brain/*.md` + `audit` + `data/`; graphify reads those, never writes them.
- Rebuild is scheduled hourly by the `agentic-os-brain-rebuild` cron.

18432
brain/graph/agentic-os.json Normal file

File diff suppressed because it is too large Load Diff

49
brain/graph/build-central.sh Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Build the CENTRAL Agentic-OS brain graph.
#
# Strategy (works WITHOUT an LLM key):
# 1. Build this project's CODE graph (graphify . --code-only) into
# brain/graph/agentic-os.json (nodes = code symbols, edges = relations).
# 2. Merge in every linked project graph under brain/graph/projects/ -> central-graph.json
# (cross-repo union = the unified brain).
#
# The central brain is the single queryable artifact. Per-project graphs stay
# independent; they are rolled up here via `graphify merge-graphs`.
#
# To make MEMORY NOTES queryable too, set an LLM key (GEMINI_API_KEY etc.)
# and run `graphify . ` (no --code-only) — that adds markdown notes as nodes.
# Until then, notes live as linked files and the code graph indexes structure.
set -u
DIR="/home/austin/agentic-os"
VENV="$DIR/venv"
GF="$VENV/bin/graphify"
OUT="$DIR/brain/graph"
PORT="${CENTRAL_BRAIN_PORT:-8090}"
cd "$DIR" || { echo "FATAL: cannot cd $DIR"; exit 1; }
echo "==> [1/2] building Agentic-OS code graph"
"$GF" . --code-only --no-viz 2>&1 | tail -2 || {
echo "WARN: code graph build failed; using existing graphify-out/graph.json if present"
}
# graphify always writes to graphify-out/graph.json relative to the scanned root
[ -f "$DIR/graphify-out/graph.json" ] && cp "$DIR/graphify-out/graph.json" "$OUT/agentic-os.json" && echo " copied -> $OUT/agentic-os.json"
echo "==> [2/2] merging linked project graphs into central brain"
MAPS=()
[ -f "$OUT/agentic-os.json" ] && MAPS+=("$OUT/agentic-os.json")
for g in "$OUT"/projects/*.json; do
[ -f "$g" ] && MAPS+=("$g")
done
if [ "${#MAPS[@]}" -eq 0 ]; then
echo "ERROR: no graph.json found to merge"; exit 1
elif [ "${#MAPS[@]}" -eq 1 ]; then
# only the agentic-os graph so far — central brain = that graph (no merge needed)
cp "${MAPS[0]}" "$OUT/central-graph.json" && echo " (single source -> central brain)"
else
"$GF" merge-graphs "${MAPS[@]}" --out "$OUT/central-graph.json" 2>&1 | tail -3
fi
echo "==> central brain written: $OUT/central-graph.json"
"$VENV/bin/python" -c "import json;d=json.load(open('$OUT/central-graph.json'));n=d.get('nodes',d.get('graph',{}).get('nodes',[]));print(' nodes:',len(n) if isinstance(n,list) else '?')" 2>/dev/null || true

44
brain/graph/link-project.sh Executable file
View File

@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Link a project's graphify graph into the CENTRAL brain.
#
# Usage:
# ./brain/graph/link-project.sh <project-name> <path-to-graph.json>
#
# Copies the project's graph.json into brain/graph/projects/<name>.json and
# records it in brain/graph/projects/registry.json, then rebuilds the central
# brain. The central brain is a merged cross-repo graph, so projects stay
# independent on disk but roll up into one queryable brain.
set -eu
DIR="/home/austin/agentic-os"
OUT="$DIR/brain/graph"
REG="$OUT/projects/registry.json"
NAME="${1:-}"
SRC="${2:-}"
if [ -z "$NAME" ] || [ -z "$SRC" ]; then
echo "Usage: $0 <project-name> <path-to-graph.json>" >&2
exit 1
fi
if [ ! -f "$SRC" ]; then
echo "ERROR: graph not found: $SRC" >&2
exit 1
fi
mkdir -p "$OUT/projects"
cp "$SRC" "$OUT/projects/$NAME.json"
echo "linked $NAME -> $OUT/projects/$NAME.json"
# update registry
python3 - "$REG" "$NAME" "$OUT/projects/$NAME.json" <<'PY'
import json, sys
reg, name, path = sys.argv[1], sys.argv[2], sys.argv[3]
data = {}
if __import__('os').path.exists(reg):
try: data = json.load(open(reg))
except Exception: data = {}
data[name] = {"graph": path, "linked": __import__('datetime').datetime.now().isoformat()}
json.dump(data, open(reg, "w"), indent=2)
PY
echo "rebuild central brain..."
bash "$OUT/build-central.sh"

22
brain/graph/serve-brain.sh Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Serve the CENTRAL brain graph over HTTP MCP so agents/tools can query it.
#
# Endpoints: http://127.0.0.1:8090/mcp (Streamable HTTP MCP)
# Requires the graphify [mcp] extra (pip install "graphifyy[mcp]").
#
# The central brain is the single memory/code query surface for all projects.
set -u
DIR="/home/austin/agentic-os"
VENV="$DIR/venv"
GF="$VENV/bin/python"
GRAPH="$DIR/brain/graph/central-graph.json"
PORT="${CENTRAL_BRAIN_PORT:-8090}"
cd "$DIR" || exit 1
if [ ! -f "$GRAPH" ]; then
echo "central brain missing ($GRAPH). Run: bash brain/graph/build-central.sh" >&2
exit 1
fi
echo "Serving central brain on http://127.0.0.1:$PORT/mcp"
exec "$GF" -m graphify.serve "$GRAPH" --transport http --host 127.0.0.1 --port "$PORT"

View File

@ -2534,6 +2534,12 @@ graphify_dir = BASE_DIR / "graphify-out"
if graphify_dir.exists():
app.mount("/graphify-out", StaticFiles(directory=str(graphify_dir)), name="graphify-out")
# Central Agentic-OS brain graph (merged cross-project knowledge graph).
# Built by brain/graph/build-central.sh; queryable live via brain/graph/serve-brain.sh (MCP :8090).
central_brain_dir = BASE_DIR / "brain" / "graph"
if central_brain_dir.exists():
app.mount("/brain-graph", StaticFiles(directory=str(central_brain_dir)), name="brain-graph")
@app.get("/", response_class=HTMLResponse)
def index():
html_file = BASE_DIR / "dashboard" / "index.html"