# DocInsight manifest reference

This page describes the public `docinsight.json` format for manifest edition `2026`, including its fields, defaults, paths, patterns, and variable syntax.

## File format

A manifest is a UTF-8 JSONC document whose root value is an object. Its conventional file name is `docinsight.json`.

Line comments, block comments, and trailing commas are allowed. Property names and string values use double quotes. An initial UTF-8 byte order mark (BOM) is ignored.

JSON `null` values and duplicate property names are not allowed. To leave an optional property unspecified, omit it.

The root object must declare a `project` object.

## Top-level structure

Property | Value | Purpose
--- | --- | ---
`$schema` | string | JSON Schema URI for editor integration
`edition` | string | Manifest edition
`requires` | object | Required manifest features
`project` | object | Project identity and metadata
`variables` | object | User-defined variables
`sources` | named collection | Shared source contexts
`content` | named collection | Publishable content
`assets` | named collection | Files copied to selected outputs
`i18n` | object | Internationalization defaults
`site` | object | Default site definition
`sites` | named collection | Named replacement site definitions
`output` | object | Output targets and default selection

Only documented properties are accepted, except for keys inside named collections and variable objects. Property names are case-sensitive.

An empty string, object, or array is an authored value, not an omitted value. Individual fields may reject empty values or give them a specific meaning.

## Names and references

In a project manifest, project, source, content, asset-set, site, and output-target names are entity names. An entity name contains 1–64 ASCII letters, digits, underscores, or internal hyphens. It must contain at least one letter or digit; a hyphen cannot appear first, last, or twice in succession.

Valid names include `docs`, `DocsAPI`, `docs_api`, `docs-api`, `2026`, and `_internal`. Invalid names include `_`, `-docs`, `docs-`, `docs--api`, and `文档`.

Spelling is preserved, while lookup is ASCII case-insensitive. Thus `Guide` and `guide` identify the same entity, but `guide-api` and `guide_api` are different names.

The `sources`, `content`, `assets`, `sites`, and `output.targets` objects are named collections. Names must be unique within each collection. References use the same case-insensitive lookup:

- `content.<name>.source` references `sources`;

- `output.targets.<name>.content` references `content`;

- `output.targets.<name>.assets` references project asset sets;

- a string-valued `output.targets.<name>.site` references `sites`;

- `output.default_targets` references `output.targets`.

These references use exact names rather than wildcard patterns.

## Paths, mounts, and glob patterns

Relative filesystem paths are resolved from the directory containing `docinsight.json`.

Value | Resolution
--- | ---
`project.reference_root` | Manifest-relative project root or real ancestor; defaults to `.`
Markdown `root` | Manifest-relative directory that must remain inside the manifest directory
Asset-set `root` | Manifest-relative directory that must remain inside the manifest directory
Delphi source `root` | Manifest-relative directory that must remain inside the manifest directory
Output target `path` | Optional manifest-relative or absolute default output path
`site.base_path` or `sites.<name>.base_path` | URL path beginning with `/`; defaults to `/`

Markdown, asset, and Delphi source roots cannot be absolute, contain a parent (`..`) component, or leave the manifest directory. No filesystem redirection is followed from the project directory to a root or through selected input; this includes symbolic links, junctions, and other reparse points. The reference root is the explicit exception to the parent-path rule: it may contain `..`, but it must canonicalize to the project root or one of its real ancestors. Output paths may resolve outside the manifest directory.

Configured output paths, mount paths, and URL paths use `/`. They do not expand `{{...}}` variable references or platform-style environment variables.

### Mount paths

`content.<name>.mount` and `assets.<name>.mount` are logical paths below an output root. An optional leading `/` is ignored, and `/` selects the output root.

When `mount` is omitted, it defaults to the declared content or asset-set name with its original spelling. For example, content named `APIReference` mounts at `APIReference`, not `api-reference`. Set an explicit mount when the published path must remain stable across renames.

Mounts use non-empty ASCII segments separated by `/`. A segment may contain letters, digits, underscores, single internal hyphens, and single dots between non-empty parts. One leading dot is allowed. Empty segments, `.`, `..`, leading or trailing hyphens, repeated hyphens, and repeated dots are invalid.

