| name | inquiry-gap |
| description | Generate a gap report on an inquiry wiki — set-level (across all active questions) or within-question (on a single page with >=3 contributions) — surfacing non-obvious observations about what the question set or a single question is missing. |
inquiry-gap
Purpose
Produce a gap report on an inquiry instrument: a dated markdown file under meta/ plus a scannable in-session summary. This is the domain's signature operation — the thing that makes the wiki an instrument rather than a notebook. Invoke this skill when the user runs /inquiry-gap, /inquiry-gap set, or /inquiry-gap within <slug>, or otherwise asks for a "gap report," "gap analysis," or "what am I missing."
Two modes, both governed by the same quality bar:
set (default) — operates on every active question page in wiki/questions/. Surfaces implicit frames, missing dimensions, overlapping pairs, too-narrow and too-broad questions.
within <slug> — operates on a single question page whose contributions count is >=3. Surfaces thin evidence, one-sided arguments, missing counter-positions, repeated sources, missing concrete examples.
The non-negotiable quality bar (PRD 6.4, SCHEMA.md "Non-obvious-observation requirement"): every run must produce at least one observation the user could not have made themselves by rereading their own questions. Generic observations are a worse outcome than no report. Self-critique enforces this bar before the file is written.
Preconditions
- The current working directory is a wiki root — it contains
SCHEMA.md.
wiki/questions/ exists and contains at least one question page with status: active.
- For
set mode: at least 3 active questions (below that there is not enough structure to find set-level patterns — see Failure modes).
- For
within <slug> mode: wiki/questions/<slug>.md exists with status: active and its ## Notes section contains >=3 contributions (one bullet per contribution per the schema).
meta/ exists at the wiki root (sibling of wiki/). Create it if absent.
- The memex helper
log_append.py is available. See Helper invocation for path resolution.
Modes
Mode selection
- If the user supplies an explicit mode (
/inquiry-gap set or /inquiry-gap within <slug>), use it.
- If the user supplies a slug without the
within keyword (/inquiry-gap <slug>), treat it as within <slug>.
- If the user supplies no argument, default to
set.
- Auto-suggest within-mode. After a
set run completes, scan wiki/questions/ for any page whose contributions frontmatter is >=3 and for which no meta/gap_report_*.md in the last 7 days contains a ## Within-question observations — <slug> section. If such a page exists, tell the user:
"Page <slug> has contributions and no recent within-question report. Want me to run /inquiry-gap within <slug> now?"
Do not auto-run without confirmation.
Set-level analysis — what to surface
Read every active page in wiki/questions/: frontmatter (for slug and title) and the ## Framing section. Then analyze the set as a whole. Look for:
- Implicit frames — assumptions the question set takes for granted across most/all questions. Example: "every question assumes a team of 10+ engineers — do any apply to solo or pair-sized teams?" or "every question assumes the reader is the builder — no questions about the buyer, the operator, or the user."
- Missing dimensions — axes no question covers. If all questions are "how to build," none may be "when to not build." If all questions are about product, none may be about distribution. Name the missing dimension concretely.
- Overlapping pairs — two questions that collapse into the same underlying inquiry once you look past surface wording. Recommend either merging or sharpening the differentiation (what would each keep that the other rules out?).
- Too-narrow — a question so specific that almost no new source could advance it. The question is really an answer in disguise, or is about one case rather than a class of cases.
- Too-broad — a question so abstract that no contribution would obviously count as advancing it. No imaginable paste-in would move the needle.
Set-level analysis — stance and domain categorisation (load-bearing)
This step is required for every set-level run. It produces the two primary lenses the report's "At a glance" and "Headline finding" sections render. Both lenses are needed; either alone misses what the other surfaces.
Stance categorisation
Sort each active question into one of four intellectual stances:
- Builder / maker — the user is designing, building, leading, or convening. Question form: "How do you build / lead / design X?" Destination is action.
- Observer / sense-maker — the user is watching a pattern unfold and trying to understand it. Question form: "What is X actually doing? What patterns emerge?" Destination is interpretation.
- Critic / skeptic — the user is interrogating a consensus. Question form: "Why is X assumed? What's wrong with the popular answer?" Destination is a sharpened argument against a prevailing view.
- Steward / preserver — the user is asking what's at risk of being lost and what they'd fight to keep. Question form: "What about X is at risk? What's worth preserving?" Destination is a defensible claim about what to keep.
Categorisation rules:
- Look at the question form as written in the title. "How do you build...?" → maker. "What patterns emerge...?" → observer. "Why is X assumed?" → critic. "What about X is at risk?" → steward.
- If form and stance disagree (e.g. "How do you build X?" but the framing makes clear the user isn't building, just wondering), flag it as a candidate for reframing in the Audit — reframe candidates sub-step below.
- Empty stances are interesting. A 0-count critic or steward slot is a finding, not a defect — held visible in the negative-space table.
Domain categorisation
Sort the active questions into 4–7 topical domains drawn from the question titles, framings, and reading patterns. Aim for roughly 1–4 questions per domain. If a single domain holds more than half the set, look for a meaningful split (e.g. "AI in my own practice" vs "AI in the world").
Naming conventions:
- Use noun-phrase titles ("Leadership & org craft", "Innovation & invention", "AI markets, agents & products"), not verb-phrase ("Leading teams").
- Group by what the question is about topically, not by stance. Two questions in the same domain may be different stances.
- Confirm the bucketing with the user before locking it in — domain naming is a sense-making act and the user's framing matters.
The cross-tab
Once stances and domains are assigned, build a cross-tab — domains as rows, stances as columns, marginal totals on both axes. Read it for non-obvious patterns:
- Single-stance domains — a domain with all its questions in one stance is structurally narrow. Sometimes right (Feynman favourites in observer mode); sometimes a reframe or addition signal.
- Complementary-stance domains — a domain with two or more stances on the same body of practice is unusually well-developed (e.g. maker + steward on the same topic).
- Where maker stance lives — maker questions tend to cluster in domains where the user has first-person practice. Maker questions in domains where the user has no practice are reframe candidates.
- Where observer stance lives — observer questions tend to cluster where the user is honestly outside (a category they watch, not run).
The cross-tab is data, not interpretation. Show it in the report only if it adds; cut it if the patterns it reveals are weak. Do not over-claim from it.
Audit — interactive reframe loop
For each maker question, ask the user directly: "Are you actually going to act on this in the next year, or are you holding the topic at sense-making distance?"
Do not trust the page's existing framing as evidence. A page that claims "Personal stake: Paul is training an AI on his own creative work" may have inherited that line from a sloppy elicitation pass and never been challenged. Ask the user about every maker question, even when the framing already asserts first-person practice — especially then. The audit's job is to catch exactly the cases where the framing's self-description has drifted from the user's actual relationship to the topic.
For each candidate, show concrete text for both paths (stay maker; reframe to observer with new title and framing). Let the user pick. Do not batch — one question per exchange. Update the report's stance counts as decisions land.
This loop is interactive in the chat and mutates the report draft as it goes. Budget for several rounds with the user before the report is finalised. See Interactive iteration below.
Within-question analysis — what to surface
Read the single target page in full: frontmatter, ## Framing, and every bullet in ## Notes. Look for:
- Thin evidence — a claim in the framing or implied by the notes is supported by only one source, or only one kind of source (all blog posts, all from one community).
- One-sided arguments — all contributions lean the same direction; no counter-position is represented. Name the side the notes favor and what a reasonable dissent would look like.
- Missing counter-positions — specific named thinkers, books, traditions, or arguments the user should engage with. Be concrete: "no contribution references — if you're serious about this question, that's the canonical counter."
- Repeated sources — multiple contributions citing the same author, venue, or community. Call out the diversity gap.
- Missing concrete examples — the notes are abstract. No lived case, no worked example, no "here is what this looked like in practice." Suggest the kind of example that would ground the question.
Steps
1. Read SCHEMA.md
Before anything else, read SCHEMA.md from the current working directory. This tells you:
- The pages directory name (this skill assumes
questions — the inquiry domain convention — but honor SCHEMA.md if it says otherwise).
- Frontmatter field names and body section names (
## Framing, ## Notes, contributions, status).
- The contribution bullet format (for parsing the
## Notes section).
- The gap report structure and location conventions (baseline:
meta/gap_report_<YYYY-MM-DD>.md).
- The log-verb convention for this operation (
gap-report).
If SCHEMA.md is missing, stop and report the error (see Failure modes).
2. Determine the mode and validate preconditions
Resolve the mode per Mode selection above. Then:
- For
set: list active question pages (status: active) in wiki/questions/. Count them. If fewer than 3, stop (see Failure modes).
- For
within <slug>: open wiki/questions/<slug>.md. If it does not exist or is not status: active, stop. If its ## Notes section has fewer than 3 bullet contributions, stop (see Failure modes).
3. First-pass analysis
Generate observations per the mode's rubric (set-level or within-question categories above). Aim for 5–8 first-pass observations across categories — more than the final report will hold, so self-critique has material to cut.
Do not write any file yet.
4. Self-critique — the non-obvious gate
This is the load-bearing step. For each first-pass observation, ask in your own reasoning:
"Could the user have made this observation by rereading their own questions (or this single page) without me? If yes, it is not non-obvious — replace it or deepen it."
Generic observations that fail the bar look like:
- "Question 3 has only two contributions." (The user can see this by looking.)
- "Most of your questions are about AI." (Restating the topic.)
- "This page is thin on evidence." (Restating what
contributions: 2 already says.)
Non-obvious observations look like:
- "All 12 questions assume the subject is an engineering team; none ask about the team's relationship with its users, and one of your re-read sources explicitly treats that as the primary axis."
- "Q4 and Q9 collapse to the same underlying question — both ask how authority is delegated in fast-moving orgs — but Q4 frames it as an org-design problem and Q9 as a hiring problem. Either sharpen the difference or merge."
- "Every contribution on this page cites a Karpathy or Karpathy-adjacent source. If this question is as important as the framing suggests, the Yudkowsky / Chollet axis of disagreement deserves at least one contribution."
At least ONE observation in the final report must clear this bar. After the self-critique pass:
- If one or more observations clear the bar, keep those and round out the report with the next-strongest surviving observations (aim for 3–5 total — depth beats count).
- If zero observations clear the bar, do not write the file yet. Revise your prompt to yourself: re-read the framings more carefully, look for tensions between pages, look for what is conspicuously absent given the user's stated concerns. Re-run the first-pass analysis. Cap this revision loop at 2 attempts. If still nothing lands after two attempts, proceed to the failure path under Failure modes — write nothing, and report honestly.
5. Rank and write the report
Order observations with the single strongest (most non-obvious) first. That single strongest observation becomes the pull-quote callout at the very top of the report — > [!quote] What these questions reveal about you — verbatim or paraphrased, identity-shaped, 2–3 sentences. It is the GIF anchor and the load-bearing claim of the entire artifact. If you cannot produce one, do not write the report (see Failure modes).
The abstract callout that follows is roadmap-shaped, not insight-shaped — it tells the reader what's in the report (stance + domain breakdowns, richness ranking, negative-space map, decisions in appendix), not what the report concluded.
The third callout — > [!question] Questions you're not asking — that you might want to explore — pulls three sample questions from the negative-space table's "not in set" rows (topics the user has signalled interest in but hasn't committed to a question on). Pick the most consumable framing from each row's four-stance options, or tighten as needed. Together the three callouts form the GIF arc: identity insight → orientation → invitation.
Write to meta/gap_report_<YYYY-MM-DD>.md. If a file with that name already exists for today, append a suffix: _b, _c, etc.
Set-level file structure (magazine voice — see Voice and form below):
# Gap Report — <YYYY-MM-DD> — set-level (vN)
> [!quote] What these questions reveal about you
> <The single most non-obvious structural finding from the audit, as a 2–3 sentence pull quote. The GIF anchor — the one sentence the user couldn't have articulated by re-reading their own questions. Identity-shaped: what the set reveals about *how the user thinks*, not what the report contains. This is the load-bearing claim that earns the report its place; if no such finding emerged, do not write the report (see Failure modes).>
> [!abstract] What this report tells you about the questions you're asking
> <2–3 sentence orientation. What the reader will find below — stance and domain breakdowns, richness ranking, negative-space map, decisions in appendix. Roadmap-shaped, NOT a restatement of the pull quote.>
> [!question] Questions you're not asking — that you might want to explore
> <Three sample questions pulled from the negative-space table's "not in set" rows (topics the user has signalled interest in but hasn't committed a question to). Format each as "**Topic** — *Question?*". Pick the most consumable framing from each row's four-stance options, or tighten if none of the four lands. Three is the right number for the GIF — fewer feels stingy, more is overwhelming. Invitation-shaped: don't prescribe; offer the slot.>
## At a glance
### By stance
| Stance | Count | |
|---|---:|:---|
| [[#Builder / maker]] | **N** | bar |
| [[#Observer / sense-maker]] | **N** | bar |
| [[#Steward / preserver]] | **N** | bar |
| [[#Critic / skeptic]] | **N** | bar (or *(open slot)* if 0) |
### By domain
| Domain | Count | |
|---|---:|:---|
| <Domain 1> | **N** | bar |
| <Domain 2> | **N** | bar |
| ... | | |
**<N> active questions · <D> decisions resolved this session · <open slots> visible negative space**
---
## The headline finding
<Magazine narrative section. Lead with the load-bearing finding. Use the cross-tab if it adds; cut if it over-interprets. Name the structural pattern (e.g. "your maker stance clusters in domains where you have first-person practice") only when clearly supported by the data.>
---
## Questions to sit with
<3-5 reflection prompts the user can bring back to the report. Lead each with the question, in bold.>
---
## How rich are these questions?
<Tier 1 / Tier 2 / Tier 3 grouping with one-line caveats per question. Use full question titles linked to wiki pages, not slugs.>
---
## What you're not asking
<Negative-space table. Topics × four stances. Bolded cells are existing questions (linked to wiki pages); unbolded cells are candidate questions in the user's voice. Include a few topics the user has signalled interest in but hasn't yet asked a question on.>
---
## Appendix — what changed this session
<Decisions made during the session, marked ✓ RESOLVED with the choice and a brief explanation. The working-notes section, deliberately below the magazine top.>
---
## Appendix — the four stances
<Definitions of each stance. Anchor targets for the [[#Heading]] links from the deck. Each definition includes "Question form", "What accumulates", and "In your set" with bulleted question titles linked to wiki pages.>
Within-question file structure — identical, except replace ## Observations with ## Within-question observations — <slug> and drop any category heading that has no observations:
# Gap Report — <YYYY-MM-DD> — within-question (<slug>)
## Summary
<Most non-obvious observation first, then context: page title, contribution count analyzed.>
## Within-question observations — <slug>
### <Category heading — e.g. One-sided arguments>
- **<One-line observation>**
<2–3 sentences. Cite specific contribution bullets by their source if possible.>
(...)
If the within mode is auto-suggested and confirmed right after a set run, produce two separate files (one per mode), not a combined file. Dated filenames plus the mode-in-title make both scannable in meta/.
5a. Voice and form
The report is read as a finished artifact. Write it as one.
Magazine voice, not AI essay. See feedback memory feedback_magazine_voice.md for full guidance. Key rules:
- Cut hedges and intensifiers ("honestly", "actually", "deliberately", "in roughly equal measure").
- No self-narration ("the non-obvious pattern is..." — just write the pattern).
- Don't restate data after showing it. Trust the reader.
- Lead each paragraph with the strongest sentence.
- Don't over-interpret. If the data only weakly supports a claim, don't claim it.
Show concrete text when proposing changes. See feedback_show_concrete_text.md. When iterating on titles, framings, or report content, show actual draft text inline — not abstract descriptions of what would change.
Use full question titles, not slugs. When referencing questions in narrative prose (deck, headline finding, appendix), write the full title (italics, in quotes, or both) and link to the wiki page. Slugs belong in filenames and frontmatter, not in the body of a magazine read.
Anchor links to the appendix. Use Obsidian wiki-link syntax ([[#Heading Name]]) for in-document jumps to stance definitions. Appendix headings are the anchor targets; no <a id> tags needed.
6. Update meta/gap_report_latest.md
After writing the dated file, update the symlink:
cd meta && ln -snf gap_report_<YYYY-MM-DD>.md gap_report_latest.md
On filesystems where symlinks are not available (rare on macOS/Linux, occasionally true of some Windows setups), fall back to writing a plain copy at the same path and note in the in-session summary that gap_report_latest.md is a copy rather than a symlink.
7. Render the in-session summary
This is what gets captured on the Week 1 demo GIF. Keep the format rigid and scannable. Print, to the conversation, exactly:
Gap report for <mode>:
Most non-obvious: <the single strongest observation, one sentence>
- <second observation, one line>
- <third observation, one line>
- <fourth observation, one line>
- <fifth observation, one line> (optional — include only if it genuinely earns its place)
Full report written to meta/gap_report_<YYYY-MM-DD>.md
Design notes for the render:
- The "Most non-obvious" line is the one the GIF camera lingers on. Make it a complete sentence that stands alone without context — someone reading the GIF frame without the question set in front of them should still get the point.
- The bullet observations are shorter — one line each, no wrapping. They establish that the headline is not cherry-picked.
- No preamble, no apologies, no "let me know if you want to dig deeper." The rigid format is what makes it GIF-legible.
- For
within mode, replace <mode> with within-question (<slug>) — naming the slug in the header keeps the screen grab unambiguous when the user is comparing reports across pages.
8. Append to log.md
Invoke the log helper via the bash tool. log.md lives inside meta/ per the baseline layout — pass --log-dir ./meta:
python3 <path-to-memex>/helpers/log_append.py \
--log-dir ./meta \
--op gap-report \
--subject "<mode>: <n> observations" \
--body "<one-line paraphrase of the headline observation>. See meta/gap_report_<YYYY-MM-DD>.md."
Examples:
--subject "set-level: 4 observations"
--subject "within-question (self-improving-software): 3 observations"
--subject "set-level + within-question (self-improving-software): 6 observations" (if a single run produced both)
See Helper invocation below for resolving <path-to-memex>.
9. End-of-session retro
After the log append succeeds, run a short wrap-up retro with the user before signing off. The tone is conversational — "one more thing before we finish" — not a form or a survey. Ask the questions one at a time and wait for each answer before moving to the next. Do not batch them.
Ask, in order, phrased naturally in your own words. Approximate phrasings:
- "One more thing before we finish — how did this go?"
- "Was the 'non-obvious observation' actually non-obvious to you? Quote the one that landed, or tell me why none did."
- "Which observations felt generic or obvious? (These should be cut from future runs.)"
- "What did the report miss that you noticed yourself?"
- "One specific change to improve the report?"
Run the retro even if the user seemed satisfied and ready to leave — the generic/obvious question is the one most likely to sharpen the next run. If the user tries to wave it off with "no feedback," push once gently: "Even one observation is useful." If they're still rushed, accept whatever they give and mark unanswered prompts as (skipped) in the file — do not accept a fully empty retro silently.
Writing the feedback file
After the final answer, write to meta/feedback_gap_<YYYY-MM-DD>.md. If a file already exists at that path (same-day retry), append a numeric suffix: _2, _3, ... — never clobber a prior session's feedback.
Resolving the version: field. Try to capture the big_questions commit SHA so feedback is tied to the skill revision that produced the report:
- Resolve this SKILL.md's real path (follow the symlink from
~/.claude/skills/inquiry-gap/ back to the repo).
- From that path, find the repo root (the enclosing
big_questions/ directory).
- Run
git -C <repo> rev-parse --short HEAD via the bash tool.
- If git is unavailable, the path doesn't resolve, or the command fails, set
version: unknown. Never fail the retro over this.
The mode: frontmatter field records which gap mode produced the report: set for set-level runs, or within-<slug> for within-question runs (e.g. within-self-improving-software).
File content (fill answers verbatim as the user gave them; preserve their words):
---
skill: inquiry-gap
date: YYYY-MM-DD
mode: set | within-<slug>
version: <sha-or-unknown>
---
# Session feedback — inquiry-gap — YYYY-MM-DD
## How did this go?
<answer>
## Was the non-obvious observation actually non-obvious?
<answer>
## Observations that felt generic or obvious
<answer>
## What the report missed
<answer>
## One specific change to improve the report
<answer>
Final message to the user
After the file is written, tell the user where it is and offer the issue-template URL. Something like:
Saved your feedback to meta/feedback_gap_<YYYY-MM-DD>.md. If you'd like to share it back to help improve the skill, file an issue using this template: https://github.com/eyefodder/big_questions/issues/new?template=skill_feedback.yml — no pressure, it's your file.
Keep the tone warm and low-friction. The file is the user's by default; sharing is opt-in.
Interactive iteration
The gap report is a working document, not a one-shot artifact. Set-level runs typically produce 3–7 versions during a single session as the user iterates with you on:
- Stance categorisation (some questions may need reframing)
- Domain naming and grouping
- Voice and structure of the report itself
- Decisions surfaced by the analysis (retire, reframe, add)
Versioning conventions:
- The version number (v1, v2, v3, …) goes in the report's H1 title in parentheses.
- The filename uses the dated convention
gap_report_<YYYY-MM-DD>.md. Same-day iterations append _b, _c, etc.
- Update
meta/gap_report_latest.md (symlink) to the most recent version after each iteration.
Decisions section (in the report's appendix):
As the user makes calls during the session, mark decisions as ✓ RESOLVED with the choice and a brief explanation. Decisions left open should be visible too, with their choices laid out (Path A / Path B / Path C with what each costs).
Page-batch step (only after all decisions are resolved and the user signs off):
- Update reframed pages (new titles, new framings, retained slugs per schema).
- Mark retired pages (
status: retired, append a retirement callout at the bottom of the page — never at the top — so the index helper picks the framing as the summary line.)
- Create new pages with full frontmatter, framing, and empty
## Notes.
- Rebuild
wiki/index.md via helpers/index_update.py.
- Append a single
gap-report log entry covering all changes via helpers/log_append.py.
Skill update step (when learnings emerge):
If the session surfaces a behavioural rule worth keeping (a new pattern to look for, a voice rule, a structural change), capture it as a memory file (feedback type) in the user's auto-memory and reference it in this skill rather than duplicating the rule inline. Memory survives across sessions; inline duplication rots.
Helper invocation
This skill shells out to one helper script via the bash tool: memex/helpers/log_append.py. No inquiry-specific helpers exist in v0.1.
Always invoke with python3 explicitly (per architecture Decision 6 — avoid ambiguous python on macOS).
Resolving the helper path. This skill is typically installed as a symlink into an instance's .claude/skills/inquiry-gap/, so helpers/ is not adjacent to the running SKILL.md. Resolve in order:
- If
./memex/helpers/log_append.py exists relative to the wiki root (the user vendored the harness into their wiki), use that.
- Otherwise, resolve the SKILL.md's real path (follow the symlinks: instance ->
big_questions/skills/inquiry-gap). The memex harness lives separately at ~/Development/memex/ on a typical install — use ~/Development/memex/helpers/log_append.py.
- If neither resolves, ask the user where the memex harness is installed. Do not silently skip the log append — the log is how week-over-week comparison works (Decision 7).
Quality enforcement — operational summary
The non-obvious requirement is enforced mechanically in Step 4 by:
- Generating more observations than will ship (5–8 first-pass) so the self-critique has headroom to cut generics.
- Applying the rereading test to each candidate — could the user have made this observation alone? If yes, the observation is disqualified from being the headline, and must be either deepened or replaced.
- Requiring at least one observation to pass the test before the file is written. The check happens in-memory before any disk write; a generic-only draft is never persisted.
- Allowing up to two revision attempts before accepting that this run did not produce a non-obvious finding. The loop is bounded; it does not stall the user.
- Failing honestly when no non-obvious finding emerges (see Failure modes). The skill reports the shortfall rather than shipping a generic report — because in this domain, a generic report is worse than no report.
- Ordering the final output most-non-obvious-first so the
## Summary lede and the in-session "Most non-obvious:" line are the same sentence, and both are the strongest sentence in the run.
Failure modes
-
SCHEMA.md is missing. Stop. Report: "No SCHEMA.md found in the current directory. /inquiry-gap expects to run from the root of an inquiry instance. Bootstrap one from memex/schema.example.md + big_questions/schema.inquiry.example.md, or cd into an existing instance."
-
Fewer than 3 active questions (set mode). Stop and report: "Set-level gap analysis needs at least 3 active questions to find structure. This instance has . Run /inquiry-elicit to build out the set, or use /inquiry-gap within <slug> if you want analysis on a single page." Do not attempt a degraded set-level pass — a gap report on two questions cannot surface implicit frames honestly.
-
Within-mode on a page with fewer than 3 contributions. Stop and report: "Page <slug> has contributions. Within-question analysis needs at least 3 to be worth the run. Run /inquiry-gap (set mode) instead, or ingest more sources against this page first." Name other pages with >=3 contributions if any exist.
-
Within-mode target page does not exist or is status: retired / status: dormant. Stop. Report which it is and list existing active pages the user may have meant.
-
Self-critique produces no non-obvious observation after 2 attempts. Do not write a file. Tell the user, honestly: "I ran two analysis passes and could not surface an observation you would not have made yourself. This can happen when (a) the question set is already sharp and my pattern-matching has nothing to add, (b) the framings are thin and there is not enough text to pattern-match against, or (c) the set is not varied enough for set-level structure to show. Options: show me the draft anyway for your own reading, rerun after ingesting more sources, or revisit the framings themselves." Offer to surface the draft as in-conversation prose (no file write) if the user wants to see what came up.
-
Helper script not found. See the resolution order under Helper invocation. If all three options fail, ask the user where memex is installed rather than silently skipping the log append.
-
meta/ directory missing. Create it (mkdir -p meta) and continue. Note the creation in the in-session summary so the user knows where reports are now living.
-
A gap_report_<YYYY-MM-DD>.md for today already exists. Write to gap_report_<YYYY-MM-DD>_b.md (then _c, etc.). Update the gap_report_latest.md symlink to point to the newest. Tell the user a prior run existed and give the filename so they can compare.
-
Git unavailable when resolving retro version:. Write version: unknown into the feedback frontmatter and continue. Never fail the retro over SHA resolution.
-
User waves off the retro entirely. Push once ("even one observation is useful"), then accept whatever they give and mark the rest (skipped). Do not silently skip the file write.