Skip to content
Agency Skills
Browse skillsContributorsContribute a skill
Install every skill
Agency Skills

Skills written by the people who run agencies, consultancies and coaching firms. Free and open source, MIT.

LibraryAll skillsCollectionsContributorsInstall every skillFor AI agents (llms.txt)
ContributeHow to contributeContributor guideGitHubReport a problem
GiaLearn about GiaBook a build session
A community project, published by Gia.PrivacyTerms
Skills/Run the firm/Write in the owner's voice
Run the firm

Write in the owner's voice

Use this skill when an agent drafts outward messages that go out under a firm owner's name (email, direct messages, posts, comments, texts) and the owner keeps catching wording they would never write. Drafts come from the owner's real sent writing: the agent changes the nouns of the nearest sent message, checks the draft against hard rules, never-written phrases, usual length and past corrections, and sends only on a pass from the last hour. Every night, drafts matched to sent mail become swaps, and a held-out test scores whether a judge can tell a draft from the real thing. Also use for "write it like me", "draft this in my voice", "reply for me", "that doesn't sound like me", "why does this read like a robot".

Paul MunroPaul MunroFounder, AppliedGTM
LinkedInappliedgtm.com
Say something like
“write it like me”“draft this in my voice”“reply for me”“that doesn't sound like me”“why does this read like a robot”
voicedraftingemailowner-ledwriting-checksend-gate
SKILL.mdView on GitHub

Applies whenever you draft a message that will go out under the owner's name, to a client, a peer, a vendor, a prospect or the public. Produces one checked draft built from the owner's own sent writing, and a pass that lets it be sent within the hour.

The play

  1. Keep a local corpus of what the owner wrote: one record per sent message, the owner's words only. Quoted replies, forwarded blocks, the signature and tracking footers are cut. It is built from mail and chat exports, or from messages you read through a connector. The corpus holds client mail and personal messages, so it stays on the owner's machine. Record shapes are in references/json-shapes.md.
  2. Before you write a word, pull the nearest examples and the register:
    examples --to ADDRESS_OR_NAME --channel email --n 8
    examples --to ADDRESS_OR_NAME --channel email --stats
    
    Examples rank by the same recipient first, then the same email domain, then the same channel and kind of recipient, then a similar length, then word overlap with the facts you give. A message that breaks a hard rule is never offered, so you cannot copy a habit the owner has since dropped. --stats gives the median length, the median sentence length, and the owner's usual openers and closers.
  3. Write the draft by changing the nouns of the nearest example. Keep its opener, its length and its close. The rules are the check, never the source.
  4. Put the exact text to be sent in a file, with no subject line, and check it:
    check FILE --to ADDRESS_OR_NAME --channel email --save-draft
    
    The check returns BLOCK, FLAG or PASS. What each catches is in references/the-check.md.
  5. Act on the result:
    • BLOCK: rewrite each listed line as a new sentence. Changing its punctuation is not a rewrite. Run the check again.
    • FLAG: read each flagged word, phrase or length note. Change whatever the owner would not write. Keep what they would, such as a name or a term from the thread.
    • PASS or FLAG writes a pass for that exact text and saves the draft for the nightly loop.
  6. Send that same text within 60 minutes. One changed word after the check needs a new check. A hook in front of every send tool refuses a send whose text has no pass from the last hour. A refusal is never worked around. The draft goes back to step 2.
  7. When the owner corrects your wording, record the correction the same turn as a swap: your phrase, their phrase. From then on the check catches it.
  8. Let the nightly loop run without the owner: yesterday's sent mail goes into the corpus, saved drafts are matched to what was sent, the changes become swaps, and a held-out test scores the drafting. The order is in references/the-loop.md.

What good looks like

  • First thing I check: whether the draft started from a sent example or from a description of my style. A draft written from rules reads like a draft written from rules. One note carried a technical phrase I had to catch myself, and that is why the system exists.
  • The mediocre version is a long style guide and a reminder to follow it. It drifts within a week. The check and the gate hold because they are mechanical.
  • I know it is working when I send drafts unchanged. Each one is recorded as a pass, and the swap list stops growing.
  • I know the drafting is good when the held-out judge sits near 0.5. That means it cannot tell the draft from what I really sent.
  • Red flag: a swap list full of the agent's own rewrites. Several drafts of one note once got written up as my corrections. Only the newest draft of a note is matched to what I sent now. The earlier ones are marked superseded and never become swaps.

