---
title: Presswork Configuration
description: Look up the strict presswork.json contract, Built-in Profiles, paths, Document Types, indexes, and Agent Skill guidance.
---

> **Configuration boundaries**
>
> Presswork reads only `presswork.json` at the Repository Root. It does not discover or merge configuration from nested directories. An unreadable or invalid file fails the operation without falling back to a Profile. Every object in Presswork Configuration is strict. Undeclared fields are invalid.

When the file is absent, the complete Basic Profile at `basic@1` applies.

## Minimal configuration

This file selects the Basic Profile explicitly and enables editor support from the published schema.

```json title="presswork.json"
{
  "$schema": "https://presswork.sh/schema/config.json",
  "version": 1,
  "profile": { "name": "basic", "version": 1 }
}
```

Presswork does not fetch `$schema` at runtime. Compatible editors can use it for documentation, examples, completion, and validation.

## Top-level fields

| Field                      | Type         | Required | Default                      | Meaning                                                                          |
| -------------------------- | ------------ | -------- | ---------------------------- | -------------------------------------------------------------------------------- |
| `$schema`                  | string       | No       | None                         | Must be `https://presswork.sh/schema/config.json` when present.                  |
| `version`                  | `1`          | Yes      | None                         | Configuration Version.                                                           |
| `profile`                  | object       | Yes      | None                         | Complete Built-in Profile identity.                                              |
| `markdownDialect`          | `"github"`   | No       | Selected Profile value       | Repository-wide link and heading semantics.                                      |
| `documentationDirectories` | string array | No       | `[]` additions               | Documentation Directories added to the selected Profile.                         |
| `rootDocuments`            | string array | No       | `[]` additions               | Root Documents added to the selected Profile.                                    |
| `indexes`                  | object       | No       | Selected Profile policies    | Index Policies keyed by Documentation Directory.                                 |
| `documentTypes`            | object array | No       | `[]` additions               | Repository-defined Document Types added to those in the selected Profile.        |
| `skillGuidance`            | object       | No       | No repository-authored hints | Inert routing hints included in generated `presswork-docs` Agent Skill guidance. |

## Profile

| Field     | Type   | Required | Allowed values        | Meaning                |
| --------- | ------ | -------- | --------------------- | ---------------------- |
| `name`    | string | Yes      | `basic`, `mattpocock` | Built-in Profile name. |
| `version` | number | Yes      | `1`                   | Profile Version.       |

Selecting a Profile replaces the Basic Profile instead of merging with it.

### `basic@1`

The Basic Profile uses the `github` Markdown Dialect. It recognizes the `docs` Documentation Directory and the Root Documents `AGENTS.md`, `CONTEXT.md`, `ARCHITECTURE.md`, and `DESIGN.md`. Its `docs` Index Policy uses root `AGENTS.md` and the `Source Of Truth Map` Index Section. It defines no built-in Document Types or declarative requirements.

### `mattpocock@1`

The Matt Pocock Profile uses the `github` Markdown Dialect. Its optional locations are the `docs/adr` Documentation Directory and the Root Documents `CONTEXT.md` and `CONTEXT-MAP.md`. Missing optional locations are valid.

It defines one non-strict `adr` Document Type at `docs/adr/{{number}}-{{slug}}.md`, with the `domain-modeling` external Creation Policy. It defines no Index Policies. Its declarative requirements cover Architecture Decision Record numbering, structure, title slug, and optional status, plus the structure of the two optional context documents.

Architecture Decision Records use the following contract:

- Each canonical filename is `NNNN-kebab-slug.md`. The four-digit numbers begin at `0001`, are unique, and form a contiguous sequence through the highest number. `0000` is not canonical.
- Each record has exactly one H1 followed immediately by a one-to-three-sentence paragraph. Presswork validates this structure and sentence count, not the paragraph's meaning. The bundled Template's authoring prompt asks the paragraph to cover the context, the decision, and why the decision was made.
- The filename slug matches the H1 after NFKD normalization, combining-mark removal, lowercasing, apostrophe removal, replacement of other non-ASCII-alphanumeric runs with `-`, and removal of leading or trailing `-`.
- Optional YAML frontmatter may set `status` to exactly `proposed`, `accepted`, `deprecated`, or `superseded by ADR-NNNN`.

