feat(campaigns): add governed collaboration thread
Module Package Release / publish-packages (push) Successful in 13s

This commit is contained in:
2026-08-22 00:09:34 +02:00
parent 5a21067e44
commit c2f083e5f6
25 changed files with 2315 additions and 24 deletions
+35 -3
View File
@@ -45,7 +45,8 @@ Campaign owns:
- message and attachment rules for a version;
- validation, review, build, queue, and delivery-control state;
- the durable jobs and attempts needed to explain delivery outcomes; and
- campaign-specific reports, shares, and frozen execution evidence.
- campaign-specific reports, shares, frozen execution evidence, and governed
human collaboration entries.
Campaign does not own:
@@ -111,6 +112,32 @@ action.
## User tasks
### Discuss campaign work
Open **Collaboration** inside a Campaign to keep human coordination beside the
work without changing its version history. Discussion access is independent
from Campaign editing: parent Campaign read access remains mandatory, while
`campaigns:discussion:read`, `campaigns:discussion:post`, and
`campaigns:discussion:moderate` separately control reading, posting, and
moderation. A read share is sufficient as the parent grant and a comment never
turns that share into write access.
Comments are append-only and bounded to 8,000 characters. They can carry one
validated reference to an immutable Campaign version, saved recipient import,
attachment rule, delivery job, or report. References to version-bound evidence
include the exact version ID and never edit that version. Authors can withdraw
their own comments; moderators can redact comments and use moderator-only
visibility. Both operations remove displayed text but preserve a tombstone,
content hash, actor snapshot, timestamp, reference context, and bounded Audit
event. There is deliberately no comment-edit API.
Mentions are limited to 20 active users who already have Campaign ownership or
share access. When Notifications is installed and healthy, Campaign emits a
content-free in-app mention notification. Collaboration remains usable without
Notifications. The thread displays only human discussion; approvals, workflow
state, delivery events, and durable system evidence remain on their owning
surfaces and in Tenant audit.
### Prepare a campaign
1. Create a campaign and confirm its owner or owning group.
@@ -563,7 +590,10 @@ namespaced Campaign references have been independently authorized and
corroborated, the provider searches only the effective tenant and isolates the
matching recipient entries and jobs. Its JSON result includes safe Campaign,
version, delivery-attempt, schedule, report-projection, share, import-mapping,
attachment, and generated-artifact metadata. Generated EML bytes and paths,
attachment, generated-artifact, and relevant collaboration metadata. It also
finds collaboration entries authored, mentioned, or moderated by the subject.
Text authored by the subject is included; somebody else's text is not copied
merely because the subject was mentioned. Generated EML bytes and paths,
storage locators, delivery target snapshots, worker claims, idempotency
material, credentials, secret-like values, and unrelated recipients are never
embedded in that result. Authorized Campaign and Files review surfaces remain
@@ -577,7 +607,9 @@ version JSON, jobs, generated messages, and managed files. The provider can
idempotently revoke an active share aimed at the subject and delete the
subject's personal recipient-import mapping profile. It does not rewrite
delivery evidence, delete generated artifacts, or report derived Campaign
counts as a separate store. Re-running an approved action is safe: already
counts as a separate store. Collaboration withdrawal and redaction retain the
tombstone, content hash, context, and Audit evidence; the DSAR workflow does
not rewrite these append-only records. Re-running an approved action is safe: already
revoked or absent data is reported as unchanged, and tenant, subject, and row
ownership are revalidated immediately before mutation.