cayce b81f7f3625
ci / lint-test-leaks (pull_request) Canceled after 0s
containment: every third-party send becomes a draft (outbox), identity file versioned
Problem: Cayce publishes straight to relays with no approval gate —
cayce-initiative publish_note, core.mjs digest/opinion/reflection/events,
mention auto-replies, social promo (Facebook/Instagram via sfeed), and
mail — while the operator believed approvals existed (they never did;
ADR-0005 Telegram queue was never implemented).

Mechanism (outbox.mjs, deployed to all runtimes):
- CAYCE_PUBLISH_MODE=draft (default): gateOutbound() stages EVERY outbound
  artifact into outbound_drafts (entity DB) with identity_path +
  identity_hash (sha256 of prompts/cayce-identity.md) before anything
  else happens. Fail-closed: if staging fails, the event is discarded,
  never published.
- CAYCE_PUBLISH_MODE=live: original behavior, unchanged (reversible with
  one line per service .env).
- Chokepoint: the nostr daemon /publish endpoint gates ALL callers
  (initiative publish_note, core.mjs ×4, banner kind 0); the daemon own
  mention-reply path gates too, storing original_event for context;
  startup profile publish gates as well. DM-to-supervisor (/dm) is
  internal and stays live.

Identity (point 8b):
- prompts/cayce-identity.md: the 5 hardcoded voice blocks extracted
  VERBATIM (verified byte-identical by runtime test) with block markers.
- core.mjs / editorials.mjs now load their voice blocks from this file
  (loadIdentityBlock); identity hash recorded on every draft.
- runtime/ holds the versioned copies of the previously-unversioned
  runtime scripts + deploy.sh installer.

No timers enabled or disabled. No production data modified.
2026-10-31 16:44:57 +00:00

Cayce Ops

CayceOps es el stack de operaciones de Cayce, un experimento de operaciones agénticas de Cayce Co. Toda acción con efectos externos requiere aprobación humana firmada criptográficamente, con una clave que nunca reside en la infraestructura de Cayce.

Cayce operates bitcoinhotels.org (Bitcoin-native travel guides) and hardcap.news (Bitcoin security intelligence).

Five decoupled components share one Postgres database. Each is a CLI command, driven by cron/systemd timers. Nothing runs without an audit trail.

Component What it does Human gate
scanner Discovers opportunities (affiliates, partnerships, content gaps) from configured sources; files them as proposals none — it only proposes
executor Runs approved proposals through registered action plugins; full audit of who approved, what ran, what happened approval required (AUTONOMOUS_MODE=false by default)
mail-negotiator Classifies merchant replies (approval / rejection / question / other) over IMAP; drafts replies; SMTP sends only human-approved drafts draft approval required
publisher Themed content calendar. Nostr (NIP-01) adapter first; Facebook/Instagram adapters exist but are disabled by default; brand images via Pillow templates publish requires approved items
monitor Static status page: daemon health, last runs, proposal queue, recent errors. No sensitive data none — read-only

State machines:

proposal: proposed -> approved -> running -> done | failed
mail:     inbound classified; draft: none -> drafted -> approved -> sent
content:  draft -> approved -> published

Quickstart (local)

uv sync --frozen            # installs Python 3.12 + locked deps
cp .env.example .env        # fill in; values are placeholders
docker compose up -d db     # Postgres 16
uv run alembic upgrade head
uv run cayceops scanner run
uv run pytest

docker compose up (everything) runs all five daemons in loops; on a VPS use deploy/systemd instead.

Layout

cayceops/            the package
  config.py          env-var config (CAYCE_OPS_*), no config files
  db.py              engine/session/upgrade helpers
  models.py          ORM schema + state machines + audit helper
  llm.py             provider-agnostic LLM interface (null by default)
  components/
    scanner/         discovery -> proposals (never executes)
    executor/        plugin execution + audit
    maild/           IMAP classify, drafts, SMTP gated on approval
    publisher/       calendar, nostr adapter, image templates
    monitor/         static status page builder
alembic/             migrations (production schema path)
tests/               pytest suite (invented fixtures only)
deploy/systemd/      VPS units + timers
docs/DECISIONS.md    architectural decisions and their costs

Security posture

  • Config exclusively via env vars; .env is gitignored, .env.example holds placeholders.
  • make check (and CI): ruff, pytest, alembic smoke, gitleaks over the full history.
  • SMTP send, social publish, and proposal execution all require a human action recorded in the audit log — unless AUTONOMOUS_MODE=true, which enables one narrow, capped, audited exception (see docs/DECISIONS.md D5).

License

MIT — see LICENSE.

S
Description
Cayce autonomous operations stack — scanner, executor, mail-negotiator, publisher, monitor. MIT.
Readme MIT
492 KiB
2026-10-19 23:34:24 +00:00
Languages
Python 64.7%
JavaScript 27.5%
Shell 3%
PLpgSQL 2.3%
TypeScript 2%
Other 0.4%