audit-7 + docs: plan systemd units, D13-D15
- cayce-ops-plan.service/.timer (daily): the @ template cannot express publisher plan, so it gets its own unit - DECISIONS: D13 no non-human approvals; D14 signatures bind content + deployment; D15 negation veto classifier
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=cayce-ops publisher plan (fills the content calendar, daily)
|
||||
After=network-online.target postgresql.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=cayce
|
||||
WorkingDirectory=/srv/cayce-ops
|
||||
EnvironmentFile=/srv/cayce-ops/.env
|
||||
ExecStart=/srv/cayce-ops/.venv/bin/cayceops publisher plan
|
||||
NoNewPrivileges=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
ReadWritePaths=/srv/cayce-ops
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Run cayce-ops publisher plan daily
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 06:00:00
|
||||
RandomizedDelaySec=300
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -95,3 +95,25 @@ caption hash-bound at approval, disabled channels are terminal (`SKIPPED`),
|
||||
publish failures burn a bounded attempt budget before abandonment.
|
||||
`risk_score` renamed `match_score` (keyword relevance) and auto-approval
|
||||
takes the HIGHEST score first.
|
||||
|
||||
## D13 — No non-human approval path (round 2, supersedes D5)
|
||||
Operator signatures are mandatory for approvals AND re-verified at
|
||||
execution/send/publish time against current content + deployment id. With
|
||||
that gate, the AUTONOMOUS_MODE auto-approval path cannot exist: it would
|
||||
produce unsigned approvals the gate refuses. `_auto_approve` is inert and
|
||||
audits `autonomy_disabled` when invoked. *Cost:* AUTONOMOUS_MODE is now
|
||||
inert by design.
|
||||
|
||||
## D14 — Signatures bind content + deployment (round 2)
|
||||
message = sha256("cayce-ops:<type>:<deployment_id>:<id>:<content_hash>").
|
||||
content_hash is canonical-json of the fields that matter per type. Full
|
||||
signatures live on the row (operator_signature) and in the audit detail.
|
||||
Verification happens again at run time: unsigned rows (raw SQL approval)
|
||||
revert to their pre-approval state with an error audit. *Cost:* a deployment
|
||||
id env var is mandatory; signatures must be recomputed if content changes.
|
||||
|
||||
## D15 — Approval classifier veto (round 2)
|
||||
Any negation token anywhere in a mail vetoes an `approval` classification →
|
||||
needs_review. Simpler and strictly conservative vs. per-pattern negation
|
||||
lists. *Cost:* genuinely-positive approvals containing stray negations
|
||||
(e.g. "we have no reason not to welcome you") need human triage.
|
||||
|
||||
Reference in New Issue
Block a user