data_reference_audit

data_reference_audit is a skill for Claude Code, Codex from nezolder/civil3d-mcp-roslyn. It costs 22 tokens per session (4,180 once invoked), scanned A, original, MIT.

Audit bounded data-reference state for selected Civil 3D object categories in the active drawing.

Skill for Claude CodeCodex

Written for no agent in particular: nothing here depends on one.

Install with agentmods
npx agentmods add skills/nezolder/civil3d-mcp-roslyn/data_reference_audit
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add nezolder/civil3d-mcp-roslyn --skill data_reference_audit
Clone the repo
git clone --depth 1 https://github.com/nezolder/civil3d-mcp-roslyn

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for data_reference_audit

README.md
[![agentmods](https://agentmods.dev/badge/skills/nezolder/civil3d-mcp-roslyn/data_reference_audit/github.svg)](https://agentmods.dev/skills/nezolder/civil3d-mcp-roslyn/data_reference_audit)
Your own site
<a href="https://agentmods.dev/skills/nezolder/civil3d-mcp-roslyn/data_reference_audit"><img src="https://agentmods.dev/badge/skills/nezolder/civil3d-mcp-roslyn/data_reference_audit/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for data_reference_audit

Your own site · 80×15
<a href="https://agentmods.dev/skills/nezolder/civil3d-mcp-roslyn/data_reference_audit"><img src="https://agentmods.dev/badge/skills/nezolder/civil3d-mcp-roslyn/data_reference_audit.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 22 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 4,180 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00022 $0.04180
Opus 5.5 $0.00009 $0.01672
Sonnet 5.5 $0.00004 $0.00836
Haiku 4.5 $0.00002 $0.00418

Measured today against content hash ff0894b8bc5a, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-02, from the pricing page.

Security

Grade A, and why

data_reference_audit scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured today.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

skills/references/data_reference_audit.skill.md · 492 lines

How it starts

The opening of the file, as written. The whole thing — 492 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Code Template

string categoryFilter = "all";
bool onlyReferences = true;
int limit = 25;
int scanLimit = 5000;

if (categoryFilter == null || categoryFilter.Trim().Length == 0 || categoryFilter.Trim().Length > 32)
    return new { success = false, error = "categoryFilter must be all or one supported category name." };
categoryFilter = categoryFilter.Trim();
if (limit < 1 || limit > 100 || scanLimit < 1 || scanLimit > 10000)
    return new { success = false, error = "limit must be 1-100 and scanLimit must be 1-10000." };
var validCategory = categoryFilter.Equals("all", StringComparison.OrdinalIgnoreCase)
    || categoryFilter.Equals("alignments", StringComparison.OrdinalIgnoreCase)
    || categoryFilter.Equals("profiles", StringComparison.OrdinalIgnoreCase)
    || categoryFilter.Equals("sampleLineGroups", StringComparison.OrdinalIgnoreCase)
    || categoryFilter.Equals("featureLines", StringComparison.OrdinalIgnoreCase)
    || categoryFilter.Equals("corridors", StringComparison.OrdinalIgnoreCase)
    || categoryFilter.Equals("surfaces", StringComparison.OrdinalIgnoreCase)
    || categoryFilter.Equals("pipeNetworks", StringComparison.OrdinalIgnoreCase);
if (!validCategory)
    return new { success = false, error = "categoryFilter must be all or one declared category name.", categoryFilter };

// Host access starts here.
var allCategories = new[] { "alignments", "profiles", "sampleLineGroups", "featureLines", "corridors", "surfaces", "pipeNetworks" };
var selectedCategories = categoryFilter.Equals("all", StringComparison.OrdinalIgnoreCase)
    ? allCategories
    : allCategories.Where(name => name.Equals(categoryFilter, StringComparison.OrdinalIgnoreCase)).ToArray();

var totals = new Dictionary<string, int>(StringComparer.Ordinal);
var stateScanned = new Dictionary<string, int>(StringComparer.Ordinal);
var referenceCounts = new Dictionary<string, int>(StringComparer.Ordinal);
var invalidCounts = new Dictionary<string, int>(StringComparer.Ordinal);
var staleCounts = new Dictionary<string, int>(StringComparer.Ordinal);
var missingSourceCounts = new Dictionary<string, int>(StringComparer.Ordinal);
var unknownStateCounts = new Dictionary<string, int>(StringComparer.Ordinal);
var problemCounts = new Dictionary<string, int>(StringComparer.Ordinal);
var objectReadErrors = new Dictionary<string, int>(StringComparer.Ordinal);
var enumerationErrorsByCategory = new Dictionary<string, int>(StringComparer.Ordinal);
var stateApiErrors = new Dictionary<string, int>(StringComparer.Ordinal);
var detailMatchCounts = new Dictionary<string, int>(StringComparer.Ordinal);
var rowsByCategory = new Dictionary<string, List<object>>(StringComparer.Ordinal);

foreach (var category in selectedCategories)
{
    totals[category] = 0;
    stateScanned[category] = 0;
    referenceCounts[category] = 0;
    invalidCounts[category] = 0;
    staleCounts[category] = 0;
    missingSourceCounts[category] = 0;
    unknownStateCounts[category] = 0;
    problemCounts[category] = 0;
    objectReadErrors[category] = 0;
    enumerationErrorsByCategory[category] = 0;
    stateApiErrors[category] = 0;
    detailMatchCounts[category] = 0;
    rowsByCategory[category] = new List<object>();
}

var diagnostics = new List<object>();
var diagnosticCount = 0;
var enumerationErrorCount = 0;

Action<string, string, string, string> addDiagnostic = (category, phase, parentHandle, errorType) =>
{
    diagnosticCount++;
    if (diagnostics.Count < 50)
        diagnostics.Add(new { category, phase, parentHandle, errorType });
};

Action<string, string, System.Exception> addEnumerationError = (category, parentHandle, error) =>
{
    enumerationErrorCount++;
    enumerationErrorsByCategory[category]++;
    addDiagnostic(category, "enumeration", parentHandle, error?.GetType().Name);
};

Action<string, string, ObjectId> inspectCandidate = (category, parentName, id) =>
{
    totals[category]++;
    if (stateScanned[category] >= scanLimit) return;
    stateScanned[category]++;

    string handle = null;
    try
    {
        if (!id.IsNull) handle = id.Handle.ToString();
    }
    catch
    {
    }

    Autodesk.Civil.DatabaseServices.Entity entity;
    try
    {
        entity = Transaction.GetObject(id, OpenMode.ForRead) as Autodesk.Civil.DatabaseServices.Entity;
        if (entity == null) throw new System.InvalidOperationException();
    }
    catch (System.Exception error)
    {
        objectReadErrors[category]++;
        unknownStateCounts[category]++;
        problemCounts[category]++;
        detailMatchCounts[category]++;
        addDiagnostic(category, "objectOpen", handle, error.GetType().Name);
        var failedRows = rowsByCategory[category];
        if (failedRows.Count < limit)
        {
            failedRows.Add(new
            {
                parentName,
                handle,
                objectType = (string)null,
                name = (string)null,
                objectReadErrorType = error.GetType().Name,
                isReference = (bool?)null,
                isValid = (bool?)null,
                isStale = (bool?)null,
                sourceExisting = (bool?)null,
                sourceIdentityStatus = "unknown",
                sourceIdentity = (object)null,
                stateReadErrors = new string[0]
            });
        }
        return;
    }

    var stateReadErrors = new List<string>();
    Func<string, Func<bool>, bool?> readFlag = (flagName, getter) =>
    {
        try { return getter(); }
        catch (System.Exception error)
        {
            stateReadErrors.Add(flagName + ":" + error.GetType().Name);
            return null;
        }
    };

    var isReference = readFlag("isReference", () => entity.IsReferenceObject);
    bool? isValid = null;
    bool? isStale = null;
    bool? sourceExisting = null;
    object sourceIdentity = null;
    var sourceIdentityStatus = "notReference";

    if (isReference == true)
    {
        referenceCounts[category]++;
        isValid = readFlag("isValid", () => entity.IsReferenceValid);
        isStale = readFlag("isStale", () => entity.IsReferenceStale);
        sourceExisting = readFlag("sourceExisting", () => entity.IsReferencedSourceExisting);

        var isCwsReference = readFlag("isCwsReference", () => entity.IsCWSReferenceObject);
        if (isCwsReference == true)
        {
            sourceIdentityStatus = "notDataShortcut";
        }
        else if (isCwsReference == false)
        {
            try
            {
                var referenceKey = entity.GetReferenceInfo();
                if (referenceKey == null)
                {
                    sourceIdentityStatus = "unavailable";
                }
                else
                {
                    var sourceDrawingExists = readFlag("sourceDrawingExists", () => referenceKey.IsSourceDrawingExistent);
                    sourceIdentity = new
                    {
                        sourceName = referenceKey.Name,
                        sourceType = referenceKey.Type.ToString(),
                        sourceDrawingExists
                    };
                    sourceIdentityStatus = "available";
                }
            }
            catch (System.Exception error)
            {
                stateReadErrors.Add("sourceIdentity:" + error.GetType().Name);
                sourceIdentityStatus = "unknown";
            }
        }
        else
        {
            sourceIdentityStatus = "unknown";
        }
    }
    else if (!isReference.HasValue)
    {
        sourceIdentityStatus = "unknown";
    }

    var coreStateUnknown = !isReference.HasValue
        || (isReference == true && (!isValid.HasValue || !isStale.HasValue || !sourceExisting.HasValue));
    if (coreStateUnknown)
        unknownStateCounts[category]++;

    var invalid = isReference == true && isValid == false;
    var stale = isReference == true && isStale == true;
    var sourceMissing = isReference == true && sourceExisting == false;
    if (invalid) invalidCounts[category]++;
    if (stale) staleCounts[category]++;
    if (sourceMissing) missingSourceCounts[category]++;
    if (invalid || stale || sourceMissing || coreStateUnknown)
        problemCounts[category]++;

    stateApiErrors[category] += stateReadErrors.Count;
    foreach (var stateError in stateReadErrors)
    {
        var separator = stateError.IndexOf(':');
        var errorType = separator >= 0 ? stateError.Substring(separator + 1) : "Unknown";
        addDiagnostic(category, "stateRead:" + (separator >= 0 ? stateError.Substring(0, separator) : stateError), handle, errorType);
    }

    string entityName = null;
    try { entityName = entity.Name; }
    catch (System.Exception error)
    {
        stateReadErrors.Add("name:" + error.GetType().Name);
        stateApiErrors[category]++;
        addDiagnostic(category, "name", handle, error.GetType().Name);
    }

    var isDetailMatch = !onlyReferences || isReference == true || !isReference.HasValue;
    if (isDetailMatch)
    {
        detailMatchCounts[category]++;
        var rows = rowsByCategory[category];
        if (rows.Count < limit)
        {
            rows.Add(new
            {
                parentName,
                handle = entity.Handle.ToString(),
                objectType = entity.GetType().FullName,
                name = entityName,
                objectReadErrorType = (string)null,
                isReference,
                isValid,
                isStale,
                sourceExisting,
                sourceIdentityStatus,
                sourceIdentity,
                stateReadErrors
            });
        }
    }
};

var needAlignments = selectedCategories.Contains("alignments")
    || selectedCategories.Contains("profiles")
    || selectedCategories.Contains("sampleLineGroups");
ObjectIdCollection alignmentIds = null;
if (needAlignments)
{
    try
    {
        alignmentIds = CivilDoc.GetAlignmentIds();
        if (selectedCategories.Contains("alignments"))
        {
            foreach (ObjectId alignmentId in alignmentIds)
                inspectCandidate("alignments", null, alignmentId);
        }
    }
    catch (System.Exception error)
    {
        if (selectedCategories.Contains("alignments"))
            addEnumerationError("alignments", null, error);
        if (selectedCategories.Contains("profiles"))
            addEnumerationError("profiles", null, error);
        if (selectedCategories.Contains("sampleLineGroups"))
            addEnumerationError("sampleLineGroups", null, error);
        alignmentIds = null;
    }

    if (alignmentIds != null
        && (selectedCategories.Contains("profiles") || selectedCategories.Contains("sampleLineGroups")))
    {
        foreach (ObjectId alignmentId in alignmentIds)
        {
            Alignment alignment;
            string parentHandle = null;
            try
            {
                parentHandle = alignmentId.Handle.ToString();
                alignment = Transaction.GetObject(alignmentId, OpenMode.ForRead) as Alignment;
                if (alignment == null) throw new System.InvalidOperationException();
            }
            catch (System.Exception error)
            {
                if (selectedCategories.Contains("profiles"))
                    addEnumerationError("profiles", parentHandle, error);
                if (selectedCategories.Contains("sampleLineGroups"))
                    addEnumerationError("sampleLineGroups", parentHandle, error);
                continue;
            }

            if (selectedCategories.Contains("profiles"))
            {
                try
                {
                    foreach (ObjectId profileId in alignment.GetProfileIds())
                        inspectCandidate("profiles", alignment.Name, profileId);
                }
                catch (System.Exception error)
                {
                    addEnumerationError("profiles", parentHandle, error);
                }
            }

            if (selectedCategories.Contains("sampleLineGroups"))
            {
                try
                {
                    foreach (ObjectId groupId in alignment.GetSampleLineGroupIds())
                        inspectCandidate("sampleLineGroups", alignment.Name, groupId);
                }
                catch (System.Exception error)
                {
                    addEnumerationError("sampleLineGroups", parentHandle, error);
                }
            }
        }
    }
}

if (selectedCategories.Contains("featureLines"))
{
    try
    {
        foreach (ObjectId siteId in CivilDoc.GetSiteIds())
        {
            Site site;
            string parentHandle = null;
            try
            {
                parentHandle = siteId.Handle.ToString();
                site = Transaction.GetObject(siteId, OpenMode.ForRead) as Site;
                if (site == null) throw new System.InvalidOperationException();
            }
            catch (System.Exception error)
            {
                addEnumerationError("featureLines", parentHandle, error);
                continue;
            }

            try
            {
                foreach (ObjectId featureLineId in site.GetFeatureLineIds())
                    inspectCandidate("featureLines", site.Name, featureLineId);
            }
            catch (System.Exception error)
            {
                addEnumerationError("featureLines", parentHandle, error);
            }
        }
    }
    catch (System.Exception error)
    {
        addEnumerationError("featureLines", null, error);
    }
}

if (selectedCategories.Contains("corridors"))
{
    try
    {
        foreach (ObjectId corridorId in CivilDoc.CorridorCollection)
            inspectCandidate("corridors", null, corridorId);
    }
    catch (System.Exception error)
    {
        addEnumerationError("corridors", null, error);
    }
}

if (selectedCategories.Contains("surfaces"))
{
    try
    {
        foreach (ObjectId surfaceId in CivilDoc.GetSurfaceIds())
            inspectCandidate("surfaces", null, surfaceId);
    }
    catch (System.Exception error)
    {
        addEnumerationError("surfaces", null, error);
    }
}

if (selectedCategories.Contains("pipeNetworks"))
{
    try
    {
        foreach (ObjectId networkId in CivilDoc.GetPipeNetworkIds())
            inspectCandidate("pipeNetworks", null, networkId);
    }
    catch (System.Exception error)
    {
        addEnumerationError("pipeNetworks", null, error);
    }
}

var categoryResults = new List<object>();
foreach (var category in selectedCategories)
{
    var total = totals[category];
    var scanned = stateScanned[category];
    var enumerationComplete = enumerationErrorsByCategory[category] == 0;
    int? stateUnscannedCount = enumerationComplete ? Math.Max(total - scanned, 0) : (int?)null;
    var stateScanComplete = enumerationComplete
        && stateUnscannedCount == 0
        && objectReadErrors[category] == 0
        && unknownStateCounts[category] == 0;
    var records = rowsByCategory[category];
    categoryResults.Add(new
    {
        category,
        objectTotal = total,
        stateScanned = scanned,
        stateUnscannedCount,
        stateScanCapped = !enumerationComplete || scanned < total,
        stateScanComplete,
        enumerationComplete,
        enumerationErrorCount = enumerationErrorsByCategory[category],
        objectReadErrorCount = objectReadErrors[category],
        stateApiErrorCount = stateApiErrors[category],
        referenceCountScanned = referenceCounts[category],
        invalidReferenceCountScanned = invalidCounts[category],
        staleReferenceCountScanned = staleCounts[category],
        sourceMissingCountScanned = missingSourceCounts[category],
        unknownReferenceStateCountScanned = unknownStateCounts[category],
        problemCountScanned = problemCounts[category],
        detailMatchCountScanned = detailMatchCounts[category],
        detailRecordsReturned = records.Count,
        detailRecordsTruncated = detailMatchCounts[category] > records.Count,
        records
    });
}

return new
{
    success = true,
    categoryFilter,
    onlyReferences,
    detailLimitPerCategory = limit,
    stateScanLimitPerCategory = scanLimit,
    categoryCount = selectedCategories.Length,
    enumerationErrorCount,
    diagnosticsReturned = diagnostics.Count,
    diagnosticsTruncated = diagnosticCount > diagnostics.Count,
    diagnostics,
    categories = categoryResults
};

Read the full file on GitHub · 492 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. today First seen · 492 lines · 22 tokens per session scan A ff0894b8bc5a

Subscribe to this mod's changes

data_reference_audit is a skill published in the GitHub repository nezolder/civil3d-mcp-roslyn (3 stars, last pushed today), licensed MIT. It adds 22 tokens to every session and 4,180 once invoked, about $0.0001 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-10-02.