Agentic Auditing
Export the full comparison context for agents.
Visual auditing is for humans. Agentic auditing is for agents: a deterministic JSON artifact with analysis instructions, a compact summary, Markdown orientation, the full result data, and row documents for chunked review.
Write an agent-readable artifact.
Use it at the same workflow boundary as debug HTML: failing tests, CI artifacts, incident handoff, support reports, notebooks, or any place where an agent needs exact temporal evidence instead of a screenshot or prose summary.
using Spanfold.Artifacts;
var result = pipeline.History
.Compare("Provider QA")
.Target("provider-a", s => s.Source("provider-a"))
.Against("provider-b", s => s.Source("provider-b"))
.Within(scope => scope.Window("DeviceOffline"))
.Using(c => c.Overlap().Residual().Missing())
.Run();
result.ExportDebugHtml("artifacts/provider-qa.html");
result.ExportLlmContext("artifacts/provider-qa.llm.json");
use spanfold::{
ComparisonDebugHtmlOptions,
ComparisonLlmContextOptions,
};
let result = pipeline
.history()
.compare("Provider QA")
.target_source("provider-a")
.against_source("provider-b")
.scope_window("DeviceOffline")
.overlap()
.residual()
.missing()
.run_with_exports(
&ComparisonDebugHtmlOptions::to_file(
"artifacts/provider-qa.html",
),
&ComparisonLlmContextOptions::to_file(
"artifacts/provider-qa.llm.json",
),
)?;
Artifact shape
One file with orientation and exact evidence.
The top-level document is deliberately redundant: agents get concise instructions and summary fields, but can always drill into the full deterministic result JSON and row-level documents.
analysisInstructions
Rules for how an agent should cite evidence, preserve row ids, and avoid unsafe inference.
summary
Plan name, validity, horizons, selected and normalized window counts, segment count, and row counts.
resultMarkdown
A compact deterministic orientation that is useful before inspecting raw row data.
fullResult
The complete comparison result export with plan, diagnostics, prepared windows, aligned segments, rows, finality, and summaries.
rowDocuments
JSON documents for streaming or chunking: the first entry is the result summary. Later entries preserve row type, identity, and finality; Rust includes the row payload while C# emits a compact row reference back into fullResult.
Example export
An abbreviated .llm.json artifact.
Real exports include the complete fullResult object. This
language-neutral excerpt keeps the common envelope visible without
hiding the parts agents rely on. Markdown wording and the row-document
payload differ slightly by runtime. The opaque row ID below is an
illustrative placeholder; exporters assign the runtime-specific value.
{
"schema": "spanfold.comparison.llm-context",
"schemaVersion": 0,
"artifact": "llm-context",
"purpose": "Portable comparison context for LLMs, coding agents, CI triage, and support handoff.",
"analysisInstructions": [
"Treat fullResult as the source of truth for exact fields, ranges, windows, segments, tags, diagnostics, summaries, and row evidence.",
"Use resultMarkdown for a concise natural-language orientation before drilling into fullResult.",
"Preserve rowId, recordIds, window ids, temporal ranges, knownAt, evaluationHorizon, and finality metadata when citing evidence."
],
"summary": {
"planName": "Provider QA",
"isValid": true,
"knownAt": null,
"evaluationHorizon": null,
"diagnosticCount": 0,
"selectedWindowCount": 2,
"excludedWindowCount": 0,
"normalizedWindowCount": 2,
"alignedSegmentCount": 3,
"rowCounts": {
"overlap": 1,
"residual": 2,
"missing": 0,
"coverage": 0,
"gap": 0,
"symmetricDifference": 0,
"containment": 0,
"leadLag": 0,
"asOf": 0
}
},
"resultMarkdown": "# Comparison Explain: Provider QA\n\nisValid: true\n\noverlap rows: 1\nresidual rows: 2",
"fullResult": {
"schema": "spanfold.comparison.result",
"artifact": "result",
"plan": {
"name": "Provider QA"
},
"prepared": {
"selectedWindows": [
{
"windowName": "DeviceOffline",
"key": "device-17",
"source": "provider-a",
"range": { "start": { "position": 3 }, "end": { "position": 6 } }
}
]
},
"aligned": {
"segments": [
{
"windowName": "DeviceOffline",
"key": "device-17",
"range": { "start": { "position": 4 }, "end": { "position": 5 } },
"targetRecordIds": [ "DeviceOffline|device-17|provider-a|3" ],
"againstRecordIds": [ "DeviceOffline|device-17|provider-b|4" ]
}
]
},
"rows": {
"overlap": [
{
"rowId": "<opaque-runtime-row-id>",
"windowName": "DeviceOffline",
"key": "device-17",
"range": { "start": { "position": 4 }, "end": { "position": 5 } },
"finality": "Final",
"targetRecordIds": [ "DeviceOffline|device-17|provider-a|3" ],
"againstRecordIds": [ "DeviceOffline|device-17|provider-b|4" ]
}
]
}
},
"rowDocuments": [
{
"schema": "spanfold.comparison.result-row",
"artifact": "result-summary",
"planName": "Provider QA",
"overlapRowCount": 1,
"residualRowCount": 2
},
{
"rowType": "overlap",
"rowId": "<opaque-runtime-row-id>",
"finality": "Final"
}
]
}
Configuration and CLI
Emit context from runs or fixtures.
Export after comparison execution when runtime configuration decides to write an artifact. Use the CLI when a fixture should become an agent-readable report without writing a custom host application. Library exporters publish their files atomically; shell redirection writes directly to the destination and does not provide that guarantee.
using Spanfold.Artifacts;
var result = pipeline.History
.Compare("Provider QA")
.Target("provider-a", s => s.Source("provider-a"))
.Against("provider-b", s => s.Source("provider-b"))
.Within(scope => scope.Window("DeviceOffline"))
.Using(c => c.Overlap().Residual())
.Run();
result.ExportLlmContext("artifacts/provider-qa.llm.json");
# From a repository checkout for the current 0.2.0-preview.1 CLI:
mkdir -p artifacts
dotnet run --project packages/dotnet/src/Spanfold.Cli/Spanfold.Cli.csproj -- \
compare fixture.json --format llm-context \
> artifacts/provider-qa.llm.json
use spanfold::ComparisonLlmContextOptions;
let result = pipeline
.history()
.compare("Provider QA")
.target_source("provider-a")
.against_source("provider-b")
.scope_window("DeviceOffline")
.overlap()
.residual()
.run_with_llm_context(
&ComparisonLlmContextOptions::to_file(
"artifacts/provider-qa.llm.json",
),
)?;
cargo add spanfold@0.1.1
cargo install spanfold-cli --version 0.1.1
mkdir -p artifacts
spanfold compare fixture.json --format llm-context \
> artifacts/provider-qa.llm.json