Doc Bridge
Spec

Configure documentation corpora, ownership routing, conformance, and gates.

View raw Markdown · llms.txt · For agents

doc-bridge config contract v1

doc-bridge.config.ts (or .js, .mjs, .json, or package.jsondocBridge) is the alpha integration point for any project. Layer 0 fields are sufficient to run index, query, and MCP without an LLM.

Reconciliation summaries also expose deterministic diagnosticsByCode and diagnosticsByStatus maps. They are additive rollups for agents and dashboards; the canonical diagnostics array remains the source of evidence.

| npm package | @agentskit/doc-bridge | | CLI binary | ak-docs | | Config file | doc-bridge.config.ts |

Standalone CLI — not merged into a framework or OS CLI.

Design rules

  1. Progressive — only schemaVersion + corpus.agent required; everything else defaults sensibly.
  2. Plugin-shaped — doc sites and monorepo layout are plugins, not hardcoded paths.
  3. No provider in core — adapter config lives under intelligence, never required.
  4. Deterministic output — paths in config are resolved at build time; no timestamps in index hash input.
  5. One config per repo — monorepo root config; packages inherit via routing / plugin discovery.

Discovery order

doc-bridge.config.ts
doc-bridge.config.mts
doc-bridge.config.js
doc-bridge.config.mjs
doc-bridge.config.json
package.json → "docBridge" field (subset, JSON only)

TypeScript/JavaScript configs are static in v0.1 alpha: defineConfig imports are supported, but arbitrary imports are not. YAML config files are planned.

Dynamic-loading coverage is evidence-backed. Literal strings, constant aliases, parenthesized strings, and string concatenations are resolved without executing repository code. Runtime-dependent import() and require() expressions remain partial/not-analyzed, and the coverage entry records representative file-and-line evidence for each observed loading site (up to the schema limit).

TypeScript shape (authoritative)

import type { DocBridgeConfigV1 } from '@agentskit/doc-bridge/config'

export default {
  schemaVersion: 1,

  /** Optional display name; defaults to package.json name or directory basename */
  project?: { name?: string; root?: string }

  /** Agent-readable knowledge (required) */
  corpus: {
    agent: AgentCorpusConfig
    human?: HumanCorpusConfig | HumanCorpusConfig[]
  }

  /** Where deterministic artifacts are written */
  index?: IndexConfig

  /** Ownership, intents, change routes — monorepo plugin fills this */
  routing?: RoutingConfig

  /** CI gate presets */
  gates?: GatesConfig

  /** CLI + MCP surfaces */
  surfaces?: SurfacesConfig

  /** Optional: chat, memory, retriever — any provider */
  intelligence?: IntelligenceConfig

  /** Optional: Playbook / Registry / remote OKF bundles */
  federation?: FederationConfig

  /** Optional deterministic documentation conformance profiles */
  conformance?: ConformanceConfig

  /** Optional language analyzers and runtime-wiring coverage */
  analysis?: AnalysisConfig

  /** Optional reconciliation scope and orphan-document policy */
  reconciliation?: ReconciliationConfig

  /** Optional resumable workflow state */
  workflow?: WorkflowConfig

  /** Optional report publication privacy; private is the default */
  report?: { privacy?: 'private' | 'anonymized' }
} satisfies DocBridgeConfigV1

corpus.agent (required)

Agent corpus = dense markdown for coding agents (OKF or for-agents layout).

type AgentCorpusConfig = {
  /** Root directory, relative to project root */
  root: string                    // e.g. 'docs/for-agents' | '.agent-docs' | 'docs'

  /** Jump table entrypoint (recommended) */
  index?: string                  // default: '{root}/INDEX.md'

  /**
   * Glob patterns under root, relative to root.
   * Default: ['**/*.md'] excluding INDEX conventions
   */
  include?: string[]
  exclude?: string[]              // default: ['**/node_modules/**', '**/.git/**']

  /** OKF frontmatter: require `type` field (soft warn vs hard gate) */
  okf?: {
    requireType?: boolean         // default: false (warn); true in strict preset
    allowedTypes?: string[]       // optional vocabulary enforcement
  }
}

Minimal solo project

corpus: {
  agent: { root: 'docs' }
}

corpus.human (optional)

Human wiki / doc site. Always via plugin — doc-bridge does not ship a site generator.

type HumanCorpusConfig = {
  plugin: HumanCorpusPluginId
  /** Plugin-specific options (see plugin docs) */
  options?: Record<string, unknown>
}

