Report schema
Every scan emits a codemore-report.json document conforming to schema version 1.0.0. The shape is identical across the CLI, the MCP server, and the VS Code extension — the “one brain, many skins” property locked by test/parity.test.ts.
Top-level fields
| Field | Type | Description |
|---|---|---|
schemaVersion | string | Semver of this schema. Breaking changes bump major. |
scannedAt | string | ISO-8601 timestamp of scan start. |
tool | object | — |
project | object | — |
summary | object | — |
issues | array | — |
agentInstructions | object | Structured instructions for a coding agent consuming this report. |
meta | object | — |
Why agentInstructions
Every report embeds a small agentInstructions block telling the consuming LLM how to apply the findings — ordering hints, directories to skip, when to stop on a validator failure. Without it, agents have to invent their own remediation policy on every run.
Full schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://codemore.dev/schema/codemore-report-v1.json",
"title": "CodeMoreReport",
"description": "The CodeMore report — the structured-feedback contract that AI coding agents read. v1.0.0",
"type": "object",
"required": ["schemaVersion", "scannedAt", "tool", "project", "summary", "issues"],
"additionalProperties": false,
"properties": {
"schemaVersion": {
"type": "string",
"description": "Semver of this schema. Breaking changes bump major.",
"pattern": "^\\d+\\.\\d+\\.\\d+$"
},
"scannedAt": {
"type": "string",
"format": "date-time",
"description": "ISO-8601 timestamp of scan start."
},
"tool": {
"type": "object",
"required": ["name", "version"],
"additionalProperties": false,
"properties": {
"name": { "const": "codemore" },
"version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+" }
}
},
"project": {
"type": "object",
"required": ["root"],
"additionalProperties": false,
"properties": {
"root": { "type": "string", "description": "Project root path (absolute or workspace-relative)." },
"framework": { "type": ["string", "null"], "description": "Detected framework (e.g. next.js, vite, sveltekit)." },
"language": { "type": ["string", "null"], "description": "Primary language detected." },
"fingerprint": {
"type": ["string", "null"],
"description": "Hashed project signature for telemetry dedupe. SHA-256 of project structure.",
"pattern": "^sha256:[a-f0-9]{64}$"
}
}
},
"summary": {
"type": "object",
"required": ["score", "issuesTotal", "bySeverity", "byCategory", "filesAnalyzed", "linesOfCode", "technicalDebtMinutes"],
"additionalProperties": false,
"properties": {
"score": { "type": "number", "minimum": 0, "maximum": 100 },
"issuesTotal": { "type": "integer", "minimum": 0 },
"bySeverity": {
"type": "object",
"required": ["BLOCKER", "CRITICAL", "MAJOR", "MINOR", "INFO"],
"additionalProperties": false,
"properties": {
"BLOCKER": { "type": "integer", "minimum": 0 },
"CRITICAL": { "type": "integer", "minimum": 0 },
"MAJOR": { "type": "integer", "minimum": 0 },
"MINOR": { "type": "integer", "minimum": 0 },
"INFO": { "type": "integer", "minimum": 0 }
}
},
"byCategory": {
"type": "object",
"additionalProperties": { "type": "integer", "minimum": 0 }
},
"filesAnalyzed": { "type": "integer", "minimum": 0 },
"linesOfCode": { "type": "integer", "minimum": 0 },
"technicalDebtMinutes": { "type": "number", "minimum": 0 }
}
},
"issues": {
"type": "array",
"items": { "$ref": "#/definitions/Issue" }
},
"agentInstructions": {
"type": "object",
"description": "Structured instructions for a coding agent consuming this report.",
"additionalProperties": false,
"properties": {
"preamble": { "type": "string" },
"orderingHint": { "type": "string", "description": "e.g. 'blockers \u2192 criticals \u2192 majors'" },
"doNotTouch": { "type": "array", "items": { "type": "string" } },
"stopOn": { "type": "string", "enum": ["first-validator-failure", "first-rule-failure", "never"] }
}
},
"meta": {
"type": "object",
"additionalProperties": false,
"properties": {
"rulesEnabled": { "type": "integer", "minimum": 0 },
"packsLoaded": { "type": "array", "items": { "type": "string" } },
"scanDurationMs": { "type": "integer", "minimum": 0 }
}
}
},
"definitions": {
"Severity": {
"type": "string",
"enum": ["BLOCKER", "CRITICAL", "MAJOR", "MINOR", "INFO"]
},
"IssueCategory": {
"type": "string",
"enum": ["bug", "code-smell", "performance", "security", "maintainability", "accessibility", "best-practice"]
},
"Lifecycle": {
"type": "string",
"enum": ["experimental", "beta", "stable", "deprecated"]
},
"Issue": {
"type": "object",
"required": [
"id",
"ruleVersion",
"instanceId",
"severity",
"confidence",
"category",
"title",
"evidence",
"whyItMatters",
"citation"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Stable rule id (kebab-case, namespaced by pack: 'vibe-supabase-rls-disabled').",
"pattern": "^[a-z][a-z0-9-]+$"
},
"ruleVersion": {
"type": "string",
"description": "Semver of the rule that produced this finding.",
"pattern": "^\\d+\\.\\d+\\.\\d+$"
},
"instanceId": {
"type": "string",
"description": "Unique id for this finding instance (ULID/UUID). Used for telemetry feedback and validate_fix calls."
},
"lifecycle": { "$ref": "#/definitions/Lifecycle" },
"severity": { "$ref": "#/definitions/Severity" },
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Detector confidence. <0.6 = experimental-grade signal."
},
"category": { "$ref": "#/definitions/IssueCategory" },
"title": { "type": "string" },
"evidence": {
"type": "object",
"required": ["file", "line", "column", "snippet"],
"additionalProperties": false,
"properties": {
"file": { "type": "string", "description": "Workspace-relative path." },
"line": { "type": "integer", "minimum": 1 },
"column": { "type": "integer", "minimum": 1 },
"endLine": { "type": "integer", "minimum": 1 },
"endColumn": { "type": "integer", "minimum": 1 },
"snippet": { "type": "string" },
"matchedPattern": { "type": "string", "description": "Internal pattern id for debugging." }
}
},
"whyItMatters": {
"type": "string",
"description": "One-paragraph explanation an LLM can use as context when fixing."
},
"citation": {
"type": "string",
"format": "uri",
"description": "URL to the rule's docs page."
},
"suggestedFix": {
"type": "object",
"required": ["type", "instructions"],
"additionalProperties": false,
"properties": {
"type": { "type": "string", "enum": ["code-patch", "config-change", "manual"] },
"instructions": { "type": "string" },
"patchTemplate": { "type": "string", "description": "Optional unified-diff template the agent can adapt." },
"verificationCriteria": {
"type": "array",
"items": { "type": "string" },
"description": "Checks the agent runs after applying the fix."
}
}
},
"suppression": {
"type": "object",
"additionalProperties": false,
"properties": {
"available": { "type": "boolean" },
"directive": { "type": "string", "description": "e.g. '// codemore-ignore: vibe-supabase-rls-disabled'" },
"scope": { "type": "string", "enum": ["same-line", "next-line", "file"] }
}
},
"baselineStatus": {
"type": "string",
"enum": ["new", "baseline", "resolved"],
"description": "Set only when scan was run with --baseline. 'new' = not in baseline (gates --fail-on); 'baseline' = pre-existing; 'resolved' = synthetic placeholder for keys that disappeared since the baseline."
}
}
}
}
}Why a versioned report
- Forward compatibility.
schemaVersionis semver; breaking changes bump major and ship a migration guide. - Per-rule semver. Each finding carries
ruleVersion. A single bad rule reverts without a tool release. - Deduplication. The
fingerprint+instanceIdpair lets CI systems compare runs and surface only NEW findings since baseline.