---
title: DocBridgeIndex v1
description: Schema reference for the deterministic Doc Bridge repository index.
---

# DocBridgeIndex v1

Zod schema: `DocBridgeIndexV1Schema` in `@agentskit/doc-bridge`.

Portable JSON Schema export: `DocBridgeIndexV1JsonSchema`.

Optional `knowledgeEntities` uses the separate [knowledge entity v1 contract](knowledge-entity-v1.md).
It is emitted only with explicit `index.knowledgeEntities.enabled: true` and
semantic hashing. Default-off output preserves legacy strict-reader compatibility;
old readers must not receive opted-in output. The section may include optional
typed `memoryRelations` with exact memory evidence; updated opt-in readers must
support that field. `AgentHandoffV1` stays unchanged.

## Shape

```json
{
  "schemaVersion": 1,
  "contentHash": "df701207f5f3663d3e0a5d0e257c7ce1b8f2898ef8e1ea1fe91d5289ec74bb3c",
  "contentHashAlgo": "sha256-normalized-v1",
  "generatedAt": "2026-07-09T00:00:00.000Z",
  "project": { "name": "my-project", "root": "." },
  "knowledge": [
    {
      "id": "auth",
      "type": "agent-doc",
      "title": "Authentication",
      "path": "docs/for-agents/auth.md",
      "description": "Auth ownership and edit workflow."
    },
    {
      "id": "document:docs/auth.md",
      "type": "document",
      "title": "Authentication",
      "path": "docs/auth.md",
      "description": "How sign-in works.",
      "tags": ["document", "human"],
      "contentHash": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
    },
    {
      "id": "module:packages/auth/src/session.ts",
      "type": "module",
      "title": "session.ts",
      "path": "packages/auth/src/session.ts",
      "symbols": ["createSession", "revokeSession"],
      "tags": ["module", "ts", "src"],
      "contentHash": "fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9"
    }
  ],
  "handoffs": {
    "auth": {
      "type": "agent-handoff",
      "schemaVersion": 1,
      "source": ".doc-bridge/index.json",
      "target": { "type": "package", "id": "auth", "path": "packages/auth" },
      "startHere": "docs/for-agents/auth.md",
      "readBeforeEditing": ["docs/for-agents/auth.md", "AGENTS.md"],
      "editRoots": ["packages/auth"],
      "checks": ["npm test -- auth"],
      "notes": ["Authentication package"]
    }
  },
  "lookup": {
    "packages": ["auth"],
    "ownership": {
      "auth": {
        "id": "auth",
        "path": "packages/auth",
        "checks": ["npm test -- auth"],
        "agentDoc": "docs/for-agents/auth.md"
      }
    }
  },
  "inputs": {
    "hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
    "fileCount": 318,
    "projectionVersion": 1
  },
  "retrieval": {
    "lexiconVersion": 1,
    "weights": { "id": 8, "symbols": 7, "title": 6, "path": 4, "tags": 3, "description": 2, "body": 1 },
    "params": { "k1": 1.2, "b": 0.75 }
  }
}
```

## Entry kinds

`knowledge` holds two kinds of record, and ranking treats them differently.

**Curated** entries (`type: "agent-doc"`) come from the agent corpus a human wrote. They are what
`llms.txt` lists, and ranking favours them slightly, because they were authored to be the answer
to a question.

**Projected** entries (`type: "document"` or `"module"`) are every documentation file and source
module the [discovery snapshot](../knowledge-engine-runbook.md) observed, projected from it rather
than scanned again, so the two cannot disagree about what exists. A module carries its exported
`symbols`; both carry the `contentHash` of the file they were projected from, so a single stale
entry is detectable without rebuilding. Body text is not here: it lives once, in the projection.
`retrieval.corpus.enabled: false` omits them.

## Projection

`projection` is the [retrieval index](../spec/retrieval-index-v1.md): what search ranks. It holds
every snapshot entity — documents, modules, areas, packages — and the routes the configuration
declares, each with the text the ranker indexes, its graph position, its content hash, provenance
and confidence. It is a pure function of the snapshot, the accepted overlay and the configuration,
and its `contentHash` is over those three inputs. `knowledge[]` above stays in step with it for
readers that predate it.

## Freshness

`inputs` fingerprints the repository the index was built from: every input file and its content
hash, plus the configuration sections the index derives from, hashed together. Query surfaces
verify freshness by re-hashing those inputs rather than rebuilding the index, which is what keeps
a search cheap on a large repository. `retrieval.lexiconVersion` is checked too, because a changed
stopword list changes ranking without changing a single file.

