Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 196 additions & 0 deletions .compound-engineering/config.example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# Compound Engineering -- repo config
# Copy to .compound-engineering/config.yaml in your project root (team defaults).
# Optional override: .compound-engineering/config.local.yaml, same keys.
# Ordinary keys: local wins when set, then this file, then the skill default.
# docs_root is repo layout -- set it only here; local docs_root is ignored.
# All settings are optional. Invalid ordinary values continue to the next layer.
# docs_root fails closed on an unusable value.

# --- Artifact root ---
# Relocate every CE-written artifact folder (solutions, plans, ideation,
# explainers, pulse-reports, dogfood-reports,
# feedback-sweep, personas) under one repo-relative root. Unset -> `docs`,
# byte-identical to today. A configured root becomes the sole location CE reads
# and writes; CE never falls back to reading `docs/`.
#
# Set this only in this tracked file so every clone and worktree share one
# artifact tree. A docs_root in config.local.yaml is ignored.
#
# The value must be a repo-relative directory whose real (symlink-resolved) path
# stays inside the repo, is not the repo root itself, and is not under `.git/`.
# Unlike every other setting here, an unusable value does NOT fall through to the
# default -- CE stops with an error so a typo can't silently write artifacts into
# the location you configured away from. `/ce-setup` reports the resolved root.

# docs_root: .compound-engineering/artifacts # repo-relative dir (default: docs)

# --- Product pulse ---
# Settings written by /ce-product-pulse first-run interview. Re-run the skill with
# argument `setup` or `reconfigure` to edit interactively.

# pulse_product_name: "Spiral" # used in report titles (no default)
# pulse_lookback_default: 24h # 1h | 24h | 7d | 30d (default: 24h)
# pulse_primary_event: "session_started" # the event that means "user showed up"
# pulse_value_event: "task_completed" # the event that means "user got value"
# pulse_completion_events: "onboarded,first_purchase" # comma-separated, 0-3 events
# pulse_quality_scoring: false # true | false (default: false; AI products only)
# pulse_quality_dimension: "answer accuracy" # dimension scored 1-5 when pulse_quality_scoring is true
# pulse_analytics_source: posthog # posthog | mixpanel | custom (no default)
# pulse_tracing_source: sentry # sentry | datadog | custom (no default)
# pulse_payments_source: stripe # stripe | custom (no default)
# pulse_db_enabled: false # true | false (default: false; read-only DB if true)
# pulse_metric_sources: "retention_d7=posthog,nps=delighted" # strategy-metric -> source overrides; comma-separated 'metric=source' pairs; unlisted metrics fall back to pulse_analytics_source
# pulse_pending_metrics: "retention_d7,nps" # comma-separated strategy metrics awaiting instrumentation; render as 'no data'
# pulse_excluded_metrics: "north_star" # comma-separated strategy metrics intentionally not in pulse

# --- Output format ---
# Per-skill output format default. Selects the exclusive format the artifact
# is written in: `md` produces a markdown file, `html` produces a single
# self-contained HTML file. The two are mutually exclusive -- there is no
# sibling artifact. See DESIGN.md or your agent instructions to influence
# HTML styling. Precedence: a format request in your prompt for that run wins
# (e.g. "output:html" or "make it HTML"); a preference you established earlier
# (in-session, saved to memory, or in your agent instructions) overrides these
# keys (this config is the persisted fallback). A headless or pipeline run
# resolves the format the same way; nothing forces `md`.

# plan_output: html # md | html (default: md)
# brainstorm_output: html # md | html (default: md)
# ideate_output: md # md | html (default: html -- ideation docs are human-facing, so HTML is the default; set md to opt out)

# --- Model elevation ---
# Send only the reasoning-heavy step of /ce-plan (interpret research, then author
# the plan) and /ce-brainstorm (generate approaches) to a model you name. The rest
# of each skill -- dialogue, research, orchestration -- stays on your session
# model. The value is a model alias (e.g. `fable`, `opus`). You can also name a
# model in a prompt for a one-off, which overrides these keys.
#
# Cross-harness: setting a key means every harness you run these skills in will
# attempt that model. The host serves it natively where it can; otherwise the
# Claude CLI is invoked when installed and authenticated; otherwise the step runs
# on your session model and the run says so. Invalid/commented/missing -> no
# elevation.

# plan_model: fable # model alias for plan authoring; candidate preference for requested Bake-offs (no default)
# brainstorm_model: fable # model alias for approach generation; candidate preference for requested Bake-offs (no default)

# --- PR concept teaching (ce-commit-push-pr) ---
# When a PR introduces a concept new to the codebase, the generated PR
# description gains a "New concepts" section teaching it. The section toggle is
# the single gate: off disables judgment, the section, the /ce-explain offer,
# and archival. Archival additionally writes the explainer to docs/explainers/
# and links it from the PR (full-workflow runs only; override per run with
# archive:on|off). Ordinary cascade: local, then this file, then the skill default.

# pr_teaching_section: false # true | false (default: true)
# pr_teaching_archive: true # true | false (default: false; full-workflow runs only)

# --- ce-commit-push-pr babysit handoff ---
# After a full-workflow PR is opened, ce-commit-push-pr auto-invokes ce-babysit-pr
# to watch CI + incoming review and drive the PR toward merge-ready. Set false to
# opt out standing (per-run override: the babysit:off token). This governs that
# standing watch only -- lfg's in-pipeline babysit is bounded (3 fix rounds) and
# still runs, since it is how that pipeline reaches "CI decided".
# auto_babysit: false # true | false (default: true)