When present, `CONTEXT.md` has exactly one H1 followed by a one-to-two sentence description. It has exactly one `Language` H2 with at least one `**Term**:` definition containing authored prose. A definition may include an `_Avoid_:` list, but the list must be non-empty when present. Lower-level grouping is optional.

When present, `CONTEXT-MAP.md` has the exact H1 `Context Map`, followed by exactly one `Contexts` H2 and exactly one `Relationships` H2. Each `Contexts` list item contains one described repository-local link to a `CONTEXT.md` document. Each `Relationships` list item uses `→` or `->` between the related contexts, followed by `:` and an authored description.

## Repository-relative paths

Configuration paths use `/` separators and are relative to the Repository Root. They cannot contain a drive prefix, backslash, NUL, trailing slash, empty segment, or `.` or `..` segment. Root Documents contain exactly one path segment. Arrays of locations reject duplicate entries.

Missing locations are allowed and contribute no Recognized Documents.

## `indexes`

Each key is a Documentation Directory. Its value either enables one Index Policy or disables index requirements for that directory.

| Field      | Type    | Required                | Meaning                                                   |
| ---------- | ------- | ----------------------- | --------------------------------------------------------- |
| `document` | string  | Yes for enabled policy  | Repository-relative Index Document.                       |
| `heading`  | string  | Yes for enabled policy  | Non-empty semantic heading of the Index Section.          |
| `enabled`  | `false` | Yes for disabled policy | Disables index requirements; no other fields are allowed. |

An entry replaces the selected Profile's policy for the same Documentation Directory. Entries for other directories are added. An enabled Index Document must be a Recognized Document.

This example explicitly preserves the Basic Profile's index owner.

```json title="presswork.json"
{
  "version": 1,
  "profile": { "name": "basic", "version": 1 },
  "indexes": {
    "docs": {
      "document": "AGENTS.md",
      "heading": "Source Of Truth Map"
    }
  }
}
```

## `documentTypes`

Each entry declares one repository-specific Document Type.

| Field              | Type    | Required            | Allowed values or default                      | Meaning                                                             |
| ------------------ | ------- | ------------------- | ---------------------------------------------- | ------------------------------------------------------------------- |
| `name`             | string  | Yes                 | Unique lower-case identifier                   | Document Type identifier.                                           |
| `directory`        | string  | Yes                 | Repository-relative path                       | Documentation Directory containing direct typed-document children.  |
| `template`         | string  | No                  | `<directory>/TEMPLATE.md`                      | Markdown Template inside the Document Type directory.               |
| `filename`         | string  | Yes                 | Literals and declared `{{field}}` placeholders | Canonical Markdown basename pattern.                                |
| `strict`           | boolean | Yes                 | `true` or `false`                              | Whether completed documents may contain undeclared headings.        |
| `fields`           | object  | Yes                 | At least one declared field                    | Field names mapped to validation kinds.                             |
| `creationPolicy`   | string  | Yes                 | `presswork`, `external`, or `manual`           | Preferred Document Creation workflow.                               |
| `externalWorkflow` | string  | Only for `external` | Lower-case identifier                          | External workflow that owns creation. Forbidden for other policies. |
| `indexEntry`       | string  | Yes                 | Literals and declared `{{field}}` placeholders | Authored Index Section entry pattern used by Document Creation.     |

Field kinds are `non-empty-text`, `slug`, and `safe-path-segment`. A `slug` uses lower-case letters and digits separated by single hyphens. A `safe-path-segment` starts with an ASCII letter, digit, or underscore and then uses ASCII letters, digits, `.`, `_`, or `-`. A `non-empty-text` field cannot appear in `filename`.

