Ready for audit #7

Open
opened 2026-10-19 21:59:04 +00:00 by cayce · 2 comments
Owner

The full stack is published and gated.

  • AUDIT.md: AUDIT.md at main
  • Audited commit: d500d88 (d500d88870) — merge of PR #7 on main
  • Gate at that commit: ruff clean (0 findings) · 44/44 pytest · alembic 0001 smoke · gitleaks full history, no leaks · make check exit 0
  • Disclosure: PRs #1-#6 carried E501 lint findings (gate output misread); PR #7 is a lint-only cleanup, no behavior change. Full note in AUDIT.md.

What to audit

  1. Component map + data flow (AUDIT.md section 1)
  2. External-call inventory: scanner GETs, IMAP, SMTP (approved drafts only), LLM (null by default), nostr relays, Meta adapters (disabled by default) — section 2
  3. Human-gate matrix: without human vs AUTONOMOUS_MODE=true — section 3
  4. Env vars + permissions per component — section 4
  5. Pinned dependencies with purpose — section 5
  6. Known risks + compensating controls — section 6

Branch/PR history: #1 skeleton · #2 scanner+executor · #3 mail-negotiator · #4 publisher · #5 monitor · #6 audit doc · #7 lint-fix (audited commit) · #8 audit update.

The full stack is published and gated. - **AUDIT.md**: AUDIT.md at main - **Audited commit**: d500d88 (d500d888701c3f1cd3305d098a448c3e20a8ad99) — merge of PR #7 on main - **Gate at that commit**: ruff clean (0 findings) · 44/44 pytest · alembic 0001 smoke · gitleaks full history, no leaks · make check exit 0 - **Disclosure**: PRs #1-#6 carried E501 lint findings (gate output misread); PR #7 is a lint-only cleanup, no behavior change. Full note in AUDIT.md. ## What to audit 1. Component map + data flow (AUDIT.md section 1) 2. External-call inventory: scanner GETs, IMAP, SMTP (approved drafts only), LLM (null by default), nostr relays, Meta adapters (disabled by default) — section 2 3. Human-gate matrix: without human vs AUTONOMOUS_MODE=true — section 3 4. Env vars + permissions per component — section 4 5. Pinned dependencies with purpose — section 5 6. Known risks + compensating controls — section 6 Branch/PR history: #1 skeleton · #2 scanner+executor · #3 mail-negotiator · #4 publisher · #5 monitor · #6 audit doc · #7 lint-fix (audited commit) · #8 audit update.
Author
Owner

Respuesta a la auditoría — corregido en c9bd441 (c9bd4411e8), PR #9.

Críticos

  1. Aprobación firmable con cualquier nombre → audit_log encadenado por hash (verify_audit_chain); con CAYCE_OPS_OPERATOR_PUBKEY configurada, approve EXIGE firma BIP-340 sobre sha256(cayce-ops:approve:); deploy/roles.sql trae roles DB de mínimo privilegio por daemon (mitad deployment).
  2. Threading muerto → los envíos crean filas OUTBOUND reales (Message-ID propio, In-Reply-To → inbound); el message_id entrante ya no se sobrescribe; maild compose abre el camino de primer contacto; fallback de threading por cadena inbound.
  3. Reenvíos duplicados → una transacción por mensaje: fallo SMTP en N ya no resucita 1..N-1; fallos auditados (send_failed) y la fila queda en cola.
  4. Clasificador → aprobaciones negadas (cannot accept / not approved / not accepting) = REJECTION 0.95 antes de la regla de keywords; llaves del prompt LLM escapadas (.format ya no KeyError en silencio).
  5. systemd → run subcommand en los 5 daemons; timer diario separado para publisher plan documentado.

Medios

  • approved_hash ata el texto aprobado (editar = re-aprobar)
  • risk_score → match_score (migración 0002); auto-aprob ordena por relevancia DESC
  • postgres 127.0.0.1 en compose
  • IMAP \Seen solo tras commit
  • canales deshabilitados = SKIPPED terminal; presupuesto de intentos acotado
  • make hooks instala el gate; runner de CI sigue pendiente (AUDIT.md §6.1)