# --- ce-plan scoping confirmation ---
# By default /ce-plan pauses before research/plan-write to show a scoping
# summary and wait for you to confirm scope. Set this to skip that wait: ce-plan
# composes the summary for itself, records any inferred scope under an
# Assumptions section, announces that it's proceeding, and keeps going. It skips
# only that confirmation -- genuine blocking questions and the post-plan menu
# still appear. Override per run with `confirm:auto` (skip) or `confirm:ask`
# (force the gate on for one run).

# plan_skip_scoping_confirm: true # true | false (default: false)

# --- Cross-model review policy and preference ---
# `cross_model_review_mode` decides whether ce-doc-review and ce-code-review may
# automatically send review content (diffs, documents) to a second model
# provider when their conditional cross-model pass activates. `off` skips that
# pass before any route is chosen or process starts, leaves every local
# reviewer in place, and reports "disabled by checkout config" instead of an
# availability failure. `auto` keeps the current behavior. A direct request in
# conversation ("use codex as the independent reviewer this time") overrides
# `off` for that run; a conversation prohibition overrides `auto`.
#
# `cross_model_peer` is the preferred peer, consulted only when the mode is
# `auto`. Conversation instructions still win, and the skills skip routes that
# cannot establish the required host/peer distinction.
# `cross_model_model` and `cross_model_effort` pin the model and reasoning
# effort of whichever peer target runs; unset keeps the skills' editorial
# mapping. The model must belong to that target's family (an alias such as
# `fable` or a full id such as `claude-opus-5` for claude; `gpt-*` for codex,
# optionally namespace-qualified such as `openai.gpt-5.6-sol` when the codex CLI
# routes through a non-default `model_provider`).
# Effort levels: claude low|medium|high|xhigh|max, codex minimal|low|medium|
# high|xhigh, grok low|medium|high; cursor/composer routes take none. A value
# the peer cannot honor skips the pass with a stated reason -- never substituted.

# cross_model_review_mode: off # auto | off (default: auto)
# cross_model_peer: codex # codex | claude | grok | cursor | composer | opencode
# cross_model_model: fable # model alias or full id for the resolved peer target (no default)
# cross_model_effort: xhigh # reasoning effort for the resolved peer target (no default)

# --- ce-work implementation engine ---
# Standing preferences for who authors implementation units. Live
# task/session/project instructions and LFG's provenance-bearing binding may
# override or narrow these defaults. `off` disables only this standing preference.
# `prefer` tries candidates in order, then falls back natively with disclosure.
# `require` keeps the requested external identity fixed while viable, then also
# falls back natively with disclosure if the route is unavailable. Harnesses:
# codex | claude | grok | cursor | opencode. Omit model to use that harness's configured
# default. Composer is a model
# family through Cursor: { harness: cursor, model: composer }. Do not put CLI flags
# or commands here. A candidate equivalent to the current host/default is skipped;
# a different explicit model in the same harness remains eligible.

# work_engine_mode: prefer # off | prefer | require (default: off)
# work_engine_preferences:
# - harness: cursor
# model: composer
# - harness: codex
# model: "gpt-5.6"
# - harness: claude # configured default model

# --- ce-promote ---
# Written automatically when you decline the Spiral setup offer in /ce-promote.
# Suppresses that one-time setup nudge in this project. Remove the key to re-enable.

# ce_promote_spiral_optout: true # true | (absent) (default: absent -- offer once)

# --- Sweep (ce-sweep) ---

# Feedback sources swept by /ce-sweep. Generic key: other skills may read this list.
# Each entry: type (slack | github-issues | email), id (short name), target (channel ID /
# owner/repo / mailbox), ack_action, closeout_action, sensitive (true withholds content
# from committed state/plan text), approved (standing approval for source-side writes).
# feedback_sources:
# - { type: slack, id: slack-alpha, target: C0XXXXXXX, ack_action: eyes, closeout_action: white_check_mark, sensitive: false, approved: true }
# - { type: github-issues, id: gh-issues, target: owner/repo, ack_action: "feedback:ack", closeout_action: "feedback:resolved", sensitive: false, approved: true }

# Sweep-owned settings.
# sweep_state_path: docs/feedback-sweep/state.yml # committed (multi-agent) or /tmp path (solo)
# sweep_ack_cap: 25 # max acks per source per run before the circuit breaker
# sweep_lease_ttl_minutes: 60 # single-writer lease staleness threshold
# sweep_shared_branch: false # true: push-gated lease for shared-docs-branch topology

# --- Compound Packs ---

# Prescriptive domain knowledge folders that planning reads and cites.
# Declared, never scanned: an entry names a source (repo-relative path,
# ~/absolute path, or git URL) and what to install from it. Lists from this
# file and config.local.yaml concatenate -- local adds packs, never replaces
# the team's. Git sources require ref (tag or sha reproduce exactly; a branch
# freezes at its cached resolution and can drift across machines). path: and
# pasted GitHub /tree/<ref>/<sub> URLs scope a source to a subfolder.
# pack: picks one id or a list; omit it to install everything the source
# publishes. id: renames a single-pack entry.
# Rules are top-level .md files with title + applies_when; subfolders are storage.

# packs:
# - source: compound-packs/local-rules # repo-relative, read live
# - source: ~/compound-packs/kk-style # machine-local, read live
# - source: https://github.com/org/rails-ce-pack # git, cached at ref
# ref: v1.2.0
# pack: [rails, inertia]
Loading