type HumanCorpusPluginId =
  | 'plain-markdown'    // docs/**/*.md, frontmatter `package`/`module`/`id`
  | 'fumadocs'          // markdown scan with index routes, (group) slugs, pages allowlists
  | 'docusaurus'        // markdown scan with id/slug frontmatter + static sidebars.js
  | 'mkdocs'            // planned
  | 'vitepress'         // file routes, srcDir/docsDir, optional cleanUrls
  | 'starlight'         // Astro content routes, slug and draft frontmatter
  | 'nextra'            // content-directory routes and contentDirBasePath
  | 'custom'            // path to user plugin module

VitePress options accept docsDir (also root or srcDir), urlPrefix, cleanUrls, and up to 64 declarative srcExclude glob patterns. Doc Bridge uses .html routes unless cleanUrls: true, matching VitePress routing without loading or executing .vitepress/config.*. Route rewrites must therefore be reflected in the configured corpus or URL prefix.

Starlight options accept contentDir (also docsDir or root) and urlPrefix. The adapter reads the standard slug and draft frontmatter, follows the default filename sluggifier, excludes underscore-prefixed partials, and never executes astro.config.*. Sites using a custom docsLoader({ generateId }) should add explicit slug frontmatter so Doc Bridge can resolve the same public route without executing project code.

Nextra options accept contentDir (also docsDir or root), urlPrefix, and contentDirBasePath. The adapter maps index.md and index.mdx to the containing route and uses Doc Bridge package, module, or id frontmatter as the join key. urlPrefix takes precedence over contentDirBasePath. Point contentDir at either content or src/content; Doc Bridge never imports or executes next.config.*, _meta.*, themes, or other project code. This adapter targets Nextra's content-directory convention; app-router page.mdx trees are not inferred by this plugin.

Bridge to agent docs

When corpus.human is set, plugins MUST:

  1. Emit resolvable humanDoc URLs/paths into AgentHandoff
  2. Support ## Human guide link validation (gate human-guide-links)
  3. Map by stable id (packageId, moduleId, slug) — config defines the join key
corpus: {
  agent: { root: 'docs/for-agents' },
  human: {
    plugin: 'fumadocs',
    options: {
      contentDir: 'apps/web/content/docs',
      urlPrefix: '/docs',           // public path prefix
      metaFile: 'meta.json',
    },
  },
}

Multiple human corpora (e.g. marketing + internal):

human: [
  { plugin: 'fumadocs', options: { contentDir: 'apps/web/content/docs', urlPrefix: '/docs' } },
  { plugin: 'plain-markdown', options: { root: 'docs/internal', urlPrefix: null } },
]

index (optional)

type IndexConfig = {
  /** Output path for DocBridgeIndex JSON */
  outFile?: string                // default: '.doc-bridge/index.json'

  /** Optional llms.txt alongside index */
  llmsTxt?: {
    enabled?: boolean             // default: true
    outFile?: string              // default: 'llms.txt' at project root
    preamble?: string             // project-specific intro paragraph
  }

  /** Optional Self-Describe companion artifact */
  capabilities?: {
    enabled?: boolean             // default: true
    outFile?: string              // default: '.doc-bridge/capabilities.json'
  }

  /** Hash algorithm for contentHash field */
  contentHash?: 'sha256-normalized-v1'  // only algo in v1
}

routing (optional — monorepo-first)

Without routing, handoffs are inferred from agent corpus links only. Monorepo plugin populates ownership graph.

type RoutingConfig = {
  plugin?: 'pnpm-monorepo' | 'npm-workspaces' | 'yarn-workspaces' | 'nx' | 'pattern-files' | 'custom'

  options?: {
    /** Workspace globs; default from package manager */
    packages?: string[]           // e.g. ['packages/*', 'apps/*']

    /** Map package id → metadata (auto-discovered if omitted) */
    ownership?: Record<string, OwnershipEntry>

    /** Curated reading paths for tasks */
    intents?: IntentEntry[]

    /** "I want to change X" → start here */
    changes?: ChangeRouteEntry[]
  }
}

type OwnershipEntry = {
  path: string                    // 'packages/auth'
  group?: string                  // logical layer / team
  layer?: string                  // L0–L4 or custom
  purpose?: string                // one line
  checks?: string[]               // default gates for this owner
  agentDoc?: string               // override path; default inferred
  humanDoc?: string               // filled by human plugin join
}

