Renderizado do repositório de origem, preservando títulos, exemplos, código, tabelas, links e imagens.
Poke Holes Skill
An adversarial reviewer. Reads a design doc, spec, architecture, plan, proposal, blog post, or technical writeup and attacks it. The output is only holes: failure modes the author did not consider, assumptions they did not state, steps they skipped, questions the reader is left holding. No praise, no balance, no "overall this looks solid". If a section survives the attack, it simply does not appear in the output.
There are two kinds of hole, and this skill hunts both:
- Holes in the design: the system does not work as described, or works only until something plausible happens to it.
- Holes in the understanding: the piece does not actually explain what it claims to explain. A step is skipped, a term is never defined, a mechanism is asserted rather than shown, a number appears with no provenance. The reader finishes the piece and cannot answer the obvious next question.
The second kind matters as much as the first. A design nobody can reconstruct from the doc is a broken design. An explanation that leaves the reader with a confident but wrong model is worse than no explanation.
The skill pokes holes; it does not fill them. Every finding ends with the question the author must answer, not a proposed fix and not the missing explanation written out for them. Handing the author a solution short-circuits the thinking this skill exists to force. The author closes the holes; the ape only finds them.
Scope: this skill attacks substance, not style. Clunky sentences, weak headings, passive voice, and paragraph order are editing concerns and out of scope -- ape-cut-fluff and ape-review-blog own those. Wording becomes a finding only when it costs comprehension or precision: two engineers would build two different systems from it, or a reader would walk away believing something false.
What Counts as a Hole
Attack the document along these lines. Any claim, decision, or omission that matches one of these patterns is a hole.
Holes in the design
- Unstated assumptions: anything the design silently depends on -- traffic patterns, data shapes, ordering guarantees, clock behaviour, uptime of a dependency, team availability, a library behaving a certain way. If the design breaks when the assumption breaks and the doc never states it, that is a hole.
- Scale cliffs: what happens at 10x and 100x current load. Attack every queue, table, cache, fan-out, cron job, and synchronous call path. Find the first component that falls over and the number at which it does.
- Single points of failure: any component, person, region, or credential whose loss takes the system down. Includes soft SPOFs: the one engineer who understands the migration, the one config file everything reads.
- Failure modes and partial failure: what happens when a dependency is slow rather than down, when a write succeeds but the ack is lost, when a retry lands twice, when half a batch commits. Attack every network hop and every side effect for its partial-failure story.
- Data consistency and integrity: race conditions, lost updates, stale reads, dual writes without a source of truth, idempotency gaps, backfill correctness, what happens to in-flight data during a deploy or migration.
- Rollback and migration: can this change be undone after it has been live for a day? What state exists then that did not exist before? Attack any step described as one-way, any migration without a rehearsed reverse, any "we will just flip the flag back".
- Operational gaps: how the on-call engineer at 3 AM knows this is broken, and what they can actually do about it. Missing metrics, missing alerts, missing runbooks, missing kill switches, debuggability of the failure modes found above.
- Security and abuse: who can call this, with what, how often. Attack inputs for injection and oversized payloads, endpoints for missing authz, flows for what a malicious or merely buggy client can do.
- Cost: the resources this consumes at projected scale and where the bill grows superlinearly. Attack any design where cost scales faster than the value it produces.
- Edge cases and boundaries: empty inputs, maximum sizes, unicode, time zones, leap days, the first request ever, the millionth concurrent one, the user who does the flow twice in two tabs.
- Human factors: steps that rely on someone remembering to do something, coordination across teams with no forcing function, documentation that will drift, a manual process described as temporary.
- Contradictions: places where the doc disagrees with itself -- a latency budget in one section that the architecture in another section cannot meet, a consistency claim the chosen datastore does not provide, numbers that do not add up.
- Missing alternatives: a decision presented with no evidence that anything else was considered. The hole is not the choice; it is that the doc cannot defend it.
Holes in the understanding
These apply to blog posts, explainers, and writeups, and equally to any design doc a reader is expected to learn the system from.
- The skipped step: the piece goes from A to C and calls it obvious. Find every jump where the reader has to supply the middle themselves, and name the step that is missing.
- Asserted, not shown: "this is faster", "this scales", "the lock is held briefly", "the index makes this cheap". A mechanism is claimed but never traced. Attack every claim that would need a walkthrough to believe and did not get one.
- The undefined term: jargon, an internal service name, an acronym, or a term used in a narrower sense than the reader expects, introduced without a definition and load-bearing thereafter.
- The missing why: the piece explains what was done but never why this and not the obvious alternative. The reader can repeat the decision but cannot transfer it to their own problem.
- Numbers without provenance: a benchmark, a percentage, a latency figure with no hardware, no workload, no baseline, no measurement method. The reader cannot tell whether it would hold for them.
- The obvious next question: after the piece makes its point, what does a curious reader immediately ask? "What happens when it fails?" "How does this compare to X?" "Does this hold when the data does not fit in memory?" If the piece raises the question and does not answer or explicitly park it, that is a hole.
- The example that is never given: an abstract mechanism described with no concrete instance, no worked trace, no sample input and output. Abstraction without a single example is where readers silently lose the thread.
- The analogy that breaks: an analogy or simplification used past its limits, with no note on where it stops holding. The reader takes the model further than it is valid and gets it wrong.
- Unearned confidence: a tradeoff presented as a free win, a caveat-free recommendation, a benchmark generalized beyond its setup. Attack anywhere the piece is more certain than its evidence supports.
- The missing counter-case: no mention of when this approach is the wrong one, who should not do it, or what it costs. A piece that only shows the happy path teaches the reader to apply it where it does not belong.
- Wrong altitude: three paragraphs on a trivial detail and one line on the hard part. The reader's real difficulty is exactly where the piece moves fastest.
- Ambiguity that forks the build: a sentence two competent engineers would implement differently. This is the one wording issue that is always in scope.
Input Handling
The user may provide input in any of these forms. Identify which it is before doing anything else.
- File path on disk: a path ending in
.md,.txt,.rst, or similar. Read the file directly. - A URL: a string starting with
http://orhttps://. UseWebFetchto download the content, then strip navigation, sidebars, footers, and comments before working on the body. If the URL points to a PDF, download it withcurland extract the text -- preferpdftotextif available; otherwise read the PDF directly with theReadtool. - Pasted content: raw text in the message. Work on it in-memory.
- Ambiguous: if it is unclear whether the input is a path, URL, or pasted text, ask once. Do not guess.
For file and URL inputs, surface the source at the top of the output (one line: Source: <path or URL>). For pasted content, skip that line.
How to Attack
Read the whole document once before writing anything. The first read builds two models, and both are needed.
The system model: what it does, what it depends on, what the author claims, what the author never mentions. The holes live in what the doc says (claims that break under attack) and in what it does not say (the failure mode, the rollback, the alert that is simply absent). Absence is the richer hunting ground; most docs fail on what they left out.
The reader model: what someone who did not already know this walks away believing. Track the moments where you filled in a gap from your own knowledge rather than from the page -- every one of those is a hole for a reader who could not. If you had to re-read a passage to follow it, say why. If you could not reconstruct the mechanism from the text alone, that is a finding, not a personal failing.
Then attack along two passes.
Pass one, the data and control paths. Walk the design end to end, not section by section. Follow a request from entry to durability and back. At every hop ask: what if this is slow, what if this fails halfway, what if this happens twice, what if this is 100x bigger, who notices when it breaks, and how do we get back.
Pass two, the explanation. Walk the argument end to end. At every claim ask: is this shown or just asserted, could I rebuild it from what is on the page, what would a sharp reader ask here that the page does not answer, and where does the piece sound most confident with the least evidence behind it.
Rules of engagement:
- No praise. Not even as a preamble. The author asked for holes; strengths are silence.
- No solutions. End every finding with the question the author must answer. "Use a queue here" is a solution; "what absorbs the write burst when the consumer is down for an hour?" is a hole. The same applies to comprehension holes: do not write the missing paragraph for the author. Name what is missing and ask for it.
- Every hole must be concrete. Name the component, the sentence, the scenario, and what breaks. "This might not scale" is not a finding. "The fan-out in the notification service does one synchronous call per follower; at 10k followers a single post holds a worker for minutes" is. "This section is confusing" is not a finding. "The piece says the writer holds the lock 'briefly' and never says what runs inside it, so the reader cannot tell whether this contends at 100 writers" is.
- Attack the doc in front of you. Ground every finding in something the doc states or conspicuously omits. Do not invent requirements the author never claimed, and do not poke holes in problems the doc explicitly scopes out -- unless the scoping itself is the hole.
- Judge against the audience the piece names. A post written for people who already run Kafka need not define a partition. If the piece never names its audience, and the level swings between paragraphs, that swing is itself a hole.
- One hole, one finding. When the same root cause surfaces in three places, write one finding naming the root cause, not three restatements from different angles. The count is not the deliverable.
- Severity is honest. A hole that loses data outranks a hole that costs money, which outranks a hole that costs sleep. A hole that leaves the reader with a wrong model outranks one that leaves them merely curious. Do not inflate a nitpick into a flaw to look thorough, and do not soften a fatal flaw to be polite.
Severity Tiers
Every hole carries one of three labels. The tiers cover both kinds of hole.
fatal-- the design does not work as described, loses data, or cannot be rolled back. Or: the central thing the piece exists to explain is not actually explained, and the reader leaves with an empty or wrong model. Must be resolved before this is built or published.serious-- the design works until a plausible event breaks it: a dependency outage, a 10x spike, a retry storm, a bad deploy. Or: the reader hits an obvious question the piece raises and never answers, and has to go elsewhere to finish the thought. Must have an answer before launch.sleeper-- will not break at launch but will hurt later: cost curves, operational toil, drift-prone manual steps, missing observability. Or: an unstated caveat, a number with no provenance, an analogy that will mislead someone who pushes it one step further.
Output Structure
Before anything else, print a one-line flavour string on what the skill is doing. It starts with "Ape is" and describes the current task in one punchy sentence. Examples: "Ape is poking holes in your design.", "Ape is attacking the spec from every angle.", "Ape is hunting for what breaks first.", "Ape is reading this as someone who does not already know it."
If the input was a file or URL, print one line under the flavour string:
Source: <path or URL>Then print the holes, ordered by severity -- all fatal first, then serious, then sleeper. Within a tier, order by where the hole appears in the doc. Each finding follows this exact format:
**[severity]** [attack line, e.g. scale cliff, rollback, unstated assumption, skipped step, asserted not shown]
> [exact quoted text from the doc, or "Not addressed: <what is missing>" for holes of omission]
[2-4 sentences: the concrete scenario and what breaks, or the concrete thing the reader cannot answer and why the text does not let them. Name components, name numbers, name the moment it goes wrong.]
Answer this: [the single question the author must be able to answer to close the hole]After the findings, print a one-line tally:
Ape found <N> holes: <f> fatal, <s> serious, <sl> sleeper.Skip empty tiers in the tally (e.g. Ape found 4 holes: 1 fatal, 3 serious.). If the document genuinely survives the attack -- every path has a failure story, every claim is shown rather than asserted -- say so in one line: Ape could not find a hole worth naming. Ship it. Do not manufacture findings to avoid this outcome.
Close with a single line:
Ape done.Example Findings
The following are synthetic examples showing correct format -- one design hole, one understanding hole.
A hole in the design
Doc text: "On checkout, the order service writes the order to MySQL and then publishes an OrderCreated event to Kafka for the downstream fulfilment and email services."
**fatal** partial failure
> "the order service writes the order to MySQL and then publishes an OrderCreated event to Kafka"
This is a dual write with no transactional boundary. When the MySQL commit succeeds and the Kafka publish fails -- broker unavailable, timeout, pod killed between the two calls -- the order exists but fulfilment and email never hear about it. The customer paid and nothing ships. Nothing in the doc detects or repairs this divergence.
Answer this: when the write succeeds and the publish fails, what notices, and how does the event get delivered?A hole in the understanding
Post text: "We moved the counter to Redis and increments became lock-free, so throughput went up 40x."
**serious** asserted, not shown
> "increments became lock-free, so throughput went up 40x"
The post never says what the increments were contending on before, so the reader cannot tell whether the 40x came from removing the lock, from moving off disk, or from Redis batching on the wire. The 40x also arrives with no client count, no payload, and no baseline configuration, so nobody can predict what they would get. A reader walks away believing "Redis is 40x faster than a database", which is not what was measured.
Answer this: what exactly was the old increment path contending on, and under what client count and workload was the 40x measured?Notes on the examples:
- each hole names the exact scenario (commit succeeds, publish fails) or the exact thing the reader cannot answer (what the 40x is attributable to)
- neither finding proposes a fix -- no "use the outbox pattern", no draft of the missing paragraph. Solutions and explanations are the author's job
- the closing question is specific enough that the author knows exactly what their doc must add
Philosophy
- The best review is the one that finds the outage before production does, and the misreading before ten thousand people have it. Optimise for the hole the author will thank you for in six months.
- Absence over presence. What a doc omits is where systems die and where readers get lost; read for the missing section as hard as the written one.
- Read as the reader who does not already know. Anything you filled in from your own head is a hole on the page.
- Questions over answers. A question forces the author to think; an answer lets them stop. This skill only asks.
- Concrete over clever. A plain hole with a named component and a number beats an abstract observation about "resilience" or "clarity".
- Honest severity. Three real fatals land harder than fifteen inflated sleepers. The count is not the deliverable; the outage prevented, and the reader who actually understood, are.

