diff --git a/.agents/docs/README.md b/.agents/docs/README.md index bd704bf..ed7acc2 100644 --- a/.agents/docs/README.md +++ b/.agents/docs/README.md @@ -1,11 +1,11 @@ # Agent / AI guidance -Project notes for coding agents (Cursor, Claude Code, etc.). +Durable project context for coding agents (Cursor, Claude Code, etc.). Feature workflow follows Compound Engineering — see [AGENTS.md](../../AGENTS.md). | Path | Purpose | |------|---------| -| [`../../AGENTS.md`](../../AGENTS.md) | Root agent entrypoint (commands + index) | -| [`DEVELOPMENT.md`](DEVELOPMENT.md) | TEE trust model, product roles (`BOT__ROLE`), dual-CVM ops | -| [`../skills/`](../skills/) | Vendored SkillsMP skills (Rust, Docker, Stripe) | +| [`../../AGENTS.md`](../../AGENTS.md) | Root agent entrypoint (CE loop, commands, index) | +| [`DEVELOPMENT.md`](DEVELOPMENT.md) | TEE trust model, product roles (`BOT__ROLE`), dual-CVM ops — read when planning TEE/role/compose work | +| [`../skills/`](../skills/) | Domain skills (Rust, Docker, Stripe); coexist with CE plugin skills | -Product docs for humans stay in [`docs/`](../../docs/). Humans: [`README.md`](../../README.md). +CE artifacts live under [`docs/brainstorms/`](../../docs/brainstorms/), [`docs/plans/`](../../docs/plans/), [`docs/solutions/`](../../docs/solutions/), and [`todos/`](../../todos/). Product docs for humans stay in [`docs/`](../../docs/). Humans: [`README.md`](../../README.md). diff --git a/.agents/skills/README.md b/.agents/skills/README.md index b1cd4cf..e4efced 100644 --- a/.agents/skills/README.md +++ b/.agents/skills/README.md @@ -2,6 +2,8 @@ Third-party [SkillsMP](https://skillsmp.com/search) / GitHub skills installed for Cursor via `npx skills add … -a cursor --copy`. +These are **domain** skills (Rust, Docker, Stripe). Feature workflow uses the Compound Engineering marketplace plugin (`/ce-brainstorm`, `/ce-plan`, `/ce-work`, …) — see [AGENTS.md](../../AGENTS.md). Prefer CE for planning/shipping; reach for these skills when writing or reviewing stack-specific code. + **Review before trust** — skills run with full agent permissions. Prefer project docs under `.agents/docs/` and `docs/` for Signal/TEE domain rules. | Skill | Use for | Source | @@ -19,4 +21,4 @@ npx skills add rbaumier/skills --skill docker -a cursor --copy -y npx skills add midudev/autoskills --skill stripe-best-practices -a cursor --copy -y ``` -Domain ops (TEE, `BOT__ROLE`, dual CVM): [../docs/DEVELOPMENT.md](../docs/DEVELOPMENT.md). Agent entrypoint: [../../AGENTS.md](../../AGENTS.md). +Domain ops (TEE, `BOT__ROLE`, dual CVM): [../docs/DEVELOPMENT.md](../docs/DEVELOPMENT.md). Agent entrypoint: [../../AGENTS.md](../../AGENTS.md). Cursor project rules: [../../.cursor/rules/](../../.cursor/rules/). diff --git a/.compound-engineering/config.local.example.yaml b/.compound-engineering/config.local.example.yaml new file mode 100644 index 0000000..b1c9480 --- /dev/null +++ b/.compound-engineering/config.local.example.yaml @@ -0,0 +1,127 @@ +# Compound Engineering -- local config +# Copy to .compound-engineering/config.local.yaml in your project root. +# All settings are optional. Invalid values fall through to defaults. + +# --- 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); pipeline contexts (e.g., LFG, +# disable-model-invocation) always force `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) + +# --- Fable elevation (Claude Code only) --- +# Claude Code ONLY; silently ignored on every other harness (Codex, Cursor, ...). +# When on, /ce-plan and /ce-brainstorm dispatch their reasoning-heavy step (plan +# authoring; approach generation) to the Fable model via a subagent, so you get +# higher-reasoning output even when your session model is cheaper -- no session +# switch. Per-skill so you can enable one without the other. You can also just +# say "use fable" in a prompt for a one-off. Invalid/commented/missing -> off. + +# plan_use_fable: true # true | false (default: false) +# brainstorm_use_fable: true # true | false (default: false) +# fable_nudge: false # true | false (default: true -- one-time tip when elevation is available but off) + +# --- 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). Note: this file is gitignored and per-checkout -- fresh +# worktrees don't inherit it. + +# 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). +# 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 preference --- +# Preferred peer for ce-doc-review and ce-code-review when their conditional +# cross-model pass activates. Conversation instructions still win, and the +# skills skip routes that cannot establish the required host/peer distinction. + +# cross_model_peer: codex # codex | claude | grok | cursor | composer + +# --- ce-work implementation engine --- +# Standing, per-checkout 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` asks before native fallback in an interactive ce-work run and blocks +# without prompting under LFG/headless execution. Harnesses: codex | claude | grok +# | cursor. 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 diff --git a/.agents/rules/commit-messages.md b/.cursor/rules/commit-messages.mdc similarity index 89% rename from .agents/rules/commit-messages.md rename to .cursor/rules/commit-messages.mdc index 51bfdd9..6a6a76d 100644 --- a/.agents/rules/commit-messages.md +++ b/.cursor/rules/commit-messages.mdc @@ -1,3 +1,8 @@ +--- +description: Conventional commit subject line style for this repo +alwaysApply: true +--- + # Commit message subject lines When drafting a git commit subject (conventional `type: subject`): diff --git a/.cursor/rules/compound-engineering.mdc b/.cursor/rules/compound-engineering.mdc new file mode 100644 index 0000000..35289d9 --- /dev/null +++ b/.cursor/rules/compound-engineering.mdc @@ -0,0 +1,30 @@ +--- +description: Compound Engineering loop, artifact paths, and product constraints +alwaysApply: true +--- + +# Compound Engineering + +Prefer the Compound Engineering loop for non-trivial work: + +brainstorm → plan → work → simplify → review → compound + +Core skills (after installing the marketplace plugin): `/ce-brainstorm`, `/ce-plan`, `/ce-work`, `/ce-simplify-code`, `/ce-code-review`, `/ce-compound`. After non-trivial fixes or features, prefer `/ce-compound` so learnings land in `docs/solutions/`. + +## Artifact paths + +| Path | Written by | +|------|------------| +| `docs/brainstorms/` | `/ce-brainstorm` | +| `docs/plans/` | `/ce-plan` | +| `docs/solutions/` | `/ce-compound` | +| `todos/` | triage / review findings | + +Product docs stay as siblings under `docs/` (architecture, voice, translation). Full agent entrypoint: `AGENTS.md`. + +## Product constraints + +- Required env: `BOT__ROLE=transcription|translation` +- Do not reintroduce tools, x402, or general chat paths +- Image digests stay pinned in compose for attestation +- Before finishing Rust work run `npm run ci` / `pnpm run ci` (never bare `pnpm ci`) diff --git a/.cursor/settings.json b/.cursor/settings.json new file mode 100644 index 0000000..8812bf5 --- /dev/null +++ b/.cursor/settings.json @@ -0,0 +1,7 @@ +{ + "plugins": { + "compound-engineering": { + "enabled": true + } + } +} diff --git a/.gitignore b/.gitignore index 8df1583..aac0b8c 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,7 @@ credentials.json # Git worktrees .worktrees/ + +# Compound Engineering machine-local config (keep *.example.yaml tracked) +.compound-engineering/*.local.yaml +.compound-engineering/config.local.yaml diff --git a/AGENTS.md b/AGENTS.md index 0a1e93b..3461ee6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,6 +6,36 @@ Short entrypoint for coding agents. Humans: see [README.md](README.md). TEE-hosted Signal bots for **voice transcription** and **group translation** (not a general AI chat assistant). Two phone numbers / two bots in a Signal group; Signal is the bus — no Docker network between CVMs. Whisper stays on the transcription stack only. +## Compound Engineering + +This repo uses [Compound Engineering](https://every.to/guides/compound-engineering) via the Cursor marketplace plugin (not vendored). Each unit of work should make the next unit easier. + +### Install / first run (manual) + +In Cursor Agent chat: + +```text +/add-plugin compound-engineering +/ce-setup +``` + +`/ce-setup` should report gitignore coverage for machine-local config, a present `.compound-engineering/config.local.example.yaml`, and no obsolete local md. Optional tools (`gh`, `ast-grep`, etc.) are informational only. + +### Core loop + +```text +/ce-brainstorm → /ce-plan → /ce-work → /ce-simplify-code → /ce-code-review → /ce-compound +``` + +| Artifact | Path | +|----------|------| +| Brainstorms | [`docs/brainstorms/`](docs/brainstorms/) | +| Plans | [`docs/plans/`](docs/plans/) | +| Solutions (compounded learnings) | [`docs/solutions/`](docs/solutions/) | +| Triage / review todos | [`todos/`](todos/) | + +After non-trivial fixes or features, prefer `/ce-compound` so the next cycle starts smarter. Domain skills (Rust, Docker, Stripe) under [`.agents/skills/`](.agents/skills/) coexist with CE plugin skills — use CE for feature workflow, domain skills for language/stack craft. + ## Setup / verify ```bash @@ -37,13 +67,15 @@ docker compose -f docker/compose.translation.yaml --env-file docker/translation. | [`docs/voice-transcription.md`](docs/voice-transcription.md) | Voice transcription product + pairing | | [`docs/in-chat-translation.md`](docs/in-chat-translation.md) | In-chat (group) bilingual auto/manual translate | | [`docs/language-threads.md`](docs/language-threads.md) | Language Threads (multilingual main + N sidecars) | -| [`.agents/skills/`](.agents/skills/) | Vendored skills (Rust, Docker, Stripe) | -| [`.agents/rules/`](.agents/rules/) | Agent rules (e.g. commit message subjects) | +| [`docs/solutions/`](docs/solutions/) | Compounded learnings from prior work | +| [`docs/plans/`](docs/plans/) | CE implementation plans | +| [`.agents/skills/`](.agents/skills/) | Domain skills (Rust, Docker, Stripe) | +| [`.cursor/rules/`](.cursor/rules/) | Cursor project rules (commits, compound loop) | ## Rules of thumb - Required env: `BOT__ROLE=transcription|translation` - Do not reintroduce tools, x402, or general chat paths - Image digests stay pinned in compose for attestation -- Commits must pass [commitlint](https://github.com/conventional-changelog/commitlint) (`type: subject`); subject all lowercase, no trailing period, dashes not snake_case — see [`.agents/rules/commit-messages.md`](.agents/rules/commit-messages.md). Run `npm install` or `pnpm install` so husky `commit-msg` / `pre-push` hooks are active +- Commits must pass [commitlint](https://github.com/conventional-changelog/commitlint) (`type: subject`); subject all lowercase, no trailing period, dashes not snake_case — see [`.cursor/rules/commit-messages.mdc`](.cursor/rules/commit-messages.mdc). Run `npm install` or `pnpm install` so husky `commit-msg` / `pre-push` hooks are active - **CI style gates are not optional.** GitHub Actions (`test.yml` + `commitlint.yml`) fails on fmt, Clippy `-D warnings`, llvm-cov ≥90% lines, and conventional commits. Before finishing Rust work run `npm run ci` / `pnpm run ci` (never bare `pnpm ci`). Husky `pre-push` runs that script; `commit-msg` runs commitlint on each commit. Cursor auto-fmts `.rs` edits and re-prompts on stop if fmt/clippy would fail CI. diff --git a/README.md b/README.md index fb62df8..e5ce77f 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ See `.env.example` and the docker `*.env.example` files. See [.agents/docs/DEVELOPMENT.md](.agents/docs/DEVELOPMENT.md) for the TEE trust model, why Signal CLI must run in the TEE, and attestation (`!verify`). -For coding agents, see [AGENTS.md](AGENTS.md). +For coding agents, see [AGENTS.md](AGENTS.md) (includes Compound Engineering install: `/add-plugin compound-engineering`, then `/ce-setup`). ## License diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 4a1108c..119fad0 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -6,7 +6,7 @@ Current product direction: - [two-cvm-architecture.md](two-cvm-architecture.md) - [language-threads.md](language-threads.md) -- [../.agents/DEVELOPMENT.md](../.agents/DEVELOPMENT.md) +- [../.agents/docs/DEVELOPMENT.md](../.agents/docs/DEVELOPMENT.md) - [../README.md](../README.md) - [issue #10](https://github.com/BreadchainCoop/sigstack-bot/issues/10) diff --git a/docs/brainstorms/README.md b/docs/brainstorms/README.md new file mode 100644 index 0000000..9a0b518 --- /dev/null +++ b/docs/brainstorms/README.md @@ -0,0 +1,5 @@ +# Brainstorms + +Requirements-oriented brainstorm docs written by `/ce-brainstorm` (Compound Engineering). + +Hand off approved brainstorms into `/ce-plan`. Product specs live alongside this folder under [`docs/`](../). diff --git a/docs/plans/README.md b/docs/plans/README.md new file mode 100644 index 0000000..a8cee41 --- /dev/null +++ b/docs/plans/README.md @@ -0,0 +1,5 @@ +# Plans + +Implementation-ready plans written by `/ce-plan` (Compound Engineering). + +Product docs stay as siblings under [`docs/`](../). Do not put durable product specs here — use the named product markdown files instead. diff --git a/docs/solutions/README.md b/docs/solutions/README.md new file mode 100644 index 0000000..72ba66d --- /dev/null +++ b/docs/solutions/README.md @@ -0,0 +1,5 @@ +# Solutions + +Institutional learnings written by `/ce-compound` (Compound Engineering). + +Each solved problem becomes searchable markdown so the next `/ce-brainstorm` / `/ce-plan` cycle starts smarter. Prefer compounding after non-trivial fixes and features. diff --git a/todos/README.md b/todos/README.md new file mode 100644 index 0000000..b12b59e --- /dev/null +++ b/todos/README.md @@ -0,0 +1,5 @@ +# Todos + +Triage and review findings from Compound Engineering workflows (`/triage`, `/ce-code-review` resolution). + +Files are typically named with priority and status (for example `001-ready-p1-…`). Work ready items with CE resolve skills; do not treat this folder as a product backlog.