---
id: "0027"
date: 2026-07-12
status: Accepted
supersedes:
superseded-by:
affected-paths: []
affected-components: []
migration_confidence: medium
migration_source: "docs/memory-system/03-architecture-decisions.md### ADR-027 — All cc-os per-project state lives under `.cc-os/<plugin>/`"
---

# 0027 — All cc-os per-project state lives under `.cc-os/<plugin>/`

## Context

The credvault smoke-test of `/os-status:fix` (issue #21) surfaced per-project dotfile sprawl: `.cc-os/` (os-status config/snoozes/state, os-backlog tracker key), `.dochygiene/` (os-doc-hygiene state), a planned `.os-adr/`, plus non-cc-os dirs (`.claude/`, `graphify-out/`). Each cc-os plugin inventing its own root-level dotdir means N gitignore entries, N places to look for state, and ad-hoc gitignore hygiene per session (observed in the credvault audit, session cd1ae1cd).

## Decision

(1) All cc-os-owned per-project state lives under **`.cc-os/`**: the shared `config` file stays at `.cc-os/config` (cross-plugin key=value contract, ADR-026); each plugin's private state lives in **`.cc-os/<plugin-domain>/`** (e.g. `.cc-os/dochygiene/`, `.cc-os/status/`, `.cc-os/adr/`). No new root-level dotdirs. (2) Existing plugins migrate with a **backward-compat fallback read** of the old path (auto-migrate on first write, then remove the old dir): os-doc-hygiene `.dochygiene/` → `.cc-os/dochygiene/`; os-status's own `snooze-*`/`state.json` → `.cc-os/status/`. (3) **`graphify-out/` is exempt** — external-tool output, disposable/rebuildable, path baked into os-vault hooks; moving it is deferred as aesthetic-only churn. `.claude/` is Claude Code's own dir, out of scope. (4) One gitignore entry — `.cc-os/` — covers all cc-os state; ensuring it is present becomes an explicit step of `/os-status:fix` (issue #23), not improvised per session.
- **Rationale**: One predictable home for the operating layer's per-project state matches the cc-os family framing (ADR-023: mutually aware, cooperating plugins) and extends the shared-config seam ADR-026 established. Fallback-read migration makes rollout painless across already-onboarded projects.

## Consequences

All cc-os-owned per-project state consolidates under .cc-os/, with each plugin's private state in .cc-os/<plugin-domain>/ (e.g. .cc-os/dochygiene/, .cc-os/status/, .cc-os/adr/) instead of each plugin inventing its own root-level dotdir, reducing gitignore entries to one and giving a single predictable location for state. Existing plugins migrate via a backward-compatible fallback read of their old path (auto-migrating on first write), while graphify-out/ and .claude/ remain exempt as out of scope.

## Alternatives rejected

**Status quo (per-plugin root dotdirs)** — sprawl grows linearly with the plugin family. **Moving `graphify-out/` too** — touches the os-vault onboard skill, SessionStart reconcile, and docs for zero functional gain.
- **Cross-references**: ADR-023 (ecosystem framing), ADR-026 (`.cc-os/config` contract); Forgejo issues #23 (fix tune-up), #24 (this consolidation).
