Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"Bash(ls skills/cgp/references/)",
"Bash(ls -la /home/soares/development/context-generic/.claude/skills/)",
"Bash(diff -q skills/cgp/SKILL.md /home/soares/development/context-generic/.claude/skills/cgp/SKILL.md)"
]
}
}
1 change: 1 addition & 0 deletions .claude/skills/cgp
207 changes: 207 additions & 0 deletions .claude/skills/dual-reader-prose/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
---
name: dual-reader-prose
description: >
Apply this skill whenever you are writing explanatory content, documentation,
instructional text, analysis, reports, or any substantive prose that will be
read by a mixed audience. Use it when the user asks you to "write clearly",
"make this readable", "explain this well", or whenever the content is long
enough that different readers might approach it differently. Also trigger when
the user explicitly asks for a style that works for both skimmers and deep
readers, or when converting bullet-heavy AI output into more readable form.
Do not use for short conversational replies, single-sentence answers, or
creative fiction.
---

# Dual-Reader Prose

Good writing serves two kinds of readers at once. Some people scan first and
read only what they need. Others read every word in order and want the full
picture. Most formats help one group and hurt the other. Bullet points help
scanners but frustrate deep readers. Dense prose helps deep readers but loses
scanners. This skill shows you how to write for both. Use prose by default, and
use bullets only when the content is truly a list.

---

## Write in Plain English

Plain words and short sentences help both readers. A scanner grasps the point
faster. A deep reader follows the argument with less effort. So the first rule
is simple: say things plainly.

**Prefer simple words.** Choose the common word over the fancy one. Write "use"
instead of "utilize", "show" instead of "demonstrate", and "help" instead of
"facilitate". A plain word is easier to read and never sounds thin.

**Write short sentences.** One sentence should carry one idea. When a sentence
runs long or holds two or three ideas, split it. Short sentences are easier to
scan and easier to follow.

**Cut words you do not need.** Remove filler like "in order to", "it is
important to note that", and "the fact that". If a word adds nothing, delete it.

**Say it directly.** Prefer the active voice and a clear subject. Write "the
reader stops here" instead of "it is at this point that the reader may cease".

Plain English is not the same as shallow writing. You keep every idea. You just
say each one in the clearest way you can.

---

## The Two Reader Types

Readers behave differently because they process information differently. The
difference is not random. It reflects how each person reads and remembers.

**Scanner-first readers** come to a text with a goal. They want to find what
they need, skip what they know, and move on. They read the first sentence of a
paragraph to decide whether to read the rest. Lists and headers are their map.
When a text is all prose with no visual anchors, they feel the writer is wasting
their time and making them dig. Bullet points feel fast and respectful. These
readers often work at speed, read a lot each day, and have learned to scan on
purpose.

**Sequential-depth readers** read a text as one argument that builds step by
step. They read prose the way others listen to music. The flow carries meaning
that single points cannot. When they hit bullet points, they feel the reasoning
has been cut out. They see claims without evidence and steps without reasons.
They also find bullets harder to remember, because prose forms a story the brain
holds on to, while loose bullets feel like a random list. These readers distrust
writing that feels thin, and they will re-read a hard passage rather than skip
it.

The two groups do not disagree about the *quality* of the information. They
disagree about the *form* that makes it easy to use. Good writing finds a form
that works for both.

---

## The Core Technique: Topic Sentence + Elaboration

The best bridge between the two readers is the topic-sentence paragraph. Start
every paragraph with one sentence that states the main point in full. The
sentences after it explain, expand, and give evidence.

Scanners read only the opening sentences and still get the whole structure of
your argument. Deep readers read everything and get the full reasoning. Neither
group loses out. This is not new. It is the standard method of good journalism,
science writing, and legal prose, and it has worked for a long time because both
reader types have always existed.

The rule this demands is simple: **the opening sentence must stand on its own.**
If a scanner reads only your first sentences and comes away with the wrong or
partial picture, your topic sentences are not doing their job. Test them by
reading only the first line of each paragraph in order. If that reading makes
sense on its own, you have succeeded.

---

## Supporting Techniques

A few more techniques back up the core method without turning the text into a
pile of bullets.

**Bold key terms, but rarely.** When a paragraph introduces a term that matters,
bold it on first use. Scanners use the bold as a landmark. Deep readers read the
sentence around it. Keep it to one or two bold phrases per section. Too much bold
teaches readers to ignore it, which defeats the point.

**Lead with the main point in each section.** State the conclusion first, then
add support in order of importance. A reader who stops partway through should
still leave with the most important idea, not a half-argument that makes no
sense.

**Keep paragraphs short and focused.** One paragraph should make one point. If a
paragraph makes three points, you have three paragraphs. Short paragraphs give
scanners clean stopping points and give deep readers one idea to hold at a time.

**Use headers only for real shifts.** Headers help scanners navigate, but they
break the flow for deep readers. Use them to mark a true change of topic, not as
decoration and not as a fix for weak transitions. A header every two paragraphs
means you have given up on prose.

**Write transitions that also summarize.** The sentence that ends one section and
opens the next should restate what you just showed and point to what comes next.
Scanners use these as checkpoints. Deep readers feel them as the glue of the
argument.

---

## When Bullets Are the Right Choice