Rules

  • MUST pull examples and the register before drafting, for every outward message in the owner's name.
  • MUST check the exact text to be sent, and check again after any change.
  • MUST rewrite every BLOCK line as a new sentence.
  • MUST send within 60 minutes of the pass, or check again.
  • MUST record each wording correction from the owner as a swap in the same turn.
  • MUST keep the corpus local, on the owner's machine.
  • NEVER upload, quote, post or link the corpus or any message in it to a connector, a shared page, a task tool or any remote host.
  • NEVER draft from the style rules alone.
  • NEVER work around a gate refusal. Go back to the examples.
  • NEVER let the drafting side of the nightly test see the real message it is drafting.
  • NEVER expect a script to do a model's job. The scripts call no model. The agent does that part.
3 reference files
references/json-shapes.md

Record shapes

All files sit in the corpus folder on the owner's machine, except the pass files, which sit in the agent's own settings folder. Addresses below are placeholders.

Corpus record

One per line in corpus.jsonl:

{"id": "gmail:3f9a0c1d2e4b5a6c", "source": "gmail", "channel": "email",
 "date": "2026-10-26T10:15:00-04:00", "to": ["client@example.com"], "to_kind": "client",
 "subject": "Re: Plan", "thread_before": "the previous message, up to 600 characters",
 "text": "the owner's words only", "words": 54, "ingested": "2026-11-01T15:52:00+00:00"}

source is gmail, slack, linkedin or text. channel is email, dm, channel, post, comment or text. to holds addresses for email, names for direct messages, #name for a chat channel, and public for posts and comments.

Add list

The input to ingest --add, a JSON list. Only source, channel, date and text are required. The full body may be pasted; it is cleaned the same way.

[{"source": "gmail", "channel": "email", "date": "2026-10-31T14:02:00-04:00",
  "to": ["client@example.com"], "subject": "Re: plan", "thread_before": "their message",
  "text": "the full body as sent"}]

Recipients

recipients.json, a flat map from an address, an @domain or a name to a kind: client, peer, vendor, friend, prospect, public or unknown. Keys starting with _ are comments.

{"client@example.com": "client", "@example.com": "client", "Sam": "vendor"}

Pass file

voice-pass/<sha256>.json, the hash taken over the normalised text. latest.json adds head, the first 200 characters.

{"ts": "2026-11-01T15:52:00+00:00", "epoch": 1793548320.0, "sha": "...", "tier": "FLAG",
 "to": ["client@example.com"], "channel": "email", "kind": null}

Saved draft

drafts/<YYYY-MM-DD>_<sha8>.json:

{"text": "...", "to": ["client@example.com"], "channel": "email", "kind": "client",
 "ts": "2026-11-01T15:52:00+00:00"}

Pair

One per line in pairs.jsonl. result is unchanged, changed or superseded.

{"draft_id": "2026-11-01_3f9a0c1d", "sent_id": "gmail:...", "to": ["client@example.com"],
 "date": "2026-11-01T16:20:00-04:00", "draft": "...", "sent": "...", "result": "changed",
 "overlap": 0.82, "changes": [["<your phrase>", "<their phrase>"]]}

Swap

One per line in swaps.jsonl:

{"my_phrase": "<your phrase>", "owners_phrase": "<their phrase>", "count": 2,
 "first_seen": "2026-10-31", "last_seen": "2026-11-02"}

Held-out test

Items, answers and results, in eval/:

{"date": "2026-11-02", "items": [{"item_id": "e1", "to": ["client@example.com"],
  "channel": "email", "kind": "client", "thread_before": "..."}]}
{"date": "2026-11-02", "answers": {"e1": {"record_id": "gmail:...", "date": "...",
  "text": "...", "words": 87}}}
{"date": "2026-11-02", "items": [{"item_id": "e1", "facts": ["..."], "draft": "...",
  "real": "...", "real_was": "A", "judge_pick": "B", "judge_correct": false}]}

In results, item_id, draft, real and judge_correct are required. judge_correct is true when the judge picked the owner's real text.

Metrics

One line per scored date in metrics.jsonl:

{"date": "2026-11-02", "n": 5, "judge_accuracy": 0.6, "length_ratio": 1.12,
 "drafts_blocked": 0, "block_hits": 0, "corpus_records": 1243, "swaps_applied": 3,
 "scored_at": "..."}
references/the-check.md

The check

