legal-generate · git:20260812.fa04b2a · 2026-08-12 · sha256 372d607f28e9b2cd

legal-generate git:20260812.fa04b2aA

Immutable. This exact content is served forever at /api/v1/blob/372d607f28e9b2cd.

---
name: legal-generate
description: "This skill should be used when generating draft legal documents for a project or company. It gathers company context interactively, invokes the legal-document-generator agent, and writes markdown output."
---

# Legal Document Generator

Generate draft legal documents from company context. Supports 8 document types across US, EU/GDPR, and UK jurisdictions. All output is marked as a draft requiring professional legal review.

## Supported Document Types

- Terms & Conditions
- Privacy Policy
- Cookie Policy
- GDPR Policy
- Acceptable Use Policy
- Data Processing Agreement
- Data Protection Disclosure
- Disclaimer / Limitation of Liability

## Phase 0: Context Gathering

Use the **AskUserQuestion tool** to gather company context. Ask for:

1. **Company name** (required)
2. **Product/service description** (required) -- what the product does, who it serves
3. **Data practices** -- what user data is collected, how it is processed, stored, shared
4. **Jurisdiction** -- which legal frameworks apply (US, EU/GDPR, UK, or multiple)
5. **Contact information** -- email and/or physical address for legal notices

If the user provides arguments after the skill name (e.g., `/legal-generate privacy-policy`), use that as the document type selection and skip Phase 1.

## Phase 1: Document Selection

Use the **AskUserQuestion tool** to select a document type from the 8 supported types listed above.

## Phase 2: Generation

Invoke the `legal-document-generator` agent via the **Task tool** with the company context and selected document type:

```
Task legal-document-generator: "Generate a [document type] for [company name].
Company: [name]
Product: [description]
Data practices: [practices]
Jurisdiction: [jurisdiction]
Contact: [contact info]"
```

**Gates measure agreement, not truth (#7349).** All five gates compare the two surfaces against
each other. None asks whether the agreed text is correct, so two byte-identical copies of a false
sentence pass every one of them. Three defects shipped past a full green run in #7349 that way: a
controllership statement drift-reduction copied onto the published page, a duplicated clause left
behind by a half-applied replacement, and "eleven processing activities" in a document whose
register carries thirty-five. Read the prose; do not read the drift number and stop.

**`BODY_EQUIVALENCE_DOCS` is a one-way ratchet.** `terms-and-conditions`, `acceptable-use-policy`
and `disclaimer` are enrolled; each was verified at ZERO normalised drift immediately before
enrolment, because enrolling a drifted document turns a required check red on arrival. Once
enrolled, any edit landing on one surface only reds that check — which is the point. `--print-vocab`
and a mutation check (inject a line, confirm the guard fails, remove it) are the two ways to prove
an enrolment is live rather than decorative.

**Two measurement traps that cost real rounds in #7349.** `collapse()` normalises `[0-9]+ AI
agents` but NOT a bare `[0-9]+ agents`, so count divergence between the record and the published
page can be invisible to the drift gate. And a grep for `Article ` will not match the corpus's
plural `Articles 15 through 22` — use `Articles? 1[5-9]`.

## Phase 2.5: Redaction Gate (BLOCKING — runs BEFORE inline presentation)

A generated legal draft can echo a secret or PII that was passed in as company context (a contact email, an API identifier pasted into a data-practices answer). **Presenting the draft inline in Phase 3 is a transcript write boundary** — the same fail-closed rule the incident skill enforces (`incident/SKILL.md` Phase 6): the sentinel must precede inline-emit, not just file-commit. So the redaction gate runs here, before the operator ever sees the draft.

1. Write the generated draft to a `mktemp` file (do NOT emit it inline yet).
2. Run the shared hardened engine against it. Resolve the path from the **deployed plugin root**
   (`${CLAUDE_PLUGIN_ROOT}`, the platform-trusted copy), falling back to the git-root for CLI/worktree
   use — NOT a bare `../incident/...` relative path, which depends on the current working directory and,
   from the wrong CWD, exits `127` *outside* the shim (bypassing the shim's fail-closed exit-2
   normalization). On the Concierge server the deployed-root anchor is load-bearing: a bare CWD-relative
   path would resolve the connected repo's **untrusted** copy of the sentinel (ADR-093):

   ```bash
   SENTINEL="${CLAUDE_PLUGIN_ROOT:-$(git rev-parse --show-toplevel)/plugins/soleur}/skills/incident/scripts/redact-sentinel.sh"
   [[ -r "$SENTINEL" ]] || { echo "legal-generate: redaction sentinel not found — halt (fail closed)"; exit 2; }
   bash "$SENTINEL" <draft-tmpfile>
   ```

   The engine is owned by the `incident` skill and shared cross-skill by relative reference (see ADR-095).

3. Dispatch on the exit code (fail-closed):
   - **exit 0 (clean)** — proceed to Phase 3 and present the draft.
   - **exit 1 (redaction needed)** — print the finding lines (each is meta-redacted; never the full token), revise/redact the offending context, regenerate, and re-run the gate until it exits 0. Do NOT present or write an un-cleared draft.
   - **exit 2 (cannot-evaluate)** — halt. The engine could not run (skill bug, `python3` absent, unreadable tmpfile). Do NOT present or write; surface the error.

No un-scanned draft ever crosses the transcript or lands on disk.

## Phase 3: Output

<decision_gate>

Present the generated document to the user. Use the **AskUserQuestion tool** with options:

- **Accept** -- Write to disk
- **Edit** -- Provide feedback to revise (return to Phase 2 with feedback)
- **Reject** -- Discard and exit

</decision_gate>

On acceptance, write the markdown file to the user-specified path or default `docs/legal/<type>.md` (e.g., `docs/legal/privacy-policy.md`).

Report: "Draft written to `<path>`. This document requires professional legal review before use."

## Important Guidelines

- All generated documents include mandatory DRAFT disclaimers -- do not remove them
- Gather context interactively every time -- do not assume context from previous sessions
- One document type per invocation -- to generate multiple types, run the skill multiple times
- Output format is markdown only -- Eleventy .njk wrapping is out of scope for this skill
- **But the mirror is NOT out of scope for the corpus.** `docs/legal/<doc>.md` is the canonical
  record; `plugins/soleur/docs/pages/legal/<doc>.md` is the surface users actually read at
  soleur.ai/legal/. Writing canonical only leaves the published site unchanged AND trips
  [lint-legal-mirror-drift-baseline.sh](../../../../scripts/lint-legal-mirror-drift-baseline.sh), which exits 2 on a document that exists on
  exactly one surface. After generating, create the mirror in the same commit.
- Five CI gates ride `docs/legal/**` (#7387). Reproduce locally before pushing:
  `bash scripts/lint-legal-scope-block-placement.sh --base origin/main` (added scope blocks:
  referent agreement, attachment, discharge -- run `--print-vocab` for the accepted phrasings)
  and `bash scripts/lint-legal-mirror-drift-baseline.sh --base origin/main` (canonical<->mirror
  drift ratchet). The other three are `check-tc-document-sha.sh` (re-pin `legal-doc-shas.ts`
  after any canonical edit), `legal-doc-consistency.test.ts`, and the `EXPECTED_COUNT` sentinel.
- If the user asks for a document type not in the supported list, suggest the closest match or explain that the type is not supported