Required creation fields are the union of placeholders used by `filename`, the loaded Template, and `indexEntry`.

This complete example adds a strict `proposal` Document Type and preserves the Basic Profile's index owner.

```json title="presswork.json"
{
  "$schema": "https://presswork.sh/schema/config.json",
  "version": 1,
  "profile": { "name": "basic", "version": 1 },
  "markdownDialect": "github",
  "documentationDirectories": ["docs"],
  "rootDocuments": ["AGENTS.md"],
  "indexes": {
    "docs": {
      "document": "AGENTS.md",
      "heading": "Source Of Truth Map"
    }
  },
  "documentTypes": [
    {
      "name": "proposal",
      "directory": "docs/proposals",
      "filename": "{{slug}}.md",
      "strict": true,
      "fields": {
        "slug": "slug",
        "title": "non-empty-text"
      },
      "creationPolicy": "presswork",
      "indexEntry": "- [{{title}}]({{slug}}.md) — Load when this proposal applies."
    }
  ]
}
```

Presswork rejects declarations with unsafe paths, duplicate names, unsupported patterns, undeclared placeholders, shared Template destinations, overlapping filename patterns in one directory, or collisions with Templates, Index Documents, or reserved descendant `README.md` files.

## Templates

Templates are readable Markdown with `{{lower-case-identifier}}` placeholders. They support four standalone, non-executable HTML-comment directives:

- `presswork:prompt-start`
- `presswork:prompt-end`
- `presswork:optional-start`
- `presswork:optional-end`

Each directive is followed by a matching lower-case identifier. Prompt boundaries mark unresolved authoring guidance. Optional boundaries wrap one complete heading section and cannot overlap or nest. Completed typed documents must contain exactly one H1, preserve required Template headings in relative order, and contain no placeholders or `presswork:` directives. Strict Templates also reject headings that the Template did not declare.

## `skillGuidance`

Both `when` and `avoid` are required non-empty arrays when `skillGuidance` is present. Each item is one strict descriptor.

This is the smallest configuration that adds repository-authored routing hints.

```json title="presswork.json"
{
  "version": 1,
  "profile": { "name": "basic", "version": 1 },
  "skillGuidance": {
    "when": [{ "kind": "path", "path": "docs" }],
    "avoid": [{ "kind": "path", "path": "vendor/docs" }]
  }
}
```

| Field   | Type             | Required                         | Minimum constraint | Meaning                                                       |
| ------- | ---------------- | -------------------------------- | ------------------ | ------------------------------------------------------------- |
| `when`  | descriptor array | Yes when `skillGuidance` is used | At least one item  | Identifies when repository-specific skill guidance applies.   |
| `avoid` | descriptor array | Yes when `skillGuidance` is used | At least one item  | Identifies paths or Document Types the guidance should avoid. |

| Field          | Type   | Required status or branch                             | Allowed value or constraint | Meaning                                                       |
| -------------- | ------ | ----------------------------------------------------- | --------------------------- | ------------------------------------------------------------- |
| `kind`         | string | Yes                                                   | `document-type` or `path`   | Identifies guidance by Document Type or repository path.      |
| `documentType` | string | Yes when `kind` is `document-type`; otherwise invalid | Lower-case identifier       | Known Document Type identifier associated with this guidance. |
| `path`         | string | Yes when `kind` is `path`; otherwise invalid          | Repository-relative path    | Repository-relative path associated with this guidance.       |

These hints are inert. They cannot select commands, grant permissions, change a Creation Policy, or replace the generated Agent Skill's fixed safety and completion instructions.

See [Create a Document Draft](/create-a-document/) to use a configured Document Type, [Generate agent guidance](/generate-agent-guidance/) to render the hints, or [Rules and diagnostics](/rules-and-diagnostics/) to interpret configuration failures.
