Um flow de n8n que orquestra um ciclo de emissão de litigation hold — emitindo o aviso de hold por e-mail e Slack para os custodiantes nomeados, rastreando confirmações com lembretes em cadência configurável, escalando não-confirmadores para o responsável de legal-ops e para o gestor do custodiante, registrando cada ação em uma tabela de auditoria imutável que a empresa usa se a adequação do hold for questionada posteriormente. Substitui o ciclo manual de planilha-e-regras-no-Outlook do admin de legal-ops (tipicamente um ônus contínuo de 2-4 horas por semana quando alguns holds estão ativos) por um flow determinístico que não consegue deixar cair um custodiante.
Quando usar
A empresa emite litigation holds com uma frequência em que o rastreamento manual começa a falhar — geralmente >3 holds ativos a qualquer momento.
Você tem uma fonte de custodians de registro: uma tabela de gestão de custodiantes na plataforma de e-discovery (Relativity, Everlaw, Logikcull) ou em um CSV de legal-ops mantido.
A empresa precisa de uma trilha de auditoria defensável para adequação do hold. A tabela de auditoria do flow é a resposta a “mostre-nos que agiu razoavelmente para preservar.”
O responsável de legal-ops e o advogado externo aprovam a emissão do hold; o flow lida com o rastreamento contínuo, não com a decisão de emitir.
Quando NÃO usar
Engajamentos de hold único onde o rastreamento manual é suficiente. O custo de setup (120 minutos, mais integração com a fonte de custodiantes) se paga a partir do ~3 holds ativos, não a partir de um.
Escalação automática que ignora o advogado. Os caminhos de escalação do flow são configuráveis, mas o padrão envia para o responsável de legal-ops, NÃO diretamente para o GC ou advogado externo. O responsável aplica julgamento sobre quais não-confirmações merecem atenção do advogado.
Avisos de hold que precisam de linguagem personalizada por custodiante. O flow utiliza templates por matter; se cada aviso precisa de linguagem artesanal, o gargalo não é a orquestração.
Substituir o julgamento do advogado sobre o escopo do hold. O flow rastreia o hold para os custodiantes que o advogado nomeou. Adicionar ou remover custodiantes é uma decisão do advogado, não do flow.
Setup
Importe o flow. Coloque apps/web/public/artifacts/litigation-hold-orchestration-n8n/litigation-hold-orchestration-n8n.json na sua instância de n8n.
Conecte as credenciais. Quatro obrigatórias: PLACEHOLDER_CUSTODIAN_DB_CRED_ID (acesso de leitura à fonte de custodiantes), PLACEHOLDER_SMTP_CRED_ID (SMTP para e-mail do aviso de hold), PLACEHOLDER_SLACK_CRED_ID (Slack para notificação no canal), PLACEHOLDER_AUDIT_DB_CRED_ID (acesso de escrita à tabela de auditoria imutável).
Crie o template do aviso de hold. Por matter, escreva um template Markdown em n8n/data/hold-notices/<matter-id>.md. O template inclui linguagem aprovada pelo advogado sobre escopo de preservação, ações proibidas (exclusão, alteração) e instruções de confirmação.
Configure os caminhos de escalação. O padrão do flow: lembrete em +3, +7, +14 dias; escalação para o responsável de legal-ops em +14; escalação para o gestor do custodiante em +21. Ajuste conforme o perfil de risco da empresa.
Configure a tabela de auditoria. Uma tabela Postgres/Snowflake com chave em (hold_id, custodian_id, action, timestamp) com uma restrição de apenas-append aplicada no nível do banco (imutável; o advogado precisa demonstrar que o log de auditoria não pode ser editado retroativamente).
Execute um dry-run em um hold fechado. Reproduza a lista de custodiantes de um hold fechado. Confirme que os tempos de notificação, lembrete e escalação correspondem ao que o admin de legal-ops fazia manualmente antes.
O que o flow faz
Sete nós, em duas fases. A Fase 1 (emissão) dispara uma vez por hold. A Fase 2 (rastreamento) é um cron diário verificando não-confirmadores e despachando lembretes/escalações.
Issue Trigger — trigger manual ou webhook da plataforma de legal-ops quando o advogado marca um hold como pronto para emitir.
Load Custodian List — extrai a lista de custodiantes da fonte configurada para o matter.
Send Hold Notice — e-mail + Slack para cada custodiante. O e-mail inclui o template do aviso de hold e um link de confirmação único por custodiante. Log de auditoria: uma linha por custodiante por notice_sent.
Daily Cron Tracker (trigger de workflow separado) — segunda a sexta às 9h no fuso horário do escritório. Verifica a tabela de auditoria por custodiantes que não confirmaram dentro da janela configurada.
Determine Action — nó de Código. Para cada não-confirmador, determina: enviar lembrete (+3, +7), escalar para o responsável de legal-ops (+14), escalar para o gestor (+21).
Dispatch Reminder / Escalation — envia e-mail de lembrete ou escalação, conforme a ação determinada. Entrada no log de auditoria por despacho.
Acknowledgement Webhook — webhook separado que recebe o clique de confirmação do custodiante. Registra na tabela de auditoria; interrompe lembretes adicionais para aquele custodiante.
Custo real
Custo de n8n — self-hosted gratuito; n8n Cloud na contagem de execuções de workflow que isso gera (~3-5/dia por hold ativo) está confortavelmente no plano Starter.
Tokens de LLM — nenhum. O flow é determinístico.
SMTP/Slack — dentro das cotas padrão.
Tempo de admin de legal-ops — o ganho. O rastreamento manual de 5-10 holds ativos é de 4-8 horas/semana. A operação do flow é monitorar a tabela de auditoria por verdadeiras exceções, ~30 min/semana.
Tempo de setup — 120 minutos incluindo o provisionamento da tabela de auditoria, mais 30-60 minutos por matter para a criação do template do aviso de hold.
Métrica de sucesso
Tempo de emissão desde a decisão “emitir” do advogado — deve cair para menos de 1 hora (o manual costuma ser um dia para listas grandes de custodiantes).
Taxa de confirmação em +14 dias — deve superar 95% em holds de rotina. Abaixo disso, o template do aviso precisa ser refeito ou a lista de custodiantes tem registros desatualizados.
Completude da auditoria na revisão do advogado — participação de holds onde o advogado consegue produzir uma cadeia de auditoria completa e defensável sob demanda. Deve ser 100%; a tabela de auditoria é a fonte.
vs alternativas
vs módulo de hold built-in da plataforma de e-discovery (Relativity Legal Hold, Logikcull, Everlaw). Escolha o módulo da plataforma se você vive na ferramenta de e-discovery. Escolha o flow se seus custodiantes abrangem Slack, e-mail e sistemas de RH e você precisa de superfícies de notificação além dos padrões da plataforma.
vs ferramentas SaaS de gestão de hold (Onna, Exterro Legal Hold). Escolha essas para self-service avançado de custodiantes e preservação integrada. Escolha o flow se você quer a orquestração na sua própria infraestrutura com o log de auditoria no seu próprio banco de dados.
vs planilha + regras do Outlook. O padrão e a fonte de custodiantes abandonados em escala. O flow é o substituto determinístico.
Pontos de atenção
Deriva da lista de custodiantes.Proteção: o flow re-extrai a lista de custodiantes por verificação, com o last_updated_at da fonte verificado. Se a lista derivou (custodiante adicionado/removido) sem aprovação do advogado, o flow apresenta o diff para o responsável de legal-ops em vez de agir silenciosamente na nova lista.
Mutabilidade da tabela de auditoria.Proteção: a tabela de auditoria deve ser apenas-append no nível do banco de dados (Postgres: REVOKE UPDATE, DELETE FROM ALL). O flow não aplica isso — o banco aplica. O README documenta o schema com a restrição inline.
Deriva do texto do aviso.Proteção: templates de aviso por matter são hashados no momento da emissão; o log de auditoria captura o hash. Se o advogado quiser alterar o aviso, a alteração é uma ação separada no flow, não uma re-emissão silenciosa.
Opt-out ou ignorância silenciosa do custodiante.Proteção: a escalação para o gestor em +21 dias converte o problema de um problema do custodiante em um problema de gestão. Além disso, o responsável de legal-ops pode precisar envolver o advogado externo — o flow apresenta mas não age.
Diferenças de hold entre jurisdições.Proteção: o flow assume a semântica de litigation hold no estilo dos EUA. O “dever de preservar” no estilo europeu sob o AI Act e o GDPR tem escopo diferente; o template de aviso por matter lida com esses casos.
Postura de privacidade no e-mail do custodiante.Proteção: avisos de hold podem sinalizar a existência de um matter de litígio para o custodiante; o caminho SMTP usa o relay de e-mail da empresa (não um SaaS de terceiros) para confidencialidade.
Stack
O bundle fica em apps/web/public/artifacts/litigation-hold-orchestration-n8n/:
litigation-hold-orchestration-n8n.json — o export do flow
_README.md — setup de credenciais, schema da tabela de auditoria, procedimento de dry-run
audit-table-schema.sql — DDL para a tabela de auditoria imutável
hold-notice-template.md — template de aviso de hold preenchível por matter
Ferramentas: n8n (orquestração), Slack (notificação no canal), Claude (opcional — para o resumo diário da atividade do log de auditoria para o responsável de legal-ops, não para nenhuma etapa de decisão).
# Litigation hold orchestration — n8n flow
Orchestrates a litigation-hold issue cycle: notification, acknowledgement tracking, reminder cadence, escalation paths, and an immutable audit log. Replaces the spreadsheet-and-Outlook-rules manual cycle with a deterministic flow that can't drop a custodian.
## Import
1. Import `litigation-hold-orchestration-n8n.json` into n8n.
2. Set workflow timezone to your office TZ.
3. Provision the audit table (DDL in `audit-table-schema.sql`).
4. Wire credentials.
5. Do NOT enable until dry-run confirms behavior on a closed hold.
## What ships in this bundle
This n8n export covers the **issuance** half of the cycle (Phase 1). The tracking + escalation half (Phase 2 — daily cron, reminders, escalation) is intentionally a separate workflow you wire to the same audit table; that lets the issuance flow be triggered fresh per hold while the tracker runs continuously across all active holds.
The Phase 2 tracker is a 4-node workflow:
1. Cron daily 9am office TZ.
2. Postgres query against the audit table: select hold/custodian pairs without `acknowledged` action.
3. Code node: determine action (reminder at +3, +7; escalation to legal-ops lead at +14; escalation to manager at +21).
4. Email send + audit-log append.
The DDL and the audit-query are in this README's appendix below; the Phase 2 export is left to the legal-ops engineer to assemble per the firm's escalation paths (which vary by jurisdiction and matter type more than the issuance step does).
## Credentials
### `PLACEHOLDER_CUSTODIAN_DB_CRED_ID` — Custodian source
Read access to wherever the custodian list lives:
- **In-house Postgres** — the default. Schema documented in the `Load Custodian List` node.
- **Relativity / Everlaw / Logikcull** — replace the Postgres node with an HTTP node calling the platform's custodian endpoint.
- **HRIS** — possible if HRIS is the source of truth, but legal-ops typically maintains the custodian list separately.
### `PLACEHOLDER_SMTP_CRED_ID` — SMTP
Use the **firm's own mail relay**, not a third-party SaaS like SendGrid. Hold notices may flag the existence of a litigation matter; routing them through a third party expands the privilege exposure.
### `PLACEHOLDER_SLACK_CRED_ID` — Slack bot token
`chat:write` scope. The bot needs to be invited to the workspaces where custodians live; per-custodian DMs require user-level scope which Slack handles automatically when the bot is in the workspace.
### `PLACEHOLDER_AUDIT_DB_CRED_ID` — Audit table
Write access to the audit table. The table itself must be append-only at the DB level (DDL below).
## Audit table schema
```sql
CREATE TABLE hold_audit (
audit_id BIGSERIAL PRIMARY KEY,
hold_id TEXT NOT NULL,
custodian_id TEXT NOT NULL,
action TEXT NOT NULL CHECK (action IN (
'notice_sent',
'reminder_sent',
'escalated_to_lead',
'escalated_to_manager',
'acknowledged',
'released'
)),
template_sha TEXT,
payload_json JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX hold_audit_lookup_idx ON hold_audit (hold_id, custodian_id, action);
-- Immutability: the audit table is the firm's defensibility chain.
-- Counsel needs to be able to demonstrate the log can't be edited.
REVOKE UPDATE, DELETE, TRUNCATE ON hold_audit FROM PUBLIC;
REVOKE UPDATE, DELETE, TRUNCATE ON hold_audit FROM <legal_ops_app_role>;
GRANT INSERT, SELECT ON hold_audit TO <legal_ops_app_role>;
```
The `REVOKE` statements are NOT optional. Without them the table is editable, and counsel cannot demonstrate the audit log's defensibility under e-discovery scrutiny.
## Hold-notice template
Save per-matter templates as `n8n/data/hold-notices/<matter-id>.md`. The template uses these placeholders, replaced per custodian by the `Personalize Notice` node:
- `{{custodian_name}}` — custodian's full name
- `{{matter_id}}` — matter identifier
- `{{hold_id}}` — hold identifier
- `{{ack_url}}` — per-custodian acknowledgement URL
Sample template structure (counsel approves the actual language):
```
Dear {{custodian_name}},
This is a litigation hold notice for Matter {{matter_id}}.
You are required to preserve all documents, communications, and electronic
data related to [counsel-defined scope]. This includes [specific systems
and document types].
You must NOT delete, alter, or destroy any potentially relevant material,
even if it would be deleted under normal retention policy.
Please acknowledge receipt of this notice by clicking the link below
within 7 business days:
{{ack_url}}
If you have questions about scope or what to preserve, contact [legal-ops
contact].
This hold remains in effect until you receive a written release notice
from the legal department.
[counsel signature block]
```
## Phase 2 tracker query
The Phase 2 daily cron uses this query to find non-acknowledgers:
```sql
WITH last_action AS (
SELECT hold_id, custodian_id, MAX(created_at) AS last_action_at,
BOOL_OR(action = 'acknowledged') AS acknowledged
FROM hold_audit
WHERE action IN ('notice_sent', 'reminder_sent', 'acknowledged', 'released')
GROUP BY hold_id, custodian_id
)
SELECT
la.hold_id,
la.custodian_id,
la.last_action_at,
EXTRACT(EPOCH FROM (NOW() - la.last_action_at)) / 86400 AS days_since_last_action,
(SELECT MIN(created_at) FROM hold_audit ha
WHERE ha.hold_id = la.hold_id AND ha.custodian_id = la.custodian_id
AND ha.action = 'notice_sent') AS first_notice_at
FROM last_action la
WHERE la.acknowledged = false
AND NOT EXISTS (
SELECT 1 FROM hold_audit ha
WHERE ha.hold_id = la.hold_id AND ha.custodian_id = la.custodian_id
AND ha.action = 'released'
);
```
The tracker computes `days_since_first_notice`, decides action, dispatches.
## Dry-run procedure
1. Provision the audit table on a non-production DB.
2. Wire credentials against staging endpoints (test SMTP, test Slack workspace).
3. Replay a closed hold's custodian list manually.
4. Confirm: notification fires once per custodian; audit log records each send; per-custodian acknowledgement URLs are unique.
5. Switch to production DB. Issue your next real hold via the flow.
## Known limits
- Phase 1 issuance only ships in this n8n export; Phase 2 tracker is documented but not bundled.
- The flow assumes per-custodian email + Slack. Custodians without Slack accounts (contractors, alumni) get email only — the Slack node fails gracefully but the failure is silent in the audit log. The Phase 2 tracker should treat email-only custodians the same as Slack+email.
- Acknowledgement URL routing requires a separate webhook endpoint (the `/ack/<hold>/<custodian>/<token>` URL) — deploy that as a small Express / Flask endpoint that writes `action: acknowledged` to the audit table. The endpoint is NOT bundled.
- The flow does not handle hold-release. Release is its own action — when counsel releases, a separate webhook writes `action: released` to the audit table per custodian. The tracker stops sending reminders to released custodian/hold pairs.
-- Litigation hold audit table — append-only DDL.
-- Counsel's defensibility chain depends on this table being immutable.
CREATE TABLE hold_audit (
audit_id BIGSERIAL PRIMARY KEY,
hold_id TEXT NOT NULL,
custodian_id TEXT NOT NULL,
action TEXT NOT NULL CHECK (action IN (
'notice_sent',
'reminder_sent',
'escalated_to_lead',
'escalated_to_manager',
'acknowledged',
'released'
)),
template_sha TEXT,
payload_json JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX hold_audit_lookup_idx
ON hold_audit (hold_id, custodian_id, action);
CREATE INDEX hold_audit_created_idx
ON hold_audit (created_at);
-- Immutability constraints. NOT optional.
-- Replace <legal_ops_app_role> with the DB role your n8n flow uses.
REVOKE UPDATE, DELETE, TRUNCATE ON hold_audit FROM PUBLIC;
GRANT INSERT, SELECT ON hold_audit TO <legal_ops_app_role>;
-- Optional: row-level revisioning if you anticipate legitimate
-- corrections (e.g. a custodian acknowledged offline and the lead
-- needs to record it). Even then, NEVER UPDATE existing rows —
-- INSERT a 'corrected_offline' action with a payload_json reference
-- to the prior row's audit_id, preserving the original record.
# Hold notice template
Per-matter template the litigation-hold flow personalizes per custodian. Copy this file to `n8n/data/hold-notices/<matter-id>.md` per matter and customize counsel-approved language.
The template uses these placeholders, replaced per custodian by the `Personalize Notice` node:
- `{{custodian_name}}`
- `{{matter_id}}`
- `{{hold_id}}`
- `{{ack_url}}`
---
# Litigation Hold Notice — Matter {{matter_id}} — Hold {{hold_id}}
Dear {{custodian_name}},
The firm's legal department is issuing a litigation hold related to Matter {{matter_id}}. As a custodian whose records may be relevant, you are required to take immediate steps to preserve potentially relevant material.
## What you must preserve
You must preserve all documents, communications, and electronic data related to [counsel-defined scope — replace with matter-specific scope]. This includes, but is not limited to:
- Email (work and any personal email used for work-related communication on this matter)
- Slack messages, including DMs and channel posts
- Documents (Google Drive, SharePoint, OneDrive, local files)
- Calendar entries
- [Other systems specific to this matter — replace with named systems]
The scope covers material from [counsel-defined date range] to the date this hold is released in writing.
## What you must NOT do
You must NOT delete, alter, modify, or destroy any potentially relevant material, even if the firm's normal retention policy would otherwise permit deletion.
You must NOT discuss this hold's scope or substance with anyone outside the legal team and your direct counsel of record.
## What this means in practice
- **Auto-deletion settings:** check email, Slack, and document-system retention settings. If any are set to delete material in the relevant scope, contact [legal-ops contact] immediately.
- **Personal devices:** if you have used personal devices or accounts for any work related to this matter, [legal-ops contact] will work with you on appropriate preservation.
- **Departing the firm:** if you leave the firm while this hold is in effect, [legal-ops contact] will work with HR and IT to preserve your records before any account decommissioning.
- **Replacement of equipment:** do not destroy or recycle hardware in scope until [legal-ops contact] confirms preservation.
## Acknowledgement
You must acknowledge receipt of this notice within 7 business days. Please click the link below:
[{{ack_url}}]({{ack_url}})
If you have not received an automated reminder by [date + 14 days], please contact [legal-ops contact] to confirm your acknowledgement was recorded.
## Questions
For questions about scope or what to preserve, contact:
- [legal-ops contact name and email]
- [outside counsel contact, if applicable]
Do NOT discuss the substance of the matter outside this channel.
## When this hold ends
This hold remains in effect until you receive a written release notice from the legal department. Verbal release is not sufficient. Until you receive written release, you must continue to preserve material in scope.
---
[counsel signature block]
[firm letterhead — match firm's standard hold-notice formatting]