Skip to content

openlogos ignore / exempt

Two commands decide what the write guard protects on a launched project:

  • openlogos ignore manages paths that should not go into version control — dependency folders, build output, caches. It maintains guard.unversioned in logos/logos.config.json and renders those entries into the OpenLogos managed block of .gitignore. Because git then ignores them, the guard no longer protects them.
  • openlogos exempt manages committed paths that need no change proposal. It maintains guard.exempt in logos/logos.config.json. Files under these paths are still tracked and committed normally; writing them just doesn’t require openlogos change.
Terminal window
openlogos ignore add <pattern...>
openlogos ignore remove <pattern...>
openlogos ignore list [--format json]
openlogos exempt add <path...>
openlogos exempt remove <path...>
openlogos exempt list [--format json]

Run them from the project root (the directory that contains logos/logos.config.json).

openlogos ignoreopenlogos exempt
Config fieldguard.unversionedguard.exempt
Effect on gitWritten to the .gitignore managed block — the paths stop being versionedNone — the paths stay tracked and committed
Effect on the guardIgnored, untracked paths are not protectedWrites under these paths need no proposal
Typical usenode_modules/, dist/, .cache/, generated reportsReference material, scratch docs you still want in git
Built-in defaultAlways contains logos/.openlogos-runtime/ (fixed)logos/resources/reference/ and logos/resources/verify/baseline-seed-runs/*/staging/

Approval: add and remove need the host’s native prompt

Section titled “Approval: add and remove need the host’s native prompt”

add and remove change what the guard protects. When an AI runs them, the guard treats them as restricted commands in every lifecycle and proposal state:

  • They must be a standalone call (a cd <dir> && prefix is allowed). Combined with any other command, they are blocked.
  • Claude Code, permission mode default or acceptEdits: the host shows its own approval prompt for that exact call; the command runs only if you approve.
  • Other permission modes (bypassPermissions, dontAsk, auto, plan) or non-interactive runs: the call is blocked, because the host would not prompt. Run it yourself — in Claude Code type ! openlogos ignore add dist/ — or switch to the default permission mode and retry.
  • Cursor: beforeShellExecution asks for approval; if the host cannot guarantee a prompt, the call is denied.
  • ZCode, Qoder, and WorkBuddy have no native approval wired; run the command in your own terminal.

Agreement typed in the chat never counts as approval, and openlogos next --auto does not cover these commands. The CLI itself does not prompt: run in your own terminal, it simply executes.

list is read-only and never restricted.

  1. All patterns are validated first. If any one is invalid, nothing is written.
  2. guard.unversioned in logos/logos.config.json is updated.
  3. The .gitignore managed block is re-rendered (the file is created if it does not exist). Content outside the block is never changed. If writing .gitignore fails, the config change is rolled back.
  4. After add, if files that are already tracked match a new pattern, they are listed. They stay in version control and remain protected. openlogos never runs git rm for you; it prints the command to run yourself:
⚠ 2 tracked file(s) match "dist/". They stay in version control and remain protected by guard:
dist/app.js
dist/app.css
To stop tracking them, run this yourself (openlogos does not run it):
git --literal-pathspecs rm --cached -- 'dist/app.js' 'dist/app.css'

With more than 20 matching files, the full list is written to logos/.openlogos-runtime/untrack-<timestamp>.lst and the printed command reads it with --pathspec-from-file.

The managed block looks like this:

# >>> openlogos managed >>>
# 由 openlogos 维护,请用 `openlogos ignore` 修改;区块外内容不会被改动
logos/.openlogos-runtime/
dist/
# <<< openlogos managed <<<

logos/.openlogos-runtime/ is a fixed entry: adding it is a no-op, removing it is an error. Outside a git repository, ignore add still writes the config and block, and notes that the guard’s version-control criterion is not in effect.

Pattern rules: standard .gitignore patterns, one per argument; not empty, single line, no NUL, must not start with # or !, and must not contain a .. segment.

  1. All paths are validated first; any invalid one means nothing is written.
  2. If guard.exempt is absent, the built-in defaults are first written out as an explicit list so they can be edited.
  3. guard.exempt is updated. Removing every entry writes an explicit empty list [], which also turns the built-in defaults off.

Path rules:

  • project-relative, / as separator;
  • a trailing / means the directory itself and everything below it; without it, the entry matches that one file;
  • * must take a whole path segment and matches exactly one segment (e.g. logos/resources/verify/baseline-seed-runs/*/staging/);
  • rejected: empty, /, a lone *, absolute paths, . / .. / empty segments, \.

exempt add rejects, and the guard ignores, any entry that would release:

  • any .gitignore (at any level);
  • .git/ or anything under it (including .git/info/exclude);
  • logos/logos.config.json;
  • logos/.openlogos-runtime/ (guard’s own state).

These stay protected even inside an exempt directory: exempting docs/ does not exempt docs/.gitignore.

Prints the current entries. For exempt, built-in defaults that have not been written to the config are marked (default).

$ openlogos exempt list
Exempt from change proposals (guard.exempt):
logos/resources/reference/ (default)
logos/resources/verify/baseline-seed-runs/*/staging/ (default)

With --format json, the output is a JSON envelope; each entry has a value and a source (config or default):

{
"command": "exempt list",
"version": "0.16.0",
"timestamp": "2026-10-10T08:00:00.000Z",
"data": {
"entries": [
{ "value": "logos/resources/reference/", "source": "default" },
{ "value": "logos/resources/verify/baseline-seed-runs/*/staging/", "source": "default" }
]
}
}

ignore list --format json has the same shape; its entries always have source: "config".

Terminal window
# Keep build output out of version control
openlogos ignore add dist/ coverage/
# Stop ignoring a path again
openlogos ignore remove coverage/
# Let the AI edit a scratch folder without opening a proposal (still committed)
openlogos exempt add docs/notes/
# Inspect the current scope
openlogos ignore list
openlogos exempt list --format json

All errors exit with code 1 and write nothing.

ErrorCauseFix
logos/logos.config.json not found.Not in the project root, or not initializedcd to the project root, or run openlogos init
logos/logos.config.json is not valid JSONConfig file is brokenFix the JSON by hand
guard.<field> contains an invalid entryAn existing entry in the config is invalidFix or remove that entry by hand
Invalid ignore pattern / Invalid exempt pathAn argument breaks the rules aboveCorrect the argument
Missing pattern. / Missing path.add / remove without argumentsPass at least one value
The openlogos managed block in .gitignore is corruptedMarkers of the managed block were editedRepair the block markers by hand
Failed to write <file> … Changes were rolled back.Disk write failedCheck permissions and retry