The semantic input fingerprint additionally binds the declared algorithm, pipeline/analyzer versions
and effective configuration. Legacy fingerprints keep their original narrower configuration projection.
Every loaded index first verifies its seal using its declared algorithm. An index written before
`inputs` existed uses a full rebuild under that same algorithm. Freshness gates also rebuild under
the stored algorithm; a valid legacy index receives an explicit migration diagnostic. Unlike
algorithms are never compared as equal.

Before migration writes, explicit `ak-docs index` reads the committed legacy artifact, verifies its
legacy seal and compares it with a legacy rebuild of the current tree. It prints a warning naming
any drift and the algorithm migration before writing. This explicit regeneration proceeds;
`gate run` stays read-only and fails on stale or invalid artifacts. Reproducibility continues to
check committed path inputs for either supported algorithm; this check does not approve migration.

## Content Hash

New explicit index regeneration writes `contentHashAlgo: sha256-semantic-v1`.
New readers verify `sha256-normalized-v1` for migration guidance only; freshness and
queries require `sha256-semantic-v1`. Unknown algorithms
fail with a diagnostic to install a compatible doc-bridge and explicitly regenerate.
The v1 field shape is retained, including embedded legacy handoffs. Old strict readers reject
the new algorithm with a schema error: upgrade readers before explicitly regenerating.

For `sha256-semantic-v1`, hash the entire index except `contentHash`, `generatedAt` and `publication`, including
its algorithm, project identity, full retrieval projection and repository input fingerprint.
The projection includes a semantic snapshot identity; revisions and reuse statistics do not reach
this seal. Index array ordering remains the writer's deterministic reading order.

For legacy `sha256-normalized-v1`, the original specialized projection remains unchanged.

The hash input is deterministic JSON containing only:

- `schemaVersion`
- `knowledge`
- `handoffs`
- `lookup`
- `retrieval`
- `inputs` (when the corpus projection is enabled)
- `projection.contentHash` (when present)

`generatedAt` is not part of the hash input. When the hash is unchanged, `ak-docs index` preserves the existing `generatedAt` so regenerated `index.json` bytes stay stable.

## Publication provenance

`publication` is optional and is written only when `ak-docs index --allow-pending-findings`
publishes past a failing `reference-findings` gate
([ADR 0025](../adr/0025-opt-in-publication-gate.md)):

```json
{
  "publication": {
    "pendingReferenceFindings": {
      "override": "allow-pending-findings",
      "pendingCount": 1,
      "baseRevision": "<base snapshot sourceRevision>",
      "reason": "pending"
    }
  }
}
```

`reason` is a code: `pending` (findings were pending), `no-base`, `base-unreadable`,
`base-invalid` or `diff-unavailable`. It never carries free text, so no local path or base file
content reaches the index. `pendingCount` is absent when the gate failed before it could count,
and `baseRevision` when no base was read. The index schema is strict, so doc-bridge releases that
predate `publication` reject an index carrying it. The capabilities file carries the same `publication` object.
`publication` is provenance, not content: it is outside the hash, so `index-freshness` still
compares content only. A later publication without the override drops it.

## Validation

```ts
import { parseDocBridgeIndex } from '@agentskit/doc-bridge'

const index = parseDocBridgeIndex(JSON.parse(raw))
```

## Partitioned persistence compatibility

Module-level injected storage APIs persist this unchanged payload inside an
`ArtifactIOV1` envelope with payload schema `DocBridgeIndexV1`, version `1`,
kind `index`, name `index`. Repository/revision identity belongs to the envelope,
not this payload or its embedded handoffs. Readers validate envelope identity
and integrity before validating this schema/hash. Local synchronous compatibility
continues to read/write the unpartitioned configured index file and check
committed legacy drift before regeneration. Availability limitations belong to
the injected operation result, never to the strict index/handoff schemas.

## Findings and negotiated handoff caveats

Region fixes and settled human decisions follow [region remediation v1](../spec/region-remediation-v1.md),
[FindingV1](../schemas/finding-v1.md), [RemediationV1](../schemas/remediation-v1.md) and
[DecisionV1](../schemas/decision-v1.md). Existing whole-file fix commands remain V1;
region creation/review is a deterministic library API. Enrichment retains settled Decision records
through cache replay, without converting remediation rejection into finding rejection.

`AgentHandoffV1` readers accept optional bounded `caveats` with `pendingFindings`,
`analyzed` repository/revision identities and `coverage` limitations. New writers emit
it only with explicit `includeCaveats: true` and caller-supplied validated caveats; unknown
capability defaults to the legacy field set. Default index and MCP writers never embed
caveats. New strict readers accept legacy payloads; old strict readers receive legacy
output. The public reader preserves negotiated caveats. Limitations cannot establish
semantic validation or invent an answer.
