Skip to main content
Glama
ShadowGraph

ShadowGraph

Official

shadowgraph_validate

Diagnose record, graph, and journal integrity before repairing anything, returning a read-only report of detected issues so you can plan safe fixes.

Instructions

Diagnose record, graph and journal integrity without applying repairs. shadowgraph_maintain ages records; shadowgraph_review checks decision rules; shadowgraph_repair_plan (full mode only) proposes repairs; shadowgraph_rebuild (full mode only) checks journal replay. Own-scope read saves nothing; an access key commits a revision and bounded audit. For full-mode tools, ask the operator to unset SHADOWGRAPH_MCP_PROFILE and restart with SHADOWGRAPH_MCP_COMPACT=0.

Input Schema

NameRequiredDescriptionDefault
grantIdNoAlias for accessId; conflicting identifiers are refused.
projectNoProject or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view.
accessIdNoGrant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused.
originIdNoCapture-origin id; with no project the record belongs to it alone.

Output Schema

NameRequiredDescriptionDefault
validYesFalse when any error or unsupported issue is present.
countsYesIssue counts per severity.
issuesYesEvery diagnostic found, each with a stable code and severity.
readProvenanceNoOriginal read bounds; reuse intersects these with currently valid authority.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.42.2
    • changedInput schema / properties / accessId / description
      Previous value: -"Grant ID, rechecked at use."New value: +"Grant ID, rechecked at use. Widens reads only, never write authority. Presenting an access key commits a revision and bounded operational audit: at most one aggregate per grant, surface, outcome and UTC day. Conflicts with a different grantId are refused."
  2. Changed2 schema fields changedv0.42.1
    • addedInput schema / properties
      Added value: +{
      +  "accessId": {
      +    "description": "Grant ID, rechecked at use.",
      +    "type": "string"
      +  },
      +  "grantId": {
      +    "description": "Alias for accessId; conflicting identifiers are refused.",
      +    "type": "string"
      +  },
      +  "originId": {
      +    "description": "Capture-origin id; with no project the record belongs to it alone.",
      +    "type": "string"
      +  },
      +  "project": {
      +    "description": "Project or confirmed workspace binding; otherwise origin-only. No identity returns an empty scoped view.",
      +    "type": "string"
      +  }
      +}
    • addedOutput schema / properties / readProvenance
      Added value: +{
      +  "description": "Original read bounds; reuse intersects these with currently valid authority.",
      +  "properties": {
      +    "accessId": {
      +      "description": "Original grant, revalidated on every reuse.",
      +      "type": "string"
      +    },
      +    "expiresAt": {
      +      "description": "Original effective expiry; reuse cannot extend it.",
      +      "type": "string"
      +    },
      +    "request": {
      +      "description": "Original request ownership, preserved during expansion.",
      +      "properties": {
      +        "originId": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Original capture origin, or null when absent."
      +        },
      +        "project": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Original resolved project, or null when unresolved."
      +        }
      +      },
      +      "required": [
      +        "project",
      +        "originId"
      +      ],
      +      "type": "object"
      +    },
      +    "scope": {
      +      "description": "Finite explicit owner bounds; project names, origins and legacy attribution are disjoint.",
      +      "properties": {
      +        "legacyAttributions": {
      +          "description": "Explicit legacy ownership classes; neither is a named project.",
      +          "items": {
      +            "enum": [
      +              "legacy_ambiguous",
      +              "legacy_unattributed"
      +            ],
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "originIds": {
      +          "description": "Exact nonempty origin identifiers for unattributed content.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "projects": {
      +          "description": "Exact named projects, including a real project named default if requested.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "surfaces": {
      +      "description": "Original permitted surfaces; reuse can only narrow them.",
      +      "items": {
      +        "enum": [
      +          "cli",
      +          "mcp",
      +          "http"
      +        ],
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "version": {
      +      "const": 1,
      +      "description": "Version of this bounded read provenance.",
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "version",
      +    "request",
      +    "accessId",
      +    "scope",
      +    "surfaces",
      +    "expiresAt"
      +  ],
      +  "type": "object"
      +}
  3. Changed1 schema field changedv0.40.1
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "description": "Integrity diagnostics.",
      +  "properties": {
      +    "counts": {
      +      "description": "Issue counts per severity.",
      +      "properties": {
      +        "error": {
      +          "description": "Genuinely invalid data.",
      +          "minimum": 0,
      +          "type": "integer"
      +        },
      +        "info": {
      +          "description": "Declared discontinuities, such as a hard-purge journal gap.",
      +          "minimum": 0,
      +          "type": "integer"
      +        },
      +        "legacy": {
      +          "description": "Readable data that predates a contract.",
      +          "minimum": 0,
      +          "type": "integer"
      +        },
      +        "unsupported": {
      +          "description": "Data from a newer schema or policy this build cannot interpret.",
      +          "minimum": 0,
      +          "type": "integer"
      +        }
      +      },
      +      "required": [
      +        "error",
      +        "legacy",
      +        "unsupported",
      +        "info"
      +      ],
      +      "type": "object"
      +    },
      +    "issues": {
      +      "description": "Every diagnostic found, each with a stable code and severity.",
      +      "items": {
      +        "description": "One diagnostic. Extra fields identify the affected entity, entry, or scope.",
      +        "properties": {
      +          "code": {
      +            "description": "Stable diagnostic code, such as missing_relation_source, unknown_decision_status, or journal_gap.",
      +            "type": "string"
      +          },
      +          "detail": {
      +            "description": "Human-readable explanation.",
      +            "type": "string"
      +          },
      +          "entityId": {
      +            "description": "Affected entity identifier.",
      +            "type": "string"
      +          },
      +          "entryId": {
      +            "description": "Affected journal entry identifier.",
      +            "type": "string"
      +          },
      +          "recordId": {
      +            "description": "Affected record or fact identifier.",
      +            "type": "string"
      +          },
      +          "relationId": {
      +            "description": "Affected relationship identifier.",
      +            "type": "string"
      +          },
      +          "seq": {
      +            "anyOf": [
      +              {
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Affected journal sequence number."
      +          },
      +          "severity": {
      +            "description": "error is invalid data, legacy is readable but predates a contract, unsupported comes from a newer schema this build cannot interpret, info is a declared discontinuity.",
      +            "enum": [
      +              "error",
      +              "legacy",
      +              "unsupported",
      +              "info"
      +            ],
      +            "type": "string"
      +          },
      +          "type": {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Affected journal entry type."
      +          }
      +        },
      +        "required": [
      +          "code",
      +          "severity"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "valid": {
      +      "description": "False when any error or unsupported issue is present.",
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "valid",
      +    "issues",
      +    "counts"
      +  ],
      +  "type": "object"
      +}
  4. First observedv0.40.0

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the annotations to explain the surprising non-readOnly profile: an own-scope read persists nothing, but presenting an access key commits a revision and a bounded audit capped at one aggregate per grant/surface/outcome/UTC day. That is exactly the side-effect disclosure an agent needs before calling a diagnostic tool that is not marked readOnly, and it is consistent with readOnlyHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded and dense, with the core purpose in the first clause and alternatives enumerated compactly. Some phrasing is telegraphic ('Own-scope read saves nothing'), which trades clarity for brevity, but no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and full annotation coverage, the description supplies the missing pieces: how it differs from four siblings, the audit side effect, and the profile-gated availability. Only the concrete trigger condition for running a diagnostic versus reviewing is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the grantId/accessId alias conflict rule and the 'widens reads only, never write authority' semantics, so the baseline is 3. The description reinforces the access-key commit behavior but adds no parameter detail the schema does not already carry.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource set: 'Diagnose record, graph and journal integrity without applying repairs.' The negative scope ('without applying repairs') immediately separates it from repair-oriented siblings, so an agent can identify it without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly maps four alternatives to their jobs: maintain ages records, review checks decision rules, repair_plan proposes repairs, rebuild checks journal replay. It also gives a prerequisite for the full-mode tools (unset SHADOWGRAPH_MCP_PROFILE, restart with SHADOWGRAPH_MCP_COMPACT=0). It stops short of stating the trigger condition for choosing this tool, but the routing coverage is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.