# Schema Versions (https://jackin.tailrocks.com/reference/runtime/schema-versions/)



This page is the canonical schema-version history for jackin-owned
configuration files and role manifests. It is written for operators,
role authors, migration authors, and agents that need to understand
which fields exist in which schema version.

## Why versioning [#why-versioning]

Breaking changes to schemas are expected — that is how the project explores ideas without dragging compatibility shims forward. The trade-off is that operators and role authors should never have to hand-edit a TOML file to recover from an upgrade. Versioning resolves the tension:

* **Each schema file carries its own `version` stamp.** When jackin reads the file, it compares the on-disk version against the binary's `CURRENT_*_VERSION` and applies any pending migration steps before parsing, so operators see a working setup after every upgrade.
* **Operator-owned files migrate automatically.** `config.toml` and `~/.config/jackin/workspaces/<name>.toml` are rewritten in place on startup; the operator does nothing.
* **Role-owned files migrate explicitly.** Role authors run `jackin role migrate <role-repo-path>` on their desktop to rewrite a `jackin.role.toml` against the latest schema, then commit and push the result. jackin' never writes back into a role repo on its own — that would silently mutate someone else's source tree. CI, validation workflows, and Renovate-style migration automation use the standalone `jackin-role migrate <role-repo-path>` binary so role repos do not need the full `jackin` operator CLI.
* **Migrations are a hard PR-review rule.** Every change to one of the three versioned files must bump the corresponding `CURRENT_*_VERSION`, add a migration step, and update this page. Adding a new enum variant counts as a schema-breaking change: old binaries cannot parse manifests that use the new variant. The full rule lives in <RepoFile path="AGENTS.md">AGENTS.md</RepoFile> and <RepoFile path="PULL_REQUESTS.md">PULL\_REQUESTS.md</RepoFile>.
* **Version mismatches produce actionable errors.** The version check runs before full TOML deserialization, so old binaries always surface a clear message rather than a cryptic parse error. When a manifest's `version` is newer than what the binary knows about, jackin rejects it with: `role manifest is at {version}, this binary only understands up to {CURRENT_MANIFEST_VERSION}; upgrade jackin`. Current binaries accept older role manifests when the file only uses fields and enum values that existed at that older version. If an older-stamped manifest uses a newer feature, jackin rejects it with a feature-specific `jackin role migrate <role-repo-path>` hint.

