Tests for the required checks, and the fixes they drove:
- Unauthorized access is denied with core permission enforcement on.
Preparation, approval, execution and the agent need separate permissions.
The optional product security key bounds what users and the agent's tools
see.
- Drafts are made without publication authority. The agent has no approve,
schedule or send tool. A draft that cites a non-released claim gets a
blocker finding, which stops approval.
- Approval is invalidated by any approved-field edit, including a schedule
change. Status and approval rows can't be forged.
- Pause, resume and cancel. Duplicate scheduling and runs are refused.
Ambiguous outcomes are reconciled or decided by a person and never retried
blindly. Repeats are deduplicated by the idempotency key. Retries happen
only when the request was certainly not sent. Expired leases need
reconciliation.
- At execution time: the kill switch, the schedule, consent and suppression,
the bulk limit, channel AI-content rules, and unconfigured transports.
- Outcome events are deduplicated by (source, external id). Raw events and
unique actors are reported separately, and uninstrumented metrics show as
"Not measured". CRM import is idempotent, and leads are qualified only by
an explicit rule.
- Missing provider: the run fails with a plain reason and manual work still
runs. Provider errors are retried or failed by kind, and no secret appears
in errors. Budgets, the concurrency limit, cancellation and the model-call
limit are enforced.
- Persistence across a restart, on the RDBMS module over a file-backed H2
database created from the shipped DDL.
- The OpenAI-compatible provider is tested against a local HTTP fixture.
Fixes:
- Service entry points run as trusted internal work after their own
permission check, the same way QQQ trusts nested calls. Agent tools still
force PermissionEnforcement.ENFORCE.
- Content status and authorType are managed rather than required, and
productId is derived.
- Schedules are kept to the second, so stored values hash the same as
approved ones on every database.
- The Result screen lists skipped records with their reason.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>