# User: /contemplate my source work skill is not triggering often enough. can you help me fix it. y... ## Retrieval Notes - Session id: `58ce8060-d94b-4f5d-970b-d19ff73eb7dd` - Last activity: `2026-02-21T16:03:47.501Z` ## My Notes <!-- Add your notes here. This section is preserved across syncs. --> ## Conversation ### User User: /contemplate my source work skill is not triggering often enough. can you help me fix it. you will nneed to think very hard about how skills work, check your knowledge and the arrhcitecture and config of the vault. make sure that you explain your analysis, justification, reasons etc etc. for your answer BEFORE giving me your final answer. Please give me a long, deep, and detailed answer, with lots of options/ideas: as we are in the 'kicking ideas around' stage, I want as much feedback as you can give me so that i have a lot to consider. Assistant: Let me gather all the relevant information before I begin contemplating. I need to understand the source-work skill, how skills trigger, and the current system architecture.Now let me also check the knowledge-base-hook to understand its exclusion logic and the system-design-practices file for context:Now let me read the proactive-capture-design knowledge file, which might have relevant architectural context:Good. Now let me check one more thing — how the skill description appears in the system-reminder list at the top of each conversation (the skills list that gets shown to Claude):Now I have a thorough picture. Let me contemplate. Alright. Nick says the source-work skill isn't triggering often enough. Let me think about this systematically by mapping every point in the chain where activation can fail, and then thinking about what kinds of prompts Nick is actually sending that should trigger it but don't. **First, let me understand how the source-work skill currently gets activated.** There are two mechanisms: 1. **The hook** (`source-work-hook.sh`) — a UserPromptSubmit hook that runs on every prompt, checks for keyword patterns, and injects a big banner telling Claude to invoke the source-work skill 2. **The skill description** in YAML frontmatter — which is always loaded in the system prompt's skills list, and tells Claude when to auto-load the skill body These are supposed to work in tandem: the hook is the "deterministic enforcement" layer that fires on keywords, and the skill description is the "Claude's judgement" layer where Claude decides the task is relevant. **Let me examine the hook's trigger patterns more carefully.** The hook has four regex categories: - `ACTIONS`: `read|compare|look at|check|find|open|extract|analyse|analyze|summarise|summarize|what does .* (say|argue|claim|write)|quote` - `OBJECTS`: `paper|pdf|epub|article|source|text|chapter|book|manuscript|monograph|dissertation|thesis` - `FOLDER`: `learning|generating.philosophy|typography` - `DIRECT`: `pdfs? folder|academic|scholarly|the .* paper` - `AUTHOR_QUERY`: `what (does|did|do) \w+ (say|argue|claim|write|mean|think)|what .* (said|argued|claimed|wrote)` The main match logic is: ``` (ACTIONS).{0,40}(OBJECTS) || FOLDER || DIRECT || AUTHOR_QUERY ``` Now... let me think about what kinds of prompts Nick actually sends when he wants to work with academic sources. This is where the rubber meets the road. The hook only fires if the *prompt text itself* matches these patterns. **Scenario 1: Referencing sources during brainstorming.** Nick's nick-context.md has this note: "Source-first in brainstorming: When discussing an academic author's framework during brainstorming — not just formal source-work — read the source first if it's available in Learning/." This is HUGE. Nick might say something like: - "Let's think about what Fisher says about this" - "How does this relate to Schellekens?" - "I think there's something in the Nguyen piece that bears on this" - "Pull up the Lopes paper" - "What's Walton's view on this?" Let me check these against the hook patterns... "Let's think about what Fisher says about this" — Does this match? AUTHOR_QUERY checks for "what does/did/do \w+ say|argue|claim..." Let me see: "what Fisher says" doesn't quite match `what (does|did|do) \w+ say` because it's "what Fisher says" not "what does Fisher say". Hmm, actually "what does Fisher say" *would* match, but "what Fisher says about this" would NOT because there's no auxiliary verb. That's a miss. "Pull up the Lopes paper" — ACTIONS has "open" but not "pull up". OBJECTS has "paper". The main regex requires `(ACTIONS).{0,40}(OBJECTS)`. "Pull up" doesn't match any ACTION. This is a miss. "How does this relate to Schellekens?" — No action word, no object word. This is a miss. It mentions an author but not in the `AUTHOR_QUERY` pattern. "I think there's something in the Nguyen piece that bears on this" — "piece" is not in OBJECTS. This is a miss. Wait, this is interesting. The hook explicitly says "Author names are not included — too many false positives." So it deliberately avoids author name matching. The AUTHOR_QUERY pattern tries to catch "what does X argue" type constructions, but it misses: - Author name alone ("the Schellekens piece") - Informal references ("pull up Nguyen") - Author + informal object ("the Fisher paper" — wait, this *would* match DIRECT: "the .* paper") Actually "the Fisher paper" would match `the .* paper` in DIRECT. Good. But "the Fisher piece" wouldn't. **Scenario 2: Working from a session note that references sources.** When Nick loads a project via a session note (like "let's work on generating philosophy"), the session note will have an "Academic References" section pointing to Learning/generating-philosophy/. The FOLDER pattern catches "generating.philosophy" and "typography". But what if Nick says: - "Let's work on the typography project" — matches "typography" ✓ - "Switch to generating philosophy" — matches "generating.philosophy" ✓ - "Let's work on the VR paper" — doesn't match any FOLDER. DIRECT has "the .* paper" which would match. ✓ Actually wait... "the VR paper" matches "the .* paper". Good. - "Let's continue with the auditory images project" — no match on FOLDER, DIRECT, or AUTHOR_QUERY. This is a miss unless there's something I'm not seeing. "project" isn't in OBJECTS either. Hmm, so project names that aren't in the FOLDER list don't get caught. **Scenario 3: Mid-conversation source consultation.** This is probably the biggest gap. Suppose Nick and Claude are already brainstorming about a topic, and then Nick says: - "Check what he says about that" - "What's the exact quote?" - "Can you find the passage where she discusses this?" - "Let me see what the text actually says" Let me check these: - "Check what he says about that" — `ACTIONS` has "check" but `OBJECTS` doesn't have "that". No match on the main pattern. AUTHOR_QUERY might catch "what he says" but... `what (does|did|do) \w+ (say|argue|claim|write|mean|think)` requires an auxiliary verb. "What he says" doesn't have one. Miss. - "What's the exact quote?" — ACTIONS has "quote" but this isn't followed by an OBJECT. And "quote" is at the end. The main pattern is `(ACTIONS).{0,40}(OBJECTS)`, requiring action THEN object. Miss. - "Can you find the passage where she discusses this?" — ACTIONS has "find", but "passage" isn't in OBJECTS. Miss. - "Let me see what the text actually says" — ACTIONS has "look at" but not "see". OBJECTS has "text". But "see what the text" — is "see" in ACTIONS? No. What about the AUTHOR_QUERY? "what the text actually says" — doesn't match `what (does|did|do) \w+` because "the" isn't followed by auxiliary + word + verb. Miss. Hmm wait, actually let me re-check: "What's the exact quote?" — does ACTIONS capture the word "quote" at the end? The pattern is `(ACTIONS).{0,40}(OBJECTS)` which means the action word must come before the object word. "Quote" is an ACTION but there's no OBJECT after it. So no match. **Scenario 4: Implicit source work.** Lots of academic work involves sources implicitly: - "Let me think about how this connects to the perception literature" - "What arguments exist for X?" - "How has this been discussed in aesthetics?" These are research-level queries that involve sources but use no obvious source-work keywords. The hook simply can't catch these. But should it? The epistemic-discipline hook might catch some of these (brainstorming triggers). But epistemic discipline is about how to handle Nick's ideas, not about quotation accuracy from external sources. **Now let me think about the skill description's role.** The current description is: ``` "Mandatory workflow for working with academic texts (PDFs, EPUBs, Markdown, text files). Use when reading, analysing, comparing, or quoting scholarly sources. Triggers: reading a paper, comparing two texts, extracting arguments from a source, creating source notes, any task involving quotation from academic material. Enforces extraction-first protocol and quotation accuracy." ``` This is already pretty good. It's not using the directive language pattern that the skill-authoring-best-practices file recommends worked well for file-management and writing-standards. It's still in descriptive mode: "Mandatory workflow for..." rather than "ALWAYS invoke this skill BEFORE..." Hmm. But the key insight from the note Nick has open is that directive language improved activation for file-management and writing-standards. The source-work description wasn't updated in that same session. Let me also think about the system-reminder block at the top of each conversation. I can see it in this very conversation — the skills list shows: ``` - source-work: Mandatory workflow for working with academic texts (PDFs, EPUBs, Markdown, text files). Use when reading, analysing, comparing, or quoting scholarly sources. Triggers:… ``` Notice the truncation with "…" — the full description might not be visible to Claude in the system prompt. The description is 320 characters. The guide says descriptions should be under 1024 characters. But I wonder if the system-reminder truncates them. Looking at the other descriptions in the list: ``` - file-management: ALWAYS invoke this skill BEFORE ANY Bash command involving Downloads, Learning, .claude, Google Drive, or external paths. NEVER attempt direct paths — Claudian WILL bl… ``` That's also truncated. So the system-reminder shows a truncated version. What matters is that the MOST IMPORTANT WORDS come first. "ALWAYS invoke" hits immediately. "Mandatory workflow" is softer. **Wait, let me think about this more carefully.** The skill descriptions appear in TWO places: 1. **The system-reminder list** at the top of every conversation — truncated, shows ~100-150 chars 2. **The YAML frontmatter** that Claude reads when deciding whether to invoke the skill — full text For auto-loading to work, Claude needs to make the connection between the user's task and the skill description in step 1 (the truncated list). If the truncated portion doesn't contain enough trigger information, Claude won't think to load the skill. Looking at what's visible before truncation: - Current: "Mandatory workflow for working with academic texts (PDFs, EPUBs, Markdown, text files). Use when reading, analysing, comparing, or quoting scholarly sources. Triggers:…" - The word "Triggers:" is right at the truncation point. So the actual trigger phrases ("reading a paper, comparing two texts...") might not be visible. OK so here's a structural problem: the trigger phrases are truncated away. **Let me now think about the interaction between the hook and the skill.** The hook fires, injects a banner that says "INVOKE the source-work skill (use the Skill tool)". Then Claude is supposed to use the Skill tool to load source-work. But... Does this actually happen reliably? The hook tells Claude to invoke the skill, but Claude might: 1. See the banner and follow the instruction → loads skill ✓ 2. See the banner but decide it can handle the task without the skill → skip ✗ 3. Have the banner compete with other priorities in a long context → miss it ✗ The hook is necessary but not sufficient. It creates an instruction, but as proactive-capture-design.md notes: "Hooks can only SUGGEST actions, not force them." Also, there's a subtlety: the hook fires on UserPromptSubmit, which means it fires *once per prompt*. If the need for source work emerges mid-conversation (e.g., during a brainstorming session about a research topic where Nick then says "ok let's check what the text actually says"), the hook fires on THAT prompt. But by then, Claude might be deep in brainstorming mode and the hook injection competes with a lot of context. **Now let me systematize the failure modes:** **Failure Mode 1: Hook doesn't fire (keyword gap)** - Prompts that should trigger source work but use words not in the regex - Examples: "pull up", "piece", "passage", "look at what she wrote", informal author references - This is fixable by expanding the regex **Failure Mode 2: Hook fires but Claude doesn't invoke the skill** - Claude sees the banner but decides it can handle things from memory - Especially likely after compaction when earlier source-work interactions are lost - The banner says "INVOKE the source-work skill" but Claude might consider the banner itself sufficient instruction and not bother loading the full skill - This is harder to fix — it's a Claude behavior issue **Failure Mode 3: Skill description doesn't trigger auto-load (no hook needed)** - For prompts where the hook doesn't fire, Claude relies on the skill description to decide - The description is descriptive, not directive - The trigger phrases are truncated in the system-reminder - This is fixable by rewriting the description **Failure Mode 4: Brainstorming drift — source work needed but not explicitly requested** - During brainstorming, Nick mentions an author or framework - Neither Nick nor Claude explicitly frames this as "source work" - The hook doesn't fire because the prompt doesn't mention papers/PDFs/sources - Claude discusses the author from training data instead of extracting the actual text - This is the scenario nick-context.md specifically calls out - This is the HARDEST failure mode because there's no explicit signal **Failure Mode 5: Continuation prompts** - After initial source work, follow-up prompts like "what about the next section" or "compare that with what she says earlier" - The hook might not fire on these because they lack explicit source-work keywords - But the skill should already be loaded from the initial prompt - However, after compaction, the skill context may be lost OK, so now I have five failure modes. Let me think about solutions for each. **For Failure Mode 1 (keyword gaps):** I could expand the regex patterns substantially. Some additions: - ACTIONS: `pull up|show me|grab|get|look at|refer to|consult|review|look through|go through|check out|revisit|dig into|return to` - OBJECTS: `piece|passage|section|paragraph|argument|claim|extract|reference|citation|work|volume|essay|tract|treatise|review|writing|contribution|readings?` - Add some author-detection heuristics that are broader But wait — there's a design tension here. The hook comment explicitly says "Author names are not included — too many false positives." And every keyword expansion increases false positive risk. The file-management hook already has false positive issues with "download." Actually, let me think about whether false positives are really that bad for source-work. If the hook fires unnecessarily, Claude gets a banner saying "extract source first." If there's no source to extract, Claude will just... not extract anything and proceed normally. The cost is wasted tokens on the banner. For a hook that fires on ~5-10% of prompts, that's a few hundred tokens per false positive. Not catastrophic. But the broader question is: can keyword expansion alone solve the problem? For Failure Mode 4 (brainstorming drift), I don't think it can. The prompts are too varied and natural-language to catch with regex. **For Failure Mode 2 (hook fires, Claude ignores):** Could strengthen the hook language. Currently says "INVOKE the source-work skill (use the Skill tool)". Could make it more directive: - "STOP. Before responding, you MUST use the Skill tool to invoke source-work. Do not proceed until the skill is loaded." - Add "If you proceed without loading the skill, you WILL fabricate quotations." Could also add a consequence framing — Nick's nick-context.md has: "Structural constraints over performative declarations." So rather than "be careful", the hook should create a structural constraint. Actually, there's an interesting idea here. What if the hook itself contained the critical rules (copy-paste only, extract first) rather than just pointing to the skill? Then even if Claude doesn't invoke the skill, the essential constraints are still injected. The hook currently does include some of this, but could be more comprehensive. But this creates token bloat — every prompt that matches would inject a large block of instructions. **For Failure Mode 3 (skill description doesn't auto-trigger):** Rewrite the description using directive language: ``` "ALWAYS invoke this skill when working with academic texts in ANY format (PDFs, EPUBs, Markdown, text files). Use when reading a paper, comparing texts, discussing what an author argues, extracting quotations, or engaging with scholarly sources. NEVER quote from memory — extraction-first is MANDATORY." ``` Front-load the directive verbs ("ALWAYS invoke") so they survive truncation. Put the trigger phrases early. **For Failure Mode 4 (brainstorming drift):** This is the hardest. Ideas: **Idea A: Modify the epistemic-discipline hook to also trigger source-work.** The epistemic-discipline hook already fires when Nick is discussing his research projects or brainstorming. Could add a secondary injection that says "If this brainstorming involves external authors/sources, also invoke source-work." But this makes the epistemic hook heavier. **Idea B: Add author/framework detection to source-work hook.** Could add known author names from Nick's projects: "fisher|schellekens|nguyen|walton|lopes|levinson|scruton|sibley|stecker" etc. But this requires maintaining a list and has false positive risk ("Fisher" is a common word in non-academic contexts). **Idea C: Add a broader "discussing what someone argues" pattern.** Currently AUTHOR_QUERY catches "what does X argue" but not "X argues that" or "Fisher's view" or "according to Nguyen". Could expand: - `\w+.?s (view|argument|account|position|framework|theory|claim|thesis)` - `according to \w+` - `\w+ (argues|claims|says|thinks|writes|suggests|proposes|maintains|contends)` These are pretty academic-specific constructions that rarely appear outside of source discussion. **Idea D: Add a CLAUDE.md instruction specifically about brainstorming + sources.** Nick already has this in nick-context.md: "Source-first in brainstorming." But that's a knowledge file, not CLAUDE.md. Moving it (or reinforcing it) to CLAUDE.md Behavioral Requirements would mean it's always loaded. Something like: "When discussing an academic author's framework during brainstorming, invoke the source-work skill and read the actual source if it's available in Learning/." **Idea E: Create a PreToolUse hook that checks for quotation-like patterns.** Instead of (or in addition to) UserPromptSubmit, have a hook on Claude's output generation that detects when Claude is about to quote something. But... PreToolUse hooks fire on tool calls, not on Claude's text generation. There's no hook point for "Claude is about to write a quotation." Dead end. **Idea F: Make the epistemic-discipline skill reference source-work.** If epistemic-discipline is already loaded for brainstorming, it could include a cross-reference: "If you are discussing external authors' views, also load source-work." This creates a cascading skill load. **Idea G: Combine the hooks.** Rather than having source-work-hook.sh as a separate, narrow hook, merge its triggers into a broader "academic work" hook that fires on either source-work keywords OR research brainstorming keywords. One injection, broader coverage. But wait, the design principle is separation of concerns. The note from the current session file mentions the hook count is growing (8 UserPromptSubmit hooks) and each adds latency. Merging could reduce count and broaden triggers simultaneously. Hmm, but merging creates a new problem: the injected text for source-work ("extract first, don't quote from memory") is different from epistemic-discipline ("don't rank Nick's ideas"). They serve different purposes. Could inject both when both are relevant, but then you need conditional logic. **For Failure Mode 5 (continuation prompts):** Once the skill is loaded, it should persist in context for the rest of the conversation (until compaction). The solution here is mainly about the initial trigger being reliable (fixing modes 1-4) and about the skill body being memorable enough that even after compaction, Claude retains the key constraint. Actually, there's a thought here about compaction. After compaction, the skill body is gone but the hook still fires on new prompts. So if Nick's follow-up prompt happens to match the hook keywords, the banner gets re-injected. But if the follow-up is "what about the next paragraph?" — no match. This is failure mode 5. One approach: make the source-work hook fire more broadly once a source-work session has been established. But hooks are stateless — they can't know whether previous prompts in the conversation involved source work. Unless... the hook checked for the presence of extraction temp files. If `Attachments/_*_temp.txt` files exist, the hook could fire on ANY prompt. That's an environmental signal that source work is happening. ```bash # If temp extraction files exist, this IS a source-work session if ls Attachments/_*_temp.txt 2>/dev/null | grep -q .; then # Fire the banner on ANY prompt fi ``` Oh that's interesting. This is a state-based trigger rather than keyword-based. If there are extraction files in Attachments/, the user is working with sources, so the hook should always fire. This catches continuation prompts beautifully. But wait — the skill says "Clean up temporary extraction files when done." So these files should only exist during active source work. If cleanup happens promptly, this works as intended. If cleanup is forgotten, you'd get persistent false positives. But that's also a useful reminder to clean up. Let me also think about the **PreToolUse** hook possibility. Could there be a hook on Bash (for pdftotext) or on Read (for reading temp files) that injects source-work reminders? The pdf-guard-hook already fires on Read for PDFs. A source-work-specific PreToolUse hook on Bash could detect pdftotext calls and remind Claude about the full protocol. But this is quite narrow. Actually, there's a more interesting PreToolUse possibility. What if there was a hook on the Skill tool that detected when source-work was being invoked and added extra context? No, that's circular — the skill is already being loaded. Let me step back and think about what the IDEAL system would look like. **The ideal source-work activation system would:** 1. Catch explicit source-work requests (read this paper, compare these texts) — DONE via hook, with keyword gaps to fix 2. Catch implicit source-work needs (discussing an author during brainstorming) — PARTIALLY via AUTHOR_QUERY, needs expansion 3. Persist once activated within a session — NOT DONE, needs state mechanism 4. Survive compaction — the hook re-fires, but only on matching prompts 5. Activate Claude's own judgment to invoke the skill — PARTIALLY via description, needs directive language **Let me now also think about whether the SKILL itself is part of the problem.** Maybe it's not just triggering that's failing — maybe when the skill IS loaded, Claude doesn't follow it well enough, leading Nick to think it wasn't triggered. But Nick specifically says "triggering" is the problem, so I'll focus there. **One more thought on the skill description.** Right now the description appears twice in the system-reminder list: ``` - source-work: Mandatory workflow for working with academic texts (PDFs, EPUBs, Markdown, text files). Use when reading, analysing, comparing, or quoting scholarly sources. Triggers:… ``` ...and then again later (I can see it's duplicated in the skills list). This might actually be a Claude Code feature where skills appear once per installation location or something. But the duplication doesn't help with triggering — it's the same truncated description. **Let me also consider the interaction between hooks and the Claudian plugin.** Nick runs Claude Code inside the Claudian Obsidian plugin. The Claudian vault restriction blocks certain Bash patterns. Could this interfere with source-work? Let me think... the source-work hook injects instructions that say "use pdftotext." The pdftotext command would need to reference external paths (Learning folder). The file-management hook exists to handle this, and pdftotext is in the Bash allow-list. So there shouldn't be a direct conflict, but there could be an indirect one: if Claude tries to run pdftotext and hits a path restriction, it might fumble and not complete the extraction, making the whole source-work flow fail. But that's an execution problem, not a triggering problem. **Let me now draft concrete recommendations.** I think there are several layers of improvement, from quick wins to more architectural changes: ### Quick Wins (description and keyword fixes) 1. **Rewrite the skill description with directive language.** 2. **Expand hook keywords** to catch more natural phrasings. 3. **Add "piece", "passage", "section", "argument" to OBJECTS.** 4. **Add "pull up", "show me", "grab", "refer to", "consult", "revisit", "dig into", "return to" to ACTIONS.** ### Medium Effort (cross-skill integration) 5. **Add academic-author patterns** to the hook — not author names, but syntactic patterns like "X argues", "according to X", "X's view/account/framework". 6. **Cross-reference source-work from epistemic-discipline skill.** When epistemic-discipline is loaded for brainstorming, include a reminder about source-work if external sources are being discussed. 7. **Add a CLAUDE.md behavioral requirement** specifically about source-first during brainstorming (not just in nick-context.md). ### Architectural (state-aware triggering) 8. **Add temp-file detection** to the hook — if `_temp.txt` extraction files exist, fire the banner regardless of keywords. 9. **Consider merging the source-work and epistemic-discipline hooks** into a unified "academic work" hook with conditional injection blocks. ### Speculative (may be overkill) 10. **Create a PostToolUse hook on Read** that detects when Claude reads a PDF or academic text and injects source-work reminders. 11. **Tag-based triggering**: When a note being discussed has tags like `#paper`, `#reference`, `#source`, have the hook fire. Wait, the hook runs on user prompt text, not on file metadata. So tag-based triggering from the hook is hard. But a CLAUDE.md instruction could say: "When working with notes tagged #paper or #reference, invoke source-work." That's judgement-based, not deterministic, but it's another layer. Actually, I realize I should also think about the `` or ``, it could fire on that basis. But I'm not sure if the XML context is part of `.prompt` in the JSON or if it's elsewhere. Actually, looking at the hook format, UserPromptSubmit hooks receive the prompt as JSON with a `.prompt` field. I believe the current_note context IS part of the prompt because it's injected by the Claudian plugin into the user message. So the hook should be able to see it. This opens up another detection avenue: if the user's current_note is in the Readwise/ folder, or is a note that seems academic, fire source-work. But this requires some sophistication — you'd need to detect "this note is about a source." Hmm, maybe simpler: if the current_note path contains "Readwise/" or "Learning/" or the prompt mentions a PDF path, fire source-work. Let me check if "Readwise" is in the FOLDER pattern... no, FOLDER only has "learning|generating.philosophy|typography". Adding "readwise" would catch when a user is looking at a Readwise import and discussing it. Actually wait, the prompt text that the hook receives would include the full user message including XML tags. So "readwise" would appear in the path. But the hook converts everything to lowercase and searches against it. So `` would become `` and the "readwise" in FOLDER would match! So adding "readwise" to the FOLDER pattern is a free win. OK, I think I've been thorough enough in the analysis. Let me also think about one more dimension: the **frequency distribution** of Nick's prompts. How often does Nick work with sources? Given he's an academic philosopher, probably quite often. The typical session might involve: - Reading a paper → clear source-work trigger - Brainstorming about ideas that involve referencing authors → fuzzy trigger - Writing a manuscript that cites sources → moderate trigger - Processing Readwise imports → implicit source work - Creating notes about readings → should trigger The "brainstorming" category is probably the most common and the hardest to catch. That's where the real gap is. One final thought: could a **completely different mechanism** work better than expanding the hook? What about a **CLAUDE.md instruction that's very explicit** about when to use source-work? Something like: "**Academic source protocol**: Before discussing what any author argues, claims, or proposes — whether formally reading a paper or casually brainstorming — check whether their text is available in Learning/ or Readwise/. If it is, invoke source-work and extract it. Never discuss a source from training data when the actual text is accessible." This is judgment-based and won't survive compaction, but combined with the hook (which does survive compaction), it covers the early-conversation period where CLAUDE.md is still in context. The hook catches the obvious cases, CLAUDE.md catches the judgment cases, and together they cover more ground. The issue is this is *yet another* CLAUDE.md instruction. Nick's CLAUDE.md is already hefty. But this one replaces the current soft instruction and makes it more explicit. OK, I think I've been thorough. Let me now organize this into a coherent final answer. ## Analysis: Why Source-Work Isn't Triggering I've read your source-work skill, hook, settings, architecture docs, the anthropic skills guide, your skill-authoring best practices, and the relevant knowledge files. Here's what I found. ### The Triggering Chain Source-work has two activation paths: 1. **Hook** (`source-work-hook.sh`) — keyword-matched, deterministic, survives compaction 2. **Skill description** — Claude's own judgement-based auto-load from the system-reminder list Both have distinct problems. --- ### Problem 1: The Hook Has Significant Keyword Gaps The hook's regex logic is `(ACTION).{0,40}(OBJECT)` plus some direct/folder/author patterns. I tested a bunch of prompts that *should* trigger source-work against these patterns, and many fall through: **Natural phrasings that miss:** | What Nick might say | Why it misses | |---|---| | "Let's think about what Fisher says about this" | AUTHOR_QUERY requires auxiliary verb ("what *does* Fisher say") — "what Fisher says" has no auxiliary | | "Pull up the Lopes paper" | "pull up" isn't in ACTIONS (has "open", "find", "read" but not "pull up") | | "How does this relate to Schellekens?" | No action word, no object word, author name alone won't match | | "I think there's something in the Nguyen piece" | "piece" isn't in OBJECTS | | "Check what he says about that" | "that" isn't in OBJECTS, so ACTION+OBJECT fails | | "What's the exact quote?" | "quote" is at the end — ACTION before OBJECT required | | "Can you find the passage where she discusses this?" | "passage" isn't in OBJECTS | | "Let me see what the text actually says" | "see" isn't in ACTIONS | | "Fisher argues that..." | Doesn't match any pattern — `\w+ argues` isn't in AUTHOR_QUERY | | "According to Nguyen..." | No pattern for "according to" | | "X's view on Y" / "the Walton account" | No possessive/author-framework pattern | The hook comment says "Author names not included — too many false positives." Fair for proper names, but the hook also misses *syntactic patterns* that are unambiguously academic ("X argues that", "according to X", "X's framework"). These are low false-positive constructions. **Also missing from OBJECTS:** piece, passage, section, paragraph, argument, essay, extract, reference, citation, work, contribution, reading(s), writing(s) **Also missing from ACTIONS:** pull up, show me, grab, get me, refer to, consult, revisit, dig into, return to, go back to, see, review, look through, go through **FOLDER only has three entries:** learning, generating.philosophy, typography. Missing: readwise, auditory, vr, propaganda, mckenna (from PROJECTS in the epistemic-discipline hook). And since the prompt text includes `` tags from Claudian, "readwise" in the FOLDER list would catch when you're viewing a Readwise import — free win. ### Problem 2: The Skill Description Uses Descriptive, Not Directive Language Your own skill-authoring-best-practices file documents that directive language ("ALWAYS invoke", "NEVER attempt") significantly outperforms descriptive language ("Mandatory workflow for...") for auto-load activation. You rewrote file-management and writing-standards but source-work still reads: > "Mandatory workflow for working with academic texts (PDFs, EPUBs, Markdown, text files). Use when reading, analysing, comparing, or quoting scholarly sources. Triggers:…" Two problems: 1. **"Mandatory workflow" is descriptive** — tells Claude what the skill *is*, not what to *do* 2. **The trigger phrases are truncated** in the system-reminder. You can see in this very conversation: "Triggers:…" — everything after that ellipsis is invisible. So the actual trigger phrases ("reading a paper, comparing two texts, extracting arguments") never reach Claude's initial assessment The most important words need to come *first*, before truncation cuts them off. ### Problem 3: The Brainstorming Gap (Hardest) Your nick-context.md has this entry: *"Source-first in brainstorming: When discussing an academic author's framework during brainstorming — not just formal source-work — read the source first if it's available in Learning/."* This is in a knowledge file, which means Claude only sees it if the knowledge-base hook fires AND Claude reads the file. The knowledge-base hook explicitly *excludes* source-work from its domain ("handled by source-work-hook.sh"). So there's a coverage gap: - Formal source requests → source-work hook fires → skill loads → ✓ - Brainstorming that involves authors → epistemic-discipline hook fires → but it says nothing about source extraction → ✗ - The instruction to check sources during brainstorming lives in nick-context.md → only loaded via knowledge-base hook if "research" keywords match → unreliable The worst-case scenario: you're brainstorming about generating philosophy, the epistemic-discipline hook fires (catches "generating philosophy"), Claude engages with your ideas, you mention "Fisher says X," Claude discusses Fisher from training data, and the source-work hook never fires because "Fisher says X" doesn't match its patterns. The actual PDF is sitting in Learning/generating-philosophy/ unused. ### Problem 4: No Session State Awareness Hooks are stateless — they can't know that the *previous* prompt involved source work. So follow-up prompts ("what about the next section?", "compare that with the earlier passage") don't trigger the hook unless they happen to contain keywords. After compaction, the skill body is gone and the hook is the only mechanism, but these continuation prompts slip through. --- ### Solutions (Graduated) #### Tier 1: Quick Wins (30 min) **1a. Rewrite the skill description with front-loaded directive language:** ```yaml description: "ALWAYS invoke when working with academic sources — PDFs, EPUBs, articles, scholarly texts. Use when reading a paper, discussing what an author argues, comparing texts, quoting, or referencing scholarly material during brainstorming. NEVER quote from memory. Extraction-first is MANDATORY." ``` This puts "ALWAYS invoke" first (survives truncation), includes "brainstorming" as a trigger context, and uses the directive pattern proven to work for your other skills. **1b. Expand hook keywords:** - Add to ACTIONS: `pull up|show me|grab|get me|refer to|consult|revisit|dig into|return to|go back to|see|review|look through|go through` - Add to OBJECTS: `piece|passage|section|paragraph|argument|essay|extract|reference|citation|work|contribution|reading` - Add to FOLDER: `readwise|auditory|vr|propaganda|mckenna` (your active research projects) - Add a new category for academic-syntactic patterns: `\w+ (argues|claims|suggests|proposes|maintains|contends|writes|holds|notes|observes) (that|this|the|a|an|we|it|there|in)|according to \w+|\w+.s (view|account|argument|framework|theory|position|thesis|claim|approach)` **1c. Broaden AUTHOR_QUERY to not require auxiliary verbs:** Currently: `what (does|did|do) \w+ (say|argue|claim|write|mean|think)` Add: `what \w+ (says|argues|claims|writes|means|thinks|said|argued|claimed|wrote|meant|thought)` This catches "what Fisher says" alongside "what does Fisher say." #### Tier 2: Cross-Skill Integration (1 hour) **2a. Add source-work cross-reference to epistemic-discipline hook.** Since the epistemic-discipline hook already fires during brainstorming, add a line to its injected text: ``` If this brainstorming involves discussing what an external author argues, also INVOKE the source-work skill and check Learning/ for their actual text. Do not discuss a source from training data when the PDF is available. ``` This is lightweight — a few extra lines in an existing injection. It means every research brainstorming session gets a reminder about source-first protocol. **2b. Promote the "source-first in brainstorming" rule to CLAUDE.md.** Currently it's buried in nick-context.md (a knowledge file). Move it to Behavioral Requirements in CLAUDE.md so it's always in context at conversation start: ```markdown - **Source-first for authors**: When discussing any academic author's framework — whether formally reading their paper or casually brainstorming — check whether their text exists in Learning/ or Readwise/. If it does, invoke source-work and extract it. Never discuss a source from training data alone when the actual text is accessible. ``` This is judgment-based (won't survive compaction), but covers early-conversation. The hook covers post-compaction. **2c. Make the epistemic-discipline skill body itself reference source-work.** If epistemic-discipline is already loaded, its instructions could include: "When engaging with external authors' views, also load source-work and follow its extraction-first protocol." This creates a cascading skill load: epistemic-discipline → source-work. #### Tier 3: State-Aware Triggering (1-2 hours) **3a. Add temp-file detection to the hook.** The skill's workflow creates `Attachments/_*_temp.txt` files during extraction. If these exist, the user is actively working with sources. Add to the hook: ```bash # State-based trigger: if extraction files exist, we're in a source-work session VAULT_ROOT=$(pwd) if ls "${VAULT_ROOT}/Attachments/"_*_temp.txt 2>/dev/null | head -1 | grep -q .; then # Fire banner [Thinking: 1 block(s), 2.0s total] [Tool Read input: file_path=/Users/nickyoung/My Obsidian Vault/Notes/Skill Triggering and Knowledge Consultation Overhaul (21 Fe... status=completed] [Tool Glob input: pattern=**/*source-work*/**, path=/Users/nickyoung/.claude/skills status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/knowledge/INDEX.md status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/skills/source-work/SKILL.md status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/knowledge/anthropic-skills-guide.md status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/knowledge/skill-authoring-best-practices.md status=completed] [Tool Grep input: pattern=source-work, path=/Users/nickyoung/.claude, output_mode=files_with_matches status=completed] [Tool Glob input: pattern=**/source-work-hook*, path=/Users/nickyoung/.claude status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/hooks/source-work-hook.sh status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/settings.json status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/knowledge/quotation-accuracy.md status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/knowledge/claude-architecture.md status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/hooks/knowledge-base-hook.sh status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/knowledge/system-design-practices.md, limit=50 status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/hooks/epistemic-discipline-hook.sh status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/knowledge/proactive-capture-design.md status=completed] [Tool Grep input: pattern=source-work, path=/Users/nickyoung/.claude, output_mode=content, -n=true status=completed] [Tool Read input: file_path=/Users/nickyoung/.claude/knowledge/nick-context.md, offset=185, limit=20 status=completed] User: "Scenario 4: Implicit source work. Lots of academic work involves sources implicitly:" don't worry about this. Don't worry about tier 3 either. I am interested in you implementing 1 and 2. but first I want you to do a deep, triple check that your suggestion is the best way of achieving what I want and won't break anything in my existing vault and config setup etc. Please do all the checks and give me a new iteration of necessary ### Assistant Let me do a thorough verification pass. I need to re-read the key files carefully and check for conflicts, false positives, and interaction effects. ### Assistant Now let me check the other hooks that might interact with my proposed changes, and look at the knowledge-base hook's exclusion logic: ### Assistant Now let me check for specific interaction risks. I need to test my proposed keyword expansions against the other hooks' patterns to identify false positive overlaps: ### Assistant Excellent. That analysis turned up several problems with my original proposals. Let me synthesize everything into a revised, verified plan. --- ## Verification Results ### What I Tested I ran every proposed keyword addition against realistic non-academic prompts (config work, system design, casual vault tasks) to check false positive rates. I also checked for substring matching risks, hook interaction effects, and overlap with existing patterns. ### What Failed Verification **1. `review` and `see` as ACTIONS — CATASTROPHIC false positive risk.** Both words are universal English verbs. Combined with OBJECTS like `text`, `source`, `work`, `section`: - "review the text of my CLAUDE.md" → fires - "let me see the source code" → fires - "review this section of the config" → fires These would trigger on roughly half of all system-design and configuration conversations. **Dropped.** **2. The ACADEMIC_SYNTAX pattern — 100% false positive rate on tech discussions.** The pattern `\w+ (argues|claims|suggests|...) (that|this|the|...)` matches: - "the plugin suggests that we update" - "the error suggests that something is wrong" - "the documentation notes that this is deprecated" - "the compiler argues that the type is wrong" And the possessive pattern `\w+'s (view|account|argument|framework)` matches: - "obsidian's approach to indexing" - "typescript's argument validation" - "the api's account balance endpoint" Academic syntax is isomorphic with anthropomorphised tech language. **Dropped entirely.** **3. Broadened AUTHOR_QUERY (dropping auxiliary verb requirement)** — High false positive risk. `what \w+ (says|means|thinks)` matches: - "what this means" → fires - "what it says in the config" → fires - "what claude thinks" → fires These are among the most common English constructions. **Dropped the no-auxiliary version.** Instead, I'm adding more auxiliary verbs to the existing safe pattern. **4. Multiple OBJECTS additions** — `section`, `paragraph`, `argument`, `reference`, `work`, `contribution`, `reading`, `extract`, `citation` all have heavy non-academic usage: - "the section on hooks" / "the argument list" / "the reference docs" / "the reading list" / "the extract from the log" **Dropped all of these.** Keeping only words that are genuinely academic: `piece`, `passage`, `essay`, `treatise`. **5. `vr` in FOLDER** — Substring matching risk. The hook uses bare `grep -qiE`, so `vr` matches inside "oeuvre", "manoeuvre", "hors d'oeuvre" — words an academic philosopher actually uses. The epistemic hook avoids this by using the full phrase `vr and perceptual`. **Dropped.** **6. `auditory`, `propaganda`, `mckenna` in FOLDER** — The subagent's recommendation was incisive: "Keep FOLDER focused on storage locations. Let the epistemic hook own project-name detection." The current FOLDER entries (`learning`, `generating.philosophy`, `typography`) are storage paths. Adding project names blurs that boundary and creates overlap with the epistemic-discipline hook, which already owns project-name detection. **Dropped from source-work FOLDER.** The Tier 2 cross-reference handles this instead. ### What Passed Verification **1. Skill description rewrite** — Pure metadata change. Directive language proven effective for file-management and writing-standards. Front-loads "ALWAYS invoke" to survive truncation. No code risk. **2. Safe ACTION additions:** `pull up`, `grab`, `get me`, `consult`, `revisit`, `dig into`, `refer to`, `go back to`, `return to`, `look through`, `go through`. All uncommon in casual/tech speech. With the narrow OBJECTS list, these generate minimal false positives. `show me` is borderline but I'm including it — it's a natural academic phrasing ("show me the Fisher paper") and with the narrow OBJECTS list, false positives are limited to "show me the source code" (already a problem with `find the source code`). **3. Safe OBJECTS additions:** `piece` (informal-academic: "the Nguyen piece"), `passage` (you don't say "the passage of the config"), `essay` (clearly academic), `treatise` (clearly academic). **4. FOLDER addition: `readwise`** — Proper noun, zero substring risk, zero non-academic usage. And it fits the storage-location model. The prompt text includes `` XML tags from Claudian, so `readwise` catches when you're viewing a Readwise import. **5. DIRECT additions: `the \w+ (piece|essay)`** — Catches "the Fisher piece", "the Orwell essay" with only one word between "the" and the noun. Restricts the `.*` greediness that `the .* paper` has. **6. AUTHOR_QUERY improvements** — Keep auxiliary verb requirement (proven safe) but add more auxiliaries and verb forms: - `is/was/has` as auxiliaries → catches "what is Fisher arguing", "what has Walton said" - Participles and irregular past tenses → catches "what is she claiming", "what has he written" **7. Epistemic-discipline hook cross-reference** — 3 lines added to the injected text. Negligible token cost (~40 tokens on prompts that already fire the epistemic banner). Advisory, not deterministic — Claude decides whether external authors are involved. If no PDF exists in Learning/, Claude just proceeds. **8. CLAUDE.md "Source-first for authors" bullet** — Already exists in nick-context.md (line 195). Promoting to CLAUDE.md Behavioral Requirements gives it always-loaded status at conversation start. Lost after compaction (which is why the hook and cross-reference exist). No conflict with existing instructions. ### Interaction Analysis **Will both hooks ever fire simultaneously?** Yes — `readwise` appears in both source-work FOLDER (proposed) and... actually no, `readwise` isn't in the epistemic hook. The epistemic hook has `generating philosophy|typography aesthetics|vr and perceptual|auditory images|mckenna|propaganda`. The only current overlap is `generating.philosophy` (source-work) vs `generating philosophy` (epistemic). Both hooks firing on the same prompt is fine — they inject complementary, non-contradictory instructions (one about extraction protocol, one about epistemic discipline). **Will source-work interact with file-management?** Potentially — if Nick says "read the paper in Learning/", both would fire (source-work from `paper` + file-management from `learning`). Both firing is correct: you need source-work protocol AND path indirection. **CLAUDE.md length impact?** Current file is ~123 lines. Adding one bullet adds ~3 lines. Well within safe limits (system-design-practices warns about issues above ~40k characters; CLAUDE.md is nowhere near that). --- ## Revised Proposal ### Change 1: Skill Description (SKILL.md) **Current:** > "Mandatory workflow for working with academic texts (PDFs, EPUBs, Markdown, text files). Use when reading, analysing, comparing, or quoting scholarly sources. Triggers: reading a paper, comparing two texts, extracting arguments from a source, creating source notes, any task involving quotation from academic material. Enforces extraction-first protocol and quotation accuracy." **Proposed:** > "ALWAYS invoke when working with academic sources — PDFs, EPUBs, articles, scholarly texts. Use when reading a paper, discussing what an author argues, comparing texts, quoting, or referencing scholarly material during brainstorming. NEVER quote from memory. Extraction-first is MANDATORY." **What survives truncation in system-reminder (~150 chars):** > "ALWAYS invoke when working with academic sources — PDFs, EPUBs, articles, scholarly texts. Use when reading a paper, discussing what an author argues" The directive framing and trigger phrases land before the cut. ### Change 2: Hook Keyword Expansion (source-work-hook.sh) ```bash ACTIONS="read|compare|look at|check|find|open|extract|analyse|analyze|summarise|summarize|what does .* (say|argue|claim|write)|quote|pull up|show me|grab|get me|consult|revisit|dig into|refer to|go back to|return to|look through|go through" OBJECTS="paper|pdf|epub|article|source|text|chapter|book|manuscript|monograph|dissertation|thesis|piece|passage|essay|treatise" FOLDER="learning|generating.philosophy|typography|readwise" DIRECT="pdfs? folder|academic|scholarly|the .* paper|the \w+ (piece|essay)" AUTHOR_QUERY="what (does|did|do|is|was|has) \w+ (say|argue|claim|write|mean|think|saying|arguing|claiming|writing|said|argued|claimed|wrote|written|meant|thought)|what .* (said|argued|claimed|wrote|written)" ``` **Coverage gained:** | Prompt that previously missed | Now matches via | |---|---| | "Pull up the Lopes paper" | `pull up` + `paper` | | "I think there's something in the Nguyen piece" | `piece` in OBJECTS (via existing `find`/`check` in context) | | "Can you find the passage where she discusses this?" | `find` + `passage` | | "Grab the Fisher essay" | `grab` + `essay` | | "Let me go back to the text" | `go back to` + `text` | | "What is Fisher arguing?" | `is` added to AUTHOR_QUERY auxiliaries | | "What has Walton said about this?" | `has` added to AUTHOR_QUERY auxiliaries | | "Dig into the Readwise highlights" | `dig into` + `readwise` in FOLDER | | "Consult the source text" | `consult` + `source`/`text` | | "Refer to the Orwell essay" | `refer to` + `essay` | | Viewing a Readwise note (current_note context) | `readwise` in FOLDER | | "The McKenna piece is relevant" | `piece` in OBJECTS (via DIRECT: `the \w+ piece`) | ### Change 3: Epistemic-Discipline Hook Cross-Reference Add to the injected banner text (after the existing bullet points, before "THIS APPLIES TO CONVERSATION"): ``` - If discussing what an external author argues or claims, also INVOKE the source-work skill and check Learning/ for the actual text. Do not discuss a source from training data when the PDF is available. ``` This means every brainstorming session that fires the epistemic hook (project names, "let's think about...", "my argument...") also gets a reminder to check for available source PDFs. ### Change 4: CLAUDE.md Behavioral Requirement Add after the existing "Source quotation" bullet (line 85): ```markdown - **Source-first for authors**: When discussing any academic author's framework — whether formally reading their paper or casually brainstorming — check whether their text exists in Learning/ or Readwise/. If it does, invoke source-work and extract it. Never discuss a source from training data alone when the actual text is accessible. ``` This promotes the instruction from nick-context.md (where it's only loaded via the knowledge-base hook) to CLAUDE.md (where it's always in context at conversation start). --- ### What This Doesn't Solve I should be honest about the remaining gaps. The defence-in-depth after these changes covers: | Scenario | Hook fires? | CLAUDE.md catches? | Epistemic cross-ref catches? | |---|---|---|---| | "Read the Fisher paper" | ✓ | ✓ | — | | "Pull up the Nguyen piece" | ✓ (new) | ✓ | — | | "What is Walton arguing?" | ✓ (new) | ✓ | — | | "Let's think about what Fisher says about this" | ✗ | ✓ | ✓ (if epistemic fires) | | "How does this relate to Schellekens?" | ✗ | ✓ | ✓ (if epistemic fires) | | "Fisher argues that perception is..." | ✗ | ✓ | ✓ (if epistemic fires) | | "What about the next section?" (continuation) | ✗ | ✗ (lost after compaction) | ✗ | The last row (continuation prompts after compaction) remains a gap. Tier 3 (state-aware triggering via temp files) would address it, but you asked me to skip that for now. And the middle rows (informal author references during brainstorming) rely on Claude's judgment via CLAUDE.md and the epistemic cross-reference rather than deterministic hook matching — which is appropriate, since regex can't distinguish "Fisher argues" (academic) from "the compiler argues" (tech) after lowercasing. The ACADEMIC_SYNTAX pattern I originally proposed was an attempt to close that gap deterministically, but verification showed it would false-positive on every system-design conversation. The judgment-based approach (CLAUDE.md + epistemic cross-reference) is the right tool for this particular gap. --- Want me to implement these four changes? *La verifica ha rivelato che l'espansione aggressiva dei pattern è un vicolo cieco — meglio tre strati sottili che funzionano insieme che uno spesso che cattura tutto.*