Prose is the default, but lists are not banned. Use bullets when you are truly
listing a set of loosely related items. These are items whose only link is that
they belong to the same group, not a chain of reasoning where each point leads
to the next. Good cases include a list of independent options, a set of
unordered settings, discrete steps a reader will do one at a time, or numbered
items a reader may want to point to on their own.

The test is whether the list form is *clearly* better than a paragraph, not just
okay. If the items flow into each other, depend on each other, or share one line
of argument, prose serves both readers better, so write prose. But if forcing
them into sentences would give you a stiff "first, second, third" paragraph that
is really a list in disguise, use the list. When you are unsure, take that doubt
as a sign: the content probably does not need bullets, so use prose.

Even when you use a list, frame it. Write a sentence before it that says what the
items share and why they matter. Add a sentence after it, when needed, that says
what to do with them. A framed list serves both readers. An orphaned one serves
only the scanner.

---

## What to Avoid

Some habits help one reader and hurt the other. Naming them makes them easier to
catch.

**Avoid orphaned bullets.** This is a list with no lead-in sentence and no
follow-up. It is the most common failure in AI writing. Scanners can read it,
but deep readers have no idea why the items matter or what to do with them. The
problem is not the list. It is the missing frame. When a list is right, keep it
and frame it with a sentence before and, when useful, a sentence after.

**Avoid reflexive bullets.** The opposite mistake is breaking prose into a list
out of habit. If the items share one line of reasoning or flow into each other,
bullets cut the thread that deep readers need and hand scanners a set of
fragments with no argument. Use bullets only when the list form is clearly
better than the paragraph.

**Avoid burying the point.** Prose that saves its conclusion for the last
sentence fails scanners, because they never reach it. Put the point at the top
and let the detail follow.

**Avoid too much bold.** Bolding more than a few phrases per page is like
shouting every third word. When everything is bold, nothing stands out. Scanners
stop tracking it, and deep readers find it noisy.

**Avoid fake structure.** Three levels of nested bullets, headers under headers
under headers, and lists of lists add visual noise without clarity. Real
structure lives in the logic of the argument, not in the indentation.

---

## A Quick Self-Check

Before you send any substantial piece of writing, run these checks.

Read only the first sentence of each paragraph in order. If that reading tells a
clear story, your topic sentences work.

Read only the bold phrases in the document. If there are more than a handful, cut
most of them.

Find your longest paragraph. Ask whether it makes one point or several. If
several, split it.

Find the first place where you state your main conclusion. If it is not in the
first or second paragraph, move it there.

Find every list. Ask whether its items are truly loosely related or an argument
in disguise. If the items flow into each other, turn the list back into prose.

Read your longest sentences aloud. If one is hard to say in one breath or holds
more than one idea, split it or cut it down.

A document that passes these checks reads well for both audiences. It is not a
compromise. It is simply better structured than pure bullets or unbroken prose.
73 changes: 30 additions & 43 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,75 +1,62 @@
name: Rust Unit Tests
name: Tests

on:
pull_request: {}
push:
branches: main
branches: [main]

env:
CARGO_INCREMENTAL: 0
CARGO_PROFILE_DEV_DEBUG: 1
CARGO_PROFILE_RELEASE_DEBUG: 1
CARGO_TERM_COLOR: always
RUST_BACKTRACE: short
CARGO_NET_RETRY: 10
RUSTUP_MAX_RETRIES: 10

# Cancel previous runs of this workflow when a new commit is added to the PR, branch or tag
# Cancel in-progress runs when a new commit is pushed to the same PR, branch, or tag.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

# To minimize supply-chain exposure this workflow uses only GitHub's own
# first-party checkout action; every toolchain and tool is installed with the
# rustup/cargo already present on the runner.
jobs:
fmt:
name: Rustfmt (nightly)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt
- uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Install nightly rustfmt
run: rustup toolchain install nightly --profile minimal --component rustfmt
- run: cargo +nightly fmt --all -- --check

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: clippy
override: true
- uses: Swatinem/rust-cache@v2
- uses: actions-rs/clippy-check@v1
with:
name: clippy-all-features
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features --all-targets -- -D warnings
- uses: actions-rs/clippy-check@v1
with:
name: clippy-no-default-features
token: ${{ secrets.GITHUB_TOKEN }}
args: --no-default-features --all-targets -- -D warnings
- name: Install pinned toolchain
run: rustup toolchain install
- name: Clippy (all features)
run: cargo clippy --all-features --all-targets -- -D warnings
- name: Clippy (no default features)
run: cargo clippy --no-default-features --all-targets -- -D warnings

test:
name: Test (nextest)
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: Swatinem/rust-cache@v2
- name: Install pinned toolchain
run: rustup toolchain install
# Prebuilt binary from the official nextest distribution.
- name: Install cargo-nextest
run: curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin
- uses: actions-rs/cargo@v1
with:
command: test
args: --all-features --no-fail-fast --no-run
- uses: actions-rs/cargo@v1
with:
command: nextest
args: run --all-features --no-fail-fast --workspace --no-capture
# Runs the whole workspace, including the trybuild compile-fail fixtures in
# cgp-compile-fail-tests (an ordinary integration test nextest picks up).
- name: Run tests
run: cargo nextest run --all-features --no-fail-fast --workspace
Loading
Loading