From ae08e1b6ec01941c48b80154226c9679da03f0a7 Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Fri, 9 Oct 2026 17:48:10 +1100 Subject: [PATCH 1/3] feat(research): add original Skill size study --- .../skill-md-size-study-2026-10-09.md | 58 + eslint.config.mjs | 3 +- .../app/components/content/SkillSizeStudy.vue | 201 + .../marketing/app/pages/learn/[...slug].vue | 31 + layers/marketing/app/utils/page-admissions.ts | 5 + layers/marketing/content.config.ts | 2 +- .../content/learn/create-agent-skills.md | 2 + layers/marketing/content/learn/index.md | 2 + .../learn/research/skill-md-size-study.md | 159 + .../0151_original_research_snapshots.sql | 11 + .../avg-skill-md-size.png | Bin 0 -> 200115 bytes .../skill-md-size-2026-10-09/measurements.csv | 19349 ++++++++++++++++ .../measurements.json | 1 + .../skill-md-size-2026-10-09/provenance.json | 17 + .../skill-md-size-2026-10-09/summary.json | 493 + .../skill-md-size-2026-10-09/words.json | 1 + scripts/research/build-size-study.ts | 106 + 17 files changed, 20439 insertions(+), 2 deletions(-) create mode 100644 docs/editorial/skill-md-size-study-2026-10-09.md create mode 100644 layers/marketing/app/components/content/SkillSizeStudy.vue create mode 100644 layers/marketing/content/learn/research/skill-md-size-study.md create mode 100644 migrations/0151_original_research_snapshots.sql create mode 100644 public/research/skill-md-size-2026-10-09/avg-skill-md-size.png create mode 100644 public/research/skill-md-size-2026-10-09/measurements.csv create mode 100644 public/research/skill-md-size-2026-10-09/measurements.json create mode 100644 public/research/skill-md-size-2026-10-09/provenance.json create mode 100644 public/research/skill-md-size-2026-10-09/summary.json create mode 100644 public/research/skill-md-size-2026-10-09/words.json create mode 100644 scripts/research/build-size-study.ts diff --git a/docs/editorial/skill-md-size-study-2026-10-09.md b/docs/editorial/skill-md-size-study-2026-10-09.md new file mode 100644 index 00000000..37e88159 --- /dev/null +++ b/docs/editorial/skill-md-size-study-2026-10-09.md @@ -0,0 +1,58 @@ +# Skill size study evidence + +The study answers how Skill descriptions, bodies, and reference inventories differ across a frozen registry sample. +Harlan requested original research using the Unhead research articles as the editorial reference. + +## Reproduction + +The source measurements are committed under `public/research/skill-md-size-2026-10-09/`. +Run `pnpm exec tsx scripts/research/build-size-study.ts` to rebuild `summary.json`. +The provenance manifest records the original export hash, measurement hash, tokenizer, and rubric version. + +Migration 0151 stores the same summary and provenance in D1. +The existing source-version description and body observations remain in `skill_generated`. +The research snapshot has no foreign key to live Skills. Source deletion must not erase published evidence. +Publish corrections with an explicit snapshot revision. Do not silently replace historical measurements. + +## Claim checks + +| Claim | Evidence | +| --- | --- | +| 12,141 filtered Skills, 2,297 repositories | Included rows and distinct repository identities | +| 12,138 matched bodies, three missing | Nonnull body token measurements | +| 8.9% reach 5,000 tokens | 1,078 / 12,138 | +| Repository weighting raises that to 10.8% | Mean of per-repository proportions, 2,296 measured repositories | +| Mean description rises from 345 to 383 characters | Skill mean versus mean of repository means | +| 11,760 normalised descriptions | Trim and collapse whitespace before SHA-256 | +| 11,764 exact descriptions | Hash exact description text before normalisation | +| File duplicates leave the tail near 8.9% | 1,061 / 11,983 measured unique raw files | +| Reference mean is 2.27, median zero | 12,091 complete inventories, nulls excluded | + +Exact text uniqueness and whitespace-normalised uniqueness use different definitions. +Neither means the source bodies are distinct. +Body counts exclude frontmatter. Whole-file kB includes frontmatter. +All percentiles use nearest rank. + +## Interpretation limits + +The corpus is neither a random sample nor a top-installed leaderboard sample. +Existing aggregator flags predate the study. Their exclusion does not establish independent mirror detection. +Models see different tokens. o200k_base estimates cannot reproduce every Agent's catalogue truncation. +Jev scores have no independent human calibration. The article labels the semantic section exploratory. +No actual Agent selection, task completion, or corpus-wide skills-ref validation claim appears. +The public row dataset omits source instructions and descriptions. Pinned commits and paths identify those sources. +Word frequencies require the source descriptions, the published stop list, and the stated token rule to reproduce. + +## Search and admission + +NuxtSEO Pro queries on 9 October 2026 measured the US `skill md` seed at 720 searches/month, KD 28. +Specific size and description-length seeds returned no provider data. This is not measured zero demand. +The owner explicitly approved original research as an authority surface, independent of keyword volume. +The admission record names that purpose and the 11 November gate in `page-admissions.ts`. +Review relevant impressions, citations, dataset use, and authoring-guide clicks separately. + +## Primary guidance + +- [Agent Skills specification](https://agentskills.io/specification): description cap, progressive disclosure, body guidance, and format validation. +- [Claude authoring guidance](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices): concise instructions and real-usage tests. +- `scripts/lib/description-review.ts`: exact Jev questions, model version, and thresholds. diff --git a/eslint.config.mjs b/eslint.config.mjs index ad8d2eef..9ac60888 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -3,7 +3,8 @@ import harlanzw from 'eslint-plugin-harlanzw' export default antfu({ // skilld sync writes .skills from skilld-dev/skilld. CI checks it with check:skills. - ignores: ['.skills/**'], + // Immutable research exports retain their recorded byte hashes. + ignores: ['.skills/**', 'public/research/**/measurements.json'], rules: { 'vue/no-useless-v-bind': 'off', 'vue/attribute-hyphenation': 'off', diff --git a/layers/marketing/app/components/content/SkillSizeStudy.vue b/layers/marketing/app/components/content/SkillSizeStudy.vue new file mode 100644 index 00000000..aa8c5bb0 --- /dev/null +++ b/layers/marketing/app/components/content/SkillSizeStudy.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/layers/marketing/app/pages/learn/[...slug].vue b/layers/marketing/app/pages/learn/[...slug].vue index e5f09a9c..59e5980a 100644 --- a/layers/marketing/app/pages/learn/[...slug].vue +++ b/layers/marketing/app/pages/learn/[...slug].vue @@ -36,6 +36,37 @@ useSeoMeta({ useHead({ link: [{ rel: 'canonical', href: canonicalUrl }], }) + +if (slug.value === 'research/skill-md-size-study') { + defineOgImage('Page.takumi', { + title: data.value.title, + description: '12,141 Skills · 2,297 repositories · Original skilld research', + }, { alt: data.value.title }) + + useSchemaOrg([ + defineArticle({ + headline: data.value.title, + description: data.value.description, + datePublished: data.value.publishedAt, + dateModified: data.value.updatedAt, + author: { '@type': 'Organization', 'name': 'skilld', 'url': siteOrigin }, + }), + { + '@type': 'Dataset', + '@id': `${canonicalUrl.value}#dataset`, + 'name': 'Skill size and description measurements, 9 October 2026', + 'description': 'Frozen registry measurements with aggregator exclusions, source hashes, description assessment, and weighting comparisons.', + 'url': canonicalUrl.value, + 'version': '2026-10-09-v1', + 'creator': { '@type': 'Organization', 'name': 'skilld', 'url': siteOrigin }, + 'distribution': ['csv', 'json'].map(format => ({ + '@type': 'DataDownload', + 'encodingFormat': format === 'csv' ? 'text/csv' : 'application/json', + 'contentUrl': `${siteOrigin}/research/skill-md-size-2026-10-09/measurements.${format}`, + })), + }, + ]) +}