type IntentEntry = {
  id: string                      // kebab-case
  title: string
  paths: string[]                 // read-before-editing list
}

type ChangeRouteEntry = {
  id: string                      // e.g. 'add-api-endpoint'
  title: string
  startHere: string
  relatedPackages?: string[]
}

routing.plugin: 'nx' reads project.json and package manifests with an nx object. It does not load Nx plugins or execute workspace code. Project roots must resolve inside the configured project root. Declared test targets become Nx test checks; non-minimal gate presets also include declared lint targets. Explicit routing.options.ownership remains authoritative. Targets created only at runtime by Nx plugins are intentionally not inferred by this read-only adapter.

Join keys (agent ↔ human ↔ ownership)

EntityPrimary keyHuman plugin maps via
Package / moduleid (folder name or package.json name)frontmatter package or path convention
Screen / featureid in screens/ or features/MDX slug
Flow / recipeid in flows/docs slug

Plugins document their join convention; gates fail on orphan links.


gates (optional)

type GatesConfig = {
  preset?: 'minimal' | 'standard' | 'strict' | 'playbook'
  /** Enabled gate ids; merged with preset */
  include?: GateId[]
  exclude?: GateId[]
  /** Gate-specific options */
  options?: {
    'human-guide-links'?: { strict?: boolean }
    'index-freshness'?: { failOnDrift?: boolean }
    'okf-type'?: { requireType?: boolean }
    'docs-style'?: {
      profile?: 'google-dev-docs' | 'playbook-okf' | 'custom'
      required?: Array<
        | 'title'
        | 'purpose'
        | 'audience'
        | 'task-orientation'
        | 'examples'
        | 'owner-source'
        | 'no-stale-wording'
      >
    }
  }
}

type GateId =
  | 'index-freshness'
  | 'human-guide-links'
  | 'link-rot'                    // reserved; emits a diagnostic and is not executed
  | 'okf-type'
  | 'docs-style'
  | 'routing-currency'            // reserved; emits a diagnostic and is not executed
  | 'bootstrap-size'              // reserved; emits a diagnostic and is not executed
  | 'documentation-standard-v1'    // opt-in ecosystem documentation profile
PresetGates
minimalindex-freshness
standard+ human-guide-links in v0.1 alpha
strict+ okf-type in v0.1 alpha

Implemented gates include index-freshness, human-guide-links, okf-type, docs-style, and the opt-in documentation-standard-v1. For v1 compatibility, link-rot, routing-currency, and bootstrap-size remain accepted as reserved IDs; including one emits AK_DOCS_RESERVED_GATE and does not claim that the gate ran. Unknown IDs are rejected.

Structural vs style validation

Alpha gates are deterministic lint checks, not editorial grading:

GateKindWhat it proves
index-freshnessstructuralGenerated index matches current docs/config
human-guide-linksstructuralLocal humanDoc links resolve through configured human-doc adapters
okf-typeOKF lintAgent docs have required type: frontmatter when strict/required
docs-stylestyle lintOpt-in deterministic profile checks for title, purpose, audience, examples, owner/source, task orientation, and stale wording

docs-style supports google-dev-docs, playbook-okf, and custom profiles. It is not part of the default alpha path and does not grade prose quality; it checks for explicit structural signals. LLM critique remains planned optional behavior.


conformance (optional)

Documentation Standard v1 is an opt-in, deterministic ecosystem profile. It validates repository evidence without executing configured commands or making network/model calls.

type ConformanceConfig = {
  documentationStandardV1?: {
    rawSources?: string[]
    contributionPaths?: string[]
    metadata?: Array<{ path: string; contains: string[] }>
    links?: Array<{ url: string; paths: string[] }>
    quickstarts?: Array<{
      id: string
      doc: string
      test: string
      command: string
      testContains: string[]
    }>
    visuals?: string[]
    diagrams?: Array<{ path: string; contains: string[] }>
    ecosystemContract?: {
      manifest: string
      claims: string
      productId: string
    }
    exceptions?: Array<{
      ruleId: DocumentationStandardRuleId
      reason: string
      approvedBy: string
      trackingUrl: string
    }>
  }
}

See Documentation Standard v1 for rule semantics, report status, commands, and the recorded stable-publication HITL decision.


reconciliation (optional)