The split-workspace layout described in [Configuration File](/reference/runtime/configuration/#one-file-per-workspace-by-design) makes per-file migration tractable: legacy global files and per-workspace files migrate independently, so a dotfile repo that is partially old still upgrades cleanly.

## Current versions [#current-versions]

| File                                      | Current version | Owner           | Migration mode                                                                                         |
| ----------------------------------------- | --------------- | --------------- | ------------------------------------------------------------------------------------------------------ |
| `~/.config/jackin/config.toml`            | `v1alpha6`      | jackin          | Automatic on startup                                                                                   |
| `~/.config/jackin/workspaces/<name>.toml` | `v1alpha6`      | jackin          | Automatic on startup                                                                                   |
| `jackin.role.toml`                        | `v1alpha5`      | Role repository | Desktop: `jackin role migrate <role-repo-path>`; CI/automation: `jackin-role migrate <role-repo-path>` |

## Timeline [#timeline]

Each entry is one upgrade path the current binary applies. <RepoFile path="crates/jackin/tests/migration_fixtures.rs">crates/jackin/tests/migration\_fixtures.rs</RepoFile> walks every fixture on every CI run, so a regression breaks here before it breaks on a delayed operator's machine. Newest first; append, never edit.

### Manifest `v1alpha5` — 2026-06-10 [#manifest-v1alpha5--2026-06-10]

| File kind                          | Predecessor | Migration mode                                                                                         | Fixture                                                                                                                                                                       |
| ---------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Role manifest (`jackin.role.toml`) | `v1alpha4`  | Desktop: `jackin role migrate <role-repo-path>`; CI/automation: `jackin-role migrate <role-repo-path>` | <RepoFile path="crates/jackin/tests/fixtures/migrations/manifest/from-v1alpha4/meta.toml">crates/jackin/tests/fixtures/migrations/manifest/from-v1alpha4/meta.toml</RepoFile> |

**Summary**: adds optional `[<agent>.providers.<id>]` tables to the `[claude]`, `[codex]`, and `[opencode]` agent configs for per-provider model overrides. The `providers` map is an additive field with a `serde` default of empty, so existing manifests round-trip cleanly and the migration is a no-op restamp. A manifest stamped older than `v1alpha5` that uses a `providers` table is rejected with a `jackin role migrate` hint, the same way the OpenCode (`v1alpha3`) and Kimi (`v1alpha4`) agent fields are gated.

**Before** (v1alpha4 manifest):

```toml
version = "v1alpha4"

[opencode]
model = "zai-coding-plan/glm-5.1"
```

**After** (v1alpha5 — no change needed; the `providers` map defaults to empty):

```toml
version = "v1alpha5"

[opencode]
model = "zai-coding-plan/glm-5.1"
```

**Example with a per-provider override** (a role pins a model when MiniMax is picked for OpenCode):

```toml
version = "v1alpha5"

[opencode]
model = "zai-coding-plan/glm-5.1"

[opencode.providers.minimax]
model = "minimax/MiniMax-M3"
```

### `v1alpha6` — 2026-06-04 [#v1alpha6--2026-06-04]

| File kind                            | Predecessor | Migration mode       | Fixture                                                                                                                                                                         |
| ------------------------------------ | ----------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Config (`config.toml`)               | `v1alpha5`  | Automatic on startup | <RepoFile path="crates/jackin/tests/fixtures/migrations/config/from-v1alpha5/meta.toml">crates/jackin/tests/fixtures/migrations/config/from-v1alpha5/meta.toml</RepoFile>       |
| Workspace (`workspaces/<name>.toml`) | `v1alpha5`  | Automatic on startup | <RepoFile path="crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha5/meta.toml">crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha5/meta.toml</RepoFile> |

**Summary**: adds the optional `sync_source_dir` field to `AgentAuthConfig` for per-scope auth-sync source folders. This is an additive, `Option`-typed field with a `serde` default of `None`, so all existing config and workspace files round-trip cleanly through the migration without any transformation. The migration is a no-op restamp.

When `sync_source_dir` is set, the `sync` auth mode copies credentials from the operator-chosen agent credential/config folder instead of the per-agent hardcoded default (`~/.claude`, `~/.codex`, `~/.local/share/amp`, `~/.kimi-code`, `~/.local/share/opencode`). For Amp, that folder is the `amp` directory under `XDG_DATA_HOME`, not `XDG_DATA_HOME` itself. Absence means "inherit from the next lower layer → hardcoded default." The field is resolved by `jackin_config::resolve_sync_source_dir(cfg, agent, workspace, role)` — the same three-layer precedence as `resolve_mode`.

**Before** (v1alpha5 config with Claude sync mode):

```toml
version = "v1alpha5"

[claude]
auth_forward = "sync"
```

**After** (v1alpha6 — no change needed; sync\_source\_dir defaults to None):

```toml
version = "v1alpha6"

[claude]
auth_forward = "sync"
```

**Example with explicit source folder** (operator sets a company-specific folder):

```toml
version = "v1alpha6"

[claude]
auth_forward = "sync"
sync_source_dir = "/Users/alice/company/.claude"
```

### Workspace `v1alpha5` — 2026-05-26 [#workspace-v1alpha5--2026-05-26]

| File kind                            | Predecessor | Migration mode       | Fixture                                                                                                                                                                         |
| ------------------------------------ | ----------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Workspace (`workspaces/<name>.toml`) | `v1alpha4`  | Automatic on startup | <RepoFile path="crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha4/meta.toml">crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha4/meta.toml</RepoFile> |

**Summary**: moves the workspace-level `op_account` onto each `op://` env reference as a per-ref `account` key, then removes the top-level `op_account`. A workspace can hold references from different 1Password accounts; a single workspace-level account cannot serve them, so a reference whose vault lives in a non-default account previously failed to resolve. Each reference now records the account it was created under, and reads pin to it. The migration walks `[env]`, every `[roles.<role>.env]`, `[github.env]`, and every `[roles.<role>.github.env]` table, stamping `account` onto each op reference; plain string values are untouched. A workspace with no `op_account` is a no-op restamp.

**Before** (v1alpha4 workspace):

```toml
version = "v1alpha4"
workdir = "/workspace/prod"
op_account = "ACCT123"

[env]
CLAUDE_CODE_OAUTH_TOKEN = { op = "op://v/i/f", path = "Vault/Item/Field" }
PLAIN_ENV = "literal-value"
```

**After** (v1alpha5):

```toml
version = "v1alpha5"
workdir = "/workspace/prod"

[env]
CLAUDE_CODE_OAUTH_TOKEN = { op = "op://v/i/f", path = "Vault/Item/Field", account = "ACCT123" }
PLAIN_ENV = "literal-value"
```

### Config `v1alpha5` — 2026-05-17 [#config-v1alpha5--2026-05-17]

| File kind              | Predecessor | Migration mode       | Fixture                                                                                                                                                                   |
| ---------------------- | ----------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Config (`config.toml`) | `v1alpha4`  | Automatic on startup | <RepoFile path="crates/jackin/tests/fixtures/migrations/config/from-v1alpha4/meta.toml">crates/jackin/tests/fixtures/migrations/config/from-v1alpha4/meta.toml</RepoFile> |

**Summary**: Introduces the `[git]` table with two independent boolean fields (both default `false`): `coauthor_trailer` enables `Co-authored-by` agent trailer injection, and `dco` enables `Signed-off-by` DCO injection. When either flag is enabled, jackin installs a `prepare-commit-msg` hook inside containers via `core.hooksPath`; each trailer is injected only when its corresponding flag is set, and both are deduplicated. The migration is a no-op restamp.

**Before** (v1alpha4 config):

```toml
version = "v1alpha4"

[roles.the-architect]
git = "https://github.com/jackin-project/jackin-the-architect.git"
trusted = true
```

**After** (v1alpha5):

```toml
version = "v1alpha5"

[roles.the-architect]
git = "https://github.com/jackin-project/jackin-the-architect.git"
trusted = true
```

### `v1alpha4` — 2026-05-17 [#v1alpha4--2026-05-17]

| File kind                            | Predecessor | Migration mode                                                                                         | Fixture                                                                                                                                                                         |
| ------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Config (`config.toml`)               | `v1alpha3`  | Automatic on startup                                                                                   | <RepoFile path="crates/jackin/tests/fixtures/migrations/config/from-v1alpha3/meta.toml">crates/jackin/tests/fixtures/migrations/config/from-v1alpha3/meta.toml</RepoFile>       |
| Workspace (`workspaces/<name>.toml`) | `v1alpha3`  | Automatic on startup                                                                                   | <RepoFile path="crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha3/meta.toml">crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha3/meta.toml</RepoFile> |
| Manifest (`jackin.role.toml`)        | `v1alpha3`  | Desktop: `jackin role migrate <role-repo-path>`; CI/automation: `jackin-role migrate <role-repo-path>` | <RepoFile path="crates/jackin/tests/fixtures/migrations/manifest/from-v1alpha3/meta.toml">crates/jackin/tests/fixtures/migrations/manifest/from-v1alpha3/meta.toml</RepoFile>   |

**Summary**: formalizes Kimi agent support after `v1alpha3` shipped with OpenCode. The `kimi` enum variant in `agents`, the `[kimi]` manifest table, and the `[kimi]` auth config tables require `v1alpha4`; older-stamped files still load as long as they do not use Kimi-specific fields. The migration is a no-op restamp: no field renames, no data moved.

**Before** (v1alpha3 manifest with Kimi):

```toml
version = "v1alpha3"
dockerfile = "Dockerfile"
agents = ["claude", "kimi", "opencode"]

[claude]
plugins = []

[kimi]
model = "kimi-k2"

[opencode]
model = "zai-coding-plan/glm-5.1"
```

**After** (v1alpha4):

```toml
version = "v1alpha4"
dockerfile = "Dockerfile"
agents = ["claude", "kimi", "opencode"]

[claude]
plugins = []

[kimi]
model = "kimi-k2"

[opencode]
model = "zai-coding-plan/glm-5.1"
```

### `v1alpha3` — 2026-05-14 [#v1alpha3--2026-05-14]

| File kind                            | Predecessor | Migration mode                                                                                         | Fixture                                                                                                                                                                         |
| ------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Config (`config.toml`)               | `v1alpha2`  | Automatic on startup                                                                                   | <RepoFile path="crates/jackin/tests/fixtures/migrations/config/from-v1alpha2/meta.toml">crates/jackin/tests/fixtures/migrations/config/from-v1alpha2/meta.toml</RepoFile>       |
| Workspace (`workspaces/<name>.toml`) | `v1alpha2`  | Automatic on startup                                                                                   | <RepoFile path="crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha2/meta.toml">crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha2/meta.toml</RepoFile> |
| Manifest (`jackin.role.toml`)        | `v1alpha2`  | Desktop: `jackin role migrate <role-repo-path>`; CI/automation: `jackin-role migrate <role-repo-path>` | <RepoFile path="crates/jackin/tests/fixtures/migrations/manifest/from-v1alpha2/meta.toml">crates/jackin/tests/fixtures/migrations/manifest/from-v1alpha2/meta.toml</RepoFile>   |

**Summary**: formalizes OpenCode agent support. The `opencode` enum variant in `agents`, the `[opencode]` manifest table, and the `[opencode]` auth config tables require `v1alpha3`; older-stamped files still load as long as they do not use OpenCode-specific fields. The migration is a no-op restamp: no field renames, no data moved.

**Before** (v1alpha2 manifest with OpenCode):

```toml
version = "v1alpha2"
dockerfile = "Dockerfile"
agents = ["claude", "opencode"]

[claude]
plugins = []

[opencode]
model = "zai-coding-plan/glm-5.1"
```

**After** (v1alpha3):

```toml
version = "v1alpha3"
dockerfile = "Dockerfile"
agents = ["claude", "opencode"]

[claude]
plugins = []

[opencode]
model = "zai-coding-plan/glm-5.1"
```

### `v1alpha2` — 2026-05-11 [#v1alpha2--2026-05-11]

| File kind                            | Predecessor | Migration mode                                                                                         | Fixture                                                                                                                                                                         |
| ------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Config (`config.toml`)               | `v1alpha1`  | Automatic on startup                                                                                   | <RepoFile path="crates/jackin/tests/fixtures/migrations/config/from-v1alpha1/meta.toml">crates/jackin/tests/fixtures/migrations/config/from-v1alpha1/meta.toml</RepoFile>       |
| Workspace (`workspaces/<name>.toml`) | `v1alpha1`  | Automatic on startup                                                                                   | <RepoFile path="crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha1/meta.toml">crates/jackin/tests/fixtures/migrations/workspace/from-v1alpha1/meta.toml</RepoFile> |
| Manifest (`jackin.role.toml`)        | `v1alpha1`  | Desktop: `jackin role migrate <role-repo-path>`; CI/automation: `jackin-role migrate <role-repo-path>` | <RepoFile path="crates/jackin/tests/fixtures/migrations/manifest/from-v1alpha1/meta.toml">crates/jackin/tests/fixtures/migrations/manifest/from-v1alpha1/meta.toml</RepoFile>   |

**Summary**: restamps existing `v1alpha1` files as `v1alpha2` and moves `version = "v1alpha2"` to the first line. This is intentionally a sequential migration rather than a silent rewrite of `v1alpha1`: operators already have `v1alpha1` files where the version key may sit below other top-level keys.

**Before** (v1alpha1 workspace file — excerpt):

```toml
workdir = "/workspace/prod"
allowed_roles = ["the-architect"]
last_role = "the-architect"
version = "v1alpha1"
```

**After** (v1alpha2):

```toml
version = "v1alpha2"
workdir = "/workspace/prod"
allowed_roles = ["the-architect"]
last_role = "the-architect"
```

### `v1alpha1` — 2026-05-10 [#v1alpha1--2026-05-10]

| File kind                            | Predecessor | Migration mode                                                                                         | Fixture                                                                                                                                                                     |
| ------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Config (`config.toml`)               | `legacy`    | Automatic on startup                                                                                   | <RepoFile path="crates/jackin/tests/fixtures/migrations/config/from-legacy/meta.toml">crates/jackin/tests/fixtures/migrations/config/from-legacy/meta.toml</RepoFile>       |
| Workspace (`workspaces/<name>.toml`) | `legacy`    | Automatic on startup                                                                                   | <RepoFile path="crates/jackin/tests/fixtures/migrations/workspace/from-legacy/meta.toml">crates/jackin/tests/fixtures/migrations/workspace/from-legacy/meta.toml</RepoFile> |
| Manifest (`jackin.role.toml`)        | `legacy`    | Desktop: `jackin role migrate <role-repo-path>`; CI/automation: `jackin-role migrate <role-repo-path>` | <RepoFile path="crates/jackin/tests/fixtures/migrations/manifest/from-legacy/meta.toml">crates/jackin/tests/fixtures/migrations/manifest/from-legacy/meta.toml</RepoFile>   |

**Summary**: introduces the top-level `version` field. The migration adds `version = "v1alpha1"` to every file kind and leaves all existing keys, comments, and section ordering untouched. Splitting legacy `[workspaces.<name>]` tables out of `config.toml` runs as a separate startup step (see [Configuration File](/reference/runtime/configuration/#one-file-per-workspace-by-design)); the version migration above is independent of that split.

**Before** (legacy operator config — excerpt):

```toml
[roles.agent-smith]
git = "https://github.com/jackin-project/jackin-agent-smith.git"
trusted = true
```

**After** (v1alpha1):

```toml
version = "v1alpha1"

[roles.agent-smith]
git = "https://github.com/jackin-project/jackin-agent-smith.git"
trusted = true
```

## Version format [#version-format]

Schema versions use Kubernetes-style names:

| Form       | Meaning                                           |
| ---------- | ------------------------------------------------- |
| `v1alpha1` | Unstable schema for the future stable `v1` family |
| `v1alpha2` | Next unstable schema in the same family           |
| `v1beta1`  | More mature but still not stable                  |
| `v1`       | Stable schema                                     |

The current project is still unstable, so all current schemas use the `v1alpha*` family.

## `config.toml` [#configtoml]

### `legacy` [#legacy]

`legacy` means the file has no top-level `version` field. For operator
config, jackin migrates this automatically before parsing.

| Change to `v1alpha1` | Detail                                                           |
| -------------------- | ---------------------------------------------------------------- |
| Added                | `version = "v1alpha1"`                                           |
| Preserved            | Global agent auth, GitHub auth, env, role sources, Docker mounts |
| Removed              | None                                                             |
| Renamed              | None                                                             |

The split-from-`config.toml` work for legacy `[workspaces.<name>]` tables runs as a separate startup migration alongside the version stamp; see [Configuration File](/reference/runtime/configuration/#one-file-per-workspace-by-design).

### `v1alpha6` [#v1alpha6]

| Field                        | Type   | Required                  | Since      | Notes                                                                                     |
| ---------------------------- | ------ | ------------------------- | ---------- | ----------------------------------------------------------------------------------------- |
| `version`                    | string | Yes                       | `v1alpha1` | Current value: `v1alpha6`                                                                 |
| `[claude].auth_forward`      | string | No                        | `legacy`   | `sync`, `api_key`, `oauth_token`, or `ignore`                                             |
| `[claude].sync_source_dir`   | string | No                        | `v1alpha6` | Host folder override for `sync` auth forwarding; omitted means use the per-agent default  |
| `[codex].auth_forward`       | string | No                        | `legacy`   | `sync`, `api_key`, or `ignore`                                                            |
| `[codex].sync_source_dir`    | string | No                        | `v1alpha6` | Host folder override for `sync` auth forwarding; omitted means use the per-agent default  |
| `[amp].auth_forward`         | string | No                        | `legacy`   | `sync`, `api_key`, or `ignore`                                                            |
| `[amp].sync_source_dir`      | string | No                        | `v1alpha6` | Host folder override for `sync` auth forwarding; omitted means use the per-agent default  |
| `[kimi].auth_forward`        | string | No                        | `v1alpha4` | `sync`, `api_key`, or `ignore`                                                            |
| `[kimi].sync_source_dir`     | string | No                        | `v1alpha6` | Host folder override for `sync` auth forwarding; omitted means use the per-agent default  |
| `[opencode].auth_forward`    | string | No                        | `v1alpha3` | `sync`, `api_key`, or `ignore`                                                            |
| `[opencode].sync_source_dir` | string | No                        | `v1alpha6` | Host folder override for `sync` auth forwarding; omitted means use the per-agent default  |
| `[github].auth_forward`      | string | No                        | `legacy`   | `sync`, `token`, or `ignore`                                                              |
| `[github.env]`               | table  | No                        | `legacy`   | Operator env values for GitHub token auth                                                 |
| `[env]`                      | table  | No                        | `legacy`   | Global operator env layer                                                                 |
| `[roles.<role>]`             | table  | No                        | `legacy`   | Role source config                                                                        |
| `[roles.<role>].git`         | string | Yes when role is declared | `legacy`   | Role repository URL                                                                       |
| `[roles.<role>].trusted`     | bool   | No                        | `legacy`   | Trust-on-first-use state                                                                  |
| `[roles.<role>.env]`         | table  | No                        | `legacy`   | Per-role operator env layer                                                               |
| `[docker.mounts]`            | table  | No                        | `legacy`   | Global and scoped Docker mount config                                                     |
| `[git].coauthor_trailer`     | bool   | No                        | `v1alpha5` | Enable `Co-authored-by` agent trailer via `prepare-commit-msg` hook; omitted when `false` |
| `[git].dco`                  | bool   | No                        | `v1alpha5` | Enable `Signed-off-by` DCO trailer via `prepare-commit-msg` hook; omitted when `false`    |
| `[workspaces]`               | table  | No                        | `legacy`   | Legacy read-only compatibility location; migrated into workspace files                    |

Full operator configuration examples live in
[Configuration File](/reference/runtime/configuration/).

## Workspace files [#workspace-files]

Workspace files live at `~/.config/jackin/workspaces/<name>.toml`.

### `legacy` [#legacy-1]

`legacy` means either a standalone workspace file with no `version`, or
a `[workspaces.<name>]` table embedded in legacy `config.toml`.

| Change to `v1alpha1` | Detail                                                                              |
| -------------------- | ----------------------------------------------------------------------------------- |
| Added                | `version = "v1alpha1"`                                                              |
| Preserved            | Workdir, mounts, role selection, env, auth overrides, keep-awake, 1Password account |
| Removed              | None                                                                                |
| Renamed              | None                                                                                |

Legacy embedded `[workspaces.<name>]` tables in `config.toml` are split into per-workspace files by a separate startup migration; see [Configuration File](/reference/runtime/configuration/#one-file-per-workspace-by-design).

### `v1alpha6` [#v1alpha6-1]

| Field                                     | Type            | Required | Since      | Notes                                                                                                                                            |
| ----------------------------------------- | --------------- | -------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `version`                                 | string          | Yes      | `v1alpha1` | Current value: `v1alpha6`                                                                                                                        |
| `workdir`                                 | string          | Yes      | `legacy`   | Container working directory                                                                                                                      |
| `allowed_roles`                           | string array    | No       | `legacy`   | Roles allowed in this workspace                                                                                                                  |
| `default_role`                            | string          | No       | `legacy`   | Preferred role for new sessions                                                                                                                  |
| `default_agent`                           | string          | No       | `legacy`   | `claude`, `codex`, `amp`, `kimi`, or `opencode`; omitted lets launch resolution use the role manifest or prompt                                  |
| `last_role`                               | string          | No       | `legacy`   | Last role selected by the operator                                                                                                               |
| `git_pull_on_entry`                       | bool            | No       | `legacy`   | Pull mounted repositories on entry                                                                                                               |
| `[env]`                                   | table           | No       | `legacy`   | Workspace operator env layer; each `op://` reference carries an optional `account` (the 1Password account it resolves against), since `v1alpha5` |
| `[[mounts]]`                              | array of tables | No       | `legacy`   | Workspace mounts                                                                                                                                 |
| `[[mounts]].src`                          | string          | Yes      | `legacy`   | Host path                                                                                                                                        |
| `[[mounts]].dst`                          | string          | Yes      | `legacy`   | Container path                                                                                                                                   |
| `[[mounts]].readonly`                     | bool            | No       | `legacy`   | Defaults to `false`                                                                                                                              |
| `[[mounts]].isolation`                    | string          | No       | `legacy`   | `shared`, `worktree`, or `clone`; legacy default is `shared`                                                                                     |
| `[keep_awake].enabled`                    | bool            | No       | `legacy`   | macOS keep-awake toggle                                                                                                                          |
| `[claude].auth_forward`                   | string          | No       | `legacy`   | Workspace Claude auth override                                                                                                                   |
| `[claude].sync_source_dir`                | string          | No       | `v1alpha6` | Workspace Claude host folder override for `sync` auth forwarding                                                                                 |
| `[codex].auth_forward`                    | string          | No       | `legacy`   | Workspace Codex auth override                                                                                                                    |
| `[codex].sync_source_dir`                 | string          | No       | `v1alpha6` | Workspace Codex host folder override for `sync` auth forwarding                                                                                  |
| `[amp].auth_forward`                      | string          | No       | `legacy`   | Workspace Amp auth override                                                                                                                      |
| `[amp].sync_source_dir`                   | string          | No       | `v1alpha6` | Workspace Amp host folder override for `sync` auth forwarding                                                                                    |
| `[kimi].auth_forward`                     | string          | No       | `v1alpha4` | Workspace Kimi auth override                                                                                                                     |
| `[kimi].sync_source_dir`                  | string          | No       | `v1alpha6` | Workspace Kimi host folder override for `sync` auth forwarding                                                                                   |
| `[opencode].auth_forward`                 | string          | No       | `v1alpha3` | Workspace OpenCode auth override                                                                                                                 |
| `[opencode].sync_source_dir`              | string          | No       | `v1alpha6` | Workspace OpenCode host folder override for `sync` auth forwarding                                                                               |
| `[github].auth_forward`                   | string          | No       | `legacy`   | Workspace GitHub auth override                                                                                                                   |
| `[github.env]`                            | table           | No       | `legacy`   | Workspace GitHub token env values; `op://` references carry the per-ref `account` since `v1alpha5`                                               |
| `[roles.<role>.env]`                      | table           | No       | `legacy`   | Per-workspace, per-role env override; `op://` references carry the per-ref `account` since `v1alpha5`                                            |
| `[roles.<role>.claude].auth_forward`      | string          | No       | `legacy`   | Per-workspace, per-role Claude auth override                                                                                                     |
| `[roles.<role>.claude].sync_source_dir`   | string          | No       | `v1alpha6` | Per-workspace, per-role Claude host folder override for `sync` auth forwarding                                                                   |
| `[roles.<role>.codex].auth_forward`       | string          | No       | `legacy`   | Per-workspace, per-role Codex auth override                                                                                                      |
| `[roles.<role>.codex].sync_source_dir`    | string          | No       | `v1alpha6` | Per-workspace, per-role Codex host folder override for `sync` auth forwarding                                                                    |
| `[roles.<role>.amp].auth_forward`         | string          | No       | `legacy`   | Per-workspace, per-role Amp auth override                                                                                                        |
| `[roles.<role>.amp].sync_source_dir`      | string          | No       | `v1alpha6` | Per-workspace, per-role Amp host folder override for `sync` auth forwarding                                                                      |
| `[roles.<role>.kimi].auth_forward`        | string          | No       | `v1alpha4` | Per-workspace, per-role Kimi auth override                                                                                                       |
| `[roles.<role>.kimi].sync_source_dir`     | string          | No       | `v1alpha6` | Per-workspace, per-role Kimi host folder override for `sync` auth forwarding                                                                     |
| `[roles.<role>.opencode].auth_forward`    | string          | No       | `v1alpha3` | Per-workspace, per-role OpenCode auth override                                                                                                   |
| `[roles.<role>.opencode].sync_source_dir` | string          | No       | `v1alpha6` | Per-workspace, per-role OpenCode host folder override for `sync` auth forwarding                                                                 |
| `[roles.<role>.github].auth_forward`      | string          | No       | `legacy`   | Per-workspace, per-role GitHub auth override                                                                                                     |
| `[roles.<role>.github.env]`               | table           | No       | `legacy`   | Per-workspace, per-role GitHub token env values; `op://` references carry the per-ref `account` since `v1alpha5`                                 |

## `jackin.role.toml` [#jackinroletoml]

### `legacy` [#legacy-2]

`legacy` means the manifest has no top-level `version` field. jackin'
does not auto-write role repositories during normal role loading. Run
`jackin role migrate <role-repo-path>` to rewrite a local copy on a
desktop, or `jackin-role migrate <role-repo-path>` in CI and
automated migration jobs.

| Change to `v1alpha1` | Detail                                                                              |
| -------------------- | ----------------------------------------------------------------------------------- |
| Added                | `version = "v1alpha1"`                                                              |
| Moved                | None                                                                                |
| Preserved            | Dockerfile, published image, identity, agents, runtime settings, hooks, env prompts |
| Removed              | None                                                                                |
| Renamed              | None                                                                                |

### `v1alpha4` [#v1alpha4]

| Field                            | Type            | Required | Since      | Notes                                                                                                                     |
| -------------------------------- | --------------- | -------- | ---------- | ------------------------------------------------------------------------------------------------------------------------- |
| `version`                        | string          | Yes      | `v1alpha1` | Current value: `v1alpha4`                                                                                                 |
| `dockerfile`                     | string          | Yes      | `legacy`   | Relative path to role Dockerfile                                                                                          |
| `published_image`                | string          | No       | `legacy`   | Pre-built role image override                                                                                             |
| `agents`                         | string array    | No       | `legacy`   | `claude`, `codex`, or `amp`; `opencode` added in `v1alpha3`; `kimi` added in `v1alpha4`; omitted means Claude-only        |
| `[identity].name`                | string          | No       | `legacy`   | Display name                                                                                                              |
| `[claude].model`                 | string          | No       | `legacy`   | Claude model override                                                                                                     |
| `[claude].plugins`               | string array    | No       | `legacy`   | Claude plugin identifiers                                                                                                 |
| `[[claude.marketplaces]]`        | array of tables | No       | `legacy`   | Claude plugin marketplace registrations                                                                                   |
| `[[claude.marketplaces]].source` | string          | Yes      | `legacy`   | Marketplace source                                                                                                        |
| `[[claude.marketplaces]].sparse` | string array    | No       | `legacy`   | Sparse checkout paths                                                                                                     |
| `[codex].model`                  | string          | No       | `legacy`   | Codex model override                                                                                                      |
| `[amp]`                          | table           | No       | `legacy`   | Empty marker table for Amp support                                                                                        |
| `[kimi].model`                   | string          | No       | `v1alpha4` | Kimi model override passed to `kimi --model`                                                                              |
| `[opencode].model`               | string          | No       | `v1alpha3` | `OpenCode` model override in `provider/model` format (e.g. `zai-coding-plan/glm-5.1`)                                     |
| `[hooks].setup_once`             | string          | No       | `legacy`   | Relative path to a one-time install script that runs on first launch only                                                 |
| `[hooks].source`                 | string          | No       | `legacy`   | Relative path to a script dot-sourced into the entrypoint shell so `export` and `PATH` mutations reach the launched agent |
| `[hooks].preflight`              | string          | No       | `legacy`   | Relative path to a per-start preflight script                                                                             |
| `[env.<NAME>]`                   | table           | No       | `legacy`   | Interactive env prompt declaration                                                                                        |
| `[env.<NAME>].default`           | string          | No       | `legacy`   | Default env value                                                                                                         |
| `[env.<NAME>].interactive`       | bool            | No       | `legacy`   | Prompt operator before launch                                                                                             |
| `[env.<NAME>].skippable`         | bool            | No       | `legacy`   | Allow empty response                                                                                                      |
| `[env.<NAME>].prompt`            | string          | No       | `legacy`   | Prompt text                                                                                                               |
| `[env.<NAME>].options`           | string array    | No       | `legacy`   | Fixed choices                                                                                                             |
| `[env.<NAME>].depends_on`        | string array    | No       | `legacy`   | Dependency references such as `env.PROJECT`                                                                               |

Full role manifest examples live in
[Role Manifest](/developing/role-manifest/).

## Migration retention [#migration-retention]

jackin' does not keep every migration forever. If a file is too old and
the current binary no longer includes the full path to the current
schema, jackin' errors and tells the operator to upgrade through an older
jackin' first.

Migration entry points:

| File kind     | Code entry point                                                                                              |
| ------------- | ------------------------------------------------------------------------------------------------------------- |
| Config        | <RepoFile path="crates/jackin-config/src/migrations.rs">crates/jackin-config/src/migrations.rs</RepoFile>     |
| Workspace     | <RepoFile path="crates/jackin-config/src/migrations.rs">crates/jackin-config/src/migrations.rs</RepoFile>     |
| Role manifest | <RepoFile path="crates/jackin-manifest/src/migrations.rs">crates/jackin-manifest/src/migrations.rs</RepoFile> |