### Glob patterns

`files` and `exclude` contain case-insensitive glob patterns relative to the associated root:

- `/` is the logical separator; input backslashes are normalized to `/`;

- a leading `/` anchors a pattern to the root;

- a trailing `/` selects a directory subtree;

- an exclusion without `/` matches that file name at any depth;

- parent (`..`) components are not allowed;

- exclusions take precedence over inclusions.

## Variables

A variable identifier contains 1–64 ASCII bytes. It starts with a letter and continues with letters, digits, or underscores. Examples include `product`, `ProductName`, and `product_2`; `2product`, `_product`, and `product-name` are invalid.

Identifier spelling is preserved and lookup is ASCII case-insensitive. Every segment of a dotted variable path follows the same rule.

Variable references use `{{name}}` or dotted `{{object.field}}` syntax. Whitespace immediately inside the braces is ignored. Unknown paths, cycles, and attempts to render an object directly are errors.

User variables may be:

- strings, which may contain variable references;

- links, written as `{ "type": "link", "label": "...", "href": "..." }`;

- objects, written directly as fields or as `{ "type": "object", "fields": { ... } }`.

Link labels and targets are literal and do not expand variables. Link targets may be relative references or use the `http`, `https`, `mailto`, or `tel` scheme.

Reserved variable names include:

text

    sys workspace project site target content topic page api

`project` exposes `name`, `title`, `description`, `homepage`, `repository`, `license`, and `copyright`. The value of `project.name` does not define an additional variable, even when it is a valid variable identifier.

`sys.docinsight` is the built-in DocInsight link and exposes `label` and `href`.

Manifest variables expand in user string variables, `site.title`, `site.title_suffix`, `site.description`, `site.footer.notice`, and the corresponding fields under `sites.<name>`. Project metadata is literal.

## Properties

Unless a property is marked required, it is optional.

### `$schema`

Optional string containing a JSON Schema URI for editor integration. DocInsight does not currently publish an official Schema URI, so this property can be omitted. It does not select the manifest edition.

### `edition`

String. The supported value is `"2026"`. When omitted, it defaults to `"2026"`.

Writers should include the edition explicitly so the manifest's intended contract is clear.

### `requires`

Compatibility object.

Property | Value | Default
--- | --- | ---
`features` | array of unique lowercase kebab-case feature IDs, each 1–64 ASCII bytes | `[]`

The current toolchain supports no optional feature IDs, so a non-empty `features` array is rejected.

### `project`

Required object containing the project identity and metadata.

Property | Value | Required
--- | --- | ---
`name` | entity name | yes
`reference_root` | relative filesystem path to the project root or an ancestor | no; default `.`
`title` | string | no
`description` | string | no
`homepage` | href string or link object | no
`repository` | href string or link object | no
`license` | label string or link object | no
`copyright` | string | no

A project link object requires a non-blank `href` and literal `label`. String-form homepage and repository values receive default labels. A license link object likewise requires both a non-blank `label` and `href`.

Root-relative paths begin with `/` and resolve against `project.reference_root`. The property is resolved from the directory containing `docinsight.json` and must resolve to a real directory that contains the current project root. DocInsight canonicalizes symbolic links, does not inspect Git, and does not treat the reference root as permission to reference a sibling DocInsight project.

### `variables`

Object keyed by variable identifiers. Object field names use the same identifier rules. Missing and `{}` both define no user variables.

json

    {
      "variables": {
        "company": {
          "name": "DevJet Software",
          "homepage": {
            "type": "link",
            "label": "DevJet Software",
            "href": "https://devjetsoftware.com/"
          }
        },
        "product": "{{project.title}}"
      }
    }

### `sources`

Named collection of shared source contexts. The supported source type is `delphi`.

#### Delphi source

Property | Value | Required or default
--- | --- | ---
`type` | `"delphi"` | required
`root` | filesystem path | `.`
`files` | non-empty array of project-file globs | required
`exclude` | array of exclusion globs | `[]`
`xref` | source namespace and project overrides | defaults below
`options` | Delphi analysis options | required

