Skip to content

Instantly share code, notes, and snippets.

@bendavis78
Created August 13, 2026 17:32
Show Gist options
  • Select an option

  • Save bendavis78/9656adb53ca512961d768a6c240c4a54 to your computer and use it in GitHub Desktop.

Select an option

Save bendavis78/9656adb53ca512961d768a6c240c4a54 to your computer and use it in GitHub Desktop.
Skill distribution channels — how skills reach users, channel by channel
<title>Skill Distribution Channels</title>
<style>
:root {
--bg: #FAF9F7;
--surface: #FFFFFF;
--surface-2: #F3F1EC;
--ink: #1F2328;
--muted: #6A7076;
--line: #E3E0DA;
--accent: #C8102E;
--qa: #A16207;
--qa-bg: #FBF3E4;
--prod: #15803D;
--prod-bg: #E9F5EC;
--sans: "Seravek", "Gill Sans Nova", Ubuntu, Calibri, "DejaVu Sans", source-sans-pro, sans-serif;
--mono: ui-monospace, "Cascadia Code", "JetBrains Mono", Menlo, Consolas, monospace;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #16181C;
--surface: #1E2126;
--surface-2: #23262C;
--ink: #E8E6E1;
--muted: #9BA1A8;
--line: #33373E;
--accent: #F04A5E;
--qa: #D9A03F;
--qa-bg: #2C2618;
--prod: #57C77B;
--prod-bg: #1B2A20;
}
}
:root[data-theme="dark"] {
--bg: #16181C;
--surface: #1E2126;
--surface-2: #23262C;
--ink: #E8E6E1;
--muted: #9BA1A8;
--line: #33373E;
--accent: #F04A5E;
--qa: #D9A03F;
--qa-bg: #2C2618;
--prod: #57C77B;
--prod-bg: #1B2A20;
}
html { background: var(--bg); }
body {
font-family: var(--sans);
color: var(--ink);
background: var(--bg);
line-height: 1.55;
margin: 0;
-webkit-font-smoothing: antialiased;
}
.wrap { max-width: 960px; margin: 0 auto; padding: 2.5rem 1.25rem 5rem; }
.eyebrow {
font-size: 0.72rem; font-weight: 600; letter-spacing: 0.12em;
text-transform: uppercase; color: var(--accent); margin: 0 0 0.5rem;
}
h1 {
font-size: clamp(1.6rem, 4vw, 2.2rem); font-weight: 750;
letter-spacing: -0.015em; line-height: 1.15; margin: 0 0 0.6rem;
text-wrap: balance;
}
.lede { color: var(--muted); max-width: 62ch; margin: 0 0 2.25rem; font-size: 1.02rem; }
.lede strong { color: var(--ink); font-weight: 600; }
h2 {
font-size: 1.2rem; font-weight: 700; letter-spacing: -0.01em;
margin: 3rem 0 0.35rem; text-wrap: balance;
}
h2:first-of-type { margin-top: 0; }
.h2-sub { color: var(--muted); font-size: 0.92rem; margin: 0 0 1.25rem; max-width: 66ch; }
.mono { font-family: var(--mono); font-size: 0.88em; }
/* ---------- channels table ---------- */
.table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
table { border-collapse: collapse; width: 100%; min-width: 900px; font-size: 0.85rem; }
thead th {
text-align: left; font-size: 0.7rem; letter-spacing: 0.09em; text-transform: uppercase;
color: var(--muted); font-weight: 700; padding: 0.7rem 0.9rem;
border-bottom: 2px solid var(--line); white-space: nowrap;
}
tbody td { padding: 0.7rem 0.9rem; border-bottom: 1px solid var(--line); vertical-align: top; }
tbody tr:last-child td { border-bottom: none; }
td.ch { font-weight: 650; white-space: nowrap; }
td .sub { display: block; font-size: 0.78rem; color: var(--muted); font-weight: 400; margin-top: 0.15rem; white-space: normal; }
.serve {
display: inline-block; font-family: var(--mono); font-size: 0.72rem; font-weight: 600;
padding: 0.16rem 0.5rem; border-radius: 6px; white-space: nowrap;
}
.serve.repo { background: var(--prod-bg); color: var(--prod); }
.serve.zip { background: var(--qa-bg); color: var(--qa); }
.serve.none { background: var(--surface-2); color: var(--muted); }
.push { font-weight: 650; }
.push.yes { color: var(--prod); }
.push.no { color: var(--accent); }
.push.mid { color: var(--qa); }
/* ---------- why cards ---------- */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0.85rem; }
.card {
background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
padding: 1rem 1.1rem;
}
.card h3 { margin: 0 0 0.35rem; font-size: 0.95rem; font-weight: 700; }
.card p { margin: 0; font-size: 0.87rem; color: var(--muted); }
.card p strong { color: var(--ink); font-weight: 600; }
ul.qs { margin: 0.5rem 0 0; padding-left: 1.2rem; font-size: 0.9rem; color: var(--muted); }
ul.qs li { margin-bottom: 0.45rem; max-width: 75ch; }
ul.qs li strong { color: var(--ink); }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
footer { margin-top: 3.5rem; font-size: 0.78rem; color: var(--muted); border-top: 1px solid var(--line); padding-top: 1rem; }
</style>
<div class="wrap">
<p class="eyebrow">Expert Intelligence Hub</p>
<h1>How skills reach users, channel by channel</h1>
<p class="lede">The channel, not the harness, determines whether we can push updates, pin versions, test privately, or recall a bad release. <strong>Served by</strong> ties each channel back to the artifact that supplies it.</p>
<h2>Distribution channels</h2>
<div class="table-scroll">
<table>
<thead>
<tr>
<th>Channel</th>
<th>Surfaces</th>
<th>Artifact</th>
<th>Updates</th>
<th>Served by</th>
</tr>
</thead>
<tbody>
<tr>
<td class="ch">Client-side git marketplace
<span class="sub">fetched with the user's own git credentials → private QA repo works</span></td>
<td>Claude Code (CLI + Desktop Code tab); ChatGPT desktop (Work &amp; Codex modes) + Codex CLI; Copilot CLI; Devin; OpenCode</td>
<td>Marketplace repo (<span class="mono">marketplace.json</span> + plugin dirs; Codex reads the same manifest)</td>
<td><span class="push yes">Push.</span> Background refresh + manual update; ref/sha pinning; Claude Code release channels</td>
<td><span class="serve repo">marketplace repo</span></td>
</tr>
<tr>
<td class="ch">Server-synced marketplace
<span class="sub">Claude-only; no documented private-repo path</span></td>
<td>claude.ai, Claude Desktop chat, Cowork (Customize → Plugins → add from repository)</td>
<td>Same repo, fetched by Anthropic's infrastructure</td>
<td><span class="push mid">Push-ish.</span> Re-synced server-side, cadence undocumented</td>
<td><span class="serve repo">marketplace repo</span></td>
</tr>
<tr>
<td class="ch">File upload (.zip / .skill)
<span class="sub">enterprise admins provision org-wide; the customer's admin becomes the publisher</span></td>
<td>claude.ai and Cowork individual upload; Team/Enterprise org-wide provisioning</td>
<td>Per-skill zip</td>
<td><span class="push no">No push from us.</span> Individuals re-upload; admins re-provision when they choose</td>
<td><span class="serve zip">per-skill zips</span></td>
</tr>
<tr>
<td class="ch">Workspace sharing (ChatGPT)
<span class="sub">OpenAI's analogue of Claude's org provisioning</span></td>
<td>ChatGPT Work, web + desktop, within one workspace</td>
<td>Plugin shared in-app to members/groups</td>
<td><span class="push mid">Push within the workspace;</span> the sharer republishes</td>
<td><span class="serve none">via customer</span></td>
</tr>
<tr>
<td class="ch">One-shot installers</td>
<td><span class="mono">npx skills add</span> (70+ agents), <span class="mono">gh skill install</span>, openskills</td>
<td>Spec-conforming <span class="mono">skills/</span> dirs, copied into place</td>
<td><span class="push no">No push.</span> Snapshot; user re-runs to update</td>
<td><span class="serve repo">marketplace repo</span></td>
</tr>
<tr>
<td class="ch">npm package</td>
<td>OpenCode natively; any <span class="mono">plugin.json</span> can source from npm</td>
<td>Published package</td>
<td><span class="push yes">Push</span> via semver resolution</td>
<td><span class="serve none">optional, later</span></td>
</tr>
<tr>
<td class="ch">Gemini CLI extensions
<span class="sub">catalog repos don't install (tracking <a href="https://github.com/google-gemini/gemini-cli/issues/28428">#28428</a>)</span></td>
<td>Gemini CLI only</td>
<td><span class="mono">gemini-extension.json</span> at repo root; one repo = one extension</td>
<td><span class="push yes">Push-capable</span> (<span class="mono">--auto-update</span>, ref pinning) but blocked for multi-skill repos</td>
<td><span class="serve none">blocked upstream</span></td>
</tr>
<tr>
<td class="ch">Vendor directories
<span class="sub">the only external source on ChatGPT web Work mode</span></td>
<td>Anthropic-curated sources; ChatGPT Plugins Directory (review portal, business-verified identity)</td>
<td>Listing that points at a marketplace</td>
<td>Inherits the marketplace's push; adds discovery</td>
<td><span class="serve repo">marketplace repo</span></td>
</tr>
<tr>
<td class="ch">Instruction-tier copies</td>
<td>Cursor, Windsurf, Cline, Kiro, Zed, anything reading <span class="mono">AGENTS.md</span></td>
<td>Copied rules file</td>
<td><span class="push no">None.</span> Dead snapshot</td>
<td><span class="serve none">n/a</span></td>
</tr>
</tbody>
</table>
</div>
<h2>What this means for planning</h2>
<div class="cards">
<div class="card">
<h3>Two artifacts cover everything</h3>
<p>The <strong>marketplace repo</strong> serves every push channel and the one-shot installers; <strong>per-skill zips</strong> serve the upload surfaces.</p>
</div>
<div class="card">
<h3>The zip channel inverts the publisher</h3>
<p>For enterprise Cowork customers (our core audience), the <strong>customer's admin</strong> decides when updates land. Keeping them current is a product problem (release notes, version display in the Hub), not an engineering one.</p>
</div>
<div class="card">
<h3>Revocation differs by channel</h3>
<p>A bad or compromised skill can be <strong>fixed forward on push channels</strong> but is unrecallable from zips, one-shot installs, and instruction-tier copies.</p>
</div>
<div class="card">
<h3>QA maps unevenly</h3>
<p>The private QA marketplace rehearses every client-side channel. Upload surfaces test natively (a QA zip is just a zip). The <strong>server-side sync is the one channel we can't rehearse privately</strong>.</p>
</div>
</div>
<h2>Open questions</h2>
<ul class="qs">
<li><strong>Enterprise private-source auth:</strong> Team/Enterprise claude.ai admin tooling may have a private-marketplace story the public docs don't cover; verify before assuming public-only for that surface.</li>
<li><strong>Directory listings:</strong> submission to the ChatGPT Plugins Directory is open via OpenAI's review portal but needs a business-verified OpenAI Platform identity. Who owns that account and the listing?</li>
<li><strong>Stale zips:</strong> what's the notification story for enterprise admins holding old zip installs?</li>
</ul>
<footer>
Expert Intelligence Hub · epic UA-5381
</footer>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment