Vercel Composition Patterns
supabase/supabase
React composition patterns that scale. An agent skill from supabase/supabase.
Trace bugs and manual fixes back to kits and prompts; fix at the source so the iteration loop can reproduce the fix autonomously.
$ npx skills add JuliusBrussee/caveman-code --skill cavekit-revision -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install JuliusBrussee/caveman-code cavekit-revision --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/JuliusBrussee/caveman-code.git skills-src && mkdir -p .claude/skills && cp -r skills-src/packages/coding-agent/skills/cavekit-revision .claude/skills/cavekit-revision && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "cavekit-revision" agent skill from https://github.com/JuliusBrussee/caveman-code/tree/main/packages/coding-agent/skills/cavekit-revision into .claude/skills/cavekit-revision/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cavekit-revision", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/JuliusBrussee/caveman-code/tree/main/packages/coding-agent/skills/cavekit-revisionType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add JuliusBrussee/caveman-code --skill cavekit-revision -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install JuliusBrussee/caveman-code cavekit-revision --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/JuliusBrussee/caveman-code.git skills-src && mkdir -p .agents/skills && cp -r skills-src/packages/coding-agent/skills/cavekit-revision .agents/skills/cavekit-revision && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "cavekit-revision" agent skill from https://github.com/JuliusBrussee/caveman-code/tree/main/packages/coding-agent/skills/cavekit-revision into .agents/skills/cavekit-revision/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cavekit-revision", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add JuliusBrussee/caveman-code --skill cavekit-revision -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install JuliusBrussee/caveman-code cavekit-revision --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/JuliusBrussee/caveman-code.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/packages/coding-agent/skills/cavekit-revision .cursor/skills/cavekit-revision && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "cavekit-revision" agent skill from https://github.com/JuliusBrussee/caveman-code/tree/main/packages/coding-agent/skills/cavekit-revision into .cursor/skills/cavekit-revision/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cavekit-revision", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/JuliusBrussee/caveman-code.git --path packages/coding-agent/skills/cavekit-revision--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add JuliusBrussee/caveman-code --skill cavekit-revision -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install JuliusBrussee/caveman-code cavekit-revision --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/JuliusBrussee/caveman-code.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/packages/coding-agent/skills/cavekit-revision .gemini/skills/cavekit-revision && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "cavekit-revision" agent skill from https://github.com/JuliusBrussee/caveman-code/tree/main/packages/coding-agent/skills/cavekit-revision into .gemini/skills/cavekit-revision/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cavekit-revision", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install JuliusBrussee/caveman-code cavekit-revisionInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add JuliusBrussee/caveman-code --skill cavekit-revision -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/JuliusBrussee/caveman-code.git skills-src && mkdir -p .github/skills && cp -r skills-src/packages/coding-agent/skills/cavekit-revision .github/skills/cavekit-revision && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "cavekit-revision" agent skill from https://github.com/JuliusBrussee/caveman-code/tree/main/packages/coding-agent/skills/cavekit-revision into .github/skills/cavekit-revision/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cavekit-revision", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add JuliusBrussee/caveman-code --skill cavekit-revision -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install JuliusBrussee/caveman-code cavekit-revision --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/JuliusBrussee/caveman-code.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/packages/coding-agent/skills/cavekit-revision .opencode/skills/cavekit-revision && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "cavekit-revision" agent skill from https://github.com/JuliusBrussee/caveman-code/tree/main/packages/coding-agent/skills/cavekit-revision into .opencode/skills/cavekit-revision/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "cavekit-revision", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
cavekit-revisionTrace bugs and manual fixes back to kits and prompts; fix at the source so the iteration loop can reproduce the fix autonomously.
Cavekit Revision is an agent skill from JuliusBrussee/caveman-code. Trace bugs and manual fixes back to kits and prompts; fix at the source so the iteration loop can reproduce the fix autonomously. Six-step revision process plus the single-failure backpropagation protocol. Use when a manual hot-fix has been applied, when convergence stalls, or when the same class of bug keeps reappearing.
Its SKILL.md is about 3.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development. The repository describes itself as: Frozen — terminal coding agent measured at 1.93× fewer tokens than Codex CLI. Still works; active development moved to JuliusBrussee/caveman (caveman wrap). The licence is MIT.
7 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 3a21be1. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
readgrepbashFrom allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Cavekit Revision loads about 3.6k tokens when it runs. Until then it costs about 85 tokens; SKILL.md has 1,328 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from JuliusBrussee/caveman-code at commit 3a21be1, republished under its MIT licence (© JuliusBrussee). 1,328 words, ~3,631 tokens.
.claude/skills/cavekit-revision/SKILL.md (or your agent's skills folder).In Cavekit, revision means tracing a production defect upstream through the cavekit chain until you find the gap that allowed it. In practice, when the built software has bugs or gaps, you trace the issue back to the kits and prompts and fix at the source -- not just in code.
Key insight: When a fix lives only in code with no corresponding cavekit update, the next iteration loop may reintroduce the same defect. The goal is that kits plus the iteration loop can reproduce any fix autonomously.
Without revision, every bug fix is a one-off patch. The next time the iteration loop runs, it may reintroduce the bug because nothing in the kits or plans prevents it.
With revision:
Without revision:
Bug found -> Fix code -> Bug may return next iteration
With revision:
Bug found -> Fix code -> Update cavekit -> Re-run iteration loop -> Fix emerges from kits aloneThis is the complete process for tracing a bug back to its cavekit-level root cause and closing the loop.
Locate the bug -- whether through manual testing, automated failures, user reports, or monitoring alerts -- and resolve it through normal debugging. This produces a working code change, but the job is far from done: until the underlying cavekit gap is closed, this fix is fragile.
# The fix produces commits that we will analyze
git log --oneline -5
# a1b2c3d Fix: connection pool exhaustion under concurrent load
# e4f5g6h Fix: missing rate limit headers in API responsesThis is the pivotal step. Ask: "Where in the cavekit chain did this requirement slip through?"
Break the analysis into five dimensions:
Example analysis:
## Revision Analysis: Database Connection Pooling
**WHAT changed:** Added pool size limits and idle timeout in `src/db/pool.ts`
**WHY:** The data layer cavekit assumed unlimited connections; under load the database
rejected new connections once the server-side limit was reached
**RULE:** "The database module MUST configure a bounded connection pool with
idle timeout and max-connection limits matching the deployment target"
**LAYER:** cavekit-data.md (no mention of pool configuration), plan-data.md (no task for pool tuning)
**Cavekit implications:** Add requirement R5 to cavekit-data.md covering connection pool settingsAdd the missing requirement or constraint to the appropriate cavekit file. Focus on acceptance criteria that are concrete enough for the iteration loop to act on:
# In context/kits/cavekit-data.md, add:
### R5: Database Connection Pool Configuration
**Description:** The database module must use a bounded connection pool
with configurable limits to prevent resource exhaustion under load.
**Acceptance Criteria:**
- [ ] Maximum pool size is configurable and defaults to a sensible value
- [ ] Idle connections are reaped after a configurable timeout
- [ ] Pool exhaustion returns a clear error rather than hanging indefinitely
- [ ] Connection health checks run before returning a connection from the pool
**Dependencies:** R1 (database client setup), R2 (environment configuration)Trace the cavekit update through every downstream context file:
# In context/plans/plan-data.md, add:
### T-DATA-005: Configure bounded connection pool
- **Status:** DONE (revised from manual fix a1b2c3d)
- **Cavekit:** R5 in cavekit-data.md
- **Files:** src/db/pool.ts
- **Acceptance criteria:**
- [ ] Max pool size enforced
- [ ] Idle timeout configured
- [ ] Exhaustion handled gracefullyWhen the defect represents a recurring class of problem rather than a one-off, elevate the fix to the prompt level so it applies across all domains:
Signs you are looking at a pattern:
Example systemic fix:
# In prompt 003, add to the validation section:
## Resource Management Validation
For every external resource integration, verify:
- [ ] Connection or handle limits are bounded and configurable
- [ ] Idle resources are cleaned up on a timeout
- [ ] Exhaustion scenarios return actionable errors
- [ ] Resource lifecycle is covered by tests under loadRun the iteration loop against the updated kits to prove the fix emerges from kits alone, then generate regression tests to prevent future recurrence:
# Proof step: remove the manual fix and re-run from specs
git stash # temporarily remove the manual fix
iteration-loop context/prompts/003-generate-impl-from-plans.md -n 5 -t 1h
# Verify the fix appears in the generated implementation
# If it does NOT, the cavekit update is insufficient -- return to Step 3Once verified, create regression tests:
# Generate tests targeting the updated cavekit
{TEST_COMMAND} --cavekit context/kits/cavekit-data.md
# Or manually create a regression test
# tests/db/connection-pool-limits.test.tsThe regression tests should:
The revision analysis automates Steps 2-4 by examining recent git history.
Analyze recent commits and classify each as:
| Classification | Meaning | Action |
|---|---|---|
| Manual fix | Human or interactive agent fixed a bug | Trace back to cavekit -- this is a revision target |
| Iteration loop | Automated iteration loop made the change | No action -- this is the system working as intended |
| Infrastructure | Build config, CI, tooling changes | No action -- not cavekit-related |
How to classify:
For each commit classified as a manual fix, determine:
## Commit: abc1234 "Fix: auth token not refreshing on 401"
### WHAT changed
- File: src/auth/client.ts
- Function: handleApiResponse()
- Behavior: Added 401 detection and token refresh logic
### WHY it was wrong
- The auth module did not handle 401 responses
- Tokens would expire and never refresh, causing cascading auth failures
### RULE (invariant that should have been specified)
- "Authentication tokens must be refreshed automatically on 401 responses"
### LAYER (which context file should have caught this)
- cavekit-auth.md: Missing requirement for error-based token refresh
- plan-auth.md: No task for 401 handling
### Cavekit Implications
- Add R7 to cavekit-auth.md: Token Refresh on Authentication Failure
- Add T-AUTH-007 to plan-auth.md: Implement token refresh on 401Dynamically discover which plan files govern the changed source paths:
Changed file: src/auth/client.ts
-> Matches pattern: src/auth/*
-> Governed by: plan-auth.md
-> Cavekit: cavekit-auth.md
Changed file: src/data/api.ts
-> Matches pattern: src/data/*
-> Governed by: plan-data.md
-> Cavekit: cavekit-data.mdUse file ownership tables (from prompts) or directory conventions to map source files to plan/cavekit files.
For each revision target, update:
# In context/impl/impl-auth.md, add:
## Revision Log
| Date | Commit | Issue | Cavekit Update | Plan Update |
|------|--------|-------|-------------|-------------|
| 2026-03-14 | abc1234 | 401 not handled | R7 added to cavekit-auth.md | T-AUTH-007 added |After updating context files, run the test suite to verify nothing broke:
{BUILD_COMMAND}
{TEST_COMMAND}For each revision target, generate a regression test that:
| Pattern | What You Observe |
|---|---|
| Declining manual intervention | Each iteration cycle requires fewer hand-applied fixes because kits capture more of the ground truth |
| Broader cavekit coverage per fix | A single revision event adds constraints that block an entire family of related defects, not just one |
| Cross-domain prevention | Prompt-level adjustments made after a bug in one module prevent analogous bugs from appearing in other modules |
| Autonomous reproducibility | After a cavekit update, the iteration loop independently produces the same correction that a human applied manually |
| Anti-Pattern | Symptom | Remedy |
|---|---|---|
| Code-only patches | The same category of defect resurfaces across iterations | Follow the full 6-step process; never stop after the code fix in Step 1 |
| Overly specific cavekit additions | Each revision prevents only the exact bug encountered, while slight variations slip through | Formulate the RULE as a general invariant, not a narrow patch |
| Skipping verification | Kits are updated but nobody confirms the iteration loop can reproduce the fix independently | Always execute Step 6; a cavekit that does not drive correct generation is incomplete |
| Brittle over-specification | Kits dictate implementation minutiae, causing breakage on minor refactors | Constrain the WHAT and WHY; leave the HOW to the implementation |
| Accumulated revision debt | A backlog of manual fixes sits un-traced, growing with each sprint | Set a cadence (e.g., end of each iteration) to clear the backlog; debt compounds quickly |
Not every code fix needs revision:
Rule of thumb: If the iteration loop could plausibly reintroduce the bug, revise. If not, skip it.
Revision directly improves convergence:
Iteration 1: 350 lines changed, 8 manual fixes needed
-> Revise all 8 fixes into kits
Iteration 2: 140 lines changed, 3 manual fixes needed
-> Revise 3 fixes
Iteration 3: 30 lines changed, 1 manual fix needed
-> Revise 1 fix
Iteration 4: 10 lines changed, 0 manual fixes needed
-> Convergence achievedEvery revision cycle tightens the kits, so the iteration loop settles into a stable solution in fewer passes. If convergence is not improving, the most likely cause is that manual fixes are being applied without tracing them back to kits.
Stalled convergence paired with ongoing manual fixes is a clear sign of revision debt. The kits have not absorbed the lessons from past corrections, so the loop keeps regenerating flawed output that demands human repair.
ck:convergence-monitoring to detect when manual fixes are decreasing (good) or increasing (revision debt).ck:prompt-pipeline design./ck:scan) identifies revision targets proactively, rather than waiting for bugs.references/convergence-patterns.md for how revision drives convergence.ck:prompt-pipeline skill for how prompt 006 (rewrite pattern) implements automated revision.ck:impl-tracking skill for the revision log format in implementation tracking documents.ck:validation-first skill for validation layers that catch issues before they require revision.© JuliusBrussee, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in packages/coding-agent/skills/cavekit-revision of JuliusBrussee/caveman-code.
Open the folder on GitHubat commit 3a21be1
Cavekit Revision next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Cavekit Revision this skillJuliusBrussee/caveman-code | 942 | — | ~3.6k | Automated safety check: Pass | MIT | |
| Vercel Composition Patternssupabase/supabase | 111k | 58 repos | ~726 | Automated safety check: Pass | MIT | |
| Finishing a Development Branchobra/superpowers | 297k | 5 repos | ~1.9k | Automated safety check: Pass | MIT | |
| Typescript Advanced Typesrolling-scopes/rsschool-app | 10k | 25 repos | ~4.2k | Automated safety check: Pass | MPL-2.0 | |
| PR Babysitteropeninterpreter/openinterpreter | 69k | 3 repos | ~4.2k | Automated safety check: Pass | Apache-2.0 | |
| Code Review ChecklistshareAI-lab/learn-claude-code | 78k | 4 repos | ~1.1k | Automated safety check: Pass | MIT |
supabase/supabase
React composition patterns that scale. An agent skill from supabase/supabase.
obra/superpowers
Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.
rolling-scopes/rsschool-app
Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications.
openinterpreter/openinterpreter
Watches an open GitHub pull request until it merges, handling review comments, diagnosing CI failures and retrying flaky checks along the way.
shareAI-lab/learn-claude-code
Reviews code against a five-part checklist covering security, correctness, performance, maintainability and testing, and reports findings in a fixed format.
onyx-dot-app/onyx
Iteratively improves a PR (GitHub), MR (GitLab), or shelved changelist (Perforce) until Greptile gives it a 5/5 confidence score with zero unresolved comments.
JuliusBrussee/caveman-code
How to write and maintain DESIGN.md as the visual specification layer for Cavekit projects.
JuliusBrussee/caveman-code
Cavekit specification-driven development methodology — the Hunt lifecycle (Draft → Architect → Build → Inspect → Monitor) and how to apply it.
JuliusBrussee/caveman-code
Validation-first design for Cavekit — every kit requirement must be automatically verifiable.
JuliusBrussee/caveman-code
Rewrites a memory file such as CLAUDE.md or a todo list in terse caveman-style text to cut input tokens, saving a readable backup outside the project tree.
JuliusBrussee/caveman-code
Scaffold a complete cave plugin bundle — generates .cave-plugin/plugin.json manifest and the standard directory structure (commands/, skills/, agents/, themes/, hooks/).
Categories
Trace bugs and manual fixes back to kits and prompts; fix at the source so the iteration loop can reproduce the fix autonomously. Cavekit Revision is an agent skill from JuliusBrussee/caveman-code. Trace bugs and manual fixes back to kits and prompts; fix at the source so the iteration loop can reproduce the fix autonomously.
Cavekit Revision fits situations like: A manual hot-fix has been applied; convergence stalls; the same class of bug keeps reappearing.
Run `npx skills add JuliusBrussee/caveman-code --skill cavekit-revision -a claude-code`. Or copy the skill folder (packages/coding-agent/skills/cavekit-revision in JuliusBrussee/caveman-code) into .claude/skills/cavekit-revision in your project. Claude Code loads it when a task matches its description.
Run `npx skills add JuliusBrussee/caveman-code --skill cavekit-revision -a codex`. Or copy the skill folder (packages/coding-agent/skills/cavekit-revision in JuliusBrussee/caveman-code) into .agents/skills/cavekit-revision in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add JuliusBrussee/caveman-code --skill cavekit-revision -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/cavekit-revision, .gemini/skills/cavekit-revision, .github/skills/cavekit-revision and .opencode/skills/cavekit-revision in your project.
Going by SKILL.md and its folder, Cavekit Revision needs the command-line tools its instructions call (git). Its frontmatter pre-approves these tools: read, grep, bash.
SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Cavekit Revision is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.6k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Cavekit Revision: Vercel Composition Patterns (supabase/supabase, 111k stars), Finishing a Development Branch (obra/superpowers, 297k stars), Typescript Advanced Types (rolling-scopes/rsschool-app, 10k stars) and PR Babysitter (openinterpreter/openinterpreter, 69k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
JuliusBrussee (a GitHub user) maintains it in JuliusBrussee/caveman-code, which has 942 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on August 14, 2026.
Source: JuliusBrussee/caveman-code on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.