<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>The Runbook · The Durability Curve</title><description>Every piece in The Runbook, in full.</description><link>https://durabilitycurve.com/</link><item><title>Did Your AI Actually Read the Doc?</title><link>https://durabilitycurve.com/blog/did-your-ai-read-the-doc/</link><guid isPermaLink="true">https://durabilitycurve.com/blog/did-your-ai-read-the-doc/</guid><description>How to give ChatGPT and Claude the same project notes in one Google Doc, and test whether a new chat can use them.</description><pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p data-lead-img=&quot;&quot;&gt;&lt;img alt=&quot;A word only the doc knows.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;1600&quot; height=&quot;900&quot; src=&quot;https://durabilitycurve.com/_astro/rb6-hero-anim.CZU6EIaC_ZnOpcq.webp&quot; &gt;&lt;/p&gt;
&lt;p&gt;Yesterday you and ChatGPT settled the plan. Today’s chat has never heard of it, and Claude never saw it either. So you paste it in again, and whatever you forget to paste gets decided twice.&lt;/p&gt;
&lt;p data-cover-after=&quot;&quot;&gt;This guide puts the plan in one Google Doc that both assistants read, in three steps, then gives you a test that shows whether a new chat is reading the current version. If you only use one assistant, its built-in Projects feature keeps your notes across chats in that app, which may be all you need.&lt;/p&gt;
&lt;h2 id=&quot;connect-both-assistants-to-google-drive&quot;&gt;Connect both assistants to Google Drive&lt;/h2&gt;
&lt;p&gt;Use the Google account you will keep the doc in. Connecting lets each assistant search everything that account can open, including files far beyond this doc. If Google says your organisation blocks it, your admin has to allow it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Claude.&lt;/strong&gt; Open &lt;a href=&quot;https://claude.ai/customize/connectors&quot;&gt;Claude’s connector settings&lt;/a&gt;, click the &lt;strong&gt;+&lt;/strong&gt; next to Google Drive, and sign in to Google. A tick means it’s already connected. Anthropic offers this on every plan, Free included; on Team and Enterprise, an Owner has to add it first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ChatGPT.&lt;/strong&gt; Open &lt;a href=&quot;https://chatgpt.com&quot;&gt;ChatGPT&lt;/a&gt; and click &lt;strong&gt;Plugins&lt;/strong&gt; in the left sidebar. If Google Drive shows a &lt;strong&gt;+&lt;/strong&gt;, click it and sign in to Google. OpenAI doesn’t list which plans include it; it was there on our Plus account. If Google Drive isn’t there, use the doc with Claude and paste its text into ChatGPT when you need it there. That copy won’t update itself.&lt;/p&gt;
&lt;h2 id=&quot;make-the-doc&quot;&gt;Make the doc&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.new&quot;&gt;Create a Google Doc&lt;/a&gt; in that same Google account, with a name no other file in your Drive uses, paste this in, fill in the brackets, and swap the example decision for one of yours. Keep everything in the body of the doc, not in comments, which some connections can’t read.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ABOUT THIS PROJECT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Goal: [what this project is for, in one sentence]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Audience: [who the work is for]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Current priority: [the next specific task]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Rules for any AI:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Read this whole document before you start.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;If you cannot open it, say so. Do not guess.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Link a source for every fact. Say when you are unsure.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Never publish, send or spend anything without asking me.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;DECISIONS (newest at the top; a newer line wins)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2026-10-15: Link every statistic. Why: one went untraced.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each time you settle something, add it as a new first line under DECISIONS, with the date. A decision made in a chat isn’t in the doc until someone writes it there.&lt;/p&gt;
&lt;h2 id=&quot;start-every-chat-the-same-way&quot;&gt;Start every chat the same way&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Claude.&lt;/strong&gt; Open a new chat in &lt;a href=&quot;https://claude.ai&quot;&gt;Claude&lt;/a&gt;, click the &lt;strong&gt;+&lt;/strong&gt; in the message box, then &lt;strong&gt;Connectors&lt;/strong&gt;, then &lt;strong&gt;Add from Google Drive&lt;/strong&gt;. Search for the doc, tick it and click &lt;strong&gt;Add to chat&lt;/strong&gt;. Anthropic says Claude re-reads it each time you send a message, so your latest edits reach it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ChatGPT.&lt;/strong&gt; Open a new chat in &lt;a href=&quot;https://chatgpt.com&quot;&gt;ChatGPT&lt;/a&gt;, type &lt;strong&gt;@&lt;/strong&gt; at the start of your message and pick Google Drive from the list.&lt;/p&gt;
&lt;p&gt;In both apps, put the prompt below in that same first message. It tells the assistant which doc to open:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Open my Google Doc &quot;[doc name]&quot; and read all of it.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Tell me the current priority and the newest decision.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Then help me with: [task]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;the-test&quot;&gt;The test&lt;/h2&gt;
&lt;p&gt;Both assistants can remember earlier chats, and an answer from memory sounds the same as an answer from the doc. An AI can even &lt;a href=&quot;https://durabilitycurve.com/blog/your-research-agent-cites-sources-it-never-read/&quot;&gt;cite a source it never read&lt;/a&gt;. So give the doc a word no chat has seen.&lt;/p&gt;
&lt;p&gt;Type a new first line under DECISIONS with today’s date and a word you make up. Type it in the doc only, never in a chat.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[today&apos;s date]: Test. Codeword: [your made-up word]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In each assistant, open a brand-new chat, attach the doc as in step 3, and ask:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Open my Google Doc &quot;[doc name]&quot;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Quote the first line under DECISIONS exactly,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;and name the doc you opened.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It quotes today’s codeword.&lt;/strong&gt; It fetched the current doc. Go on to the second question below.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It quotes anything else.&lt;/strong&gt; It didn’t fetch the current doc. Check you attached the right one, then try once more in a new chat. If it still fails, don’t rely on that assistant for this project yet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It can’t find the doc.&lt;/strong&gt; Check that the Google account you connected in step 1 is the one that owns the doc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Quoting a line shows it can fetch the doc. To check it can use it, ask in the same chat:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Which decisions are settled, and what should you do next?&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It should name your current priority and leave everything under DECISIONS settled. If it reopens a decision or picks other work, make that decision or the current priority clearer in the doc and ask again. We ran both questions in Claude and ChatGPT on 15 October 2026: both quoted the codeword, and both followed the newer of two conflicting decisions.&lt;/p&gt;
&lt;p&gt;Delete the test line afterwards. Rerun the test with a new codeword whenever you change assistant, plan or settings.&lt;/p&gt;
&lt;h2 id=&quot;when-to-move-it-to-github&quot;&gt;When to move it to GitHub&lt;/h2&gt;
&lt;p&gt;Skip this unless you want your assistants to hand work to each other. A repository on GitHub is a project folder that keeps every version of its files, and a change there can set an assistant working once you have set up a task to watch for it. On ChatGPT Plus or Pro, you can &lt;a href=&quot;https://help.openai.com/en/articles/10291617&quot;&gt;create a task&lt;/a&gt; in &lt;strong&gt;Work&lt;/strong&gt; that starts by itself when someone opens a pull request, GitHub’s name for a proposed change. OpenAI names only Gmail, Slack and GitHub as triggers for these tasks, so a Google Doc isn’t one of them. On a paid Copilot plan, you can &lt;a href=&quot;https://docs.github.com/en/copilot/how-tos/use-copilot-agents/cloud-agent/use-cloud-agent-on-github&quot;&gt;hand a task to Copilot&lt;/a&gt;, GitHub’s own assistant, or (in preview) to Claude or OpenAI’s Codex, and get a proposed change back to review.&lt;/p&gt;
&lt;p&gt;To move, you need a &lt;a href=&quot;https://github.com/signup&quot;&gt;free GitHub account&lt;/a&gt;. Signed in, open &lt;a href=&quot;https://github.com/new&quot;&gt;github.com/new&lt;/a&gt;, type a name, choose &lt;strong&gt;Private&lt;/strong&gt;, add a README, and click &lt;strong&gt;Create repository&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Open README.md, click the pencil at the top right of the file to edit it, and replace its text with this, filled in from your doc:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# [Project name]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- Goal: [what this project is for, in one sentence]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- Audience: [who the work is for]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- Current priority: [the next specific task]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;## Rules for any AI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- Read README.md and DECISIONS.md before you start,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  and tell me which files you read.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- If you cannot open a file, say so. Do not guess.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- Link a source for every fact. Say when you are unsure.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- Never publish, send or spend anything without asking me.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Click &lt;strong&gt;Commit changes…&lt;/strong&gt;, then &lt;strong&gt;Commit changes&lt;/strong&gt; in the box that opens, leaving it on the main branch. Click the repository’s name at the top to go back to its main page, then click &lt;strong&gt;Add file&lt;/strong&gt;, then &lt;strong&gt;Create new file&lt;/strong&gt;, and name it DECISIONS.md. Paste this, replace the example line with your decisions from the doc, newest first, each starting with a dash, and save it the same way:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;# Decisions (newest at the top; a newer line wins)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;- [date]: [what you decided]. Why: [why]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The doc and the repository won’t update each other, so edit only the repository from then on. For ChatGPT, add &lt;strong&gt;GitHub&lt;/strong&gt; from &lt;strong&gt;Plugins&lt;/strong&gt;, as in step 1, and give it access to this repository (&lt;a href=&quot;https://help.openai.com/en/articles/11145903-connecting-github-to-chatgpt&quot;&gt;OpenAI’s steps&lt;/a&gt;); a new repository can take about five minutes to appear there. For Claude, add the repository to a chat or a project (&lt;a href=&quot;https://claude.com/docs/connectors/github&quot;&gt;Anthropic’s steps&lt;/a&gt;); in a project, select &lt;strong&gt;Sync now&lt;/strong&gt; after you change a file.&lt;/p&gt;
&lt;p&gt;Neither connection can write, so you or a coding assistant make the changes. A connection only gives access, so open each chat by asking for README.md and DECISIONS.md. To run the test here, put the codeword line, starting with a dash, at the top of the list in DECISIONS.md and ask a brand-new chat to quote the first decision in DECISIONS.md exactly, then delete the line. We run our own team of assistants this way, and each one needed its own trigger, because the repository tells nobody when new work arrives.&lt;/p&gt;
&lt;h2 id=&quot;two-rules&quot;&gt;Two rules&lt;/h2&gt;
&lt;p&gt;Keep passwords and private details out. Deleted text can usually be brought back from the doc’s version history, so if a password gets in, change it.&lt;/p&gt;
&lt;p&gt;Treat text other people add as a stranger’s instructions. If you share the doc, anyone who can edit it can write something your AI will read and may follow. &lt;a href=&quot;https://invariantlabs.ai/blog/mcp-github-vulnerability&quot;&gt;Invariant Labs&lt;/a&gt; showed this in a May 2025 demonstration: a message they planted in a GitHub issue steered an AI agent into leaking private data.&lt;/p&gt;</content:encoded></item><item><title>Use AI to Learn Without Getting Worse at It</title><link>https://durabilitycurve.com/blog/learn-with-ai-without-getting-worse/</link><guid isPermaLink="true">https://durabilitycurve.com/blog/learn-with-ai-without-getting-worse/</guid><description>Answer-giving AI left learners worse off once it was gone. Three setups built to keep the thinking with you, and a way to check what stuck.</description><pubDate>Thu, 24 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p class=&quot;lede-dek&quot;&gt;&lt;em&gt;Answer-giving AI left learners worse off once it was gone. Three setups built to keep the thinking with you, and a way to check what stuck.&lt;/em&gt;&lt;/p&gt;
&lt;hr class=&quot;lede-rule&quot;&gt;
&lt;p&gt;If you have used ChatGPT this month to get through something you are learning (a spreadsheet formula, a new codebase, the rules of a new job), it probably felt like progress. The answer was always one message away.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.pnas.org/doi/10.1073/pnas.2422633122&quot;&gt;A team of researchers tested it&lt;/a&gt;. Nearly 1,000 Turkish high-school students practised maths, some of them with a ChatGPT-style assistant beside them. That group’s practice scores rose 48%. Then the assistant was taken away for the exam, and they scored 17% lower than students who had never had it. The analysis the authors registered in advance puts the drop about a third smaller, but it is still a drop. In the chat logs, students had often asked for the answer and copied it.&lt;/p&gt;
&lt;p data-cover-after=&quot;&quot;&gt;Easier practice is not evidence that you learned the thing. The effort you skip is often &lt;a href=&quot;https://durabilitycurve.com/blog/difficulty-was-making-you/&quot;&gt;the part that was teaching you&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When you only need the answer, take it. This is about &lt;a href=&quot;https://durabilitycurve.com/blog/the-things-you-used-to-know-by-heart/&quot;&gt;the times you need the skill&lt;/a&gt;, because you will have to do it again with nobody to ask.&lt;/p&gt;
&lt;h2 id=&quot;experienced-programmers-too&quot;&gt;Experienced programmers too&lt;/h2&gt;
&lt;p&gt;The Turkish students were teenagers. In January, Anthropic &lt;a href=&quot;https://arxiv.org/abs/2601.20245&quot;&gt;published a trial&lt;/a&gt; with 52 Python programmers, recruited through a crowd-work platform, learning a Python library that was new to them. More than half had seven or more years of coding experience. Half of them worked with an AI assistant; afterwards everyone took a quiz with no AI allowed.&lt;/p&gt;
&lt;p&gt;The AI group scored 4.15 points lower on the 27-point quiz, roughly 15 percentage points, and they were not significantly faster. They learned less and got little or no time back.&lt;/p&gt;
&lt;h2 id=&quot;who-did-the-thinking&quot;&gt;Who did the thinking&lt;/h2&gt;
&lt;p&gt;Some of those programmers scored well anyway, and they had used the assistant differently. Those who handed it the work, leaned on it more as the task went on, or had it debug for them averaged 24% to 39% on the quiz. Those who asked it conceptual questions averaged 65%, about the same as the group with no AI. The best result, 86%, came from two people who let it write the code and then questioned it until they understood what it had written. The groups were small and sorted after the fact, so treat them as a clue.&lt;/p&gt;
&lt;p&gt;A separate team found the same split. In &lt;a href=&quot;https://arxiv.org/abs/2409.09047&quot;&gt;pre-registered experiments&lt;/a&gt; with German university students learning to code, the researchers found no effect of a chatbot on learning overall. Inside that average, students who used it to generate solutions covered more topics but understood less, and students who used it to ask for explanations understood more. That split was exploratory. In the same study, 42% of requests for a solution came before the student had tried at all.&lt;/p&gt;
&lt;p&gt;Only the Turkish trial tested the design directly. Its second AI group had an assistant told to give hints, with the correct solutions loaded. Their practice scores rose 127% and the exam damage disappeared, though they did no better than students with no AI. Two other trials show well-designed tutors teaching well without isolating who did the thinking. &lt;a href=&quot;https://www.nature.com/articles/s41598-025-97652-6&quot;&gt;At Harvard&lt;/a&gt;, 194 physics students each learned one lesson from a tutor told to encourage a first try and release the solution one step at a time, and another in an active-learning class; median gains with the tutor were more than double the class’s, though it answered whenever a student demanded it. In Nigeria, &lt;a href=&quot;https://documents1.worldbank.org/curated/en/099548105192529324/pdf/IDU-c09f40d8-9ff8-42dc-b315-591157499be7.pdf&quot;&gt;teacher-guided sessions with a chatbot&lt;/a&gt; raised English scores 0.238 standard deviations against students who got no programme at all.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Who did the work, and what happened&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;3200&quot; height=&quot;4120&quot; src=&quot;https://durabilitycurve.com/_astro/fig1-evidence.D8IuC4NX_Z1BgSSt.webp&quot; &gt;&lt;/p&gt;
&lt;p&gt;Not every result fits. &lt;a href=&quot;https://storage.googleapis.com/deepmind-media/LearnLM/learnLM_sierraleone_may26.pdf&quot;&gt;Google’s trial&lt;/a&gt; of Gemini’s Guided Learning raised maths scores overall, but its younger year group did slightly worse. The German study found no overall effect either way.&lt;/p&gt;
&lt;p&gt;The consistent part is narrow and useful. In two randomised trials, an AI assistant used freely during practice left people worse off once it was gone. In both studies that looked at how people used it, those who asked for explanations did better than those who asked for answers. So keep the thinking on your side of the chat: try before you ask, and ask it to explain. Three ways to set that up follow.&lt;/p&gt;
&lt;h2 id=&quot;level-1-switch-on-the-learning-mode-you-already-have&quot;&gt;Level 1: switch on the learning mode you already have&lt;/h2&gt;
&lt;p&gt;As of September 2026, according to each company’s help pages and apps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ChatGPT:&lt;/strong&gt; type &lt;code&gt;@study&lt;/code&gt;, or press &lt;code&gt;+&lt;/code&gt; and choose &lt;code&gt;Study&lt;/code&gt;. It is on every plan, though it does not work inside Projects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gemini:&lt;/strong&gt; &lt;code&gt;Add files&lt;/code&gt;, then &lt;code&gt;More tools&lt;/code&gt;, then &lt;code&gt;Guided Learning&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude:&lt;/strong&gt; first switch on &lt;code&gt;Code execution and file creation&lt;/code&gt; under &lt;code&gt;Settings&lt;/code&gt;, then &lt;code&gt;Capabilities&lt;/code&gt;. Then add Anthropic’s &lt;code&gt;learn&lt;/code&gt; skill from &lt;code&gt;Customize&lt;/code&gt;, then &lt;code&gt;Skills&lt;/code&gt;, then &lt;code&gt;Discover&lt;/code&gt;. It stays out of coding tasks by design; for code, see Level 2.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot:&lt;/strong&gt; open &lt;code&gt;Quick response&lt;/code&gt; under the prompt and choose &lt;code&gt;Study and learn&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Code:&lt;/strong&gt; type &lt;code&gt;/output-style learning&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Then one habit: before you send a question, write your own answer, even a bad one.&lt;/p&gt;
&lt;p&gt;Treat the modes as a start. OpenAI’s &lt;a href=&quot;https://help.openai.com/en/articles/11780217-using-study-mode-in-chatgpt&quot;&gt;own help page&lt;/a&gt; says Study mode may still give a direct answer, and the companies’ own trials are early. In OpenAI’s &lt;a href=&quot;https://openai.com/index/understanding-ai-and-learning-outcomes/&quot;&gt;one-session study&lt;/a&gt;, students using Study mode scored roughly 15% higher than with ordinary online resources in microeconomics, and no differently in neuroscience.&lt;/p&gt;
&lt;h2 id=&quot;level-2-paste-a-tutor-prompt&quot;&gt;Level 2: paste a tutor prompt&lt;/h2&gt;
&lt;p&gt;The modes are not everywhere, and they slip. A prompt goes anywhere. Paste this at the start of any chat where you are learning, and fill in the last two lines:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Be my tutor for this. I&apos;m trying to learn it, not just get it done, so help me work it out myself.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1. Don&apos;t give me the answer or write the solution for me. Give me one hint or one step at a time, then wait for my reply.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2. If I ask you to just tell me, ask me to try first. Count every wrong answer or guess as a try. After my second wrong try, give me the answer and explain the step I missed.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3. When I get something right, confirm it and ask me why it works.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;4. Keep every reply to a few sentences.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5. When we finish, give me a similar problem to try on my own.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;6. If you&apos;re not sure something is correct, say so.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;What I already know: [e.g. basic percentages, nothing about probability]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;The problem: [paste it here]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It borrows Harvard’s try-first, one-step shape and the Nigeria exercises’ hint-then-answer rule, and it is stricter than Harvard’s tutor, which answered on demand.&lt;/p&gt;
&lt;p&gt;I ran it eight times with a scripted learner: seven across Claude, Gemini and GPT, one in the ChatGPT app. Each time the learner demanded the answer, the tutor asked for an attempt, and after the second wrong try it gave the answer and named the missed step. Once, asked for fixed code, GPT held back the code but described the fix in words, which gave most of it away.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;ChatGPT holding the answer back after &amp;quot;just tell me&amp;quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;920&quot; height=&quot;520&quot; src=&quot;https://durabilitycurve.com/_astro/fig2-hold.BEMYf2DC_ZGGmsv.webp&quot; &gt;&lt;/p&gt;
&lt;p&gt;On a long problem some models count tries per step, so the answer arrives a step at a time; that is fine. If a hint gives the answer away, reply “smaller hint”.&lt;/p&gt;
&lt;p&gt;This is the same move as &lt;a href=&quot;https://durabilitycurve.com/blog/ask-for-the-step-before-the-answer/&quot;&gt;asking for the step before the answer&lt;/a&gt;, kept on for a whole session.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you are learning code,&lt;/strong&gt; use &lt;code&gt;/output-style learning&lt;/code&gt; in Claude Code, or paste the prompt with the function or error as “the problem”. When it does write code, do what Anthropic’s top-scoring pair did: ask why each part is there until you could write it yourself. Then, my suggestion: close the chat and write it.&lt;/p&gt;
&lt;h2 id=&quot;level-3-give-it-your-material-then-test-yourself-cold&quot;&gt;Level 3: give it your material, then test yourself cold&lt;/h2&gt;
&lt;p&gt;Levels 1 and 2 set up the tool. This level adds your own material, and it measures you.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create a project for the thing you are learning.&lt;/strong&gt; In ChatGPT, &lt;code&gt;New project&lt;/code&gt; in the sidebar. In Claude, &lt;code&gt;Projects&lt;/code&gt;, then &lt;code&gt;New Project&lt;/code&gt; (the free plan allows five). In Gemini, a Gem with your files added.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Paste these instructions&lt;/strong&gt; into the project’s instructions:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;You are my tutor for the material in this project. I&apos;m here to learn it, not to look things up, so make me work for every answer.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1. Before you answer anything about the material, check the files in this project. Use them as the source of truth. If they don&apos;t cover it, say so before you answer from general knowledge.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2. Whenever I ask a question about the material, don&apos;t answer it yet, even if I say &quot;just tell me&quot;. First ask me what I think, or give me one hint.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3. Count every wrong answer or guess as a try. After my second wrong try, give me the answer from the files and explain the step I missed.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;4. When I get something right, confirm it and ask me why it works.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;5. Keep every reply to a few sentences.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;6. If you&apos;re not sure something is correct, say so.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;Upload your material:&lt;/strong&gt; course notes, documentation, your team’s handbook if you are allowed to put it into that service, and an answer key if you have one. The Harvard team loaded every question with its worked answer; without your material, a tutor falls back on what it already knows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test the setup before you trust it.&lt;/strong&gt; Ask a question about the material and add “just tell me”. If it answers straight away, the setup is not holding. My first version failed exactly this test in the ChatGPT app, answering at once from general knowledge. The version above passed with a hint drawn from the file.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learn in chats inside the project.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A few days later, run the cold check.&lt;/strong&gt; Open a new chat in the project, paste this, and fill in the topics you studied:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Cold check. Quiz me on what I&apos;ve been learning from the files in this project.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Only ask about these topics: [list what you studied]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Ask 6 questions, one at a time. Mix &quot;what is&quot; questions with &quot;what would you do if&quot; questions.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Don&apos;t give hints and don&apos;t tell me whether I&apos;m right until all 6 are done.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Then score me out of 6, show the correct answer from the files for each one I missed, and list what I should review.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Answer from memory, with no notes. In the ChatGPT app, with a planted mix of right and wrong answers, every question stayed on topic, it gave no feedback until the sixth, and it scored 3 out of 6, marking exactly my wrong answers and correcting each from the file. I did not test the Claude or Gemini apps themselves, so run it once with answers you know are right and wrong before relying on the score.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;A cold-check scorecard from my ChatGPT test run&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;3200&quot; height=&quot;2376&quot; src=&quot;https://durabilitycurve.com/_astro/fig3-scorecard.BeCzq2cg_jWN8w.webp&quot; &gt;&lt;/p&gt;
&lt;p&gt;The German study found students felt they had learned more than they had. A score checked against your files is a better guide than that feeling, though I tested the marking only on short factual questions, so check each marked miss against the source. Put the check in your calendar and paste the prompt yourself. Whatever you missed goes back into a tutoring chat.&lt;/p&gt;
&lt;h2 id=&quot;what-the-research-can-and-cannot-tell-you&quot;&gt;What the research can and cannot tell you&lt;/h2&gt;
&lt;p&gt;None of the seven studies tested people again weeks or months later, so none shows the learning lasted. Only two went through journal peer review. The evidence on how people used the AI comes from patterns inside two studies, not from assigning them. Three trials were run by AI companies, and in Nigeria the comparison group got no programme at all.&lt;/p&gt;
&lt;p&gt;Your own cold check a few days later is the only follow-up test in this piece.&lt;/p&gt;
&lt;h2 id=&quot;the-checklist&quot;&gt;The checklist&lt;/h2&gt;
&lt;p&gt;Next time you open an AI to learn something:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Decide whether you need the answer or the skill. For the skill, keep the thinking on your side.&lt;/li&gt;
&lt;li&gt;Switch on your app’s learning mode, or paste the tutor prompt.&lt;/li&gt;
&lt;li&gt;Write your own answer before you ask, then ask it to explain.&lt;/li&gt;
&lt;li&gt;If a hint gives it away, ask for a smaller one.&lt;/li&gt;
&lt;li&gt;For anything you need to know properly, put your material in a project and test the setup with “just tell me”.&lt;/li&gt;
&lt;li&gt;A few days later, run the cold check on the topics you studied, with no notes, and send what you missed back into a tutoring chat.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;The Nigeria exercises drew in part on &lt;a href=&quot;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4475995&quot;&gt;tutor prompts&lt;/a&gt; published by Ethan and Lilach Mollick in 2023.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title>The Skill That Never Fired</title><link>https://durabilitycurve.com/blog/skill-that-never-fired/</link><guid isPermaLink="true">https://durabilitycurve.com/blog/skill-that-never-fired/</guid><description>A Claude skill can fail two ways: its instructions are wrong, or Claude never picks it. Anthropic&apos;s own tooling scores whether one skill fires. This tests it against the neighbour that can quietly win its requests, with a small routing eval you run yourself.</description><pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A skill can fail in two ways. Its instructions can be wrong, so it does the job badly. Or Claude can decide never to load it, so the instructions never run at all. The first failure is obvious when you test the skill by name. The second only shows up when you test whether Claude chooses it on its own.&lt;/p&gt;
&lt;p&gt;The second failure is the quiet one. You write a skill, you invoke it by name to check it, and it works. Then in normal use it just sits there. Claude answers without it. Nothing errors, nothing warns you, and the skill still shows as installed. It was never wrong. It was never chosen.&lt;/p&gt;
&lt;p data-cover-after=&quot;&quot;&gt;That choice is a routing decision, and Claude makes it by matching the request against your skill’s name and description, before it reads a word of the body. The Claude Code docs say it directly: the description is what helps Claude decide when to load a skill. Anthropic tells you to test that decision, separate from the skill’s output, and ships a tool that does it. Its &lt;code&gt;skill-creator&lt;/code&gt; scores one target skill over repeated runs: does this skill fire on the prompts it should, and stay quiet on the ones it should not?&lt;/p&gt;
&lt;p&gt;What that score does not tell you is what happened when another plausible skill was there too: whether the neighbour took the request, both fired, or neither did. That is the failure this piece is interested in, where your skill sits beside one that could answer it and the winner is not guaranteed to be yours. This walks through building a skill, watching that decision for yourself, and grading it against the neighbour it can lose to. You can run a first pass in about 15 minutes at a terminal.&lt;/p&gt;
&lt;h2 id=&quot;what-a-skill-is&quot;&gt;What a skill is&lt;/h2&gt;
&lt;p&gt;At its simplest, &lt;a href=&quot;https://durabilitycurve.com/blog/skills-are-package-management-for-your-ai/&quot;&gt;a skill&lt;/a&gt; is a folder with one required file, &lt;code&gt;SKILL.md&lt;/code&gt;. It can also hold scripts and reference files that load only when needed, but the minimum is the one file:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;name: customer-date&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;description: Format a date for customer-facing UK correspondence (emails, letters, messages to customers) as D Month YYYY. For CSV or data exports, use export-date.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Rewrite the date the user gives in UK long form, for example 30 August 2026. Reply with only the formatted date.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a normal auto-invocable skill, the name and description sit in Claude’s discovery context so it can decide whether the skill is relevant. The body below the frontmatter loads only when the skill is invoked, whether Claude chooses it or you type its name. Claude sees both the name and the description, and the description is the main field Anthropic gives you for saying when the skill should run. Write it for the router, not as a note to yourself. Claude Code also accepts a &lt;code&gt;when_to_use&lt;/code&gt; field, appended to the description; these skills use only a name and a description.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;A request meets two installed skills. For each, only the name and description sit in Claude&amp;#39;s discovery context, and they are loaded for both. Claude matches the request against that metadata and picks customer-date; only then does customer-date&amp;#39;s body load. export-date&amp;#39;s body never loads. The route is chosen from the name and description, before the body is read at all.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;1560&quot; height=&quot;860&quot; src=&quot;https://durabilitycurve.com/_astro/fig-routing-surface.C9iBb117_2kkjM1.webp&quot; &gt;&lt;/p&gt;
&lt;p&gt;Three common ways to use a skill. In claude.ai, turn on code execution, open Customize then Skills, and upload the folder as a zip. In Claude Code, put the folder in &lt;code&gt;.claude/skills/&lt;/code&gt; for one project or &lt;code&gt;~/.claude/skills/&lt;/code&gt; for all of them. Through the Claude API, you upload it and reference its &lt;code&gt;skill_id&lt;/code&gt;. The core &lt;code&gt;SKILL.md&lt;/code&gt; format travels across all three, though installation differs and some frontmatter, including the &lt;code&gt;disable-model-invocation&lt;/code&gt; used later, is specific to Claude Code.&lt;/p&gt;
&lt;h2 id=&quot;watching-the-routing-decision&quot;&gt;Watching the routing decision&lt;/h2&gt;
&lt;p&gt;The mistake to avoid is judging a skill by its output. Ask Claude to format a date and you might get &lt;code&gt;30 August 2026&lt;/code&gt; whether your skill ran or not, because the model can format a date on its own. The output tells you nothing about routing.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;The same request produces the same output, 30 August 2026, two ways: when the customer-date skill fires, which leaves a Skill tool call in the stream, and when no skill fires and the model formats the date itself, which leaves no call. The output is identical, so it cannot tell you which happened; only the tool call can.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;1560&quot; height=&quot;820&quot; src=&quot;https://durabilitycurve.com/_astro/fig-same-output.CRI7JPni_Z2v8aIj.webp&quot; &gt;&lt;/p&gt;
&lt;p&gt;You want the decision itself. In Claude Code, a skill runs through a &lt;code&gt;Skill&lt;/code&gt; tool that appears in the event stream. Run a prompt non-interactively and filter the stream down to the skill call:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; claude&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -p&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Rewrite this date for the customer email: 2026-08-30&quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    --output-format&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; stream-json&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --verbose&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; jq&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -c&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;select(.type==&quot;assistant&quot;) | .message.content[]?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;           | select(.type==&quot;tool_use&quot; and .name==&quot;Skill&quot;) | .input&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;&quot;skill&quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;&quot;customer-date&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;&quot;args&quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;&quot;2026-08-30&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That last line is the filtered result, not the raw stream, which wraps each event in more metadata. If the reader prints nothing, dump a raw event and look for a &lt;code&gt;Skill&lt;/code&gt; call by hand, because the stream’s shape shifts between versions. It is the routing decision read from the tool call, not guessed from the output. &lt;code&gt;/skills&lt;/code&gt; shows which skills are available to Claude and &lt;code&gt;/context&lt;/code&gt; shows the discovery listing’s context cost, but neither proves this prompt invoked one. In claude.ai there is no equivalent machine-readable event. Anthropic’s guidance is to review Claude’s thinking to confirm a skill loaded, which works for checking by eye but not for building the kind of record above. And the event stream shows the skills Claude actually invoked, both of them when it invokes two, which is how a &lt;code&gt;both&lt;/code&gt; shows up at all. What it does not expose is the candidate set: the other installed skills that were plausible but never invoked. You see what fired, not what it beat.&lt;/p&gt;
&lt;h2 id=&quot;routing-is-a-decision-you-can-grade&quot;&gt;Routing is a decision you can grade&lt;/h2&gt;
&lt;p&gt;Whether a skill fires is a choice among whatever skills could plausibly answer the request. You can only grade that choice if you know what the right answer was before you run it.&lt;/p&gt;
&lt;p&gt;So I built two skills with different jobs. &lt;code&gt;customer-date&lt;/code&gt;, above, formats dates for customer emails in long form. &lt;code&gt;export-date&lt;/code&gt; formats them for CSV exports as &lt;code&gt;DD/MM/YYYY&lt;/code&gt;. Then I wrote a labelled prompt set: 4 requests that clearly want the customer skill, 4 that clearly want the export skill, and 4 date-adjacent requests that should fire neither. Every result gets one of four labels: right, wrong, none, or both.&lt;/p&gt;
&lt;p&gt;Start with the failures, because they are where the method earns its keep.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ambiguous request.&lt;/strong&gt; Ask “Format this date: 2026-08-30” with both skills installed, and the results scatter: sometimes one fires, sometimes both, sometimes neither. That scatter is the expected result of an ambiguous request. The request never said whether it wanted the customer or the export format, so there is no correct answer to grade against. An ambiguous prompt is not a failed test, it is an ungradable one. If you cannot label the right skill before running it, the result cannot tell you whether Claude chose well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Names and descriptions that draw no line.&lt;/strong&gt; I named two skills for their output format, &lt;code&gt;long-date&lt;/code&gt; and &lt;code&gt;slash-date&lt;/code&gt;, and gave them the same vague description, “Format a date.” Their bodies did different things, but their discovery metadata claimed the same job, so there was no boundary for the router to use and nothing told Claude which one fits a customer request. The grades went bad in the way that matters: one customer prompt fired nothing at all, and 2 export prompts fired both skills at once. Misses and double-fires, which is why “both” has to be one of your outcome labels.&lt;/p&gt;
&lt;p&gt;Then the control, so you can see what clean looks like. Give the two skills distinct, use-case descriptions, and ask prompts whose wording matches those use cases, and routing is clean: 8 out of 8 to the right skill, and the neither-prompts correctly firing nothing. That is the model doing the keyword and intent matching you made easy for it. It is the case that should work, and it does. Note that the customer prompts contain words like “customer email” that are already in the customer skill’s description. Clean routing here is a control condition, &lt;a href=&quot;https://durabilitycurve.com/blog/the-evaluation-inversion/&quot;&gt;not proof that routing is robust&lt;/a&gt;. The evidence is in the failures above.&lt;/p&gt;
&lt;h2 id=&quot;the-fix&quot;&gt;The fix&lt;/h2&gt;
&lt;p&gt;Routing runs on the discovery metadata Claude can see, which is the name and the description together, and my runs show either one can carry it. When the names were the vague part but the descriptions were sharp, routing was clean. When the descriptions were the vague part but the names said the use case, &lt;code&gt;customer-date&lt;/code&gt; and &lt;code&gt;export-date&lt;/code&gt;, routing was also clean, 8 out of 8 on the same prompts. That name-only run is an easy case, mind: the prompts carry the same words as the names, customer and export, so it shows a name helps when the request echoes it, not that a bare name is a strong signal on its own. It broke in one condition only: format-only names, &lt;code&gt;long-date&lt;/code&gt; and &lt;code&gt;slash-date&lt;/code&gt;, plus a shared vague description, where neither field told Claude what set the two skills apart.&lt;/p&gt;
&lt;p&gt;That broken condition is the useful one. I left the weak names alone and rewrote only the descriptions around use cases, and the mess went to 8 out of 8. A good description rescued names that carried no signal. A good name had already done the same for descriptions that carried none. What you cannot do is leave both vague and expect Claude to find the line.&lt;/p&gt;
&lt;p&gt;So write the description as a routing rule, not a summary. Put the use first. Include the words people actually type when they want this skill. Draw the boundary against the neighbour it might be confused with.&lt;/p&gt;
&lt;p&gt;Some skills should not be auto-routed at all. Anything with a side effect or a real cost is safer as a skill you invoke by name, &lt;code&gt;/customer-date&lt;/code&gt;, or one you lock with &lt;code&gt;disable-model-invocation: true&lt;/code&gt; so only a person can trigger it. For those, manual invocation is the design, not a workaround. The rule underneath: how much routing error you can accept depends on what a wrong route costs. When the cost is high, the fix is often to stop routing automatically rather than to tune the description harder.&lt;/p&gt;
&lt;h2 id=&quot;the-failure-that-has-nothing-to-do-with-your-skill&quot;&gt;The failure that has nothing to do with your skill&lt;/h2&gt;
&lt;p&gt;There is one more way a skill stops firing, and no description work touches it. For skills still exposed to the model, Claude Code keeps every skill’s name in the discovery listing, but the listing has a budget, around 1% of the model’s context window, and once it runs over, Claude Code starts dropping descriptions, beginning with the skills you invoke least. That can strip out exactly the words that told two skills apart. So a skill whose description used to distinguish it cleanly can start missing once your catalogue grows large enough, with nobody editing it. &lt;code&gt;/doctor&lt;/code&gt; reports the listing’s cost. If a skill that used to route well starts slipping, check the size of your catalogue before you rewrite the skill: prune the skills you do not use, shorten the descriptions that survive so the distinguishing words fit, set low-priority skills to &lt;code&gt;name-only&lt;/code&gt; so Claude keeps their names without their descriptions, or set rarely-used skills to &lt;code&gt;disable-model-invocation: true&lt;/code&gt;, which takes them out of the router and its listing entirely; you still invoke those with &lt;code&gt;/name&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Worth knowing before it bites a team: skills with the same name at different levels do not merge, one shadows the other. The order is enterprise, then personal, then project, so a &lt;code&gt;/deploy&lt;/code&gt; skill in your &lt;code&gt;~/.claude/skills/&lt;/code&gt; silently overrides the one your repo ships in &lt;code&gt;.claude/skills/&lt;/code&gt;. If you commit skills for a team, give them names that will not collide, and do not rely on the project copy winning. This is also where overlap arrives for people who did not build it: a marketplace pack or an inherited folder drops in a skill whose description competes with one of yours, and the first you hear of it can be a skill that used to fire and now does not.&lt;/p&gt;
&lt;h2 id=&quot;which-layer-failed&quot;&gt;Which layer failed&lt;/h2&gt;
&lt;p&gt;The check separates two layers that a vague “it didn’t work” runs together. Execution failure means Claude loaded the skill and the body did the wrong thing. Selection failure means the right body never got its chance to run at all. Everything else in this piece is a kind of selection failure: a discovery miss, interference from a neighbour, two definitions that overlap, a listing truncated at scale, a same-name skill shadowing yours. Only execution failure is about the instructions. The rest is why a skill can regress with nobody touching it, and why testing the body is only half the job.&lt;/p&gt;
&lt;p&gt;The stakes climb once the skills matter. A date formatter losing to its twin costs you a wrong date format. A &lt;code&gt;code-review&lt;/code&gt; skill that loses requests to a generic “help me with this file” skill costs you the review you thought ran on every change. Whether that happens turns on the same thing as the date skills: whether the two descriptions draw a line the router can use. The installed list will not tell you, so check it directly. Ask “look at this diff” with both installed and the route can go four ways: cleanly to the review skill, to a &lt;code&gt;both&lt;/code&gt;, to the generic skill alone, or to neither. Give it requests whose correct skill you know, install it next to the neighbour you suspect, and read which one the &lt;code&gt;Skill&lt;/code&gt; tool actually calls.&lt;/p&gt;
&lt;h2 id=&quot;run-it-yourself&quot;&gt;Run it yourself&lt;/h2&gt;
&lt;p&gt;The official &lt;code&gt;skill-creator&lt;/code&gt; plugin measures a target skill’s trigger rate for you. The manual version here adds the identity of the competing skill, so you can tell a miss from interference, a neighbour firing instead of the target or alongside it, reproduce a collision between two specific neighbours, and read the &lt;code&gt;Skill&lt;/code&gt; call yourself. There is a second reason to read the calls rather than trust a score: as of the &lt;a href=&quot;https://github.com/anthropics/skills/blob/main/skills/skill-creator/scripts/run_eval.py&quot;&gt;current evaluator&lt;/a&gt; (August 2026), it reads the first tool call in a run and counts the target as not fired if anything else, a neighbour skill included, gets there first, so the interference this piece is about can quietly lower the very rate meant to catch it. Here is the whole pack. Two skills, twelve prompts, four outcome labels, and the one-line reader from earlier. It is also a download, at &lt;a href=&quot;https://durabilitycurve.com/tools/skill-routing-eval/&quot;&gt;durabilitycurve.com/tools/skill-routing-eval&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The skills, with descriptions that draw the boundary:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;name: customer-date&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;description: Format a date for customer-facing UK correspondence (emails, letters, messages to customers) as D Month YYYY. For CSV or data exports, use export-date.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Rewrite the date the user gives in UK long form, for example 30 August 2026. Reply with only the formatted date.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;name: export-date&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;description: Format a date for CSV or database exports (spreadsheets, data files) as DD/MM/YYYY. For customer emails and letters, use customer-date.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Rewrite the date the user gives in slashed form, for example 30/08/2026. Reply with only the formatted date.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The prompts, each with its known-correct skill:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;should fire customer-date:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Rewrite this date for the customer email: 2026-08-30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Put this date in a letter to the client: 2026-08-30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Format the date for a message to a customer: 2026-08-30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Tidy the date in this customer-facing note: 2026-08-30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;should fire export-date:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Format this date for the CSV export: 2026-08-30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Put this date into the spreadsheet export: 2026-08-30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Format the date for the database file: 2026-08-30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Prepare this date for a data export: 2026-08-30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;should fire neither (date-adjacent work these formatters should refuse):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  What is today&apos;s date?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  When did the Second World War end?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Parse this log timestamp: 2026-08-30T14:22Z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  What day of the week is 2026-08-30?&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install both skills, run each prompt through the &lt;code&gt;jq&lt;/code&gt; reader above, and mark the result right, wrong, none, or both. Those labels roll up into three numbers worth watching. Recall: of the requests that should fire a skill, how many did. False triggers: of the requests that should not, how many fired it anyway. Interference: with a neighbour installed, how often that neighbour fires on a request meant for this skill, either instead of it or alongside it. Recall and false triggers are what the standard trigger-rate test measures for one skill, from its positive and negative cases. Interference is the number it cannot give you, because it only records whether the target fired, not which competing skill fired instead or alongside it. Score a &lt;code&gt;both&lt;/code&gt; as a hit on recall and on interference at once: the intended skill ran, but so did a skill that should have stayed quiet. A skill that scores well alone and badly in company has a selection problem, and editing the body will not touch it.&lt;/p&gt;
&lt;p&gt;What I measured on Claude Opus 5, arranged by what actually distinguished the two skills:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;A two-by-two of the routing eval, arranged by what set the two skills apart. Rows: the name draws the line, or the name is format-only. Columns: the description draws the line, or the description is vague. Three of the four corners route eight of eight prompts to the right skill: name and description both sharp, the name alone with vague descriptions, and the description alone with format-only names. Only the fourth corner, where neither the name nor the description draws a line, breaks: one prompt fires nothing and two fire both skills at once.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;3120&quot; height=&quot;1760&quot; src=&quot;https://durabilitycurve.com/_astro/fig01-routing-2x2.hFK9fC41_TYnBR.webp&quot; &gt;&lt;/p&gt;
&lt;p&gt;In this run, either signal alone held the line; only the condition where neither field distinguished the jobs produced misses and double-fires.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Results table, one run on Claude Opus 5. With name and description both distinct: customer prompts 4 of 4 right, export 4 of 4 right. Name only: 4 of 4 and 4 of 4. Description only: 4 of 4 and 4 of 4. Neither field distinct: customer 3 right and 1 none, export 2 right and 2 both.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;1960&quot; height=&quot;904&quot; src=&quot;https://durabilitycurve.com/_astro/fig02-results-table.Ai28oFaw_aj1sE.webp&quot; &gt;&lt;/p&gt;
&lt;p&gt;On the date-adjacent negatives above, run against the distinct-description pair, both skills stayed quiet: 0 false triggers in 4. Those negatives ran against the sharp descriptions only, so this does not show how false triggers rise as a description gets vaguer. Run the same set against the descriptions you plan to ship: a clean positive-routing score will not tell you whether a skill grabs adjacent work it should leave alone. Small numbers, one model, one surface, and single runs. The routing choice is a model decision that can scatter, so a clean 8 out of 8 is one draw, not a settled rate; run each prompt a few times and read how often the right skill wins, not a single mark. This is a diagnostic you run on your own skills, not a benchmark, and the caption matters more than the cells: this is the shape of the thing, not what Opus 5 does in general. Two skills is the floor, not necessarily the hard case. A real catalogue may have several plausible neighbours, so run the eval beside the skills your target actually competes with, not only against a clean pair.&lt;/p&gt;
&lt;h2 id=&quot;the-habit&quot;&gt;The habit&lt;/h2&gt;
&lt;p&gt;A skill has two ways to fail. Its instructions can be wrong, and you probably test that already. Or Claude can never choose it, and that one leaves no mark: the skill sits installed, looking healthy, and quietly does nothing.&lt;/p&gt;
&lt;p&gt;Test whether Claude chooses the skill. The output looking right does not prove the skill ran. The skills you never test that way are the ones you only think are working.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;The pack here, two skills, twelve labelled prompts, and the &lt;code&gt;run.sh&lt;/code&gt; reader, needs only the &lt;code&gt;claude&lt;/code&gt; CLI and &lt;code&gt;jq&lt;/code&gt; and is yours to keep: &lt;a href=&quot;https://durabilitycurve.com/tools/skill-routing-eval/&quot;&gt;durabilitycurve.com/tools/skill-routing-eval&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title>Stop Re-Priming Claude Code by Hand</title><link>https://durabilitycurve.com/blog/stop-re-priming-claude-code-by-hand/</link><guid isPermaLink="true">https://durabilitycurve.com/blog/stop-re-priming-claude-code-by-hand/</guid><description>The context you paste at the start of every session, put into one file you invoke with /prime.</description><pubDate>Mon, 10 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p class=&quot;lede-cover&quot;&gt;&lt;img alt=&quot;A retyped session-start prompt collapses into one command, $ /prime, and a live green check returns.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;1600&quot; height=&quot;900&quot; src=&quot;https://durabilitycurve.com/_astro/hero.D9xuwKyH_1ecQyX.webp&quot; &gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What you will do:&lt;/strong&gt; take the block of context you paste at the start of every Claude Code session and put it in one file, so you type &lt;code&gt;/prime&lt;/code&gt; instead. About fifteen minutes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Who this is for:&lt;/strong&gt; you come back to the same project across many sessions, and you keep re-pasting the same “here is the project, here is where things stand” preamble before real work starts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Who should skip it:&lt;/strong&gt; if you open a fresh project every time, or never re-explain anything, there is nothing here for you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You need:&lt;/strong&gt; Claude Code (a recent 2.1.x release; the mechanics here were checked against the docs on 9 August 2026), a project you return to, and a shell.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Every session starts the same way. You open Claude Code and spend the first few minutes telling it where you are. This is the project. Here is what you changed last time. Here is the thing that is half-finished. Leave the migration alone. You have typed some version of that briefing fifty times, and you are the one keeping it in your head and re-entering it by hand.&lt;/p&gt;
&lt;p data-cover-after=&quot;&quot;&gt;That is a prompt you repeat, and a prompt you repeat should be a command you type. Claude Code lets you save one as a file and invoke it with a slash. The good version does more than paste static text back at you: it runs a couple of commands and reads a couple of files first, so the context arrives already filled with your project’s current state. By the end of this you will have &lt;code&gt;/prime&lt;/code&gt;, and starting a session will be one word.&lt;/p&gt;
&lt;h2 id=&quot;one-file-becomes-one-command&quot;&gt;One file becomes one command&lt;/h2&gt;
&lt;p&gt;The smallest possible version is a single file with one line in it. In your project, create &lt;code&gt;.claude/skills/prime/SKILL.md&lt;/code&gt; (a &lt;code&gt;prime&lt;/code&gt; folder with a &lt;code&gt;SKILL.md&lt;/code&gt; inside it):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;markdown&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Summarise where this project stands and what I should work on next.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save it. In Claude Code, type &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;prime&lt;/code&gt; shows up in the list; run &lt;code&gt;/prime&lt;/code&gt; and the agent does what the file says. The folder name is the command: a &lt;code&gt;prime&lt;/code&gt; folder gives you &lt;code&gt;/prime&lt;/code&gt;. Claude Code watches existing skills folders and picks up a new or edited skill the moment you save it, no restart. The one exception is the very first time: if &lt;code&gt;.claude/skills/&lt;/code&gt; did not exist when you started the session, restart Claude Code once so it begins watching the new folder, and saves are live after that.&lt;/p&gt;
&lt;p&gt;That is already a command, and it already saves you the typing. But it is static. It says the same sentence every session and knows nothing about what actually changed since last time. The next step is where it earns its place.&lt;/p&gt;
&lt;h2 id=&quot;make-it-load-your-real-state&quot;&gt;Make it load your real state&lt;/h2&gt;
&lt;p&gt;Two small pieces of syntax turn the file from a saved sentence into a live briefing.&lt;/p&gt;
&lt;p&gt;A line that starts with &lt;code&gt;!`command`&lt;/code&gt; runs that shell command and drops its output into the file &lt;em&gt;before Claude reads it&lt;/em&gt;. The docs call this dynamic context injection: “the command runs first, and its output gets inserted into the prompt,” so the agent receives the actual data, not the instruction to go and get it.&lt;sup&gt;&lt;a href=&quot;https://durabilitycurve.com/blog/stop-re-priming-claude-code-by-hand/#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; A line with &lt;code&gt;@path/to/file&lt;/code&gt; inlines that file’s contents the same way. Put them together and &lt;code&gt;/prime&lt;/code&gt; can walk in already knowing your latest commits, your uncommitted changes, and whatever notes you keep.&lt;/p&gt;
&lt;p&gt;Open that same file and replace its one line with the fuller version below, which you can adapt to any repository. Swap &lt;code&gt;NOTES.md&lt;/code&gt; for the short file where you keep current project state, not your whole project history:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;markdown&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF;font-weight:bold&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;description: Load where this project stands and print a short situation report&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;argument-hint: &quot;[optional focus area]&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;allowed-tools: Bash(git log *) Bash(git status *)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF;font-weight:bold&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Recent work on this branch:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;`git log --oneline -10`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Branch and uncommitted right now:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;`git status --short --branch`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Current state notes, read in full:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@NOTES.md&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Give me a four-line situation report: what branch I am on, what changed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;recently, what is unfinished, and what to pick up next. If I named a focus&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;area ($ARGUMENTS), orient every line to it.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The point is what the reader on the other end receives. Not “go check git” but the actual log, the actual dirty files, the actual notes, already in front of the model, followed by a request to make sense of them. &lt;code&gt;$ARGUMENTS&lt;/code&gt; is whatever you typed after the command, so &lt;code&gt;/prime the auth refactor&lt;/code&gt; pushes “the auth refactor” into that placeholder and the report orients to it. The two lines at the top of the frontmatter are optional labels: &lt;code&gt;description&lt;/code&gt; is the text that shows beside &lt;code&gt;/prime&lt;/code&gt; in the menu, and &lt;code&gt;argument-hint&lt;/code&gt; is the grey prompt after it.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;The two instruction lines resolve before Claude reads the file: the command line is replaced by its output and the @file by the file&amp;#39;s contents, which is what Claude actually receives.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;  width=&quot;1520&quot; height=&quot;760&quot; src=&quot;https://durabilitycurve.com/_astro/fig01-fill.nb1Gbo27_271mlV.webp&quot; &gt;&lt;/p&gt;
&lt;p&gt;To show it doing real work, here is ours. Our project is a large notes vault whose rulebook says: before you touch anything, read the pipeline status, read the working briefing, read the vault vitals, and check none of it is stale. That was three files and a freshness check we opened by hand at the start of every session. Our &lt;code&gt;/prime&lt;/code&gt; injects all of it and ends with a read. Invoked against our live state, it returned:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1. Pipeline: red. One red alert, a knowledge-review backlog; two yellow,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   the weekly cleanup twelve days overdue and a staging queue filling up.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2. Binding constraint: the output bottleneck. Six pieces ship-pending,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;   all marked critical, the oldest sixty-four days. Ship before building.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3. Last session: perfected and shipped the opening piece of a new series.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;4. Next: take one of the built-and-parked series pieces to publish-ready.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is the whole payoff: the state of the project, the one thing that matters most, and where to start, assembled before I said a word. Those four lines are ours, from our injects; run the git template above and &lt;code&gt;/prime&lt;/code&gt; hands you the same shape filled with your own project, your commits and dirty files and notes in place of our pipeline and briefing.&lt;/p&gt;
&lt;h2 id=&quot;let-it-run-without-asking&quot;&gt;Let it run without asking&lt;/h2&gt;
&lt;p&gt;Unless those commands are already allowed by your own permission settings, Claude Code stops and asks the first time each injected command runs. The &lt;code&gt;allowed-tools&lt;/code&gt; line in the frontmatter above pre-approves them for you, so &lt;code&gt;/prime&lt;/code&gt; runs clean:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;allowed-tools&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Bash(git log *) Bash(git status *)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each entry is a pattern: &lt;code&gt;Bash(git log *)&lt;/code&gt; means “any command starting with &lt;code&gt;git log&lt;/code&gt;, no prompt,” and &lt;code&gt;Bash(git status *)&lt;/code&gt; does the same for &lt;code&gt;git status&lt;/code&gt;. These two pre-approve only the reads &lt;code&gt;/prime&lt;/code&gt; actually needs; anything else stays subject to your normal permission prompts. A blanket &lt;code&gt;Bash(git *)&lt;/code&gt; would pre-approve &lt;code&gt;git push&lt;/code&gt;, &lt;code&gt;git reset&lt;/code&gt;, and every other git command without a prompt too, so keep the grant to the narrow pair. It is scoped to the turn that &lt;code&gt;/prime&lt;/code&gt; runs in and clears when you send your next message, so you are not opening a standing hole in your permissions either.&lt;/p&gt;
&lt;p&gt;One honest wrinkle from ours: our freshness line runs &lt;code&gt;TZ=&apos;Europe/London&apos; date&lt;/code&gt;, and the leading &lt;code&gt;TZ=&lt;/code&gt; assignment does not always match the command prefix cleanly, so the first run still asks once. We approve it and move on. If one of your lines keeps prompting despite an &lt;code&gt;allowed-tools&lt;/code&gt; entry, that mismatch is why; simplify the command or approve it the once.&lt;/p&gt;
&lt;p&gt;One caution that matters more once the file is not yours to begin with: a skill runs shell commands and can pre-approve its own tools, so treat one you pulled from someone else’s repository like a script you are about to run. Read its &lt;code&gt;!`&lt;/code&gt; lines and its &lt;code&gt;allowed-tools&lt;/code&gt; before you invoke it.&lt;/p&gt;
&lt;h2 id=&quot;why-not-just-put-this-in-claudemd&quot;&gt;Why not just put this in CLAUDE.md?&lt;/h2&gt;
&lt;p&gt;If Claude Code already reads a &lt;code&gt;CLAUDE.md&lt;/code&gt; at the start of every session, a fair question is why this is not a few more lines there. The docs draw the line by what changes. &lt;code&gt;CLAUDE.md&lt;/code&gt; is for facts that hold every session: your conventions, your architecture, the guidance you want in front of Claude every time. It loads into every session, which makes it the wrong home for anything that moves underneath it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/prime&lt;/code&gt; is for the things that move. Where the tests live belongs in &lt;code&gt;CLAUDE.md&lt;/code&gt;; what you touched last, what is uncommitted, the one thing on fire this morning, all of that is different by the next session, and you want it recomputed when you ask rather than hand-edited into a file.&lt;/p&gt;
&lt;p&gt;That is the real move here, and it is bigger than one command. The durable thing to save is the procedure that fetches the state. A commit list or a status line goes stale the moment you write it down; a command that runs &lt;code&gt;git&lt;/code&gt; and reads your notes fetches the current answer every time. Keep the procedure narrow, though: whatever &lt;code&gt;/prime&lt;/code&gt; injects stays in the conversation and costs tokens on every later turn, so its job is to locate the work, not to preload your whole project. If it starts turning into a project dump, stop adding files.&lt;/p&gt;
&lt;h2 id=&quot;you-may-see-the-older-one-file-form&quot;&gt;You may see the older one-file form&lt;/h2&gt;
&lt;p&gt;If you read around, you will find the same trick written as a single &lt;code&gt;.claude/commands/prime.md&lt;/code&gt; file with no folder. That is the older shape, and it still works: a &lt;code&gt;.claude/commands/prime.md&lt;/code&gt; and a &lt;code&gt;.claude/skills/prime/SKILL.md&lt;/code&gt; both create &lt;code&gt;/prime&lt;/code&gt; and behave the same way. The skills folder is the form the docs point you to now, and the reason is room to grow. A folder holds more than the one file, so it carries supporting scripts when your &lt;code&gt;/prime&lt;/code&gt; gets ambitious, and a skill can let Claude reach for it on its own when it fits (add &lt;code&gt;disable-model-invocation: true&lt;/code&gt; to keep it strictly manual, &lt;code&gt;/prime&lt;/code&gt; only). If you already have a one-file command, leave it alone, it keeps working. Reach for the folder when the command outgrows a single file, and if you ever keep both under one name, the skill wins.&lt;/p&gt;
&lt;h2 id=&quot;when-it-does-not-fire&quot;&gt;When it does not fire&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It is not in the &lt;code&gt;/&lt;/code&gt; list.&lt;/strong&gt; You are probably not in the project, or the file is not at &lt;code&gt;.claude/skills/prime/SKILL.md&lt;/code&gt; (the folder has to be named &lt;code&gt;prime&lt;/code&gt; and the file &lt;code&gt;SKILL.md&lt;/code&gt;). A skill in &lt;code&gt;~/.claude/skills/&lt;/code&gt; instead works in every project.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It runs, but Claude never reaches for it on its own and the menu shows no hint.&lt;/strong&gt; The frontmatter did not parse. A malformed YAML block does not remove the skill: &lt;code&gt;/prime&lt;/code&gt; still works, but it loads with empty metadata, so the &lt;code&gt;description&lt;/code&gt; no longer matches. Start Claude Code with &lt;code&gt;--debug&lt;/code&gt; to see the parse error, then line up the &lt;code&gt;---&lt;/code&gt; fences.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It prompts for permission every single run.&lt;/strong&gt; Your &lt;code&gt;allowed-tools&lt;/code&gt; pattern does not match the command you inject. Line the prefix up exactly, for example &lt;code&gt;Bash(git log *)&lt;/code&gt; for a &lt;code&gt;git log&lt;/code&gt; line.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;$1&lt;/code&gt; is not what you expected.&lt;/strong&gt; In the skills model, indexed arguments are zero-based: &lt;code&gt;$0&lt;/code&gt; is the first argument, &lt;code&gt;$1&lt;/code&gt; the second. Reach for &lt;code&gt;$ARGUMENTS&lt;/code&gt; when you just want “everything I typed,” and leave positions alone unless you genuinely need them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The output did not appear.&lt;/strong&gt; The injection only fires from a &lt;code&gt;!`…`&lt;/code&gt; backtick span with a leading &lt;code&gt;!&lt;/code&gt;. A command sitting in a plain fenced block is shown to the model as text, not run.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;prove-it-loads&quot;&gt;Prove it loads&lt;/h2&gt;
&lt;p&gt;Do not take my word that the injection fired. Run &lt;code&gt;/prime&lt;/code&gt; and read the top of what comes back. If it references your actual latest commit message and your actual files, the commands ran and the state is real. If it hands you generic advice that would fit any repository, nothing injected: your &lt;code&gt;!`…`&lt;/code&gt; or &lt;code&gt;@&lt;/code&gt; lines are the place to look. A command that prints the same thing regardless of your project is just a saved sentence, which is where we started.&lt;/p&gt;
&lt;p&gt;Once it loads real state, you have turned a paragraph you retyped every session into one word, and the machine does the fetching. That is the pattern for the whole series: a thing you do by hand, moved into a tool you set up once and then just run. This one only read your project. The next rung is about letting Claude Code change it safely: a guardrail that stops the agent before it edits a file you marked off-limits. That is the next Runbook.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Sibling piece, same tool, different job: &lt;a href=&quot;https://durabilitycurve.com/blog/never-let-claude-code-tell-you-its-done/&quot;&gt;Never Let Claude Code Tell You It’s Done&lt;/a&gt; wires a test the agent cannot talk its way past.&lt;/em&gt;&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Claude Code documentation: &lt;a href=&quot;https://code.claude.com/docs/en/slash-commands&quot;&gt;dynamic context injection and slash-command syntax&lt;/a&gt;. &lt;a href=&quot;https://durabilitycurve.com/blog/stop-re-priming-claude-code-by-hand/#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item></channel></rss>