type ReconciliationConfig = {
  /** Semantic comparison level; discovery still preserves raw file relations. */
  scope?: 'file' | 'module' | 'package'
  /** Observed relation kinds that require documentation declarations. */
  requiredRelationKinds?: string[]
  /** Limit missing-declaration findings to relations between internal project entities. */
  requiredRelationTargets?: 'all' | 'internal'
  /** Emit info findings for documentation with no observed package/module join. */
  includeOrphanedDocuments?: boolean
}

Use scope: 'package' for monorepos where file imports should be compared as package-level architecture evidence. Omit requiredRelationKinds to require all observed kinds; an empty array intentionally disables undocumented-relation findings and must be treated as an explicit exemption.

Use requiredRelationTargets: 'internal' when the repository wants package or module architecture declarations without requiring Markdown to enumerate every external library import. External relations remain in the raw snapshot and report as evidence; they simply do not generate missing-declaration findings.

The reconciliation documentation summary reports package health separately from relation findings: fresh means the package has coverage documentation and no known discrepancy; stale means a declared relation conflicts with observed architecture; missing means no coverage document was found; and unverified means coverage exists but at least one relevant relation or analyzer boundary could not be verified. Package-level aggregation preserves the relation endpoints used for this classification, so an undocumented relation cannot be reported alongside a falsely fresh package.

The same summary keeps document inventory separate from coverage claims: documentCount and documentClassificationCounts describe every discovered Markdown document, while documentedDocumentCount and documentedDocumentClassificationCounts describe documents that declare a knowledge relation. The classification keys are analyzer output (for example agent, human, project, archive, and unclassified); consumers must not interpret total repository Markdown coverage as agent-corpus coverage. Use the agent pair when measuring the configured agent documentation surface.

report (optional)

report?: {
  /** Replace project identity, names, paths, snippets, and finding text in HTML output. */
  privacy?: 'private' | 'anonymized'
}

private is the default and keeps local evidence useful for debugging. anonymized is intended for reports shared outside the repository: it preserves counts, relation kinds, topology, and coverage status while removing project-specific identity and evidence content. The generated HTML and every lazy chunk use the same mode.

safety (optional)

type RepositorySafetyConfig = {
  /** Additional project-relative glob patterns excluded from repository discovery. */
  exclude?: string[]
  maxFiles?: number
  maxBytes?: number
  maxTimeMs?: number
  maxMemoryMb?: number
  redactSecrets?: boolean
}

Discovery always excludes unsafe or generated trees by default, including .git, node_modules, dist, build, coverage, .doc-bridge, .next, out, .turbo, .svelte-kit, .mcpb-build, and .mcpb-output, plus common secret files. safety.exclude adds project-specific patterns; it does not replace the built-in safety boundary. Excluded files remain outside the snapshot and are represented by analyzer coverage when relevant.

analysis (optional)

type AnalysisConfig = {
  /** Ordered language/framework analyzer plugins. */
  plugins?: Array<{
    id: string
    enabled?: boolean
    order?: number
    options?: Record<string, unknown>
    reason?: string
  }>
  jsTs?: {
    /** Property-access methods considered runtime wiring entry points. */
    runtimeWiringMethods?: string[]
    /** Additional adapter methods that represent runtime wiring. */
    runtimeWiringAdapters?: Array<{ id: string; methods: string[] }>
    /** Include test/spec modules in runtime-wiring coverage. Default: false. */
    includeTestRuntimeWiring?: boolean
  }
}

The JS/TS analyzer defaults to register, use, mount, and attach. Generic APIs such as bind and listen are intentionally opt-in to avoid classifying ordinary function binding and server startup as architecture. When a configured method receives an identifier bound to a static import, Doc Bridge records a runtime-wiring relation with metadata.detection: 'runtime-wiring-static'. Reflective, computed, or otherwise unbound targets remain explicit not-analyzed coverage entries. Dynamic import() and require() targets are resolved when their specifier is a literal, a const string binding, a parenthesized static expression, or a concatenation of other statically known strings. Expressions that depend on runtime values remain explicit not-analyzed coverage entries; Doc Bridge does not execute repository code to guess their targets. Test/spec modules are excluded from this signal by default because their registrations usually construct fixtures rather than production architecture; set includeTestRuntimeWiring: true when test wiring is part of the contract. This keeps runtime behavior useful without claiming that arbitrary dependency injection or reflection was resolved. Analyzer plugins must implement the versioned contract in docs/spec/analyzer-plugin-v1.md; malformed or unsupported output remains explicit not-analyzed evidence.

workflow.stateDir optionally relocates the content-addressed workflow artifacts. Runs are resumable and idempotent; pipeline and analyzer versions are part of the run identity.

