Critical 1 (approval forgery): audit_log is now hash-chained (prev_hash/entry_hash, verify_audit_chain); executor approve REQUIRES a BIP-340 signature over sha256(cayce-ops:approve:<id>) when CAYCE_OPS_OPERATOR_PUBKEY is set; deploy/roles.sql ships least-privilege per-daemon DB roles. Critical 2 (threading dead): sends create real OUTBOUND rows (own Message-ID, In-Reply-To -> inbound); inbound message_id never overwritten; maild compose adds the first-contact path; _match_proposal falls back to inbound chains. Critical 3 (duplicate sends): per-message transactions in send path — SMTP failure on message N no longer resurrects 1..N-1; failures audited (send_failed) and the row stays queued. Critical 4 (classifier): negated approvals (cannot accept / not approved / not accepting) classify REJECTION at 0.95 before the bare-keyword rule; LLM prompt braces escaped (.format no longer KeyError into silent fallback). Critical 5 (systemd): every daemon has a run subcommand (maild run = poll+send, publisher run = publish-due, monitor run = build); deploy README documents the separate daily publisher plan timer. Mediums: approved_hash binds drafts/captions to the approved text (edited text refuses to send/publish until re-approved); risk_score renamed match_score (migration 0002) and auto-approve orders HIGHEST relevance first; compose binds postgres to 127.0.0.1; IMAP marks \\Seen only after commit (fetch returns (num, raw), mark post-commit); disabled channels are terminal (ContentStatus.SKIPPED) and publish failures burn a bounded attempt budget before abandonment; make hooks installs the pre-push gate. tests: 12 new — 56 total, all green; ruff 0 findings; gitleaks clean.
57 lines
2.0 KiB
Bash
57 lines
2.0 KiB
Bash
# Cayce Ops — copy to .env and fill in. EVERY value below is a placeholder.
|
|
# NEVER commit real credentials. .env is gitignored; gitleaks guards history.
|
|
|
|
# --- core ---
|
|
CAYCE_OPS_DATABASE_URL=postgresql+psycopg://user:password@localhost:5432/cayce_ops
|
|
CAYCE_OPS_AUTONOMOUS_MODE=false
|
|
CAYCE_OPS_LOG_LEVEL=INFO
|
|
CAYCE_OPS_STATE_DIR=./
|
|
CAYCE_OPS_MEDIA_DIR=./media
|
|
|
|
# --- scanner ---
|
|
# JSON array of sources: [{"type":"rss","url":"https://example.org/feed.xml"},
|
|
# {"type":"page","url":"https://example.org/partners"}]
|
|
CAYCE_OPS_SCANNER_SOURCES=[]
|
|
CAYCE_OPS_SCANNER_KEYWORDS=affiliate,partnership,bitcoin,lightning,travel
|
|
CAYCE_OPS_SCANNER_USER_AGENT=cayce-ops-scanner/0.1
|
|
|
|
# --- executor ---
|
|
# with AUTONOMOUS_MODE=true: which proposal kinds may be auto-approved, daily cap
|
|
CAYCE_OPS_AUTONOMOUS_KINDS=
|
|
CAYCE_OPS_AUTONOMOUS_DAILY_CAP=0
|
|
CAYCE_OPS_MAX_ATTEMPTS=2
|
|
CAYCE_OPS_ENABLE_HTTP_ACTIONS=false
|
|
# when set (64-char hex x-only pubkey), executor approve REQUIRES a BIP-340
|
|
# signature over sha256("cayce-ops:approve:<id>") made by the operator key
|
|
CAYCE_OPS_OPERATOR_PUBKEY=
|
|
|
|
# --- mail (IMAP read / SMTP send-approved-drafts-only) ---
|
|
CAYCE_OPS_IMAP_HOST=imap.example.org
|
|
CAYCE_OPS_IMAP_PORT=993
|
|
CAYCE_OPS_IMAP_USER=agent@example.org
|
|
CAYCE_OPS_IMAP_PASSWORD=change-me
|
|
CAYCE_OPS_IMAP_MAILBOX=INBOX
|
|
CAYCE_OPS_SMTP_HOST=smtp.example.org
|
|
CAYCE_OPS_SMTP_PORT=587
|
|
CAYCE_OPS_SMTP_USER=agent@example.org
|
|
CAYCE_OPS_SMTP_PASSWORD=change-me
|
|
CAYCE_OPS_MAIL_FROM=agent@example.org
|
|
|
|
# --- llm (null = no LLM; components fall back to rules) ---
|
|
CAYCE_OPS_LLM_PROVIDER=null
|
|
CAYCE_OPS_LLM_MODEL=
|
|
CAYCE_OPS_LLM_BASE_URL=https://api.openai.com/v1
|
|
CAYCE_OPS_LLM_API_KEY=
|
|
CAYCE_OPS_LLM_REVIEW_THRESHOLD=0.7
|
|
|
|
# --- publisher / nostr (key: 32-byte hex; relays: wss:// comma list) ---
|
|
CAYCE_OPS_NOSTR_PRIVATE_KEY=
|
|
CAYCE_OPS_NOSTR_RELAYS=wss://relay.example.org,wss://other.relay.example.org
|
|
CAYCE_OPS_ENABLE_FACEBOOK=false
|
|
CAYCE_OPS_FACEBOOK_PAGE_TOKEN=
|
|
CAYCE_OPS_ENABLE_INSTAGRAM=false
|
|
CAYCE_OPS_INSTAGRAM_USER_ID=
|
|
|
|
# --- monitor ---
|
|
CAYCE_OPS_MONITOR_OUTPUT=./status.html
|