Created
August 13, 2026 17:32
-
-
Save bendavis78/9656adb53ca512961d768a6c240c4a54 to your computer and use it in GitHub Desktop.
Skill distribution channels — how skills reach users, channel by channel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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 & 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