Skip to content

Auto-sync the knowledge graph after agent and workspace changes #545

Description

@mohanagy

Problem

Madar currently detects when a graph is stale, but normal users must manually run madar generate . --update or keep madar watch . running. Agent installs provide routing guidance, not graph maintenance.

That breaks the expected agent-first workflow:

  1. An agent uses Madar to understand the repo.
  2. The agent (or a second agent, IDE, Git, or script) changes many files.
  3. A later Madar request can rely on an old graph unless the user remembered to refresh it.

Desired contract

Install Madar once; any supported workspace change is reflected before Madar gives its next graph-backed answer.

Normal users should not have to remember a refresh command. The graph need not rebuild after every keystroke, but Madar must not silently present stale graph context as current.

Why session-end is not the primary trigger

A rebuild only at agent-session end is insufficient:

  • the same agent may ask follow-up questions after edits;
  • another agent may query the repo before the first session ends;
  • agent sessions can crash or be terminated without a reliable end event;
  • IDE edits, Git operations, scripts, and other agents are outside one agent's lifecycle.

Session-end / post-write hooks can be a best-effort flush optimization, not the source of truth.

Proposed lifecycle

workspace source/config edit
  -> one project-local refresh controller observes/marks it dirty
  -> debounce and coalesce edits
  -> one serialized incremental or full rebuild
  -> validate the input snapshot
  -> atomically publish a new graph generation
  -> MCP resolves that generation on its next request
  • Enable an automatic sync mode through madar <agent> install, without requiring a separate foreground command for normal use.
  • Use filesystem observation as the cross-agent source of truth; agent hooks may submit a lightweight dirty/flush request but must not run a full build synchronously.
  • Before a graph-backed MCP response, perform a final freshness check. If a rebuild is pending or an event was missed, wait/refresh or explicitly return a refreshing/stale state instead of answering from an old graph.
  • Coalesce bursts of edits (for example, a short debounce) and use incremental updates only when safe; use a conservative full rebuild for config, rename/delete, framework, or uncertain dependency changes.
  • Expose fresh, dirty, refreshing, and failed in madar status. Keep manual refresh as an escape hatch.
  • A persistent daemon can be optional later; an agent-session-owned controller plus an on-demand freshness gate is a reasonable first UX.

Correctness and concurrency requirements

Do not let each MCP subprocess or agent independently rebuild out/.

  • One repo-local owner/lease must serialize refreshes and coalesce changes that occur during a build.
  • Build into a temporary immutable generation, validate it, then atomically switch the active generation/pointer.
  • Readers must keep seeing the last known-good graph if a refresh crashes or is interrupted.
  • Capture input fingerprints before and after a build; if the workspace changed during extraction, discard/requeue rather than marking a mixed snapshot fresh.
  • Reconcile filesystem events with an authoritative fingerprint/discovery pass, including build-affecting config/ignore files and large repositories.

Existing foundations

  • madar watch already observes changes, debounces them, and invokes an incremental rebuild.
  • The stdio MCP server already reloads a graph when its artifact changes.
  • Freshness metadata and --require-fresh-graph already provide a basis for the read-time correctness gate.

The missing work is making this lifecycle automatic, singleton-safe, and atomically published.

Acceptance criteria

  • An edit made by Claude, Codex, Cursor, an IDE, Git, or a shell is reflected before the next freshness-required graph request, without a user command.
  • Multiple agents changing/querying one repo result in one coordinated writer and no partial JSON, lost update, or mixed generation.
  • A crash during refresh leaves the previous graph queryable and reports the repo as dirty/failed.
  • Changes during a refresh cause one follow-up refresh rather than being lost.
  • Build-affecting configuration changes and watcher coverage limits are surfaced and reconciled.
  • Existing manual generate / watch flows remain supported.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions