Skip to content

Releases: Scaffoldic/agentforge-graph

v0.6.3 — watch mode + CI indexing

Choose a tag to compare

@kjoshi07 kjoshi07 released this 07 Jul 02:51
0016e3d

agentforge-graph 0.6.3 — keep the graph fresh, automatically

Theme: freshness / ops. 0.6.2 made it one command to connect the graph to
your agent; 0.6.3 makes it automatic to keep it current. Re-indexing was
already cheap and incremental — now you don't have to remember to run it. A local
ckg watch loop tracks your working copy; a scaffolded CI workflow keeps the
shared central index fresh. The two target different stores, and the engine keeps
them apart.

Highlights

ckg watch — local freshness on a trigger you choose (feat-014)

pip install "agentforge-graph[watch]"
ckg watch                       # re-index on a trigger (on-commit by default)
ckg watch --trigger on-idle     # or reflect uncommitted edits when you pause
ckg watch --status              # trigger · store · last indexed commit · dirty?
ckg watch --once                # one refresh if dirty, then exit
  • Won't churn or burn spend. Default trigger is on-commit — ordinary saves
    do nothing; the graph tracks committed state. on-idle / on-save /
    interval / manual are there when you want them, all debounced and
    single-flight so bursts coalesce. A watch refresh is structural-only by
    default (embed_on_watch / enrich_on_watch off), so it never runs embeddings
    or LLM enrichment per save.
  • Branch-gated. Watches feature branches, skips main / release/* by
    default (watch.branches).
  • Can't corrupt a shared store. ckg watch refuses a central
    (store.central_root) or read-only store — that split is enforced in the
    engine, so a developer's loop never races writes into the authoritative graph.

ckg ci init — deterministic central indexing (feat-014)

ckg ci init                     # write .github/workflows/ckg-index.yml
ckg ci init --print             # preview, write nothing
ckg ci init --extra bedrock --enrich

Scaffolds a self-contained workflow that indexes into the central store on
merge-to-main + nightly, single-writer (concurrency group, no write
races), incremental (only the diff since the last indexed commit). CI is the sole
authoritative writer, so read-only consumers can trust it. Managed-marker +
idempotent; won't clobber a hand-edited file without --force.

See the new guide: Watch mode & CI indexing.

Fixed

  • Post-release verification no longer false-alarms (#148). postrelease.yml
    now triggers off the Release workflow completing successfully
    (workflow_run) instead of the GitHub release: published event — under
    on-demand OIDC publishing the release exists before the artifact reaches PyPI,
    so the old trigger polled too early and auto-opened a spurious failure issue
    each release.

v0.6.2 — ckg setup (agent auto-configuration)

Choose a tag to compare

@kjoshi07 kjoshi07 released this 27 Jun 10:00
a54800b

agentforge-graph 0.6.2 — one command to wire the graph into your agent

Theme: adoption. 0.6 made it easy to build an org-scale code graph; 0.6.2
makes it easy to connect one. New ckg setup writes your coding agent's
MCP config for you — no hand-editing JSON — and (with --hooks) nudges the agent
to actually use the graph.

Highlights

ckg setup — agent auto-configuration (feat-013)

ckg setup            # detect agent → show a diff → confirm → write .mcp.json → connection check
ckg setup --print    # dry-run
ckg setup --hooks    # also add the "prefer the graph" nudge to AGENTS.md/CLAUDE.md
ckg setup --undo     # reverse everything it wrote
  • Repo-level by default — writes a committable <repo>/.mcp.json (the
    portable MCP standard, read by Claude Code and other clients). Commit it and
    the whole team's agents are wired. --scope user writes the global
    ~/.claude.json instead.
  • Safe on files you didn't author — edits are structural (never text
    splicing), marked (_managed_by: agentforge-graph), idempotent, and
    conflict-safe: a ckg entry you wrote is never clobbered without
    --force. Everything is reversible with --undo.
  • Connection check — after writing, it spawns the server and confirms the
    agent can reach it (connected ✓).
  • --hooks — appends a short, non-blocking nudge block to
    AGENTS.md/CLAUDE.md so the agent prefers the ckg_* tools over grep/glob.
  • Extensible — new agents register via the
    agentforge_graph.agent_adapters entry-point group (Claude Code built in).

Frictionless first run (FA-001 Phase 1)

  • Try it with zero install: uvx agentforge-graph index . /
    pipx run agentforge-graph serve-mcp --repo ..
  • ckg --version now reports how it was launched, e.g. ckg 0.6.2 (uvx).

See the new guide: Agent auto-configuration.

Validation

  • Gate: ruff + ruff format + mypy --strict clean; 903 passed / 45
    skipped, 94.71% coverage
    .
  • Live end-to-end: a real MCP client (mcp SDK) connected to a spawned
    ckg serve-mcp → 10 tools; project/user scope, --hooks, conflict/--force,
    idempotency, and --undo exercised against a real repo; the uvx trial path
    verified from a built wheel.

Install / upgrade

pip install -U agentforge-graph        # 0.6.2
ckg --version                          # ckg 0.6.2 (pip)

No index-schema change — existing .ckg/ indexes are unaffected.

Full changelog

See CHANGELOG.md.

v0.6.1

Choose a tag to compare

@kjoshi07 kjoshi07 released this 23 Jun 09:26
b6cff83

Docs/packaging patch ahead of the repo going public. No code or behavior changes.

Changed

  • Generalized third-party tool/protocol names out of the published docs, README, guides, and source comments, keeping the technical substance (e.g. "stable descriptor-based symbol IDs", "personalized-PageRank repo-map recipe"). Names of modules/backends the project actually integrates (tree-sitter, Kuzu, LanceDB, Neo4j, SurrealDB, pgvector, Bedrock, OpenAI, Anthropic, MCP, …) are unchanged.
  • The prior-art / research survey is now local-only and no longer shipped in the source distribution (the wheel never contained it, so pip install was always unaffected).

Gate: ruff + ruff format + mypy --strict clean; 839 passed, 94.67% coverage.

pip install -U agentforge-graph

v0.6.0 — workspace build

Choose a tag to compare

@kjoshi07 kjoshi07 released this 22 Jun 06:58
a8b3547

The workspace build release — the build/setup side of org-central knowledge. 0.5 made consuming a central, federated graph easy; 0.6 makes building it easy: stand up a multi-repo CKG from one workspace.yaml + one config + one command, with fail-fast validation and (optionally) repos cloned from git URLs.

Highlights

  • ckg build + --workspace (ENH-021) — index every member (and embed where enabled, --enrich for tags) in one command, with a per-member report.
  • Workspace config cascade (ENH-022) — a defaults: block in workspace.yaml (or sibling ckg.yaml) inherited by every member, with per-member overrides. Configure the org once.
  • Per-member embed toggle (ENH-023) — embed.enabled / embed: false; structure-only members build with no embedder (no creds).
  • ckg doctor + fail-fast preflight (ENH-026) — validate config (drivers installed, credentials present) before any work, with the exact pip install / export fix; --workspace checks every member at once.
  • Remote repo sources (ENH-024) — a member can be a git/github URL (git: + ref:), cloned into a managed, git-ignored .checkouts/ via your ambient git auth.
  • ckg --version and config/CLI-controlled logging/tracinglogging.level in ckg.yaml, --log-level/--debug/-v, $CKG_LOG_LEVEL; traces index/embed/checkout/workspace-build end to end.

Deferred: ENH-025 (Voyage embedder) — raised upstream first.

Validation

839 tests / 94.67% coverage, mypy --strict + ruff clean. Verified end-to-end on sample repos and with a live AWS Bedrock build + semantic query.

Full notes: CHANGELOG.

v0.5.0 — org-level central knowledge

Choose a tag to compare

@kjoshi07 kjoshi07 released this 21 Jun 09:04
fa21888

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-map and ckg trace CLI 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.yaml prints from → to edges
    (with handler + via), and ckg 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
    bundled examples/microservices workspace (web→gateway→orders→payments,
    spanning JS fetch, Python httpx/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_map now matches calls against
    the declared contract too — giving authoritative paths, the operationId as
    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 its via (framework |
    openapi). Precision + coverage upgrade over URL-string matching alone.
  • JS/TS cross-service calls (fetch / axios) (ENH-020 C-full). A new
    jshttpclient pack (spanning .js + .ts) captures fetch("…"),
    axios.get("…") / axios.post("…") and axios("…") as ServiceCall nodes —
    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
    httpclient pack now also captures calls through a client instance
    s = requests.Session(); s.get(…) and c = httpx.Client(base_url="http://orders"); c.get("/v1/x") — composing base_url + path into the matched URL. This is the
    dominant real-world pattern (previously only module-qualified requests.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 graph downstream (what it
    calls — data flow) or upstream (who calls it — blast radius), to a depth.
    Returns the reachable hops (with hop numbers) and the services reached; cycles
    terminate. Turns the ckg_services_map edges 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
    outbound ServiceCall to a Route in another member by (method, path)
    with path-parameter awareness ({id} / :id / <id>) — and exposes the org
    call graph via a new ckg_services_map tool (from_service → to_service,
    method, path, handler, plus unresolved calls). 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 new httpclient framework pack records module-qualified requests.get("…")
    / httpx.post("…") calls as ServiceCall graph nodes (method + URL + path),
    riding the caller file's subgraph like routes. Surfaced via
    CodeGraph.service_calls() and ckg 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 match Route nodes 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.yaml serves 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 its service
    (with a per-service staleness envelope); the pinpoint tools (ckg_symbol,
    ckg_impact, ckg_neighbors, ckg_explain, ckg_history, ckg_repo_map)
    take a service to target one member. A single repo is unchanged (no
    services envelope). 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 _Engine to honor store.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). Set store.central_root: /shared/ckg and 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
    .ckg root is now resolved through one helper (store.location.resolve_root),
    de-duplicating ~10 call sites. ckg status shows the resolved location
    ((central) when hosting is on). First rung of the org-central-knowledge theme.
  • ckg now discovers the repo root from the working directory (ENH-019).
    When no path is given, every subcommand — including ckg serve-mcp — walks up
    from the cwd to the nearest .ckg/ / agentforge.yaml / ckg.yaml / .git
    (nearest wins), like git. So a bare ckg serve-mcp from anywhere inside a
    repo serves that repo — no --repo needed — 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 / --repo always 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 → workspace services-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.

v0.4.0

Choose a tag to compare

@kjoshi07 kjoshi07 released this 20 Jun 13:20
9b5b1b0

agentforge-graph 0.4.0 — framework awareness goes wide, retrieval gets measured, config gets simpler.

Highlights

  • SurrealDB storage backend (ENH-010) — graph + vectors in one server, conformance-verified.
  • Cross-file framework resolution (ENH-011) — include_router prefix composition + DI grounding (FastAPI).
  • Four new route packs (ENH-012) — Gin (Go), ASP.NET (C#), Laravel (PHP), Rails (Ruby) → 11 packs across 6 languages, plus generic cross-file route-handler grounding.
  • Bedrock-native reranker + measured benchmark (ENH-013) — torch-free Bedrock Rerank; an objective NL→code benchmark (388 queries / 4 OSS repos) shows base retrieval MRR 0.95 / recall@1 0.92 and a statistically-significant rerank lift (ΔMRR +0.019, p<0.001). See the README "Retrieval quality (measured)".
  • One config file — engine config consolidated into agentforge.yaml under app: (auto-discovered; plain pyyaml, ADR-0001); ckg.yaml standalone still supported.
  • HTTP MCP auth now rides the framework's from_http(middleware=) seam (no reimplemented runner).
  • Developer guides (numbered learning path + TL;DRs) incl. a Getting-started walkthrough, a demo GIF, community health, and the AgentForge pin bumped to >=0.3,<0.4.

Full detail: CHANGELOG.

Verification: 724 tests / 95% coverage / ruff + mypy clean; live Bedrock embed + rerank, live MCP HTTP auth, and Neo4j/pgvector/SurrealDB conformance all green. PyPI publish to follow after manual validation.

v0.3.3

Choose a tag to compare

@kjoshi07 kjoshi07 released this 19 Jun 11:20
2ddd8b0

[0.3.3] - 2026-06-19

Leaner base install + the refreshed README on PyPI.

Changed

  • Dropped the unused fastembed dependency from the base install (and the
    heavy onnxruntime wheel it pulled). It was a leftover from the original
    feat-005 plan to default to local embeddings; the shipped embedders are
    bedrock / openai / fake, none of which import it. Removing it keeps the
    promise true: the base install carries only what the engine actually uses, and
    every model/DB provider is opt-in. (No local-embeddings driver existed, so
    nothing is lost; a fastembed driver behind a [local] extra can be added as
    a deliberate feature later.)
  • README refreshed (out-of-the-box overview, quick start, demo) now renders on
    the PyPI project page.

v0.3.2

Choose a tag to compare

@kjoshi07 kjoshi07 released this 19 Jun 05:01
7ad435b

[0.3.2] - 2026-06-19

Packaging fix — base-install completeness (caught on a TestPyPI dry run).

Fixed

  • pip install agentforge-graph now works out of the box. The deterministic
    graph engine dependencies (tree-sitter, tree-sitter-language-pack, kuzu,
    lancedb, fastembed, networkx) moved from the optional engine extra into
    the base dependencies — the package's top-level import chain loads the
    parse/store/embed/repo-map stack, so a bare install previously failed at
    import agentforge_graph with ModuleNotFoundError: No module named 'kuzu'.
    The engine extra is kept as an empty no-op for backward compatibility
    (pip install agentforge-graph[engine] still resolves).

v0.3.1

Choose a tag to compare

@kjoshi07 kjoshi07 released this 19 Jun 04:49
afca954

[0.3.1] - 2026-06-19

Packaging release — the PyPI debut. No functional changes.

Packaging

  • Add PyPI distribution metadata: readme (renders the README on the project
    page), keywords, and trove classifiers.
  • Pin the AgentForge framework dependencies (agentforge-py,
    agentforge-anthropic, agentforge-mcp) to the validated >=0.2.4,<0.3
    line, so a fresh pip install resolves the framework version this release was
    built and tested against (rather than an unvalidated newer line).

v0.3.0

Choose a tag to compare

@kjoshi07 kjoshi07 released this 19 Jun 04:19
6573841

[0.3.0] - 2026-06-19

The History + decisions release, plus the framework-aware extractors
differentiator landed early. feat-009 temporal layer (shipped in 0.2.0) +
feat-010 ADR/docs ingestion complete the 0.3 theme; feat-011 adds framework
edge extraction across Python, JavaScript/TypeScript, and Java. The on-disk
index schema is unchanged from 0.2.0 (the new node/edge kinds were reserved at
0.1).

Added

  • NestJS routes — TypeScript (feat-011). A built-in NestJS pack extracts
    controller endpoints into Route nodes + HANDLED_BY edges. A class is a
    route source only with an @Controller decorator (its @Controller('base')
    arg is the base path); each @Get/@Post/@Put/@Delete/@Patch/@All
    method becomes a route (base joined with the decorator path) handled by the
    Class#method symbol. Handles TS's preceding-sibling decorator placement.

  • Spring MVC routes — Java (feat-011). A built-in Spring pack extracts
    controller endpoints into Route nodes + HANDLED_BY edges. A class is a
    route source only when it's a controller (@RestController/@Controller or a
    class-level @RequestMapping); each @GetMapping/@PostMapping/… (or
    @RequestMapping(method=RequestMethod.X)) method becomes a route whose path is
    the class base path joined with the method path, handled by the Class#method
    symbol. First Java framework extractor.

  • Express routes — JavaScript + TypeScript (feat-011). A built-in Express
    pack extracts app.get('/x', handler) / router.post('/x', mw, handler) into
    Route nodes. A named handler (the call's last argument) gets a HANDLED_BY
    edge to its symbol; an anonymous inline handler still yields the Route (with
    attrs.handler = ""). app.use/app.listen and dynamic paths are
    skipped/counted. The pack spans both languages via a new FrameworkPack.slugs
    property and builds handler ids with the file's own slug; shared JS/TS
    tree-sitter helpers live in packs/_js_ast.py.

  • Flask routes (feat-011). A built-in Flask framework pack extracts
    @app.route("/x", methods=[...]) / blueprint @bp.route(...) and the Flask
    2.0 shortcuts (@app.get …) into Route nodes + HANDLED_BY edges. A route
    decorator defaults to GET and emits one route per listed method; class-based
    handlers resolve to Class#method; a dynamic (non-literal) path is counted
    unresolved. Shares the route helpers with FastAPI (now in packs/_python_ast).

  • Class-based FastAPI handlers & DI consumers (feat-011). A route decorator
    or Depends/Security parameter on a method now resolves to its
    Class#method symbol — HANDLED_BY / INJECTED_INTO land on the real method
    node — instead of being counted unresolved. Only a dynamic (non-literal) route
    path remains unresolved.

  • FastAPI dependency injection as Service / INJECTED_INTO (feat-011). A
    parameter defaulting to Depends(provider) / Security(provider) becomes a
    Service node (the provider) with an INJECTED_INTO edge to the consuming
    function — so "what is injected into this handler" and "where is get_db
    injected" are graph traversals. Intra-file, module-level consumers (class-based
    consumers counted, not dropped). Surfaced via CodeGraph.services(), the
    ckg services CLI, and IndexReport.services_extracted.

  • Django ORM models (feat-011). A built-in Django framework pack extracts
    models.Model classes into DataModel nodes with HAS_FIELD columns and
    RELATES_TO edges for ForeignKey/OneToOneField/ManyToManyField (kind
    fk|o2o|m2m; FK/O2O also a column, M2M relation-only). Model evidence is a
    Model-tail base or any models.*Field assignment (catching abstract-base
    subclasses); the table comes from class Meta: db_table when set. Relation
    targets (class ref, "app.Model" string, or "self") resolve by class name.
    Built on shared ORM rails (frameworks/orm.py, packs/_python_ast.py) now
    used by both the SQLAlchemy and Django packs.

  • ORM RELATES_TO edges from relationship/ForeignKey (feat-011). The
    framework pass-2 hook (FrameworkPack.resolve) is now wired into the full
    pipeline and the incremental indexer. The SQLAlchemy pack records each
    relationship("X") / ForeignKey("t.c") string target in pass-1 and stitches
    them into cross-file RELATES_TO edges in pass-2 (attrs.kind =
    relationship|fk, attrs.via = the field): relationship → the model whose
    class is X, fk → the model whose table matches. Unique-match-only
    (ambiguous class names left unresolved). Globally idempotent — an incremental
    refresh converges to the full-index graph. Surfaced via ModelInfo.relations,
    ckg models, and IndexReport.relations_resolved.

  • SQLAlchemy ORM models as DataModel nodes (feat-011). The built-in
    SQLAlchemy framework pack extracts declarative models into DataModel nodes
    (table from __tablename__, the underlying class in attrs.class) with
    HAS_FIELD edges to each mapped column — a Variable field carrying its
    column_type. Classic (name = Column(Integer)) and 2.0-style
    (id: Mapped[int] = mapped_column()) forms both recognised; a class becomes a
    model only with declarative evidence (__tablename__ or ≥1 column), so plain
    classes never mint false models. Surfaced via CodeGraph.models(), the
    ckg models CLI, and IndexReport.models_extracted. (Cross-file
    relationship/ForeignKeyRELATES_TO edges land in the companion entry
    above.)

  • JS/TS JSDoc as DESCRIBES doc nodes (feat-010). A /** … */ block comment
    immediately before a function/class/method becomes a DocChunk that DESCRIBES
    the symbol — extending docstring ingestion (Python) to JavaScript/TypeScript. The
    cleaner strips /** */ markers + per-line *; only /** blocks count (plain
    // / /* */ comments are ignored). Embedded + retrievable like any DocChunk.
    (Java/C# doc comments, Go/Rust/Ruby/PHP conventions, and module-level docstrings
    remain follow-ups.)

  • Commit-message ingestion (feat-010). With knowledge.commit_messages: on, the
    last commit_messages_limit (50) git commit subjects that are conventional commits
    (feat:/fix:/…) or carry an issue ref (#123/PROJ-45) become DocChunks that
    DESCRIBES the in-repo files they touched — so "why did the retry logic change?"
    reaches the commit and its code. Keyed by sha, added idempotently (re-index skips
    known shas). Read via git log (no framework import); off by default.

  • Code-vs-doc retrieval weighting (feat-010). ADR/doc (source_type: doc)
    vector hits are scaled by retrieve.doc_weight (default 0.7) so code outranks
    equally-similar prose by default — mitigating doc-volume dilution. When the query
    smells architectural (why/decision/design/convention/…) the penalty is
    lifted and docs keep their full score. Applies to both the item score and its
    graph-expansion seed.

  • Incremental doc embedding (feat-010). The doc-embed pass now fingerprints all
    DocChunks (ids + content hashes + embedder) under .ckg/doc_embed.hash and skips
    the whole pass when nothing changed — so ckg embed after an incremental refresh
    no longer re-embeds unchanged ADR/doc/docstring prose. Any doc change triggers a
    clean re-embed (orphan-safe for the small doc set).

  • General Markdown docs as DESCRIBES nodes (feat-010). Docs matched by
    knowledge.doc_globs (e.g. ["**/*.md"] — READMEs, guides) are sectioned into
    DocChunks that DESCRIBES the code each section unambiguously mentions (a
    repo-relative path or a unique symbol name). No Decision node — docs describe,
    ADRs govern; ADR files are excluded (handled by the ADR pass). Each doc is its
    own per-file subgraph, so edits/deletes ride incremental indexing (with GC of
    removed docs); IndexReport gains docs_indexed/describes_resolved. Empty
    (off) by default.

  • Docstrings as DESCRIBES doc nodes (Python, feat-010). A Python symbol's
    leading docstring (the first body string of a class/function/method) is now
    extracted as a DocChunk that DESCRIBES the symbol. The docstring prose
    becomes its own searchable node (embedded by the doc-chunk pass, source_type: doc); a vector hit on it seeds the symbol it describes, so a docstring-prose
    query reaches the code. Carried in the code file's subgraph, so it rides
    incremental indexing; symbols without a leading docstring get nothing. (JSDoc /
    Java-C# doc comments / module docstrings are follow-ups.)

  • infer_governs LLM pass for ADRs (feat-010). An optional, budgeted matcher
    proposes GOVERNS edges for decisions whose prose names no code — matching the
    decision text against the repo's candidate symbols and writing edges with honest
    llm provenance + confidence + rationale. It only considers decisions with
    zero parsed GOVERNS (never overrides a deterministic link) and is idempotent
    on re-run. The matcher is injectable (ScriptedMatcher for tests,
    ClaudeGovernsMatcher over Bedrock/Anthropic via enrich.provider). Off by
    default — ckg enrich --decisions (or CodeGraph.infer_governs); USD-capped by
    knowledge.infer_budget_usd.

  • Embed ADR/doc prose for semantic search (feat-010). The embed pass now embeds
    DocChunk prose (ADR sections) into the vector store, tagged source_type: doc
    (code chunks tagged source_type: code). A doc-chunk vector hit surfaces the
    chunk and seeds its containing Decision, which expands through GOVERNS to
    the code it governs — so an architectural query ("why is auth built this way?")
    reaches the decision and the governed code, not just prose. Clean-replaced by the
    DocChunk kind each embed run (GCs vectors for removed ADRs); EmbedReport. doc_chunks counts them. (Doc-incremental-by-hash and source_type-aware
    code-vs-doc retrieval weighting are follow-ups.)

_Work toward 0.3.0 (0.3.0.dev0). Open backlog:...

Read more