Skip to content

Level 2a Agent Index

Level 2a extends Level 1 with an Agent Index graph. The graph lists clean, AI-readable endpoints and declares the metadata needed to validate those endpoints.

Level 2a Agent Index validation is available through validateIndexAi() and the index-ai CLI.

Level 2a scope

Level 2a validation currently covers:

  • manifest access.agent_index
  • Agent Index graph fetch
  • graph JSON content-type check
  • graph JSON parse check
  • graph schema validation
  • nodes array validation
  • deprecated pages array failure
  • total_nodes mismatch warning
  • per-node llm_url structural validation
  • per-node llm_url fetch
  • clean endpoint content-type validation
  • hard HTML leak failure
  • soft inline HTML warning
  • content_chars exact and max validation
  • private llm_url host blocking by default
  • heuristic security checks against fetched clean endpoint text
  • Level 2a conformance computation

Agent Index location

The AI Manifest declares the Agent Index with:

txt
access.agent_index

When the manifest uses this value:

txt
/agent-index.json

the validator resolves it against the target origin and fetches that graph.

access.agent_index is the manifest field name that points to the Agent Index graph.

Graph shape

The Agent Index must use a nodes array.

The deprecated pages array must fail.

Top-level graph fields include:

FieldRequiredRule
generatedYesNon-empty string.
spec_versionYesMust be "1.0".
nodesYesNon-empty array.
total_nodesNoWarns if it does not match nodes.length.
pagesNoMust not be present as an array.

Node required fields

Each node must include:

FieldRequiredRule
idYesNon-empty string.
typeYesNon-empty string.
labelYesNon-empty string.
descriptionYesNon-empty string.
contentYesObject with clean endpoint metadata.
metaYesObject with freshness metadata.

Each node content object must include:

FieldRequiredRule
llm_summaryYesNon-empty string.
llm_urlYesHTTP URL or root-relative path after resolution.
content_charsYesInteger greater than or equal to 1.
content_chars_modeYesexact or max.
summary_methodYesmanual, truncate, or llm.
languageYesNon-empty string.

Each node meta object must include:

FieldRequiredRule
updatedYesNon-empty string.
refresh_frequencyYesNon-empty string.

Clean endpoint rules

For each node, the validator resolves and fetches content.llm_url.

Private or local llm_url hosts fail by default. Use allowPrivateHosts only for trusted local or private development targets.

The clean endpoint must be served as:

txt
text/markdown
text/plain

Other content types fail the clean endpoint content-type check.

HTML leak checks

Hard HTML leakage fails. Examples include document or layout tags such as:

txt
<!doctype html>
<html>
<body>
<script>
<div>
<nav>

The detector ignores HTML-like examples inside Markdown code spans and fenced code blocks.

Tolerated inline markup such as <br> is reported as a soft warning.

content_chars rules

content_chars is measured from the fetched clean endpoint body.

ModeRule
exactThe measured Unicode NFC code point count must equal content_chars.
maxThe measured Unicode NFC code point count must be less than or equal to content_chars.

content_chars must be an integer greater than or equal to 1.

Emoji count as one code point. Decomposed accents are normalized with Unicode NFC before counting.

Validation flow

Conformance result

validateIndexAi() can return:

txt
level-2a

when Level 1 checks pass and the Level 2a Agent Index checks pass.

Warnings can still affect passed when failOnWarn or strict warning behavior is enabled. See Conformance vs Passed.

Scope

Level 2a is the highest structural level the validator emits. For what it does not implement, see Scope.