v0.5.0 — org-level central knowledge
The org-level central knowledge release — take CKG from "indexes my one repo"
to "is my org's shared code brain": host the index centrally and consume it
read-only, serve a multi-repo workspace from one federated MCP endpoint,
and trace requests across services (HTTP client → route, matched by path or
OpenAPI contract). (Also: the scaffold template was upgraded to AgentForge 0.3.1.)
Added
ckg services-mapandckg traceCLI commands (ENH-020). The cross-service
call graph and request tracing — previously MCP-only — are now on the command
line:ckg services-map --workspace workspace.yamlprintsfrom → toedges
(with handler +via), andckg trace <service> --workspace … [--direction downstream|upstream] [--depth N]walks the graph (data flow /
blast radius). See the org topology from a terminal, not just an agent.- Microservices demo + end-to-end test for the org-central features. A
bundledexamples/microservicesworkspace (web→gateway→orders→payments,
spanning JSfetch, Pythonhttpx/requests, and a contract-first OpenAPI
service) with a runnable walkthrough, plus an automated e2e test that exercises
ENH-018 (central hosting + read-only), ENH-019 (cwd discovery) and ENH-020
(federation +ckg_services_map+ckg_trace) in one flow — the demo is the
test fixture, so they can't drift. - OpenAPI contract anchoring for the cross-service map (ENH-020 C-full). When
a member ships an OpenAPI/Swagger spec (openapi.{json,yaml,yml}/
swagger.{json,yaml}at the repo root),service_mapnow matches calls against
the declared contract too — giving authoritative paths, theoperationIdas
the handler, and coverage for contract-first services with no detected
framework. A framework route and its spec twin are deduped (param-agnostic) so
they never make a call ambiguous; each edge reports itsvia(framework|
openapi). Precision + coverage upgrade over URL-string matching alone. - JS/TS cross-service calls (fetch / axios) (ENH-020 C-full). A new
jshttpclientpack (spanning.js+.ts) capturesfetch("…"),
axios.get("…")/axios.post("…")andaxios("…")asServiceCallnodes —
fetch's method read from a literal{ method: "POST" }option, default GET.
So a JS/TS frontend or BFF now appears as a caller in the cross-service map /
ckg_services_map/ckg_trace, not just Python services. - HTTP client coverage: instance clients +
base_url(ENH-020 C-full). The
httpclientpack now also captures calls through a client instance —
s = requests.Session(); s.get(…)andc = httpx.Client(base_url="http://orders"); c.get("/v1/x")— composingbase_url + pathinto the matched URL. This is the
dominant real-world pattern (previously only module-qualifiedrequests.get(…)
with a literal URL was seen), so the cross-service map covers far more actual
calls. Still conservative: dynamic URLs are counted, not guessed. ckg_trace— walk a request across services (ENH-020 C-full). From a
starting service, trace the cross-service call graphdownstream(what it
calls — data flow) orupstream(who calls it — blast radius), to a depth.
Returns the reachable hops (with hop numbers) and the services reached; cycles
terminate. Turns theckg_services_mapedges into the answer to "what does
this service depend on / which services break if I change it" — impact
analysis that spans service boundaries. Federation-only tool.- Cross-service call graph (ENH-020, C-full increment 2). The federated MCP
server now draws who-calls-whom across services: it matches each member's
outboundServiceCallto aRoutein another member by(method, path)—
with path-parameter awareness ({id}/:id/<id>) — and exposes the org
call graph via a newckg_services_maptool (from_service → to_service,
method, path, handler, plusunresolvedcalls). Computed live because member
graphs are separate stores; unique-match-only (ADR-0004) — an ambiguous call is
reported, never guessed. This completes the microservices payoff: an agent can
see the whole org's service topology from one endpoint. - Outbound HTTP client calls are captured (ENH-020, C-full increment 1).
A newhttpclientframework pack records module-qualifiedrequests.get("…")
/httpx.post("…")calls asServiceCallgraph nodes (method + URL + path),
riding the caller file's subgraph like routes. Surfaced via
CodeGraph.service_calls()andckg service-calls. Conservative (ADR-0004):
literal URLs only; dynamic URLs / client-instance calls are counted, not
guessed. This is the caller side of a cross-service edge — at federation
time these matchRoutenodes in other services (the next increment:
ckg_services_map/ckg_trace). - Federated MCP over a workspace (ENH-020, C-lite).
ckg serve-mcp --workspace workspace.yamlserves many member repos/services from one
endpoint. The survey tools (ckg_search,ckg_routes,ckg_decisions,
ckg_status) fan across every member and tag each result with itsservice
(with a per-service staleness envelope); the pinpoint tools (ckg_symbol,
ckg_impact,ckg_neighbors,ckg_explain,ckg_history,ckg_repo_map)
take aserviceto target one member. A single repo is unchanged (no
servicesenvelope). This is the microservices payoff of the
org-central-knowledge theme — one code brain for the whole org. (Cross-service
contract edges — tracing a request across services — are the next phase,
C-full.) Also fixes the MCP_Engineto honorstore.central_root(ENH-018). - Read-only consumers (ENH-018).
store.read_only: true(or--read-only/
$CKG_READ_ONLY) makes a store consume-only: the write verbs (index,
embed,enrich) refuse with a clear message and a non-zero exit, and opening
a missing index errors instead of silently creating one. Read verbs
(query,map,routes,serve-mcp, …) work normally. This is what lets a
team host one central index (built by CI) and hand it to many developers and
agents without risk of accidental mutation. - Host the index outside the repo with
store.central_root(ENH-018).
By default the index stays in the gitignored.ckg/inside the repo (the
laptop story, unchanged). Setstore.central_root: /shared/ckgand each repo's
artifacts move to a stable, collision-free per-repo subdir under that root
— keyed by git remote (org/repo, host-independent) or<dirname>-<hash>with
no remote — so a team/CI can build once and host many repos centrally. The
.ckgroot is now resolved through one helper (store.location.resolve_root),
de-duplicating ~10 call sites.ckg statusshows the resolved location
((central)when hosting is on). First rung of the org-central-knowledge theme. ckgnow discovers the repo root from the working directory (ENH-019).
When no path is given, every subcommand — includingckg serve-mcp— walks up
from the cwd to the nearest.ckg//agentforge.yaml/ckg.yaml/.git
(nearest wins), likegit. So a bareckg serve-mcpfrom anywhere inside a
repo serves that repo — no--reponeeded — which is what an MCP client
launching the server in a project directory wants. Falls back to.when no
marker is found (unchanged for a bare directory); an explicit positional /
--path/--repoalways wins; when discovery climbs above the cwd the
resolved root is announced on stderr. First rung of the org-central-knowledge
theme (zero-config consumption).
Changed
- Getting-started guides reorganised by setup into three step-by-step
walkthroughs — single repo,
workspace, and
central store — under a hub
(01-getting-started.md, kept so existing links resolve). The 10 topic guides
are unchanged. - README refreshed for the three setups with a new
docs/assets/setups.gif
(single repo → central store → workspaceservices-map/trace), rendered by
scripts/render-setups-gif.sh. - Scaffold template upgraded to AgentForge 0.3.1 (
agentforge upgrade); the
files we own are forked so future upgrades skip them.