The check reads one file holding exactly the text that will be sent: the email body or the chat message, with no subject line. It returns one of three tiers and an exit code, and lists every hit with its line.

check FILE --to ADDRESS_OR_NAME --channel email --save-draft
check - --to ADDRESS_OR_NAME --channel dm        (reads the draft from standard input)

BLOCK (exit 2)

Any hit on the firm's hard rules. No pass is written. Hard rules are the things the owner has ruled out for good. A typical set:

  • punctuation the owner never uses, such as a long dash;
  • banned words and stock phrases, and filler transitions;
  • announcement phrases of the "we're excited to" kind;
  • internal labels left in a draft, such as a revision number;
  • contrast shapes that define a thing by what it is not, in any punctuation: "It's not X. It's Y.", "a X, not a Y", "Not X. Y."

Each hit is listed with its line. Rewrite the sentence. Swapping the punctuation keeps the shape, and the shape is what was banned.

FLAG (exit 1)

Things the owner might write, but has not yet:

  • Words and two-word phrases the owner has never written. Names, web addresses, numbers and a short stoplist of common words are ignored.
  • Length. A draft more than 1.5 times the median length of the owner's messages to this recipient. With too few messages to that person, the median for that kind of recipient is used, then the channel.
  • Swaps. Any phrase the owner has replaced twice or more, shown with the owner's replacement.
  • Filler intensifiers, allowed only in a warm social line.
  • A spaced short dash.

A FLAG still writes a pass. Read each line and change what is not the owner's. A term the other person used in the thread can stay.

PASS (exit 0)

None of the above.

The pass file

On PASS or FLAG the check writes a pass named by a hash of the normalised text: markup stripped, curly quotes straightened, whitespace collapsed, letters lowercased. So a change in spacing or quote style keeps the pass, and a changed word loses it. Passes older than seven days are removed.

--save-draft also keeps the draft for the nightly match against what was sent.

The gate

A hook runs before every send tool call. It refuses:

  • a mail send, reply, forward or draft, or a chat send or scheduled send, whose exact text has no pass from the last 60 minutes;
  • a browser click whose summary says send, post, publish, reply, submit or share, when no draft at all has passed in the last 30 minutes.

Messages only to the owner pass. Nothing else is stopped. Any error inside the hook lets the call through, so the gate can never break a turn. A refusal means the draft goes back to the examples.

references/the-loop.md

The loop

The system improves every night from two signals that need nothing from the owner: everything they send, and the difference between your draft and what they actually sent. It runs inside a scheduled early-morning run on weekdays.

The nightly order

  1. Read yesterday's sent mail and chat messages through the connectors. Write them to a dated file in the corpus inbox, in the list shape in json-shapes.md.
  2. Add them to the corpus:
    ingest --add INBOX/<date>_sent.json
    
    The same script also reads a mail export (--mbox), a chat export folder (--slack-json) or a social network data export (--linkedin-dir).
  3. Match drafts to sent messages:
    reconcile
    
  4. Pick the held-out items:
    evaluate sample --n 5
    
  5. Do the agent's part of the test, below.
  6. Score it:
    evaluate score <date>
    
  7. Mondays only, the one-line summary:
    evaluate report
    

Reconcile and swaps

Reconcile takes each saved draft from the last seven days and looks for the message the owner sent: same recipient, sent within 72 hours of the draft, sharing at least 5 distinct words that make up at least half of the shorter text's distinct words.

  • A draft sent unchanged is recorded as a pass.
  • A changed draft yields swaps. Each short stretch the owner replaced or cut becomes a swap: your phrase, their phrase. A swap is counted every time it recurs, and the check applies any swap seen twice or more.
  • Several saved drafts of one note (same recipient, within 72 hours of each other, overlapping above the same floor) count as one note. Only the newest is matched. The earlier ones are recorded as superseded and never become swaps. Without this rule, your own successive rewrites get written up as the owner's corrections.

A correction the owner gives you directly goes into the swaps file the same turn, so it does not wait for the nightly match.

The held-out test

Sample picks five messages the owner sent in the last 90 days. The same date always gives the same pick. A message qualifies when it has 15 to 400 words, passes the hard rules, was not used in an earlier test, and has at least two other messages to the same recipient (or of the same kind and channel), so the drafting side has examples to work from. It writes two files: the items the drafting side may see, and the answers, for the facts step and the scorer only.