Project discovery accepts `.groupproj`, `.dproj`, `.dpr`, and `.dpk` files.

`files` and `exclude` form a file scope relative to `root`. `exclude` filters only project and project-group entries matched directly by `files`; it is not reapplied to projects or units reached while expanding the selected graph. Project, unit, and symbol publication filtering belongs to Delphi content.

Property | Value | Default
--- | --- | ---
`xref.namespace` | Xref namespace for the source | `project.name`
`xref.projects` | exact project-name-to-namespace object | `{}`

The effective Xref namespace for a Delphi project is selected in this order: an exact `xref.projects` mapping, `xref.namespace`, then the manifest's `project.name`. Effective namespaces are normalized to lowercase. `xref.projects` keys are case-insensitive `.dproj` filename stems and do not accept wildcard patterns; each value is a complete namespace. For example:

json

    {
      "xref": {
        "projects": {
          "MyLibrary.Tests": "mylibrary.tests"
        }
      }
    }

This maps the Delphi project `MyLibrary.Tests` to `mylibrary.tests`; projects without an override use `project.name` when `xref.namespace` is omitted. The source filesystem `root` does not affect Xref namespaces.

The namespace is the first segment of every Delphi Xref. The Delphi content name and mount do not affect it, so content named `api` still exports an Xref such as `mylibrary/MyLibrary.Collections/IList{T}`, not `api/...`. Package local IDs start at the fully qualified unit name. Program and library local IDs start with the Delphi project name, so `MyLibrary.Tests` under the default namespace may produce `mylibrary/mylibrary.tests/...`. An exact project override to `mylibrary.tests` removes the repeated project segment and produces `mylibrary.tests/...`. A source-wide `xref.namespace` does not remove it.

`options` contains:

Property | Value | Required or default
--- | --- | ---
`compiler` | Delphi compiler ID | required
`environment` | local or custom environment object | local x86
`platform` | platform string | required for multi-platform compilers; otherwise `Win32`
`config` | configuration string | toolchain default
`defines` | array of conditional symbols | `[]`
`properties` | string-valued property object | `{}`

Compiler IDs are `delphi_2007`, `delphi_2009`, `delphi_2010`, `delphi_xe` through `delphi_xe8`, `delphi_10` through `delphi_10_4`, `delphi_11`, `delphi_12`, and `delphi_13`.

Set `platform` explicitly when the selected compiler supports more than Win32. Compilers that support only Win32 default to `Win32` when it is omitted.

A local environment uses `"type": "local"` and accepts `arch` (`"x86"` or `"x64"`) and `registry_root`. A custom environment uses `"type": "custom"` and accepts string-valued `variables` and `search_paths`. The property names `Platform`, `Config`, and `Configuration` are reserved in `options.properties`, case-insensitively.

### `content`

Named collection of publishable content. Every content entry has:

Property | Value | Required or default
--- | --- | ---
`type` | `"markdown"` or `"delphi"` | required
`title` | display string | content name
`mount` | mount path | content name

#### Markdown content

Property | Value | Required or default
--- | --- | ---
`root` | manifest-relative directory | required
`files` | non-empty array of globs | `["**/*.md"]`
`exclude` | array of exclusion globs | `[]`

`root` defines the entry's Markdown source path space and the containment boundary for includes, snippets, and content-local assets. `files` and `exclude` select the `.md` source files that belong to the entry as topic candidates. They are membership filters, not a security boundary and not a guarantee that every candidate is published. Draft filtering, `toc.md` navigation, and output-target selection determine later publication.

Markdown content entries may share or overlap a `root`; the content entry name, not the directory, is the content and Xref namespace. After resolving roots and enumerating the actual file scopes, one physical Markdown topic source may belong to only one content entry across the project. This is validated before draft, TOC-publication, or target-selection filtering. A `toc.md` is navigation source rather than a topic and may be read by more than one entry.

Files inside `root` that are not selected as topics may still be referenced explicitly as include fragments, snippet sources, or content-local assets. Such dependencies may be shared by multiple content entries, are not topics merely because they are inside `root`, and are not published as topics automatically. Use separate roots, rather than `files` or `exclude`, when content must have a different filesystem containment boundary.

