CtrlK
BlogDocsLog inGet started
Tessl Logo

base/fill-the-gaps

Assumption-first planning and design gap analysis. Use when user is in PLANNING mode, explicitly asks to plan or discuss, asks for a gap analysis / design review / stress-test of a spec or design document, or when agent faces open decisions — including headless tasks where the deliverable is proposals and open questions as files. Instead of interrogating the user, the agent proposes concrete tagged answers in small verify-style rounds (or directly in the output documents when no user is in the loop), surfaces contradictions as questions, and asks only the questions that genuinely fork the design.

78

1.05x
Quality

91%

Does it follow best practices?

Impact

56%

1.05x

Average score across 1 eval scenario

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.md

name:
fill-the-gaps
description:
Assumption-first planning and design gap analysis. Use when user is in PLANNING mode, explicitly asks to plan or discuss, asks for a gap analysis / design review / stress-test of a spec or design document, or when agent faces open decisions — including headless tasks where the deliverable is proposals and open questions as files. Instead of interrogating the user, the agent proposes concrete tagged answers in small verify-style rounds (or directly in the output documents when no user is in the loop), surfaces contradictions as questions, and asks only the questions that genuinely fork the design.

Fill the Gaps

Systematic approach for closing open decisions before implementation — by drafting answers, not by interrogating.

Core Inversion

The user is an editor, not an answer machine. Producing a correct answer is expensive for the user; recognizing a wrong one is cheap. So for every open decision the agent proposes a concrete answer and lets the user veto it, instead of asking and waiting. Questions are reserved for decisions where a wrong guess is expensive to undo.

The review is brought to the user, in small bites, with everything needed to judge shown in place — the user never hunts through a document. And the review happens before the document is touched: proposals live in the conversation; the document receives only final text, once.

When to Activate

  • User is in PLANNING mode
  • User explicitly asks to "plan", "discuss", "let's think through", "review approach", "before we start", "what do you think about"
  • User asks for a gap analysis, design review, or to stress-test a spec / design document
  • The task's deliverable is proposals, an analysis, or open questions over an underspecified document — even with no user in the loop (see Headless Mode)
  • Agent identifies choices between 2+ valid approaches
  • Agent lacks context needed for confident decision-making

When NOT to Activate

  • Fixing obvious bugs/typos (clear single correct solution)
  • User explicitly says "do as you see fit" or similar
  • Trivial changes with single logical approach
  • User already provided specific requirements

Headless Mode (No User in the Loop)