Verificación: ruff 0 · 56/56 tests · alembic 0001→0002 · gitleaks clean · make check exit 0.

Alcance: git bundle con todo el historial en la raíz del host: /home/ubuntu/cayce-ops-audit.bundle (git clone cayce-ops-audit.bundle).

Pendiente declarado: roles DB aplicados en prod (SQL listo), runner de CI, NIP-05.

**Respuesta a la auditoría** — corregido en c9bd441 (c9bd4411e8338a675ff84e3aa594421ac3786dc5), PR #9. ## Críticos 1. **Aprobación firmable con cualquier nombre** → audit_log encadenado por hash (verify_audit_chain); con CAYCE_OPS_OPERATOR_PUBKEY configurada, approve EXIGE firma BIP-340 sobre sha256(cayce-ops:approve:<id>); deploy/roles.sql trae roles DB de mínimo privilegio por daemon (mitad deployment). 2. **Threading muerto** → los envíos crean filas OUTBOUND reales (Message-ID propio, In-Reply-To → inbound); el message_id entrante ya no se sobrescribe; maild compose abre el camino de primer contacto; fallback de threading por cadena inbound. 3. **Reenvíos duplicados** → una transacción por mensaje: fallo SMTP en N ya no resucita 1..N-1; fallos auditados (send_failed) y la fila queda en cola. 4. **Clasificador** → aprobaciones negadas (cannot accept / not approved / not accepting) = REJECTION 0.95 antes de la regla de keywords; llaves del prompt LLM escapadas (.format ya no KeyError en silencio). 5. **systemd** → run subcommand en los 5 daemons; timer diario separado para publisher plan documentado. ## Medios - approved_hash ata el texto aprobado (editar = re-aprobar) - risk_score → match_score (migración 0002); auto-aprob ordena por relevancia DESC - postgres 127.0.0.1 en compose - IMAP \Seen solo tras commit - canales deshabilitados = SKIPPED terminal; presupuesto de intentos acotado - make hooks instala el gate; runner de CI sigue pendiente (AUDIT.md §6.1) **Verificación**: ruff 0 · 56/56 tests · alembic 0001→0002 · gitleaks clean · make check exit 0. **Alcance**: git bundle con todo el historial en la raíz del host: /home/ubuntu/cayce-ops-audit.bundle (git clone cayce-ops-audit.bundle). Pendiente declarado: roles DB aplicados en prod (SQL listo), runner de CI, NIP-05.
Author
Owner

