Files
ironclaw/scripts/codebase-graph.sh
firat.sertgoz 0b26d0dea6 chore(agents): wire codebase knowledge graph + OpenWiki for agent code discovery (#5532)
* chore(agents): wire codebase knowledge graph + OpenWiki for agent code discovery

Give every agent (fresh session, teammate, cloud, CI) first-class code discovery
so they stop rebuilding the map by grepping 1.27M lines. Two complementary layers,
both auto-maintained.

Graph (structural, precise -- codebase-memory MCP):
- .mcp.json: declare the codebase-memory-mcp server at project scope so any Claude
  Code session in this repo auto-connects (it was only in personal global config,
  so only one machine had access)
- scripts/dev-setup.sh: install the single static binary (no deps, no keys, local)
- .gitignore: treat .codebase-memory/ as a build artifact (it was neither tracked
  nor ignored -- one `git add .` from a 234MB accidental commit)
- scripts/codebase-graph.sh: freshness helper (indexed commit vs HEAD)

OpenWiki (narrative, prose -- auto-generated, read-only):
- .github/workflows/openwiki-update.yml: weekly + manual regen of openwiki/,
  Anthropic provider (ANTHROPIC_API_KEY), auto-merged PR opened via the
  GH_RELEASES_MANAGER app so required checks trigger and it lands on main hands-off

Docs:
- CLAUDE.md / AGENTS.md: "Code Discovery" section -- query the graph first (with
  recipes: search_graph / trace_path calls|data_flow|cross_service), read openwiki/
  for narrative orientation

Behavior: no product code touched. dev-setup/CI gain an install step; agents gain
tools they call, not code that runs in the app.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(agents): steer new work to the Reborn stack, not the v1 src/ monolith

Add a "Reborn-first" directive to AGENTS.md + CLAUDE.md: new features go in
crates/ (product_workflow -> composition -> webui_v2 -> runtime/serve -> frontend,
entry reborn_cli), not src/main.rs. src/ is v1 in retirement -- maintain existing
behavior, don't add new features. Fills the gap where the docs' "Where to Work"
pointed almost entirely at src/, steering agents into v1 by default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(openwiki): open a PR for human review, not auto-merge (SOC 2)

Auto-merging the generated wiki to main bypasses human change review, which
SOC 2 change management (CC8.1 / separation of duties) does not allow. Drop the
enable-auto-merge step; the bot only authors the PR and a human reviews + merges.
Keep the GitHub App token so required checks still trigger on the bot PR (a
GITHUB_TOKEN-opened PR triggers no workflows, leaving the reviewer no checks).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 12:23:17 +03:00

60 lines
2.0 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# codebase-graph.sh — freshness status for the codebase-memory knowledge graph.
#
# The graph (.codebase-memory/graph.db.zst) is a git-ignored build artifact indexed
# by the codebase-memory MCP server. This script only INSPECTS freshness; the actual
# (re)indexing is done through the MCP tools invoked by an agent:
# - build: index_repository(repo_path=".")
# - delta/impact: detect_changes(since="<indexed-commit>")
#
# Usage: bash scripts/codebase-graph.sh [status]
#
set -euo pipefail
repo_root="$(git rev-parse --show-toplevel)"
artifact="$repo_root/.codebase-memory/artifact.json"
read_field() { python3 -c "import json,sys;print(json.load(open('$artifact')).get('$1','?'))"; }
status() {
if [ ! -f "$artifact" ]; then
echo "graph: MISSING (no .codebase-memory/artifact.json)"
echo "action: build it once — call index_repository(repo_path=\".\") via the codebase-memory MCP"
return 2
fi
local indexed head nodes edges when
indexed="$(read_field commit)"
nodes="$(read_field nodes)"
edges="$(read_field edges)"
when="$(read_field indexed_at)"
head="$(git rev-parse HEAD)"
echo "graph: indexed @ ${indexed:0:9} (${nodes} nodes / ${edges} edges, ${when})"
echo "HEAD: ${head:0:9}"
if [ "$indexed" = "$head" ]; then
echo "status: FRESH (matches HEAD)"
return 0
fi
if git merge-base --is-ancestor "$indexed" HEAD 2>/dev/null; then
local n
n="$(git rev-list --count "$indexed"..HEAD 2>/dev/null || echo '?')"
echo "status: STALE — ${n} commit(s) behind HEAD"
echo "action: delta — detect_changes(since=\"$indexed\") (changed symbols + blast radius)"
echo " or full refresh — index_repository(repo_path=\".\")"
return 1
fi
echo "status: DIVERGED — indexed commit is not in current history (rebase/force-push?)"
echo "action: full re-index — index_repository(repo_path=\".\")"
return 1
}
case "${1:-status}" in
status) status ;;
*) echo "usage: $0 [status]" >&2; exit 64 ;;
esac