Some tasks ask for the analysis as files — a gap analysis, a design review, a batch run — with no user available for a veto pass. The whole process still applies; only the review surface moves: the output documents are the veto pass, prepared for a reader who will veto later.

  • Proposals land in the proposals document exactly as they would be printed in a veto pass: grouped by theme, full final concrete text, each tagged safe default / judgment call, dependencies noted (builds on #N).
  • Questions that survive triage are parked as one-line topic: recommended answer entries — the recommendation is mandatory. A bare question hands the reader a generation task instead of a veto. One line means literally one line: no sub-sections, no trade-off discussion, no alternatives list — if a question needs that context, it belongs in the proposals document under the related theme, and the parked entry links to it by number.
  • The contradiction rule tightens, if anything: a contradiction found in the source material is escalated as a parked question with a recommended resolution — never silently settled by a proposal that picks a side.
  • The triage budget still holds: more than ~3–5 parked questions means the triage lost its nerve — re-triage.
  • Proposals are analysis, not implementation: no code blocks, migrations, or config files in the outputs; name the mechanism ("unique constraint on (event_id, channel)") instead of writing it out.
  • **Assumption:** markers are unnecessary in documents that are explicitly proposals — the whole file is unconfirmed by construction. They still apply when writing into the design document itself.

The Triage Rule

Every open decision goes into exactly one bucket:

  • Assume (the default) — a wrong guess costs one edit in one place. → Propose a concrete answer for the veto pass.
  • Ask — the decision forks the design. Test with three criteria: it is hard to reverse; a future reader would wonder why; and there is a genuine trade-off between real alternatives. All three true → ask, with options. If there is no real alternative, there is nothing to ask — assume the obvious thing.
  • Park — nothing in the current scope depends on the answer. → Record it as an open question and move on.

Hard rule: a contradiction is never assumed away. When two sources disagree — the doc with itself, the doc with the code, the user with either — surface it as a question no matter how cheap the fix looks. The boundary: filling silence is assuming; overwriting what the user or the doc already says is contradicting, even when you are sure the existing text is wrong. Contradictions are exactly the hidden problems this process exists to find.

Heuristic: assume anything fixable with one edit; ask anything other decisions depend on.

If more than ~3 questions survive triage, re-triage — you are over-asking. Most "questions" are assumptions that lost their nerve.

Process

1. Mine the context first

Stack, conventions, constraints, scale signals: pull what you can from the project itself (code, docs, config, git history) before involving the user. A question the repository can answer is never asked and never assumed — it is looked up. If the project keeps a glossary (CONTEXT.md) or a decision log (docs/adr/, decisions.md), read it first: settled terms and settled decisions are neither re-asked nor re-assumed.

2. Collect, triage, and cut into themes

Scan the entire task and collect ALL decision points first, then triage them as one batch. Never surface questions one at a time as you stumble on them — drip questioning is exactly what this skill exists to prevent.

Then partition the surviving decision points into themes — one section or subtree each (retries and failures, storage layout, CLI shape). A theme is the unit of one work round: small enough to review in one sitting.

3. Work theme by theme

Process one theme per round: walk its tree, stress-test it with scenarios, propose its answers in the conversation, and only after the user's veto write the confirmed text into the document. The rhythm is analyze → propose → confirm → write, theme by theme — never one giant review, and never writing ahead of the review. A round should carry 3–7 proposals; if a theme yields more, split it. Each round builds on decisions the user just confirmed, so vetoes stay cheap and never cascade far.

4. Walk the tree

The breadth scan finds surface gaps; the hidden problems sit one level down. Within the current theme, resolve decision points in dependency order, and after drafting each proposal ask: what does this decision imply? Drafting "retries are configured per reviewer" immediately raises "what is the retry budget?" and "does partial output from the failed attempt survive?" — decision points no surface scan produces. Walk each branch until it stops generating new points.

5. Stress-test with scenarios

Invent a handful of concrete, awkward scenarios and trace each one through the design end to end. Wherever the design goes silent, or two parts of it disagree about what happens, you have found a new decision point — send it through triage. Prefer the weird scenarios: the empty input, the double failure, the thing that arrives twice. Scenarios find gaps that checklists cannot.

6. Sharpen the language

A fuzzy or overloaded term is a decision point in disguise. When the same concept has two names, or one name covers two concepts, propose a canonical definition — as a proposal, like any other. When the user's wording conflicts with the project's established vocabulary, that is a contradiction: surface it. Update the project glossary once a term is confirmed (create CONTEXT.md lazily if none exists; definitions only, no implementation details).

7. Propose in the conversation

Close every theme with a veto pass in the conversation, before touching the document. The user must be able to judge each proposal without opening anything — show the proposal's full final text plus the one line of surrounding context it hangs on.

The full text lives in a plain text message, printed before any question tool is called. Question-tool fields (question text, option labels, option descriptions) are too small to carry a proposal — a topic label like "config file shape" is not vetoable text. The tool call only references the numbers from the printed list; the list itself is the review surface. A veto pass with no text message above it is a blind veto pass.

Every proposal follows these rules:

  • Be concrete. "Timeout of 15 minutes" is vetoable; "a reasonable timeout" is not. Propose the exact text that will go into the document.
  • When a proposal builds on another one, say so: (builds on #2). A vetoed proposal takes its dependents down with it — the user needs to see the blast radius.
  • Tag each proposal with its tier:
    • safe default — mechanically derivable or purely conventional: exact file names, type shapes, standard backoff values. Nothing a reasonable person would argue about.
    • judgment call — changes observable behavior, narrows semantics, or picks between real alternatives. When in doubt, it is a judgment call.

The veto pass itself:

  • Judgment calls are reviewed interactively, in groups of 3–4. The framing is always verification — "is this right?" — never generation ("what should it be?"). If the harness provides a question tool with selectable options, use it: one question per proposal, drafted answer as the recommended option, real alternatives after it.
  • Safe defaults are presented as one compact numbered list (full text, per above) with a single collective question — "apply all?". The only listed option is "apply all" as the recommendation; a veto arrives as free text through the tool's built-in "Other" ("2 and 5 are wrong"). Never add a decoy option like "veto by numbers" whose meaning is "pick Other instead" — an option must be choosable as-is.
  • Questions that survived triage for this theme are asked here too, with options and a stated recommendation (strongly recommend / lean towards / no strong preference).
  • Number proposals in the order they are shown, and keep that order in the tool call — when the user vetoes "number 2", there must be exactly one thing it can mean.
  • A veto cascades: rewrite the proposal and its dependents, then re-show only what changed.

8. Write once, after the veto

Only after the user has responded does the document change. Write each confirmed decision in its final form, in the place where it belongs — once. Confirmed text is plain text: no marker, it was just reviewed.

The **Assumption:** marker is reserved for text written without explicit confirmation — skipped questions (step 9), cheap assumptions made mid-execution (step 10), anything the user has not seen:

> **Assumption:** on timeout the reviewer process gets SIGTERM and is counted
> as failed, no automatic retry; partial stdout is kept as raw output.

Use the exact literal **Assumption:** so markers can be found mechanically (grep). A marker stays until the user confirms the decision at the next veto pass — then drop it.

Never write a proposal into the document before its veto pass and edit it again after: every piece of text lands once. The only second write a decision ever gets is a real veto.

9. Unanswered questions and interrupted rounds

If the user skips a question, re-ask it once, explicitly. If it is still unanswered and the dependent work cannot be parked, proceed with your recommended option written as a marked assumption, flagged loudly at the top of the next veto pass. Do not block indefinitely; do not convert silently.

A rejected veto pass (the user dismisses the question tool) or a session that ends mid-round is open, not vetoed — but its analysis lives only in the conversation and dies with it. On rejection, stop and wait as the harness demands; the next contact starts by re-showing that round in full before any new theme. If the user is wrapping up with the round still open ("let's stop here"), park its items in the document's open-questions section first — topic + recommended answer, one line each; parking a summary is not writing the proposal — so the next session can pick the round up instead of re-deriving it.

10. Mid-execution discoveries

New ambiguity during implementation goes through the same triage — assume if cheap (written with the marker, confirmed at the next contact), park if deferrable, stop and ask only if it forks the remaining work. Exception: anything that contradicts a confirmed decision or an explicit earlier answer from the user is always stop-and-ask.

11. Record what survives

A confirmed fork decision (asked, answered) gets recorded durably, so no future round — or other model — re-asks it. A one-paragraph ADR is enough: what was the context, what was decided, why (1–3 sentences; docs/adr/NNNN-slug.md, or the project's decision log if it keeps one). Apply the same gate as for asking: hard to reverse, surprising without context, real trade-off — decisions that fail the gate don't need an ADR, the confirmed text in the document is enough.

Write artifacts — glossary entries, ADRs — right after the veto pass that confirmed them, while the context is fresh.

12. Marker hygiene

  • Markers must not stack. If this round's work depends on a marked assumption from a previous round that was never confirmed or vetoed, re-show it at the top of the current veto pass before building on it.
  • Markers must not outlive the plan. By the time the work is declared done, every **Assumption:** has been either confirmed (marker removed) or vetoed (text rewritten).
  • Implementation starts only after every theme has had its veto pass. Not "after every proposal is confirmed" — that is interviewing again — but never before the user has seen each round's list.

Key Principles

  1. Draft, don't interrogate — vetoing a wrong answer is cheaper than producing a right one
  2. Collect once, review in bites — one breadth scan up front; theme-sized veto rounds after, never one giant pass
  3. The hidden problems are one level down — walk each decision's implications and trace concrete scenarios; don't stop at the surface scan
  4. A question must earn its place — only hard-to-reverse, genuinely traded-off decisions get the user's attention
  5. Contradictions always surface — filling silence is assuming; overwriting existing text is contradicting, and that is always a question
  6. Confirm, then write — proposals live in the conversation; the document receives only final text, once; markers only for what the user hasn't seen
  7. Bring the review to the user — full text with context, printed as a message before any question tool fires; never send the user hunting through the document, and never hide a proposal inside a tool's option label
  8. Decisions outlive the session — confirmed forks become ADRs or log entries so no future round re-asks them

SKILL.md

tile.json