moat.json Reference
moat.json is the distilled behavioral memory for your project — an open, standardized JSON file that captures what agents actually do. moatlog distill generates it from .moatlog/events-*.jsonl. The _generated field marks it as machine-owned — edit events or re-distill instead of hand-editing the file.
Because moat.json is committed to git, version-stable, and well-defined, it's designed as an open contract for tool integration. Any tool — IDE extensions, LLM systems, code analysis platforms, security scanners — can read moat.json to understand project structure, agent behavior patterns, and high-context file relationships.
Schema
{
// Machine notice — do not edit manually
"_generated": "do not edit manually — run moatlog distill to regenerate",
"_version": "1.5.0",
// Project identity
"scope": "root",
"projectName": "moatlog",
"generatedAt": "2026-06-14T18:43:30.866Z",
"generatedFrom": "415 events across 18 sessions",
// Summary stats (path-tracked cursor events only)
"totalEvents": 415,
"totalSessions": 18,
// Distillation health signals
"dataHealth": {
"readsCaptured": true,
"windowCounts": { "high": 26, "low": 20, "meta": 163 }
},
// Ranked file profiles — hotFiles[0] is most active
"hotFiles": [
{
"relativePath": "docs/app/globals.css",
"agents": ["cursor"],
"readCount": 0,
"writeCount": 57,
"totalEvents": 57,
"sessionsAppeared": 5,
"coAccessedWith": [
{ "path": "docs/app/layout.tsx", "support": 8 },
{ "path": "docs/app/docs/DocsHeader.tsx", "support": 6 }
]
},
{
"relativePath": "packages/mcp/src/server.ts",
"agents": ["cursor"],
"readCount": 0,
"writeCount": 43,
"totalEvents": 43,
"sessionsAppeared": 2,
"coAccessedWith": [
{ "path": "packages/core/src/types.ts", "support": 4 },
{ "path": "packages/core/src/distiller.ts", "support": 4 }
]
},
{
"relativePath": "docs/styles/tokens.css",
"agents": ["cursor"],
"readCount": 2,
"writeCount": 15,
"totalEvents": 17,
"sessionsAppeared": 4,
"coAccessedWith": [
{ "path": "docs/app/layout.tsx", "support": 4 },
{ "path": "docs/styles/base.css", "support": 3 }
]
}
],
// Prompt windows — each prompt_start closed by agent_stop
"promptWindows": [
{
"id": "9430c8f9-937d-4fa9-acb8-bc6aed4135b5",
"timestamp": "2026-06-11T05:25:46.000Z",
"sessionId": "8a88eb30-578a-4220-8789-0508c6d70653",
"agent": "cursor",
"files": [
"docs/lib/docs.ts",
"docs/content/index.json",
"docs/content/how-it-works.json",
"docs/content/moat-json.json"
],
"taskExcerpt": "Build the docs site content. We have the renderer working — now write the actual pages…",
"windowQuality": "high",
"pathsInTask": ["docs/content/index.json"]
},
{
"id": "6eb22449-78b4-41ae-8893-cddc9cbc5f23",
"timestamp": "2026-06-11T05:38:03.000Z",
"sessionId": "8a88eb30-578a-4220-8789-0508c6d70653",
"agent": "cursor",
"files": [
"docs/content/index.json",
"docs/app/docs/DocsHeader.tsx",
"docs/app/globals.css"
],
"taskExcerpt": "Send these fixes to Cursor — sidebar cleanup, rename Watch→Capture…",
"windowQuality": "high"
}
],
// Recurring file clusters from prompt windows
"taskFileSets": [
{
"id": "tfs-0-docs_content_getting_started_json_docs_c",
"files": [
"docs/content/getting-started.json",
"docs/content/how-it-works.json",
"docs/content/index.json",
"docs/lib/docs.ts"
],
"occurrences": 2,
"lastSeen": "2026-06-11T18:41:26.000Z"
}
],
// Event counts by file extension
"extensionBreakdown": {
".ts": 170,
".css": 143,
".tsx": 65,
".json": 16
}
}Field reference
| Field | Type | Description | Use cases |
|---|---|---|---|
_generated | string | Machine notice. Do not edit manually. | Signals that file is auto-generated; skip if your tool regenerates it. |
_version | string | Schema version. Current: 1.5.0. Breaking changes require a new version number. | Check version before parsing; handle version-specific fields conditionally. |
scope | string | Scope of the moat: 'root' or nested path (future). Monorepo support. | Filter which moats to use in multi-moat projects. |
projectName | string | Project identifier from git root or config. | Match moat.json to the right project in multi-project tooling. |
generatedAt | ISO timestamp | When this moat was last distilled. | Check staleness; decide whether to re-distill before using. Warn if older than N days. |
generatedFrom | string | Summary: '415 events across 18 sessions'. | Assess moat coverage; skip if too sparse (fewer than N events or sessions). |
totalEvents | number | Count of path-tracked events (reads, writes, deletes, renames). | Confidence signal; higher event count = more reliable patterns. |
dataHealth | object | readsCaptured (boolean) and windowCounts by quality (high / low / meta). | Assess data quality; warn if readsCaptured is false. Use quality counts for retrieval thresholds. |
hotFiles | FileProfile[] | Ranked by totalEvents. Each has agents[], readCount, writeCount, sessionsAppeared, coAccessedWith (support scores). | Navigation/routing (prioritize hot files), code review context, architectural analysis, impact analysis (changed file affects coAccessedWith?), dependency inference, test selection (which tests touch these files?), security scanning (prioritize hot files for audit). |
promptWindows | PromptWindow[] | Each prompt_start closed by agent_stop. Includes taskExcerpt (first ~200 chars of the prompt), windowQuality (high/low/meta), files touched in that context window. | Semantic search (match new prompts to past windows), task history (what has this team been working on?), context retrieval (given a prompt, which files are relevant?), documentation generation (extract prompts as inline docs). |
taskFileSets | TaskFileSet[] | Recurring file clusters from prompt windows. Each has files[], occurrences count, and lastSeen timestamp. | Task routing (map new tasks to past patterns), test suite optimization (which files change together?), change impact (editing file A likely affects files B, C, D), code review workflows (file clusters that always change together can be reviewed as a unit). |
sessions | Session[] | Session metadata: startedAt, endedAt, eventCount, agent name, filesRead/filesWritten. | Session-level analytics (duration, scope), agent-specific insights, timeline reconstruction. |
extensionBreakdown | Record<string, number> | Event counts grouped by file extension (.ts, .css, .json, etc.). | Language-specific tooling (which languages are active?), linter/formatter config (run tools for active extensions first), polyglot project dashboard. |
Integration patterns
Third-party tools can read moat.json from your repository to enhance their own features. No API calls required — the file is always available in git.
Reading moat.json
moat.json is a standard JSON file. Read it from disk, parse it, check the _version, and use the fields you need:
import fs from 'fs';
const moat = JSON.parse(fs.readFileSync('.moatlog/moat.json', 'utf-8'));
if (moat._version !== '1.5.0') {
console.warn(`moat.json version ${moat._version} — some fields may differ`);
}
// Get hot files
const hotFiles = moat.hotFiles.slice(0, 10);
// Find files touched by recent prompts
const recentWindows = moat.promptWindows.filter(
w => new Date(w.timestamp) > new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
);
// Get file clusters that change together
const fileClusters = moat.taskFileSets
.filter(ts => ts.occurrences >= 2)
.map(ts => ts.files);Example integrations
- IDE extensions — Use hotFiles for quick navigation suggestions, or taskFileSets to suggest related files when editing.
- Code review tools — Highlight files with high co-access counts as ones that should be reviewed together.
- Test runners — Use hotFiles and co-access patterns to select tests most likely to catch regressions in changed code.
- LLM context selection — Feed hotFiles, taskFileSets, and prompt windows to an LLM system to auto-populate context for code generation.
- Architecture / dependency analysis — coAccessedWith edges reveal actual behavioral dependencies (not just import statements).
- Documentation generators — Extract taskExcerpt from promptWindows to auto-generate decision records, architectural ADRs, or file overviews.
- Security scanning — Prioritize hotFiles for security audit. dataHealth signals help you assess coverage.
Regenerating
moatlog distillRegenerate moat.json from event logs
Validate with moatlog check-moat to confirm moat.json is fresh relative to current events.