> ## Documentation Index
> Fetch the complete documentation index at: https://xspec.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Managing xspec Workspace Files with Git

> Understand which xspec output files are derived vs durable, what to commit, how to configure .gitignore, and how staleness detection works.

Every file that xspec writes has deterministic bytes — stable ordering, sorted keys, no timestamps, no absolute paths. This means derived files are safe to commit (they diff cleanly), safe to regenerate (rebuilding produces the same result), and safe to check for staleness in CI. Understanding the distinction between **derived** and **durable** files tells you what you must commit and what you may optionally regenerate.

## File inventory

For a source file at `specs/AUTH.mdx`, xspec produces the following files:

| Path                             | What it contains                                                                       | Class       |
| -------------------------------- | -------------------------------------------------------------------------------------- | ----------- |
| `specs/AUTH.xspec.ts`            | Generated TypeScript module                                                            | Derived     |
| `specs/AUTH.xspec.impl.js`       | Runtime implementation                                                                 | Derived     |
| `specs/AUTH.xspec.impl.d.ts`     | Types and hover documentation                                                          | Derived     |
| `specs/AUTH.xspec.impl.d.ts.map` | Declaration map (go-to-definition into `.mdx`)                                         | Derived     |
| `specs/AUTH.md`                  | Pure Markdown (only emitted when `markdown.emit` is enabled)                           | Derived     |
| `.xspec/graph.json`              | Graph data used by `check`, `ids`, `show`, `coverage`, `impact`, `review`, and `query` | Derived     |
| `.xspec/journal`                 | Identity journal for `rename` and `move`                                               | **Durable** |
| `.xspec/reviews/<name>.json`     | Review sessions                                                                        | **Durable** |

## Derived vs durable

**Derived files** are fully reproducible from your source MDX files, your xspec configuration, and the journal. If a derived file is missing, corrupted, or stale, run `xspec build` to regenerate it. You can always trust a rebuild to produce the same bytes for the same inputs.

**Durable files** are written only by specific xspec commands (`xspec rename`, `xspec move` for the journal; `xspec review create`, `xspec review resolve`, etc. for sessions). They are never regenerated and must not be modified by hand. If a durable file is lost or corrupted, you must restore it from version control — there is no rebuild path.

## What to commit

### Journal and review sessions — non-negotiable

The journal (`.xspec/journal`) maps old node identities to new ones. Losing it breaks baseline comparisons for every consumer of your repository. Review sessions record work in progress that cannot be reconstructed. Both must be committed without exception.

<Warning>
  Do **not** add `.xspec/` to `.gitignore` wholesale. Doing so would ignore the journal and review sessions, silently destroying identity continuity and review history.
</Warning>

### Generated TypeScript modules and companions

The generated TypeScript module (`*.xspec.ts`) and its companion files (`*.xspec.impl.js`, `*.xspec.impl.d.ts`, `*.xspec.impl.d.ts.map`) are what downstream consumers import. Committing them means consumers can resolve `./NAME.xspec` without running xspec themselves.

Running `xspec check` in CI proves that committed generated files match current sources. This gives you a clean two-step: commit the files, verify they are up to date in CI.

### Emitted Markdown and graph.json

You have two options for `specs/**/*.md` and `.xspec/graph.json`:

* **Commit them** — the same reasoning applies as for generated modules. Consumers and tooling can use them without a build step, and `xspec check` validates staleness.
* **Ignore them and rebuild in CI** — add them to `.gitignore` and run `xspec build` as the first CI step before `xspec check`. This keeps the repository smaller at the cost of a build step on every CI run.

Both approaches are correct. Choose based on your team's preference for repository size vs CI simplicity.

## `.gitignore` for the regenerate-in-CI policy

If you choose to regenerate derived files in CI rather than committing them, use this pattern:

```gitignore theme={null}
# Derived files — rebuilt by `xspec build` in CI
# IMPORTANT: do NOT ignore .xspec/ wholesale — journal and reviews are durable
*.xspec.*
specs/**/*.md
.xspec/graph.json
```

<Note>
  The pattern `*.xspec.*` matches the TypeScript module and all companion files. It does **not** match `.xspec/journal` or `.xspec/reviews/` because those paths do not contain `.xspec.` with a trailing dot.
</Note>

## Staleness detection

`xspec check` compares each derived file against what `xspec build` would produce for the current sources. A stale file produces an error like:

```
specs/AUTH.xspec.ts: stale generated output (14.10): … run `xspec build` to regenerate
```

The version number in parentheses (`14.10`) identifies the xspec version that generated the file, which helps diagnose staleness caused by an xspec upgrade rather than a source edit.

<Tip>
  In CI, run `xspec build && xspec check` as a single gate. This catches both missing files (not yet generated) and stale files (generated from an older version of sources).
</Tip>

## Filesystem behavior

A few properties of xspec's file I/O are worth knowing when integrating with other tooling:

* **Writes are atomic in effect.** A partial write will not leave a file in an inconsistent state.
* **Mutating commands are mutually exclusive per workspace.** Two xspec processes cannot run simultaneous mutations in the same workspace directory.
* **Symlinks are never followed** during file discovery or when writing output. xspec operates only on real files at their canonical paths.
* **No network access.** xspec reads from git only where the documentation explicitly states it does (e.g., `xspec impact --base`), and never writes to git.
