# Pack index

> The index.json a pack build emits: the pack's tools, guardrails, agents and flows as data, plus where each tool handler and guardrail check lives.

`@kindgi/specs/pack-index.schema.json`, schema version 1.4.0.

The `index.json` a pack build emits: the pack's tools, guardrails, agents and flows as data, plus where each tool handler and guardrail check lives. A runtime registers the pack's primitives from it, and a pack service loads the modules it names and resolves every call by id. Any indexer (the TypeScript `kindgi-index`, the Python `python -m kindgi.pack index`) emits this shape. Determinism: every list is sorted by `id` (code-unit order), keys are sorted at every level, the file is UTF-8 JSON indented by two spaces with a trailing newline, and integral numbers carry no fraction, so the same source indexes to the same bytes. Consumers refuse an envelope `v` they don't recognize.

- `v` (`1`, required): Envelope version. Additive fields on an existing entry shape don't bump it.

- `packId` (string, required): The pack's id (`pack.id` in the pack config).

- `packVersion` (string, required): The pack's version (`pack.version` in the pack config).

- `artifactVersion` (string, required): This build of the pack. A pack build pins it; a local indexer defaults to `YYYYMMDD.N` (UTC date, N counting up from the previous index of the same day).

- `publishedAt` (string (date-time), required): When the index was built — ISO 8601 UTC with milliseconds (`2026-09-20T14:32:07.104Z`). A pack build pins it for reproducible output.

- `tools` (array of [tool](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#tool), required): Tools with handler code, sorted by `id`.

- `guardrails` (array of [guardrail](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#guardrail), required): Guardrails whose check is pack code, sorted by `id`.

- `agents` (array of [agent](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#agent), required): Agents, sorted by `id`.

- `flows` (array of [flow](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#flow), required): Flows, sorted by `id`.

- `env` (object): The process environment the pack's code reads (`env` in `kindgi.config`; `[tool.kindgi.env]` in `pyproject.toml`). Absent when the pack declares none. A deployment injects exactly these names. With a `required` name unset or empty, the pack service isn't ready (unless its env check is `warn`); `/readyz` and `/v1/info` name it. Not `needsSpec.env`: that is per-call context.

  - `required` (array of [envName](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#envname), required): Names the pack service needs, set and non-empty, to be ready. Sorted.
  - `optional` (array of [envName](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#envname), required): Names the pack reads when present. Sorted. Never also in `required`.

## Definitions

### envName

A process environment variable name. `KINDGI_*` names configure Kindgi and are never a pack's.

Type: string

### modulePath

The source file the primitive was declared in, relative to the pack root: forward slashes, no leading `./` (`tools/echo/index.ts`, `tools/ledger.py`). A pack service resolves it against its module root; a build may point it at a bundle instead. Several entries may share one module (a Python module can declare several tools).

Type: string

### jsonSchema

A JSON Schema (Draft 2020-12) in wire form. Open: any JSON Schema keyword is allowed, so this node carries no `additionalProperties` restriction.

Type: object

### openObject

An object whose shape is defined by the primitive's own schema (`tool.schema.json`, `guardrail.schema.json`, `agent.schema.json`, `flow.schema.json`); the index carries it as declared.

Type: object

### tool

- `id` (string, required): Tool id — what a pack service resolves an `invoke` by.
- `description` (string): What the tool does — the model reads it.
- `version` (string): The tool's version. A caller that names a version gets `tool-version-mismatch` when it differs.
- `input` ([jsonSchema](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#jsonschema), required): JSON Schema the input must satisfy; the pack service validates before running the handler.
- `output` ([jsonSchema](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#jsonschema), required): JSON Schema the handler's return value must satisfy; the pack service validates it.
- `effects` (array of [openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): Declared side effects (`tool.schema.json` `effects`).
- `needs` (array of [openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): Declared needs (`tool.schema.json` `needs`).
- `needsSpec` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): Typed needs (`tool.schema.json` `needsSpec`).
- `sandbox` (string): Isolation posture (`tool.schema.json` `sandbox`).
- `limits` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): Resource limits (`tool.schema.json` `limits`).
- `network` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): Network policy (`tool.schema.json` `network`).
- `mutating` (boolean): Whether the tool may change something (`tool.schema.json` `mutating`). `false` makes it read-only: it runs in a dry run, and per-tool approval gates don't ask before it by default. Absent means it may.
- `needsApprovalWhenUnattended` (boolean): Whether a person must say yes to every call of the tool in a run no person started (`tool.schema.json` `needsApprovalWhenUnattended`). Absent means `false`.
- `spec` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): A declarative tool's spec (`tool.schema.json` `spec`, e.g. `kind: 'http'`). A runtime runs a tool that has one itself, resolving its `secretRef`s, rather than calling the pack service.
- `modulePath` ([modulePath](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#modulepath), required)

### guardrail

- `id` (string, required): Guardrail id.
- `name` (string): Human-readable name.
- `kind` (string, required): How the guardrail is checked (`guardrail.schema.json` `kind`).
- `action` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject), required): What a violation does (`guardrail.schema.json` `action`, with `on-violation`).
- `severity` (string): Severity (`guardrail.schema.json` `severity`).
- `scope` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): When the guardrail applies (`guardrail.schema.json` `scope`).
- `checkModulePath` ([modulePath](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#modulepath), required)
- `checkId` (string): The check's id — what a pack service resolves a `check-invoke` by. Absent: the guardrail's `id`.
- `checkBuiltIn` (`true`): The guardrail names a built-in check (`checkId`) without shipping a check of its own: `checkModulePath` is only the file it's declared in. The CLI sets it; a runtime warns about a guardrail naming a built-in without it.
- `configSchema` ([jsonSchema](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#jsonschema)): JSON Schema of the check's config.
- `config` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): What the check is configured with (`guardrail.schema.json` `config`).
- `sandbox` (string): Isolation posture.
- `limits` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): Resource limits.
- `network` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): Network policy.

### agent

An agent as declared (`agent.schema.json`); the runtime validates it in full when it registers the pack.

- `id` (string, required)

- `version` (string, required)

- `name` (string, required)

- `instructions` (one of the objects below, required)

  - string

  - an object

    - `prompt` (string, required)
    - `version` (string, required)

- `settings` (array of any)

- `modelSettings` (object)

- `capabilities` (array of any, required)

- `tools` (array of object, required)

  - `id` (string, required)
  - `version` (string, required): Semver range.

- `retrieval` (array of any)

- `memory` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject))

- `guardrails` (array of string)

- `budget` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject))

- `parameters` (array of any)

- `preferredProvider` (string)

- `preferredModel` (string)

- `description` (string)

- `tags` (array of string)

- `conversationPolicy` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject))

- `output` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): Typed output (`{ schema, name?, maxRepairs? }`), its schema already JSON Schema.

- `toolErrors` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject)): How the agent's turns retry failed tool calls (`{ maxRetries?, retryOn? }`, `agent.schema.json` `toolErrors`).

- `modulePath` ([modulePath](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#modulepath), required)

### flow

A flow as declared (`flow.schema.json`), plus the kernel payload version.

- `id` (string, required)
- `version` (string, required)
- `name` (string)
- `description` (string)
- `nodes` (array of any, required)
- `edges` (array of any, required)
- `maxParallelism` (integer)
- `metadata` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject))
- `output` ([openObject](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#openobject))
- `kernelPayloadVersion` (`1`, required): Version of the flow payload inside the index, independent of the envelope `v`.
- `modulePath` ([modulePath](https://docs.kindgi.com/v0.1.9/reference/schemas/pack-index.md#modulepath), required)