A relative Markdown topic link first resolves to a topic owned by the current content entry. If no local topic matches, the path may resolve from the containing file to a topic owned by another content entry. Root-relative topic links may also cross content entries. Every output target that includes the source content must include the destination content; otherwise check and build report an unpublished topic dependency. Xrefs remain useful when semantic IDs are more stable than physical source paths.

Relative and root-relative image or file links may likewise bind to a local asset below another Markdown content's `root`. The asset is published below the destination content's `mount`, and every target that includes the source content must also include that destination content. Paths outside all Markdown content roots remain invalid; rooted project assets continue to require a selected project asset set.

Only `toc.md` directly under `root` is the content's root TOC. When there is no root TOC, a root-level `index.md` is preferred as the default topic, followed by the first publishable topic. If exactly one topic is publishable, it is treated as a single-page landing topic wherever it is located and whatever it is named. For example, `root: "docs"` with `files: ["release-notes/2026.1/index.md"]` is supported without moving the content root.

Each Markdown topic has an ID local to its content entry. By default, the ID is the topic's `root`-relative source path without the `.md` extension. A topic may override it with the front matter `id` property:

markdown

    ---
    id: getting-started
    ---

    # Getting started

The ID supplies the topic's local Xref identity and conventional output route. It must be unique within one content entry; different content entries may use the same ID because the content entry name supplies the namespace. The front matter property is `id`; `name` is not a compatibility alias.

A Markdown topic may also configure its document-local Xref scope with front matter `xref`:

markdown

    ---
    xref:
      base: mylibrary/MyLibrary.Collections
      aliases:
        list: mylibrary/MyLibrary.Collections/IList{T}
    ---

Both `base` and `aliases` are optional. `base` installs the document's default binding; `aliases` maps local names to absolute Xref bindings. For address forms and lookup order, see Configure a document Xref scope.

#### Delphi content

Property | Value | Required or default
--- | --- | ---
`source` | Delphi source name | required
`filter` | declaration filter object | defaults below
`reference` | reference-page options | defaults below
`structure` | TOC and path options | defaults below

Property | Values | Default
--- | --- | ---
`filter.xref_namespaces` | name filter object | all namespaces
`filter.projects` | name filter object | all projects
`filter.units` | name filter object | all units
`filter.symbols` | name filter object | all symbols
`filter.sections.implementation` | boolean | `false`
`filter.visibility.private` | boolean | `false`
`filter.visibility.strict_private` | boolean | follows `private`
`filter.visibility.protected` | boolean | `true`
`filter.visibility.strict_protected` | boolean | follows `protected`
`reference.inherited_members` | `"none"`, `"linked"` | `"linked"`
`structure.toc.scope` | `"unified"`, `"project"`, `"unit"` | `"project"`
`structure.path.project` | `"none"`, `"auto"`, `"always"` | `"auto"`

Public, published, and automated declarations are always included.

Each semantic name filter accepts a non-empty `include` array, a non-empty `exclude` array, or both. An omitted filter or omitted `include` selects all names in that dimension. `exclude` is applied after `include`, so exclusion wins when both match. Patterns are case-insensitive, whole-name wildcard patterns: `*` matches zero or more characters and `?` matches exactly one. They are not filesystem globs; `.` is an ordinary character, `*` can match across it, and `/` and `\\` are invalid.

`xref_namespaces` matches each project's effective Xref namespace, `projects` matches its `.dproj` filename stem, `units` matches the declared fully qualified unit name, and `symbols` matches the unit-qualified symbol name without parameter types or an overload signature. All applicable dimensions must match for a declaration to be published.

For example, this content publishes selected projects while excluding internal units and deprecated symbols:

json

    {
      "type": "delphi",
      "source": "main",
      "filter": {
        "projects": {
          "include": ["MyLibrary*"]
        },
        "units": {
          "exclude": ["*.Internal"]
        },
        "symbols": {
          "exclude": ["*.Deprecated"]
        }
      }
    }

### `assets`

Named collection of project asset sets. Assets are published into each output target that explicitly selects the set. Defining a set does not change any target's output.

