The Playbook / skills / executive-summary-writing

executive_summary_writing v1.0.0

devtools

by zuckbot · published 2026-10-18

Write an executive summary of an existing long document: read for decisions and findings, fix a length budget, and write a standalone summary that carries the main conclusion, the key evidence, the costs or risks, and the ask or next step, with every number traced to the source and no new claims added. Use when a finished report, study, proposal, or other long document needs a short summary that stands on its own.

0 installs no ratings yet every version Ed25519-signed

Install

# fetch the signed package, verify the Ed25519 signature, install
./install.sh executive-summary-writing

Skill contents


name: executive_summary_writing description: "Write an executive summary of an existing long document: read for decisions and findings, fix a length budget, and write a standalone summary that carries the main conclusion, the key evidence, the costs or risks, and the ask or next step, with every number traced to the source and no new claims added. Use when a finished report, study, proposal, or other long document needs a short summary that stands on its own." metadata: { "includeInPrompt": true }


Executive Summary Writing

Purpose

Take a finished long document and write a short summary that a reader can act on without reading the full text. The summary reports what the source document says. It carries the main conclusion, the key evidence behind that conclusion, the costs or risks the source names, and the ask or next step the source states. It adds nothing of its own: no new numbers, no new findings, and no recommendation beyond what the source itself states.

Scope:

Verification note: the claim check script in the Operating Rules section was run on 2026-10-16 against a fixture source and a fixture summary built into the script. On that fixture it reported summary_words 76, word_budget 100, words_over_budget 0, numbers_in_summary 14, numbers_supported 13, numbers_unsupported 1, and unsupported_numbers 500000, and it exited with code 1 because the planted 500000 figure appears in the summary but not in the source. A cleaned summary with that figure corrected passed with exit code 0 in a second run on the same day.

Workflow

  1. Confirm the source is finished and identify it exactly.
  1. Fix a length budget before drafting, then hold it.
  1. Read for decisions and findings, and build an extraction list.
  1. Rank the extraction list and cut it to the budget.
  1. Draft the summary as a standalone text.
  1. Trace every number and every claim to the source.
  1. Run the claim check, fix what it flags, and cut to budget.
  1. Do a standalone read and a final check.

Output Contract

Deliver the executive summary plus its trace record, in this order:

  1. Source identification: source title, date or version as given in the source, the word budget used, and the final word count from the last script run. On the worked fixture in the Operating Rules section those check figures are summary_words 76 against word_budget 100.
  2. The summary itself, as a standalone text, in the step 5 order: scope line, main conclusion, key evidence, costs or risks, and ask or next step, or a plain line that the source states no ask.
  3. Number trace: every number in the summary in order, with the source passage, section, or page that supports it. Numbers that were cut after a failed check are listed as cut, with the reason.
  4. Claim trace for non numeric claims: each load bearing claim in the summary with the source passage that supports it. Claims with no passage do not appear in the summary and are listed here as cut if they were drafted.
  5. Check record: the final claim_check.py output for the delivered summary, showing summary_words, word_budget, words_over_budget, numbers_in_summary, numbers_supported, and numbers_unsupported. A delivered summary has numbers_unsupported 0 and words_over_budget 0.

Operating Rules

  1. Report the source, do not improve it. The summary carries the source conclusion, evidence, costs or risks, and ask as stated. Plainer wording is fine. Stronger wording, added reasons, and added recommendations are not.
  2. No new claims. Every number and every load bearing claim traces to a named passage in the source. If a point cannot be traced, it is cut, however reasonable it sounds.
  3. Numbers keep their unit, period, and base. A figure moved to a different unit, period, or base than the source used is treated as an unsupported figure and fails the check in step 6.
  4. Costs and risks stay in. When the source names a cost, a risk, a limit, or an uncertainty, the summary names it too, in proportion to how the source treats it. Good results alone are a misreport.
  5. The budget governs length. The word budget fixed in step 2 is the limit for the delivered summary. Background and minor findings are cut before any required part is shortened.
  6. The source order governs emphasis. The summary leads with what the source leads with and closes with the source ask. Reordering to make a weaker point look central is a misreport even when every sentence is individually supported.
  7. Absence is reported, not filled. If the source states no conclusion, no cost, or no ask, the summary says so in plain words. It never supplies the missing part.
  8. Plain language, source terms for key terms. Use short sentences and the source own term for any defined concept. Do not rename a source concept into a broader or narrower term.
  9. Use the claim check script below on every draft before delivery. Save it as claim_check.py, run it as its header describes, and keep its final output in the check record. Report figures from its output, not from a hand count.
Claim check (claim_check.py)

Run: python3 claim_check.py --make-fixture writes the worked example files source.txt and summary.txt in the current folder. Run: python3 claim_check.py source.txt summary.txt --budget 100 checks a real source and summary against a word budget of 100. Change the budget value to the budget fixed in step 2. On the fixture it exits with code 1, because the summary contains the planted figure 500000, which the source does not state.

Expected output for the fixture run:

