---
name: professional-document
description: >
  Compose a print-ready A4 PDF of a generic business document — proposal, report
  (market / analysis / strategic), brief, memo, white paper, plan (non-fundraise),
  or case study — from an operator brief plus brand tokens and graph context.
  Trigger phrases: "write me a proposal", "draft a proposal", "draft a report",
  "produce a report", "compile a report", "draft a market report", "draft an
  analysis report", "draft a strategic report", "write me a brief", "draft a
  brief", "write me a memo", "draft a memo", "send a memo", "draft a white paper",
  "write a white paper", "draft a plan", "write me a plan" (triggers a fundraise
  vs non-fundraise gate), "write me a case study", "draft a case study". Refuses
  and redirects briefs that are owned by another composer: fundraise documents
  (prospectus / term sheet / business plan / data room) route to
  `venture-studio:investor-data-room`; property brochures route to
  `real-agent:property-brochure`; pre-valuation packs route to
  `real-agent:property-preval`; consulting decks (new-business or credentials
  pitch, client findings or recommendation deck, thought-leadership deck) route
  to `management-consulting:pitch-deck`; founder fundraise decks route to
  `venture-studio:investor-data-room`; generic slide decks the operator already
  wrote or supplies as HTML route to `admin:deck-pages` (format spec). Does NOT
  trigger on
  format-only phrasings ("PDF", "one-pager", "A4", "brochure", "executive
  document", "market analysis") — those are owned by `admin:a4-print-documents`.
---

# Professional document

Invoked from `specialists:content-producer`.

Compose a single A4 PDF of a generic business document from an operator brief, brand tokens, and the graph. The skill body is the workflow contract; load it once via `Skill professional-document` at the start of the turn and follow it through to delivery.

## Refusal taxonomy (run first, before any composition)

These checks run in order against the operator brief. The first match wins and stops the workflow with a one-sentence refusal that names the correct composer. Do not compose when any refusal fires.

| Brief mentions | Refuse, redirect to | Why |
|---|---|---|
| prospectus, term sheet, data room, business plan, investor, fundraise, raise, round, SEIS, EIS, cap table | `venture-studio:investor-data-room` | Owns the UK seed-raise pack end-to-end (16-section plan, prospectus, term sheet, FCA self-cert appendices). |
| property brochure, property listing brochure | `real-agent:property-brochure` | Owns the estate-agent brochure pipeline (brand → property → A4 PDF). |
| pre-valuation, preval, valuation pitch, pre-appraisal | `real-agent:property-preval` | Owns the 5-page pre-valuation pitch pack. |
| consulting deck, credentials pitch, capabilities deck, client findings deck, recommendation deck, steering-committee deck, board strategy deck, thought-leadership deck | `management-consulting:pitch-deck` | Owns the consulting deck method and the house-voice gate across all three modes. |
| founder pitch deck, investor deck, fundraise deck | `venture-studio:investor-data-room` | Owns the founder fundraise pitch. |
| deck, slides, slide deck, presentation (generic, operator-supplied, or save-this-HTML) | `admin:deck-pages` | Slide format spec and generic renderer; not an A4 document and not a consulting composer. |
| noun is "plan" and none of the fundraise tokens above match | **Ask the operator** before proceeding: "Is this a fundraise plan (business plan for investors) or an operating / strategic / marketing / transition plan?" If fundraise → refuse, redirect to `venture-studio:investor-data-room`. If non-fundraise → proceed. | The word "plan" splits cleanly between the two composers; the precision doctrine requires asking rather than guessing. |

Emit `[professional-document] refuse reason=<owned-by-other-composer> redirect=<skill-name>` on any refusal. Emit `[professional-document] plan-disambiguation asked` when the plan gate fires and `[professional-document] plan-disambiguation answered=<fundraise|non-fundraise>` once the operator answers.

When a refusal fires, return a single sentence naming the correct composer: e.g. "That's a fundraise document — ask `venture-studio:investor-data-room` instead." Do not draft, do not outline, do not load `a4-print-documents`.

## Document-type catalogue

Each entry below names the document type, its purpose, the default section order, the length range (which determines the page count target for the A4 build), the default tone, and the existing skills it composes with. Pick the matching entry from the operator brief; if the brief is ambiguous between two types, ask which one before drafting.

### `proposal`
- **Purpose:** Persuade a named recipient (customer, partner, supplier) to accept a defined offer.
- **Section order:** Cover / Summary of the offer / The problem we are solving for you / Proposed approach / What you get / Pricing and timeline / Why us / Next step.
- **Length:** 4–8 pages.
- **Tone:** Direct, customer-centred, second person ("you"). No filler.
- **Composes with:** `memory-search` for the recipient's known context; `prose-craft` for sentence review when writer-craft is enabled; `a4-print-documents` for the A4 shell.

### `report`
- **Purpose:** Present findings on a defined subject (market, analysis, strategic) to a defined audience. Sub-types: market report, analysis report, strategic report.
- **Section order:** Cover / Executive summary / Scope and method / Findings (numbered sections, one per finding) / Implications / Recommendations / Sources and references.
- **Length:** 5–15 pages, depending on findings density.
- **Tone:** Third person, evidence-led. Every quantitative claim cites a source (graph node id when grounded in the graph, named publication when grounded by research-assistant brief-back).
- **Composes with:** `memory-search` for graph-known facts; `research-assistant` brief-back (via the admin agent) for facts not in the graph; `prose-craft` when writer-craft is enabled; `a4-print-documents` for the A4 shell. Numbered references render in the footer area per `a4-print-documents` page-margin patterns.

### `brief`
- **Purpose:** Hand off a defined unit of work or context to a named owner. Decision-ready.
- **Section order:** Cover / Context (1 paragraph) / The ask (3-5 bullets) / Constraints / Out of scope / Owner and timing.
- **Length:** 1–3 pages.
- **Tone:** Imperative, terse. The reader should know what to do after one read.
- **Composes with:** `memory-search` for the context paragraph; `a4-print-documents` for the A4 shell. `prose-craft` review is optional at this length and is skipped if it would add a turn for negligible benefit.

### `memo`
- **Purpose:** Internal communication of a decision, position, or update to a defined audience.
- **Section order:** Header (To / From / Date / Subject) / Bottom line up front (1 paragraph) / Background / Decision or position / What changes / Open questions.
- **Length:** 1–4 pages.
- **Tone:** First person plural ("we") for organisational memos, first person singular ("I") for personal memos. Direct.
- **Composes with:** `memory-search` for the background section; `a4-print-documents` for the A4 shell. `prose-craft` review optional.

### `white-paper`
- **Purpose:** Establish a position on a substantive topic for a broad professional audience. Often used to influence a market or regulatory conversation.
- **Section order:** Cover / Abstract / Introduction / The problem in detail / Our analysis / Our position / Implications for [audience] / Conclusion / Citations.
- **Length:** 8–20 pages.
- **Tone:** Authoritative, third person, citation-dense.
- **Composes with:** `memory-search`; `research-assistant` brief-back for any factual claim not in the graph; `prose-craft` when writer-craft is enabled; `a4-print-documents` for the A4 shell.

### `plan` (non-fundraise)
- **Purpose:** Define how a named outcome will be achieved over a stated horizon. Includes operating plans, strategic plans, marketing plans, transition plans, hiring plans, integration plans.
- **Section order:** Cover / The outcome / Why now / Current state / Target state / Workstreams (numbered) / Milestones / Owners and cadence / Risks and mitigations / Out of scope.
- **Length:** 5–15 pages.
- **Tone:** Outcome-led, owner-named, dated.
- **Composes with:** `memory-search` for owners, projects, and prior state; `prose-craft` when writer-craft is enabled; `a4-print-documents` for the A4 shell. The plan-disambiguation gate above must have fired and returned "non-fundraise" before this branch runs.

### `case-study`
- **Purpose:** Document a completed engagement (customer, project, internal initiative) as a credibility artefact for use elsewhere.
- **Section order:** Cover / At-a-glance (1 paragraph + 3 numbers) / The situation / What we did / What changed / Quotes / What's next.
- **Length:** 3–6 pages.
- **Tone:** Narrative, named-subject. Numbers are dated. Quotes attributed by name and role.
- **Composes with:** `memory-search` for the named subject and adjacent facts; `prose-craft` when writer-craft is enabled; `a4-print-documents` for the A4 shell.

## Workflow

Run these phases in order. Do not skip; do not parallelise. Each phase emits its observability line on completion.

### 1. Resolve brand tokens

Read `brand.json` for the active brand. Take colours from `defaultColors` (`primary`, `primaryHover`, `primarySubtle`, `primaryGlow`, `accent`, `background`, `agentBubble`) and fonts from `defaultFonts` (`display`, `body`). These feed the `:root` CSS variables in the A4 HTML built later. Do not invent colours; if a brand override is missing, fall back to the default brand's values rather than hard-coding hex.

### 2. Ground in the graph

Run `memory-search` against the brief's named subjects (people, organisations, projects, products). Pull every relevant property into the outline. If the brief depends on a fact the graph does not carry (a market figure, a regulatory citation, a named comparable), do not invent it: hand the admin agent a brief-back asking it to dispatch `research-assistant`, and pause until the fact is returned.

### 3. Draft the outline

Compose an outline using the section order from the document-type catalogue for the matched type. Number every section. For each section, write one line stating what it will say (the claim) and one line stating which graph facts or research-assistant returns will ground it.

Emit `[professional-document] outline doc-type=<type> sections=<n>`.

### 4. Operator-approve the outline

Return the outline to the operator as a turn. Wait for the operator to answer "go" / "approve" / "yes" or to send revisions. If revisions are requested, re-draft the outline once and re-emit; if a second revision is requested, propose continuing inline rather than another full re-draft.

Emit `[professional-document] outline-approval asked` when the outline goes to the operator, and `[professional-document] outline-approval answered=<approve|revise>` when the operator answers.

Do not start section drafts until the outline is approved.

### 5. Draft each section

Draft section by section in outline order. Each section uses the brand tokens from phase 1, the graph facts from phase 2, and the section's stated claim from phase 3. Cite sources inline (graph node id for graph-grounded facts, named publication for research-assistant-returned facts).

Emit `[professional-document] draft section=<i/n> wordcount=<n>` after each section.

### 6. Optional prose review

Attempt `skill-load skillName=prose-craft`. If it returns the skill body, apply it as a review pass over the draft and emit `[professional-document] prose-review applied`. If it returns skill-not-found (writer-craft not enabled on this brand or account), apply a one-shot self-review prompt against the doctrine in this skill and emit `[professional-document] prose-review skipped reason=writer-craft-not-enabled`. Never block the workflow on prose review.

### 7. Build the A4 HTML

The first tool call of this phase MUST be `Skill a4-print-documents`. Any browser tool call before that skill is loaded into context is a contract violation. Load `skill-load skillName=a4-print-documents` and follow its rules verbatim — page margins, glassmorphism fallback, page-break rules, dark-background colour-adjust, the cover and backpage pattern. Do not paraphrase those rules; the print-CSS contract lives in that skill.

Emit `[professional-document] render → a4-print-documents`.

### 8. Ask the operator for the output path

Before saving the PDF, ask the operator where they want it saved. When the document is a deliverable for a known Job (its scope of works, budget estimate, warranty, valuation, or completion certificate), propose `jobs/<jobNumber>/<file>` as the default path, where `<jobNumber>` is the job's canonical numeric id, the same key the quote path uses at `quoting/jobs/<jobId>/`. If no `jobs/<jobNumber>/` folder exists yet, it is created; `jobs/` is an ontology entity bucket, so the deliverable sits directly under the job's folder, not in `output/`. For a document tied to no Job record, ask without proposing a default. The operator can always confirm the default or name a different path, and the path the operator confirms is where the PDF is written and what the observability line records. Do not write to a path the operator has not confirmed.

### 9. Save the PDF

`browser-navigate` to the served HTML, then `browser-pdf-save` to write the PDF to the operator-named path (on-device Chromium print pipeline; no Playwright).

Emit `[professional-document] pdf-saved path=<operator-named-path> bytes=<n>`.

### 10. Deliver

The PDF you saved is the deliverable. How you hand it over depends on the surface this turn arrived on. On a message channel (web chat, WhatsApp, Telegram), call `SendUserFile` with the saved path and the platform forwards the PDF to that conversation as a real attachment. On the admin dashboard, any saved path under `accounts/<accountId>/` (a job's `jobs/<jobNumber>/` folder, `output/`, or elsewhere in the account tree) appears in the Artefacts panel (downloadable) and is reachable on the file share. Either way, state the complete path in your reply, never a vague pointer. See the `file-presentation` skill for the wording.

## Doctrine

- **Compose, do not duplicate.** `a4-print-documents` owns the print-CSS rules; this skill loads it and follows it. `prose-craft` owns sentence-level review; this skill invokes it when present. `memory-search` owns graph reads; this skill calls it for grounding. The seam is "this skill is the workflow; the loaded skills carry the rules."
- **Refuse before composing.** Every brief runs through the refusal taxonomy first. A skill that drafts something it should have refused is a routing defect, not a quality issue.
- **Operator-named output path.** For a deliverable tied to a known Job, the skill proposes that job's `jobs/<jobNumber>/` entity folder as the default; for anything else it proposes no path. The operator confirms the default or names a different path, and the skill never writes to a path the operator has not confirmed. This matches how `investor-data-room` and the property composers work.
- **Approve the outline before drafting.** Long documents whose structure is wrong cost more to re-draft than they cost to re-outline. The approval turn is cheap; the wasted draft is expensive.
- **No invented facts.** Every quantitative or named claim grounds in `memory-search` or a `research-assistant` brief-back. If the graph does not carry the fact and the operator has not asked for research, draft a one-line gap statement in place ("[GAP: <description>]") and surface it in the outline-approval turn.
- **No live web research from this skill.** If a fact is missing, ask the admin agent to dispatch `research-assistant`. This skill does not call `WebFetch` or `WebSearch` directly.
- **Brand tokens or fallback, never hard-coded hex.** Colours and fonts come from `brand.json#defaultColors` / `defaultFonts`. If the active brand omits an override, use the default brand's value, not a literal hex.

## Observability lines (full list)

These are the lines this skill emits. They surface in `server.log` via the existing PTY stdout capture; no new log file, no new structured event.

```
[professional-document] refuse reason=<owned-by-other-composer> redirect=<skill-name>
[professional-document] plan-disambiguation asked
[professional-document] plan-disambiguation answered=<fundraise|non-fundraise>
[professional-document] outline doc-type=<type> sections=<n>
[professional-document] outline-approval asked
[professional-document] outline-approval answered=<approve|revise>
[professional-document] draft section=<i/n> wordcount=<n>
[professional-document] prose-review applied
[professional-document] prose-review skipped reason=writer-craft-not-enabled
[professional-document] render → a4-print-documents
[professional-document] pdf-saved path=<operator-named-path> bytes=<n>
```