Your part, for each item:

  1. A facts step reads the answer and writes the bare facts as a short list: who, what, dates, numbers, the ask. Never the wording.
  2. A drafting step that never sees the answer runs examples --to ... --channel ... --exclude-eval <date> and drafts from the facts and those examples. --exclude-eval leaves the held-out messages out, so a draft never sees its own answer.
  3. A separate model, the judge, gets the draft and the real text as A and B in random order and guesses which one the owner wrote.

Write the results file, then score. The score gives the judge's accuracy, the length ratio and the hard-rule blocks, and keeps the trend. A judge accuracy of 0.5 means it cannot tell the two apart. That is the goal.

Tests

Every script takes --corpus DIR to work on another folder. Test every change on a scratch folder, never on the real corpus.

Install this skill

Pick the app you use. We remember it for next time.

  1. Download the skill as a ZIP.
  2. In Claude, open Customize, then Skills, then Your skills.
  3. Choose Upload skill and pick the ZIP. Leave it switched on.
Download ZIPOpen Claude skills

Then ask: “write it like me”

Want the whole library, kept up to date? .

Run it on your own playbookBook 30 minutes. We build it onto a Company Brain live.
Run the firmcollection
Operationscategory
MITlicense

Install this skill

Pick the app you use. We remember it for next time.

  1. Download the skill as a ZIP.
  2. In Claude, open Customize, then Skills, then Your skills.
  3. Choose Upload skill and pick the ZIP. Leave it switched on.
Download ZIPOpen Claude skills

Then ask: “write it like me”

Want the whole library, kept up to date? .

A Company Brain

Want this sounding like you?

Out of the box it runs on general knowledge. On a Company Brain it runs on your framework, your pricing and the proposals you’ve already won with, so the output comes back in your voice.

Book 30 minutes

More from Paul

Win the work

Pipeline by script

When a small firm runs its pipeline from its own folder with no CRM and an agent records what happens on each deal. Every movement (a send, a reply, a booking, a decision that changes the next step or whose move it is) goes in through one script command that writes the pipeline row, the activity log line, an archive copy and the rebuilt dashboard together, and a drift check at the start of every agent turn names any row left behind its log line. Produces one Markdown pipeline file (open deals, channels, clients won, closed, and a dated activity log), a generated dashboard whose weekly counts come from event tags, and the commands that keep them in step. Also use for "log that reply", "move the deal", "add this to the pipeline", "close it out", "update the client row", "track pipeline without a CRM", "why is this row out of date".

Paul Munro · AppliedGTM
Win the work

Pre-session flash card

Before every session with a recurring coaching or advisory client, when you need one page to run the hour from. Produces the flash card: why this hour matters, the calls you make before the session, the opening move with the words to say, what the client decides today, the development block they asked for, dates and owners, a run sheet, what is already settled, and one closing line on how to be in the room. Built from the transcript of the last session and the recap you sent. Optionally produces a pre-read beside it. Also use for "flash card", "session card", "run sheet", "prep card", "pre-read", "prep me for my next session", "coaching session prep".

Paul Munro · AppliedGTM

More in Run the firm

Run the firm

Candidate interview coach

When a sales manager is about to interview a salesperson, has just finished one, or is about to make an offer. Three modes: /prep turns a CV or LinkedIn profile into red flags, forensic commercial-maths questions, a 45-second cold-call roleplay and accountability probes; /evaluate scores interview notes or a transcript on five dimensions with a hire, conditional or reject call; /contract generates a signature-ready Pre-Employment Accountability Agreement. Also use for "interview questions for a sales hire", "is this candidate any good", "sales rep CV review", "accountability agreement", "forensic interview".

Tony Dowling · CONVRG
Run the firm

CEO exec assistant

When the person running a small agency needs to know what the week actually demands, pulled from the project tool and the calendar rather than from memory. Produces a short brief: what is committed today and this week, what is at risk, what the calendar makes impossible, and the three things to do first. Also use for "what's on this week", "am I missing anything", "catch me up before Monday", "what's slipping".

Christian Beck · Five Four
Run the firm

Commercial KPI scoreboard

When a sales manager or rep asks how the numbers look for a rep or the whole team over today, this week, this month or the quarter. Produces a six-row scoreboard from live CRM deal data: presentations made, closing ratio, sales velocity, average order value, current billing, and position against target, with a 2 to 3 line commercial read. Also use for "how is Danny doing this month", "team scoreboard", "closing ratio", "sales velocity", "are we on target", "KPI check".

Tony Dowling · CONVRG