{"id":23477,"date":"2026-08-25T05:13:06","date_gmt":"2026-08-25T05:13:06","guid":{"rendered":"https:\/\/scannn.com\/karl-koch-on-teaching-ai-how-you-work\/"},"modified":"2026-08-25T05:13:06","modified_gmt":"2026-08-25T05:13:06","slug":"karl-koch-on-teaching-ai-how-you-work","status":"publish","type":"post","link":"https:\/\/scannn.com\/lv\/karl-koch-on-teaching-ai-how-you-work\/","title":{"rendered":"Karl Koch | On teaching AI how you work"},"content":{"rendered":"\n<div>\n<p>I\u2019ve been writing down how interfaces should feel, how HTML should carry behaviour and how AI drafts should be judged. Essays are good at teaching people but awkward to paste into every new chat; skills package the same judgement so an agent can discover it, load the relevant slice and apply it without me re-explaining five years of notes.<\/p>\n<h2 id=\"the-collection\">The collection<\/h2>\n<p>I published the set at <a href=\"https:\/\/github.com\/kemiljk\/skills\"><code>kemiljk\/skills<\/code><\/a>: eleven skills, one repository, MIT licensed.<\/p>\n<p>Two of them already existed as standalone repos:<\/p>\n<p>Those remain the public names. The consolidated versions are tighter, with clearer triggers, smaller activated files, examples moved into references and an explicit precedence rule between motion taste and platform-native CSS.<\/p>\n<p>Eight more encode lessons from the writing that kept reappearing whenever I reviewed AI output:<\/p>\n<table>\n<thead>\n<tr>\n<th>Skill<\/th>\n<th>Job<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>semantic-html-first<\/code><\/td>\n<td>Prefer native elements and platform contracts<\/td>\n<\/tr>\n<tr>\n<td><code>interface-affordances<\/code><\/td>\n<td>Make possible actions perceptible across input modes<\/td>\n<\/tr>\n<tr>\n<td><code>write-first-design<\/code><\/td>\n<td>Decide in prose before pixels or code<\/td>\n<\/tr>\n<tr>\n<td><code>design-engineering<\/code><\/td>\n<td>Handshake between design intent and production code<\/td>\n<\/tr>\n<tr>\n<td><code>product-delight<\/code><\/td>\n<td>Anticipation and reliability over decorative novelty<\/td>\n<\/tr>\n<tr>\n<td><code>subtractive-design<\/code><\/td>\n<td>Remove anything without a demonstrable purpose<\/td>\n<\/tr>\n<tr>\n<td><code>ai-output-judgement<\/code><\/td>\n<td>Treat generated work as a draft with a last-mile review<\/td>\n<\/tr>\n<tr>\n<td><code>prototype-to-production<\/code><\/td>\n<td>Harden happy paths for real edge cases<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The eleventh is <code>dxe<\/code>, which doesn\u2019t encode taste of its own; it runs the other ten.<\/p>\n<p>Browse and compose them here:<\/p>\n<p><astro-island uid=\"Z1CCb09\" prefix=\"r15\" component-url=\"\/_astro\/DemoRenderer.wTxljvQg.js\" component-export=\"default\" renderer-url=\"\/_astro\/client.fij4Y61k.js\" props=\"{&quot;name&quot;:[0,&quot;skills-collection&quot;]}\" ssr=\"\" client=\"visible\" opts=\"{&quot;name&quot;:&quot;DemoRenderer&quot;,&quot;value&quot;:true}\" await-children=\"\"><!--astro:end--><\/astro-island><\/p>\n<h2 id=\"install-the-lot\">Install the lot<\/h2>\n<p>Ten narrow lenses were fine while I was picking one at a time, but I kept reaching for the same install command in every new repo and then forgetting which machine had which subset. So the recommended path is now global and complete:<\/p>\n<pre class=\"not-prose language-bash\" data-language=\"bash\"><code class=\"language-bash\">npx skills <span class=\"token function\">add<\/span> kemiljk\/skills <span class=\"token parameter variable\">-g<\/span> <span class=\"token parameter variable\">--all<\/span>\n<\/code><\/pre>\n<p>Check what landed, and update later:<\/p>\n<pre class=\"not-prose language-bash\" data-language=\"bash\"><code class=\"language-bash\">npx skills <span class=\"token function\">ls<\/span> <span class=\"token parameter variable\">-g<\/span>\nnpx skills update <span class=\"token parameter variable\">-g<\/span>\n<\/code><\/pre>\n<p>Selective installs still work, and are still right when you\u2019re committing skills into a shared repo rather than onto your own machine:<\/p>\n<pre class=\"not-prose language-bash\" data-language=\"bash\"><code class=\"language-bash\">npx skills <span class=\"token function\">add<\/span> kemiljk\/skills <span class=\"token parameter variable\">--list<\/span>\n\nnpx skills <span class=\"token function\">add<\/span> kemiljk\/skills <span class=\"token parameter variable\">-g<\/span> <span class=\"token punctuation\">\\<\/span>\n  <span class=\"token parameter variable\">--skill<\/span> fluid-design <span class=\"token punctuation\">\\<\/span>\n  <span class=\"token parameter variable\">--skill<\/span> modern-css-html <span class=\"token punctuation\">\\<\/span>\n  <span class=\"token parameter variable\">--skill<\/span> ai-output-judgement\n<\/code><\/pre>\n<p>Drop the <code>-g<\/code> to commit them into a project so a team picks up the same constraints. You can also target particular agents with <code>-a cursor -a claude-code<\/code>.<\/p>\n<h2 id=\"one-command-for-the-whole-pass\">One command for the whole pass<\/h2>\n<p>The thing I got wrong the first time was assuming I\u2019d compose skills by hand, but in practice I never did. I\u2019d invoke one, get a narrow answer, and forget that the subtractive pass or the production hardening existed until something shipped badly.<\/p>\n<p><code>dxe<\/code> is the fix, and it\u2019s named after <a href=\"https:\/\/designengineer.xyz\">d\u00d7e<\/a> because it\u2019s the same argument in executable form. One short name, one full-suite pass over a repo or a scoped path. It reads every sibling <code>SKILL.md<\/code> and stops if any are missing, which is why the global <code>--all<\/code> install is the prerequisite rather than a suggestion.<\/p>\n<table>\n<thead>\n<tr>\n<th>Prompt<\/th>\n<th>Behaviour<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>dxe<\/code><\/td>\n<td>Full workspace review; propose fixes<\/td>\n<\/tr>\n<tr>\n<td><code>dxe src\/components<\/code><\/td>\n<td>Scope to that path<\/td>\n<\/tr>\n<tr>\n<td><code>dxe review<\/code><\/td>\n<td>Findings only; no edits<\/td>\n<\/tr>\n<tr>\n<td><code>dxe fix<\/code><\/td>\n<td>Findings, then high-confidence fixes<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>You get back one report rather than ten opinions: a hypothesis for what the pass is improving, findings by severity with each one tied to the skill that caught it, the subtractive cuts stated explicitly, and the remaining work ordered.<\/p>\n<p>Use a single skill when you want a narrow lens. Use <code>dxe<\/code> when you want the argument applied end to end.<\/p>\n<h2 id=\"composition\">Composition<\/h2>\n<p>Skills overlap on purpose, but without precedence they become noise. <code>dxe<\/code> runs this order, and it\u2019s the same order to follow by hand:<\/p>\n<ol>\n<li><strong>Intent<\/strong>: <code>write-first-design<\/code> and <code>subtractive-design<\/code> decide whether the work should exist.<\/li>\n<li><strong>Platform<\/strong>: <code>semantic-html-first<\/code> and <code>modern-css-html<\/code> choose native materials.<\/li>\n<li><strong>Feel<\/strong>: <code>fluid-design<\/code>, <code>interface-affordances<\/code> and <code>product-delight<\/code> shape interaction quality.<\/li>\n<li><strong>Bridge<\/strong>: <code>design-engineering<\/code> maps design structure onto code structure, so taste stays attached to tokens and rendering rather than to a handoff document.<\/li>\n<li><strong>Shipping<\/strong>: <code>ai-output-judgement<\/code> and <code>prototype-to-production<\/code> catch the median draft before it escapes.<\/li>\n<\/ol>\n<p>When motion taste and CSS purity disagree, fluid design owns the desired behaviour and modern CSS owns the most native implementation that can still deliver it. JavaScript earns its place for interruption, velocity and gesture continuity that CSS can\u2019t express.<\/p>\n<h2 id=\"migration-from-the-standalone-repos\">Migration from the standalone repos<\/h2>\n<p>If you already installed <code>kemiljk\/fluid-design<\/code> or <code>kemiljk\/modern-css-html<\/code>, point new installs at the collection:<\/p>\n<pre class=\"not-prose language-bash\" data-language=\"bash\"><code class=\"language-bash\">npx skills <span class=\"token function\">add<\/span> kemiljk\/skills <span class=\"token parameter variable\">-g<\/span> <span class=\"token parameter variable\">--skill<\/span> fluid-design\nnpx skills <span class=\"token function\">add<\/span> kemiljk\/skills <span class=\"token parameter variable\">-g<\/span> <span class=\"token parameter variable\">--skill<\/span> modern-css-html\n<\/code><\/pre>\n<p>The skill names stay the same, while the internals are improved: less repetition, clearer review checklists and references instead of one oversized file.<\/p>\n<h2 id=\"essays-and-skills\">Essays and skills<\/h2>\n<p>Essays still carry the stories, demos and reasons; skills carry the executable part: triggers, defaults, rejections and exit checks. If the collection works, I spend less time retyping \u201cuse tokens\u201d, \u201cprefer native buttons\u201d and \u201csprings not linear 300ms\u201d, and collaborators get the same constraints without sitting through the archive. <code>dxe<\/code> is the version of that I actually use day to day; the individual skills are what it\u2019s made of.<\/p>\n<h2 id=\"when-to-steal-this\">When to steal this<\/h2>\n<p>Build a personal skills collection when you notice yourself repeating the same review comments across AI drafts, pasting essay excerpts into prompts, maintaining multiple overlapping instruction files or teaching the same taste to different tools.<\/p>\n<p>Start from writing you already trust. Compress it into triggers, rules and checks. Keep examples in references. Publish the set so other people can install the judgement without inheriting the whole archive.<\/p>\n<\/p><\/div>\n<p><a href=\"https:\/\/karlkoch.me\/writing\/on-teaching-ai-how-you-work\/?utm_source=tldrdev\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I\u2019ve been writing down how interfaces should feel, how HTML should carry behaviour and how AI drafts should be judged. Essays are good at teaching people but awkward to paste into every new chat; skills package the same judgement so an agent can discover it, load the relevant slice and apply it without me re-explaining [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":23478,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[143],"tags":[],"class_list":["post-23477","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai"],"_links":{"self":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts\/23477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/comments?post=23477"}],"version-history":[{"count":0,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/posts\/23477\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/media\/23478"}],"wp:attachment":[{"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/media?parent=23477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/categories?post=23477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scannn.com\/lv\/wp-json\/wp\/v2\/tags?post=23477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}