Property | Value | Required or default
--- | --- | ---
`root` | manifest-relative directory | `.` (the manifest directory)
`files` | non-empty array of globs | required
`exclude` | array of exclusion globs | `[]`
`mount` | mount path | asset-set name

`files` is the positive publication allowlist. DocInsight never treats an omitted `files` property as `["**/*"]`; to publish the complete root, write `"files": ["**/*"]` explicitly. `exclude` filters the allowlist and is not a security boundary. The root is only the resolution boundary for patterns and relative paths.

Only regular files that remain inside the resolved root are published. Missing exact files, invalid patterns, path traversal, filesystem redirection, and patterns with no publishable matches fail validation. Redirection includes symbolic links, junctions, and other reparse points, even when the destination remains inside the root. Published paths retain their path relative to `root` below `mount`.

Markdown references a project asset by a root-relative path, for example `/project1/assets/images/logo.svg`. Asset-set names are not part of authored URLs. For each target, the physical file must match exactly one selected set, unless multiple matches provably produce the same artifact identity. Query strings and fragments do not participate in source lookup.

Delphi XML documentation does not use project asset sets for local links. Its local files are relative to the containing `.pas` file and must remain inside the declared Delphi source root.

The former property name `resources` is not accepted as an alias.

### `i18n`

Internationalization object.

Property | Value | Default
--- | --- | ---
`default_locale` | locale string | `"en-US"`

An empty or whitespace-only `default_locale` also resolves to `"en-US"`.

### `site`

Default site definition inherited by site-aware HTML and CHM targets whose target-local `site` property is omitted. When this definition is absent, those targets have no selected site definition and still derive rendered values such as title and description from project metadata.

Property | Value | Default
--- | --- | ---
`title` | interpolated string | project title, then project name
`title_suffix` | interpolated string | resolved site title prefixed by a space-pipe-space separator
`description` | interpolated string | project description
`origin` | HTTP(S) origin | none
`base_path` | absolute URL path | `/`
`favicon` | published `.ico`, `.svg`, or `.png` asset path | Web output reuses `favicon.ico` or supplies a built-in icon
`robots` | robots meta content | none
`footer.notice` | interpolated string | none

`origin` contains only an HTTP or HTTPS origin: no user information, path, query, or fragment. `base_path` begins with one `/`; a trailing `/` is added when needed.

A configured `favicon` must name a file published by one of the project asset sets explicitly selected by the current target. A favicon never auto-selects an asset set.

### `sites`

Named collection of alternative site definitions. Each value has the same shape as `site`. A target selects one by name with its target-local `site` property.

A named site is a full replacement for the top-level default site. DocInsight does not merge `site` with `sites.<name>`, does not implicitly select the sole named site, and does not treat any site name as special.

json

    {
      "project": { "name": "docs" },
      "site": { "title": "Documentation" },
      "sites": {
        "offline": { "title": "Offline Help" }
      },
      "output": {
        "targets": {
          "site": {
            "type": "html",
            "path": "dist/site",
            "content": ["guide"]
          },
          "help": {
            "type": "chm",
            "path": "dist/help.chm",
            "site": "offline",
            "content": ["guide"]
          }
        }
      }
    }

### `output`

Output configuration.

Property | Value | Default
--- | --- | ---
`default_targets` | non-empty array of target names | all targets in canonical identity order
`targets` | named target collection | `{}`

`docinsight init` names its generated HTML target `site` and places it at `dist/docs/site`. Target names are not reserved, and URL behavior remains explicitly configured on each target.

Each target contains:

Property | Value | Required
--- | --- | ---
`type` | `"html"` or `"chm"` | yes
`path` | literal default filesystem path | no; require an external binding when selected
`site` | `false`, `true`, or site name | no; inherit top-level `site`
`canonical` | `false`, `true`, or `{ "target": name }` | no; defaults to `false`
`content` | non-empty ordered array of content bindings | yes
`assets` | non-empty array of project asset-set names | no; publish no project asset sets