Round 2 — aclaración de trazabilidad y nueva entrega (PR #10)

0. Trazabilidad

  • 61d5cfd es un commit de documentación POSTERIOR a c9bd441: agrega únicamente AUDIT.md (la tabla de respuesta round-1). No toca código. El diff de PR #9 (2da5f3f..c9bd441) no lo incluye porque es un commit suelto sobre main tras el merge. Con el bundle nuevo ya es verificable en contexto.
  • Bundle nuevo con historial completo: /home/ubuntu/cayce-ops-audit.bundle (mismo path que pediste). Incluye todos los branches y el historial hasta el commit auditado.

Entrega round 2 — PR #10, un commit por punto

  • audit-1 40453aa: firmas obligatorias (1a-1f): mensaje sha256(cayce-ops:<tipo>:<deployment_id>:<id>:<content_hash>) (deployment_id = env nueva obligatoria); firma COMPLETA en fila (col operator_signature, migración 0003) y audit; re-verificación en ejecución/envío/publicación con reversión al estado previo y auditoría de error; sin ramas if approved_hash and …; fallos auditados desde el CLI.
  • audit-2 903c591: clasificador — cualquier negación en el mail veta approval → needs_review (las 6 oraciones pedidas, todas ≠ approval).
  • audit-3 d774091: roles.sql reescrito (roles por daemon, cayce_approver único aprobador, triggers por tabla, sin contraseñas literales — falla sin las -v, exit 3) + test de integración en Postgres con ciclo completo por rol (chain alembic upgrade→downgrade→upgrade).
  • audit-4 ffe4253: cadena serializada (pg_advisory_xact_lock / RLock-sqlalchemy hasta commit), génesis explícito para filas legacy, monitor anchor publica el hash como nota Nostr firmada 1 vez/día y lo audita.
  • audit-5 56b35d3 (commit marcador; el código entró dentro de audit-1 — maild.py se stageó entero): send_approved del CLI llama _send_approved con factory; fallos auditados + daemon_runs; exit ≠ 0 con cualquier error.
  • audit-6 c855f01: CI con servicio postgres:16 — upgrade/downgrade/upgrade de migraciones + suite de integración.
  • audit-7 3bde785: cayce-ops-plan.service/.timer (diaria).

Gate en 13db399 (HEAD, AUDIT.md con tabla hallazgo→commit→test): ruff 0 · 65 unit + 1 integración PG · alembic 0001→0003 round-trip en PG · gitleaks --all limpio · make check exit 0.

No marco nada como resuelto: queda a tu verificación. Pendientes declarados: aplicar roles.sql en producción (lo hacen ustedes; la credencial de cayce_approver no existe en ningún .env ni sistema mío) y provisionar el runner de CI.

PR #10: audit-round2 → main (merge aba42a4); AUDIT.md 13db399; bundle /home/ubuntu/cayce-ops-audit.bundle.

**Round 2 — aclaración de trazabilidad y nueva entrega (PR #10)** ## 0. Trazabilidad - `61d5cfd` es un commit de documentación POSTERIOR a `c9bd441`: agrega únicamente AUDIT.md (la tabla de respuesta round-1). No toca código. El diff de PR #9 (`2da5f3f..c9bd441`) no lo incluye porque es un commit suelto sobre main tras el merge. Con el bundle nuevo ya es verificable en contexto. - **Bundle nuevo con historial completo**: `/home/ubuntu/cayce-ops-audit.bundle` (mismo path que pediste). Incluye todos los branches y el historial hasta el commit auditado. ## Entrega round 2 — PR #10, un commit por punto - audit-1 `40453aa`: firmas obligatorias (1a-1f): mensaje `sha256(cayce-ops:<tipo>:<deployment_id>:<id>:<content_hash>)` (deployment_id = env nueva obligatoria); firma COMPLETA en fila (col operator_signature, migración 0003) y audit; re-verificación en ejecución/envío/publicación con reversión al estado previo y auditoría de error; sin ramas `if approved_hash and …`; fallos auditados desde el CLI. - audit-2 `903c591`: clasificador — cualquier negación en el mail veta approval → needs_review (las 6 oraciones pedidas, todas ≠ approval). - audit-3 `d774091`: roles.sql reescrito (roles por daemon, cayce_approver único aprobador, triggers por tabla, sin contraseñas literales — falla sin las -v, exit 3) + test de integración en Postgres con ciclo completo por rol (chain alembic upgrade→downgrade→upgrade). - audit-4 `ffe4253`: cadena serializada (pg_advisory_xact_lock / RLock-sqlalchemy hasta commit), génesis explícito para filas legacy, `monitor anchor` publica el hash como nota Nostr firmada 1 vez/día y lo audita. - audit-5 `56b35d3` (commit marcador; el código entró dentro de audit-1 — maild.py se stageó entero): send_approved del CLI llama _send_approved con factory; fallos auditados + daemon_runs; exit ≠ 0 con cualquier error. - audit-6 `c855f01`: CI con servicio postgres:16 — upgrade/downgrade/upgrade de migraciones + suite de integración. - audit-7 `3bde785`: cayce-ops-plan.service/.timer (diaria). **Gate en `13db399` (HEAD, AUDIT.md con tabla hallazgo→commit→test)**: ruff 0 · 65 unit + 1 integración PG · alembic 0001→0003 round-trip en PG · gitleaks --all limpio · make check exit 0. **No marco nada como resuelto**: queda a tu verificación. Pendientes declarados: aplicar roles.sql en producción (lo hacen ustedes; la credencial de cayce_approver no existe en ningún .env ni sistema mío) y provisionar el runner de CI. PR #10: audit-round2 → main (merge `aba42a4`); AUDIT.md `13db399`; bundle `/home/ubuntu/cayce-ops-audit.bundle`.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: cayce/cayce-ops#7