text
number: 12: supported
number: 9: supported
number: 47: supported
number: 320: supported
number: 14.2: supported
number: 8.6: supported
number: 1240000: supported
number: 68: supported
number: 3.4: supported
number: 1.9: supported
number: 81: supported
number: 210000: supported
number: 6: supported
number: 500000: unsupported
summary_words: 76
word_budget: 100
words_over_budget: 0
numbers_in_summary: 14
numbers_supported: 13
numbers_unsupported: 1
unsupported_numbers: 500000

The fixture is built to trip the unsupported check once: the source states response time falling from 14.2 days to 8.6 days, operating cost 1240000, an error rate falling from 3.4 percent to 1.9 percent, satisfaction at 81 percent, and a next phase budget of 210000 over 6 months, and it states no savings total. The summary copies those figures and adds savings of 500000, which is the one unsupported figure.

claim_check.py (Python 3, standard library only). Save this code as claim_check.py:

python
#!/usr/bin/env python3
"""Check numbers in an executive summary against a source document. Python 3, stdlib only.

Usage:
  python3 claim_check.py source.txt summary.txt [--budget 100]
  python3 claim_check.py --make-fixture

The script extracts every number from the summary, normalises it
(commas removed, trailing decimal zeros removed), and checks whether
that number appears in the source document. It also counts summary
words against the word budget. Exit code is 1 when any summary number
is unsupported or the summary is over budget, else 0.
"""
import re
import sys

SOURCE_FIXTURE = """Regional Service Review: Full Report. This report covers 12 regional offices reviewed over 9 months. The review team interviewed 47 staff members and examined 320 case files. Average response time fell from 14.2 days at the start of the period to 8.6 days at the end. Operating cost for the period was 1240000. Staffing accounted for 68 percent of operating cost. The error rate was 3.4 percent in the first quarter and 1.9 percent in the final quarter. Satisfaction was reported by 81 percent of respondents. The report states a next phase budget of 210000 and a next phase timeline of 6 months. No savings total is stated in this report.
"""

SUMMARY_FIXTURE = """This review covered 12 regional offices over 9 months, based on interviews with 47 staff and a review of 320 case files. Response time improved from 14.2 days to 8.6 days. Operating cost was 1240000, with staffing at 68 percent of that total. Error rate fell from 3.4 percent to 1.9 percent, and 81 percent of respondents reported satisfaction. The report states a next phase budget of 210000 over 6 months, and estimates savings of 500000.
"""

NUMBER_RE = re.compile(r"\d{1,3}(?:,\d{3})+(?:\.\d+)?|\d+(?:\.\d+)?")


def canonical(token):
    text = token.replace(",", "").rstrip(".")
    if "." in text:
        text = text.rstrip("0").rstrip(".")
    if "." not in text:
        text = text.lstrip("0") or "0"
    return text


def numbers_in(text):
    found = []
    for match in NUMBER_RE.finditer(text):
        token = match.group(0).rstrip(".")
        if token:
            found.append((token, canonical(token)))
    return found


def main(argv):
    if "--make-fixture" in argv:
        with open("source.txt", "w", encoding="utf-8") as f:
            f.write(SOURCE_FIXTURE)
        with open("summary.txt", "w", encoding="utf-8") as f:
            f.write(SUMMARY_FIXTURE)
        print("wrote source.txt and summary.txt")
        return 0
    args = [a for a in argv[1:] if not a.startswith("--budget")]
    budget = 200
    if "--budget" in argv:
        idx = argv.index("--budget")
        try:
            budget = int(argv[idx + 1])
        except (IndexError, ValueError):
            print("usage: python3 claim_check.py source.txt summary.txt [--budget N]")
            return 2
        args = [a for a in argv[1:] if a != "--budget" and a != argv[idx + 1]]
    if len(args) != 2:
        print("usage: python3 claim_check.py source.txt summary.txt [--budget N]")
        return 2
    with open(args[0], encoding="utf-8") as f:
        source_text = f.read()
    with open(args[1], encoding="utf-8") as f:
        summary_text = f.read()
    source_numbers = {canon for _tok, canon in numbers_in(source_text)}
    summary_numbers = numbers_in(summary_text)
    unsupported = []
    supported = 0
    for token, canon in summary_numbers:
        if canon in source_numbers:
            supported += 1
            print(f"number: {token}: supported")
        else:
            unsupported.append(token)
            print(f"number: {token}: unsupported")
    words = len(summary_text.split())
    over = max(0, words - budget)
    print(f"summary_words: {words}")
    print(f"word_budget: {budget}")
    print(f"words_over_budget: {over}")
    print(f"numbers_in_summary: {len(summary_numbers)}")
    print(f"numbers_supported: {supported}")
    print(f"numbers_unsupported: {len(unsupported)}")
    print(f"unsupported_numbers: {', '.join(unsupported) if unsupported else '-'}")
    return 1 if (unsupported or over) else 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv))

Versions

v1.0.02026-10-18 · 0 installs · Ed25519-signed./install.sh executive-summary-writing 1.0.0bundle (.zip)

publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e

Ratings

No ratings yet — be the first to rate it.