For HTML and CHM targets, omitting `site` or setting it to `true` selects the top-level default. Setting it to `false` disables site selection. A site name selects `sites.<name>` as a full replacement. A target without a selected site definition still receives normal renderer-derived values from project metadata. Inline site objects are invalid.

Canonical links are disabled by default. Set `canonical` to `true` to use the current target's routes, URL settings, and selected site. Use `{ "target": "name" }` to use another declared target as the canonical URL source; the referenced target must exist. Set it to `false` to disable them.

Target content, asset-set, and named-site references must exist. Content and asset-set references cannot contain duplicates or wildcards. Omitting `assets` publishes no project asset sets; references in selected content do not auto-select a set. Content-local assets remain internal dependencies of selected content and do not appear in this array.

A selected asset set publishes every file matched by its `files` and `exclude` patterns.

A target content binding is either an exact content-name string or an object with `name` and an optional target-specific mount projection. String and object bindings may be mixed while retaining array order:

json

    {
      "content": [
        "api",
        {
          "name": "docs",
          "mount": {
            "/release-notes/": "/release-notes/2026.1",
            "/": "/2026.1"
          }
        }
      ]
    }

`"docs"` and `{ "name": "docs" }` are equivalent and inherit `content.docs.mount`. A binding's optional `mount` accepts either:

- a string replacing the complete content mount for this target; or

- an object mapping content-local rooted directory prefixes to target mounts.

`"mount": "/2026.1"` is equivalent to `"mount": { "/": "/2026.1" }`. A mount projection object must be nonempty and include `/` as its complete fallback. Matching uses the longest path-segment prefix, consumes that prefix, and does not depend on JSON property order. Source keys are `/` or rooted directory prefixes; `/release-notes` and `/release-notes/` are equivalent. They reject empty, `.`, `..`, and backslash-separated segments, and equivalent spellings cannot both be declared. Destination values use the ordinary mount grammar with an optional trailing `/`; `/` selects the target root.

The projection applies equally to topics and content-owned assets. A cross-content local asset uses the binding of the content that owns the asset. Project asset sets retain their own `assets.<name>.mount`. Mount projection is resolved before HTML/CHM artifact and URL encoding; `site.base_path` and clean URL behavior are applied later.

#### HTML target

An HTML target path is a directory. It also accepts URL generation settings:

Property | Value | Default
--- | --- | ---
`urls.page` | `"html"` or `"clean"` | `"html"`
`urls.link` | `"relative"` or `"root_relative"` | `"relative"`

`urls.page` controls public page URLs. `"html"` preserves generated `.html` file names. `"clean"` removes the extension and maps `index.html` pages to their containing directory.

`urls.link` controls generated internal links. `"relative"` writes links from the current page. `"root_relative"` prefixes links with the selected site's `base_path`.

#### CHM target

A CHM target path is a file whose extension is `.chm`.

Property | Value | Default
--- | --- | ---
`title` | string | resolved project title

The CHM `title` controls the window and artifact title. It takes precedence over the title in the selected site definition.

## Validation and compatibility

DocInsight rejects invalid JSONC, duplicate properties, `null` values, a missing or invalid project declaration, unknown properties, invalid field values, unresolved references, and invalid paths or patterns.

An omitted edition always means edition `2026`; it will not begin to mean a newer edition when one is introduced. Unsupported editions and required features are rejected before the manifest is interpreted under the current edition.

Unknown fields and enum values are not accepted for forward compatibility. New syntax is introduced through a declared feature or a later edition.

## Important defaults

Property | Default
--- | ---
`edition` | `"2026"`
`requires.features` | `[]`
`i18n.default_locale` | `"en-US"`
Markdown `files` | `["**/*.md"]`
Asset-set `root` | manifest directory (`.`)
Asset-set `files` | required; no implicit default
Content and asset-set `mount` | declared entity name
Target string or `{ "name": ... }` content binding | inherit the content mount
target `assets` | publish no project asset sets
target `site` | inherit top-level `site`, otherwise remain unbound
HTML `urls.page` | `"html"`
HTML `urls.link` | `"relative"`
`site.base_path` | `/`
target `canonical` | `false`
`output.default_targets` | all targets in canonical identity order

For a complete configuration, see Manifest examples.