surfaces (optional)

type SurfacesConfig = {
  cli?: {
    /** Published binary name (package.json bin) */
    bin?: string                    // default: 'ak-docs'
    /** Default output: json | text */
    defaultFormat?: 'json' | 'text'
  }

  mcp?: {
    enabled?: boolean               // default: true
    /** Tool ids to expose; default: core set */
    tools?: McpToolId[]
    transport?: 'stdio' | 'http'
    http?: { port?: number; path?: string }
  }
}

type McpToolId =
  | 'handoff.resolve'
  | 'doc.search'                   // deterministic index search
  | 'doc.get'
  | 'gate.status'
  | 'playbook.pattern.get'         // requires federation

intelligence (optional — any provider)

Absent intelligence = Layer 0 only. AgentsKit is the reference implementation of this block.

type IntelligenceConfig = {
  /** When false, ignore all other intelligence fields */
  enabled?: boolean                 // default: false

  adapter?: {
    /** Provider id or path to custom adapter module */
    provider: 'openai' | 'anthropic' | 'ollama' | 'openrouter' | 'custom'
    model?: string
    /** Env var name for API key; never inline secrets in config */
    apiKeyEnv?: string
    baseUrl?: string
    options?: Record<string, unknown>
  }

  chat?: {
    enabled?: boolean
    /** Corpus scopes for retrieval */
    sources?: ('agent' | 'human' | 'federation')[]
    /** Prefer deterministic handoff before RAG when confidence high */
    handoffFirst?: boolean          // default: true
  }

  retriever?: {
    enabled?: boolean
    /** local | remote | bm25-only */
    mode?: 'local' | 'remote' | 'bm25'
    embedModel?: string
    chunkSize?: number
  }

  memory?: {
    enabled?: boolean
    adapters?: MemoryAdapterId[]
    ingestDir?: string              // default: '.agent-memory'
    classify?: boolean              // default: false — opt-in
    promote?: {
      enabled?: boolean
      targets?: ('agent' | 'human' | 'agents-md')[]
      requireApproval?: boolean     // default: true
    }
  }

  /** Reference runtime; custom path for non-AgentsKit engines later */
  runtime?: 'agentskit' | 'custom'
  runtimeModule?: string

  registry?: {
    enabled?: boolean
    agentId?: string
    agentRoot?: string
    runnerModule?: string
    cli?: {
      /** Executable name or absolute path; arguments are passed without a shell. */
      command: string
      args?: string[]
    }
    deterministic?: boolean
    maxInputBytes?: number
    timeoutMs?: number
    maxTokens?: number
    maxResponseBytes?: number
    maxConcurrency?: number
  }
}

type MemoryAdapterId =
  | 'playbook-memory'              // .agent-memory/MEMORY.md layout
  | 'cursor-rules'                 // .cursor/rules/*.mdc
  | 'session-export'               // manual JSON/md drop folder
  | 'bootstrap-delta'              // git diff on AGENTS.md

Registry agents are advisory and must come from the AgentsKit Registry. The adapter redacts secrets, validates the proposal contract, bounds execution and response size, and requires human approval before any change is applied. The default agent is ecosystem-doc-bridge-corpus-scanner; compatible Registry agents may be selected explicitly.


federation (optional — ecosystem)

Not required for any project. Private dogfood enables this profile to validate scale; public consumers do not depend on private repos.

type FederationConfig = {
  enabled?: boolean
  sources?: FederationSource[]
}

type FederationSource = {
  id: string                        // 'playbook' | 'agentskit' | custom
  llmsTxt?: string                  // URL or local path
  rawBaseUrl?: string               // e.g. 'https://playbook.agentskit.io/raw'
  includeInRetriever?: boolean
  includeInChat?: boolean
}

Layer 0 exports a local retriever helper over DocBridgeIndex:

import { createDocBridgeRetriever } from '@agentskit/doc-bridge'

const retriever = createDocBridgeRetriever(index, { property: 'my-project' })
const chunks = retriever.retrieve('auth ownership')

Chunk keys are stable: {property}:{type}:{id}. Deterministic CLI search and exact handoff resolution stay first; semantic/RAG runtimes can inject this retriever and add federated sources later.


AgentHandoff emission rules

When ak-docs query <target> --agent runs:

type AgentHandoffV1 = {
  type: 'agent-handoff'
  schemaVersion: 1
  source: string                    // index.outFile path
  target: { type: TargetType; id: string }
  startHere: string
  readBeforeEditing: string[]
  editRoots: string[]
  checks: string[]
  humanDoc?: string | null
  playbookPatterns?: string[]       // only if federation enabled
  notes: string[]
}

type TargetType =
  | 'package' | 'module' | 'app'
  | 'screen' | 'flow' | 'component'
  | 'intent' | 'change'
  | 'search'                       // --agent on search picks best match

Merge precedence (later wins):

  1. Agent corpus frontmatter (checks, humanDoc)
  2. routing.ownership[id]
  3. gates.preset default checks
  4. Global handoff.defaults (if set in future minor version)

Example configs

1. Solo library (minimal)

// doc-bridge.config.ts
import { defineConfig } from '@agentskit/doc-bridge'

export default defineConfig({
  schemaVersion: 1,
  corpus: {
    agent: {
      root: 'docs',
      index: 'docs/INDEX.md',
    },
  },
})

2. pnpm monorepo + ownership

import { defineConfig } from '@agentskit/doc-bridge'

export default defineConfig({
  schemaVersion: 1,
  corpus: {
    agent: { root: 'docs/for-agents' },
  },
  routing: {
    plugin: 'pnpm-monorepo',
    options: {
      packages: ['packages/*', 'apps/*'],
    },
  },
  gates: { preset: 'standard' },
})

3. Monorepo + Fumadocs (standard profile)

import { defineConfig } from '@agentskit/doc-bridge'

export default defineConfig({
  schemaVersion: 1,
  corpus: {
    agent: { root: 'docs/for-agents' },
    human: {
      plugin: 'fumadocs',
      options: {
        contentDir: 'apps/web/content/docs',
        urlPrefix: '/docs',
      },
    },
  },
  routing: { plugin: 'pnpm-monorepo' },
  gates: { preset: 'standard' },
  intelligence: {
    enabled: true,
    adapter: { provider: 'ollama', model: 'llama3', apiKeyEnv: '' },
    chat: { enabled: true, handoffFirst: true },
  },
})

4. Docusaurus + optional memory

import { defineConfig } from '@agentskit/doc-bridge'

export default defineConfig({
  schemaVersion: 1,
  corpus: {
    agent: { root: '.agent-docs' },
    human: {
      plugin: 'docusaurus',
      options: {
        docsDir: 'website/docs',
        sidebarsFile: 'website/sidebars.js',
        urlPrefix: '/docs',
      },
    },
  },
  intelligence: {
    enabled: true,
    adapter: { provider: 'openrouter', model: 'openai/gpt-4o-mini', apiKeyEnv: 'OPENROUTER_API_KEY' },
    chat: { enabled: true, sources: ['agent', 'human'] },
    memory: {
      enabled: true,
      adapters: ['cursor-rules', 'playbook-memory'],
      classify: true,
      promote: { enabled: true, requireApproval: true },
    },
  },
})

5. JSON config (no TypeScript)

{
  "schemaVersion": 1,
  "corpus": {
    "agent": { "root": "docs/for-agents" }
  },
  "routing": {
    "plugin": "npm-workspaces"
  },
  "gates": { "preset": "minimal" }
}

CLI mapping

CommandConfig sections used
ak-docs initscaffolds minimal corpus.agent + optional plugin prompt
ak-docs indexcorpus, routing, index, plugins
ak-docs query <t> --agentindex + routing + handoff merge
ak-docs search <q>index
ak-docs retrieve <q>index + federation
ak-docs gate rungates
ak-docs conformance run documentation-standard-v1corpus, routing, index, conformance
ak-docs mcpsurfaces.mcp
ak-docs chatplanned; intelligence.*
ak-docs memory ingestdeterministic local ingest; MemoryCandidate[]
ak-docs memory classifydeterministic route classifier
ak-docs memory promotedraft promotion + safety scan
ak-docs registry topologydoc-curator topology
ak-docs playbook draftdraft Playbook feedback payload

Validation

  • Config validated with Zod at CLI startup (ak-docs validate-config).
  • Unknown schemaVersion → hard error with migration link.
  • Unknown plugin id → hard error listing built-in + custom path.
  • intelligence.enabled: true without adapter → warn + chat/memory subcommands disabled.

Versioning

VersionScope
v1This document. Additive fields only in v1.x.
v2Breaking changes require schemaVersion: 2 + codemod.

See also

The AgentsKit ecosystem

Build the agent. Then take it all the way.

On this page