P3.11 · D3 + D2 · Process38% of CCA-F26 min build

Agent Skills for Enterprise KM.

An enterprise-scale Skills registry. Each Skill is a markdown file with frontmatter (name + version + description + tags + dependencies + access_level), stored in .claude/skills/{team}/{name}.md so naming collisions become structural impossibilities. The registry indexer rebuilds on every commit, the search service surfaces the right Skill from 200+, semver gates breaking changes, and a permission-aware layer enforces ACLs before invocation (support agents cannot invoke finance Skills, no matter how cleverly prompted). Empirically confirmed on the real CCA-F exam by multiple pass-takers as one of the highest-leverage beyond-guide scenarios.

Mental modelArchitecture chooses the flow. Deterministic controls enforce policy. Structured state preserves truth.
Loop mascot illustrating Agent Skills for Enterprise KM.
Share
01 · System & parts

What this system is, and its 5 parts

Think of this as the way a 5,000-person company stops re-inventing the same agent prompt fifteen times. Every team writes its own Skills. Refund handling, expense reporting, deployment runbooks. And they all live in one shared library, organised by team and version, just like a code repo. When an agent on any team needs to do something, it searches the library, finds the right Skill, checks that the user is allowed to use it (finance Skills are not for the support team), and runs it. The whole point is that knowledge gets re-used safely at enterprise scale, not copy-pasted into a hundred system prompts.

5Components
D3Primary domain
8Build steps
9Decision traps
8Concept links
Stack · Claude Code · Git · search service (full-text or embeddings)Needs · Skills frontmatter · Git semver · file ACLs
Agent Skills for Enterprise KM component architecture.
5 components. Each owns one concept.
01

Skill Definition File

.claude/skills/{team}/{name}.md

The unit of enterprise knowledge. Markdown body holds the instructions; YAML frontmatter holds the metadata the registry indexes (name, version, description, tags, depends_on, access_level). Lives in version control next to code, reviewed via PR like any other team artifact.

ConfigurationPath convention: .claude/skills/{team}/{name}.md. Frontmatter required: name, version (semver), description, tags, depends_on, access_level. Body: the actual prompt + examples. Reviewed in PRs.
Concept: skills
02

Shared Registry & Indexer

rebuilds on every commit

A CI job that walks .claude/skills//*.md, parses frontmatter, validates schema, builds a searchable index, and publishes it to the registry service. Idempotent. Fast (sub-minute on 500 Skills). When a Skill commit lands, the index is fresh within 60s and the new version is discoverable.

ConfigurationTriggered on push to main. Steps: glob skills, parse YAML, validate (semver, ACL, deps exist), upload index to registry. Reindex SLA: <60s. Failed parses fail the CI; bad Skills never reach the registry.
Concept: structured-outputs
03

Search Service

embeddings-based at scale

Indexes Skill descriptions + tags + frontmatter. Agents query in natural language ('find a Skill for processing customer refunds') and get the top-k matches with their metadata. Full-text works at <50 Skills; embeddings (OpenAI / Voyage) become essential past 100; org-wide deployments use a hybrid (embeddings for recall, full-text for precision).

ConfigurationPOST /search { query, k=5, filters: { team?, access_level?, tag? } } → [{slug, version, description, score}]. Latency p95 < 200ms. Cache embeddings keyed by (skill_slug, content_hash); recompute only on content change.
Concept: context-window
04

Git-Based Versioning

semver in frontmatter + Git tags

Every Skill carries a semver version in its frontmatter; every release tags Git so older versions stay reachable. Callers pin a MAJOR version (refund-resolver:v1.x); the registry serves the latest patch within that major. Breaking changes bump the major; old callers keep working until they migrate.

ConfigurationFrontmatter: version: 1.2.3. Caller: depends_on: ['support/refund-resolver:1.x']. Registry resolves to latest patch within pinned major. Deprecated versions stay queryable for 6 months before archive.
Concept: tool-calling
05

Access Control Layer

permission-aware invocation

Sits between Skill discovery and Skill execution. Reads the calling agent's role + the Skill's access_level (public | team | role-restricted | sensitive). Denies invocation when the agent's role isn't in the allowlist. Returns a structured permission-denied error. The agent observes it and can request access via the org's standard flow, not bypass it.

ConfigurationPre-invocation: { agent_role, skill_acl } → { allowed: bool, reason }. ACL stored in frontmatter access_level + team-level org config. Denied: structured error { code: 'ACL_DENIED', skill, reason, request_url }.
Concept: evaluation
02 · Problem framing

The problem

What the user needs
  1. One source of truth across 15 teams. No copy-pasted Skill prompts drifting in 15 different repos.
  2. Discoverable at enterprise scale. An agent on the marketing team finds the right finance Skill in seconds, not hours.
  3. Permission-aware. Finance's budget-approval Skill must be unreachable from support's agent, no matter how the support agent is prompted.
Why naive approaches fail
  1. 200+ Skills in one flat folder → collision week 1 (refund-resolver exists in support/, growth/, AND finance/, all mean different things).
  2. No semver → v2 silently breaks v1 callers when frontmatter shape changes; agents start failing silently across the org.
  3. No ACL → support agent invokes finance/budget-approval because the Skill description sounded relevant; policy violation at scale.
Definition of done
  • Naming collision rate = 0 (team namespace prefix enforced)
  • Breaking-change incidents = 0 (semver in frontmatter, callers pin major)
  • Cross-team unauthorized invocation rate = 0 (ACL check before execution)
  • Skill-discovery p95 latency < 200ms (embeddings or full-text index)
  • Reindex SLA < 60s from commit to searchable
03 · Data flow

One run, traced end to end

Agent Skills for Enterprise KM sequence diagram.
Agent Skills for Enterprise KM end-to-end flow.
04 · Build

8 steps to production

01

Lay out the team-namespaced directory

Create .claude/skills/{team}/{name}.md per team. Even on day one with 5 Skills, namespace from the start. Retrofitting a flat layout into namespaces at 100 Skills is painful. The directory IS the registry's source of truth.

Concept: skills
Python
# Repository layout
# .claude/
# └── skills/
#     ├── support/
#     │   ├── refund-resolver.md       # support/refund-resolver
#     │   └── escalation-router.md     # support/escalation-router
#     ├── platform/
#     │   ├── deploy-runbook.md
#     │   └── incident-triage.md
#     ├── data/
#     │   ├── query-builder.md
#     │   └── pii-redactor.md
#     └── finance/
#         └── budget-approval.md       # access_level: sensitive

# Bootstrap script for a fresh repo
import os
TEAMS = ["support", "platform", "data", "growth", "finance"]
for t in TEAMS:
    os.makedirs(f".claude/skills/{t}", exist_ok=True)
    with open(f".claude/skills/{t}/.gitkeep", "w") as f:
        pass
print("namespace-by-team layout ready; commit and start authoring.")
02

Define the Skill frontmatter schema

Every Skill carries the same YAML frontmatter shape, validated by the indexer. Required: name, version (semver), description, tags, access_level. Optional: depends_on, deprecated, owners. Schema lives in the repo so PRs that break it fail CI before merging.

Concept: structured-outputs
03

Build the registry indexer

A CI job walks .claude/skills//*.md, parses each Skill's frontmatter, validates the schema, resolves dependencies, and writes a searchable index. Runs on every push to main; reindex SLA <60s on 500 Skills. Bad Skills (broken schema, missing dep, semver violation) fail the CI. They never reach the registry.

Concept: structured-outputs
04

Add semantic search over the registry

At <50 Skills, full-text on description+tags is enough. Past 100, agents need to discover by intent rather than keyword (a Skill that handles customer refunds should match refund-resolver even without the word 'refund' in the query). Embeddings + vector index over Skill description+tags is the play; cache embeddings keyed by body_hash so re-embedding only fires on content change.

Concept: context-window
05

Pin versions on every dependency edge

Every depends_on in a Skill's frontmatter pins a MAJOR version (support/case-facts:1.x), not a fixed PATCH. The registry resolves to the latest PATCH within the pinned major. When case-facts ships a breaking change, it bumps to v2. Old callers continue against v1.x; new callers opt in to v2 explicitly. This is exactly how pip / npm work, applied to Skills.

Concept: tool-calling
06

Enforce ACLs before invocation

Permission-aware RAG isn't built into Claude. You implement it. Read the calling agent's role + the Skill's access_level, run a hard check before invoking, and return a structured error on deny. This is a deterministic gate, not a prompt-language constraint; the Skill's body never executes if ACL fails.

Concept: evaluation
07

Wire the agent's Skill discovery into its tool loop

Expose two tools to every agent: search_skills(query, filters) and invoke_skill(name, version, payload). The agent finds Skills by intent, the ACL gate runs inside invoke_skill, and the Skill body executes only on allow. The agent never sees the registry's raw 200+ entries. Just the top-k matches for its query, gated by access_level.

Concept: tool-calling
08

Track usage + deprecation lifecycle

Once Skills are in production, the registry needs to know which Skills are hot, which are stale, which have known broken versions. Log every invoke_skill call with name, version, agent role, outcome. Surface a deprecation notice in search_skills results when an old version is queried. Auto-archive Skills with zero invocations in 6 months.

Concept: evaluation
05 · Right call, wrong call

9 decisions the exam turns into distractors

01 · Org has 200+ Skills across 15 teams
Looks right

Flat folder, full-text search, no ACL ('we'll add permissions later')

Actually right

Team-namespaced directory ({team}/{name}) + shared registry + embeddings search + ACL layer

DEC-01
02 · Skill `case-facts` is shipping a breaking change
Looks right

Edit v1 in place; tell teams to update their callers

Actually right

Bump major (v2.0.0); existing callers stay on v1.x until they migrate; deprecation notice in v1's frontmatter

DEC-02
03 · Support agent's prompt suggests calling `finance/budget-approval`
Looks right

Trust the prompt; finance Skills not in support agent's tool list

Actually right

ACL gate denies pre-execution; structured ACL_DENIED error with request_url returned to the agent

DEC-03
04 · Agent needs to find a Skill but doesn't know its exact name
Looks right

Show all 200+ Skills in the agent's tool list

Actually right

search_skills(query). Embeddings/full-text returns top-k matches with metadata

DEC-04
05 · Unbounded skill count in flat layout
Looks right

200+ Skills in .claude/skills/ flat folder. Naming collisions appear in week 1 (refund-resolver exists in support, growth, and finance contexts, all meaning different things). Discovery becomes a grep contest.

Actually right

Team-namespaced layout: .claude/skills/{team}/{name}.md. Collisions become structurally impossible. support/refund-resolver and growth/refund-resolver are distinct paths. Past 50 Skills, add an embeddings-based search service.

AP-20
06 · No versioning
Looks right

Skill case-facts ships a breaking change (frontmatter shape changes). Every agent in the org that depends on it starts failing silently. No way to roll back a single Skill's update.

Actually right

Semver in frontmatter (version: 1.2.3) + Git tags. Callers pin major (case-facts:1.x); registry resolves to latest patch. Breaking changes bump major, callers migrate deliberately.

AP-21
07 · Naming collisions across teams
Looks right

Two teams independently author a refund-resolver Skill. Both end up in .claude/skills/refund-resolver.md (last commit wins). Agents call the wrong one; nobody notices for weeks.

Actually right

Team namespace prefix: support/refund-resolver vs growth/refund-resolver. The directory layout enforces uniqueness; the indexer rejects duplicates. PR review surfaces collisions before merge.

AP-22
08 · No access control
Looks right

Support agent's prompt is cleverly engineered (or injected via PR content) to invoke finance/budget-approval. The Skill executes; an unauthorized $50K refund is approved. Audit log shows the agent did it; ACL log shows nothing because there is no ACL.

Actually right

ACL gate (access_level: public | team | role-restricted | sensitive) on every Skill, checked pre-invocation. Denied calls return a structured ACL_DENIED error; the agent observes it and either escalates or routes differently. Deterministic, not prompt-based.

AP-23
09 · Skills as one-off prompts
Looks right

Each agent's system prompt copy-pastes the relevant Skill content inline. When the Skill changes, 12 agents need updating. Nobody updates them all; behavior drifts over months.

Actually right

Skills are reusable, composable, versioned units. Agents reference them via invoke_skill('support/refund-resolver:1.x', payload). One source of truth; one Skill update propagates to every caller automatically.

AP-24
Agent Skills for Enterprise KM failure map.
06 · Budget

Cost & latency

~$0.0024 per invocationSkill execution (avg 800 tokens)

Skill body ~500 tokens system + ~200 input + ~100 output. Sonnet 4.5 pricing. Most Skills are narrow, focused units. No inflation from generic prompt scaffolding.

~$0.0001 per querySearch service (embeddings)

Voyage / OpenAI embedding ~512 dims at fractional cost per query. Embeddings cached by body_hash so re-embedding only fires on content change. At 1M queries/month, ~$100.

~$0 (compute) + ~$0.01 (embedding refresh)Reindex CI job (per push to main)

Indexer is pure parsing on GitHub Actions free tier. Only cost is re-embedding Skills with changed content. Typically <5% of the registry per push.

~+0.01ms per invocation, ~0% token costACL check overhead

ACL is a deterministic dictionary lookup against frontmatter + agent role. No LLM call. Latency is unmeasurable in the pipeline; cost is in maintenance, not execution.

~$3K-8K/yearAnnual registry hosting (5K Skills, 20K queries/day)

Embeddings store + search service + reindex compute. Small relative to the per-invocation Skill execution cost which dominates total spend at scale.

07 · Ship checklist

Check every gate before release

0/11 checked
  • skills
  • structured-outputs
  • tool-calling
  • context-window
  • tool-calling
  • evaluation
08 · Practice

5 exam-pattern questions

Work through one question at a time, check the architecture, then move through the set.

Question 1 of 5 · D3Choose the best answer

An enterprise has 200+ Skills across 15 teams. Skill-name collisions occur weekly (refund-resolver exists in support, growth, and finance, all meaning different things). How should you structure the registry to prevent this structurally?

09 · FAQ

Frequently asked

What's the maximum number of Skills per organization?

Unbounded with the right infrastructure. Per-project (a single agent's working set), keep <12 for discoverability. Per-team, low hundreds is comfortable with a search service. Org-wide, thousands work with embeddings + namespaces + ACLs. The bottleneck is rarely raw Skill count. It's how the agent finds the right one and how the org governs change.

Can a Skill depend on other Skills?

Yes, declared in frontmatter. depends_on: ['support/case-facts:1.x', 'shared/escalation-queue:2.x']. The registry validates dependencies exist at index time (CI fails on missing dep) and resolves them topologically at invocation time. Avoid cycles. The dep resolver detects them and rejects.

How do you version Skills without breaking existing agents?

Semver in frontmatter + callers pin major. A Skill at v1.2.3 keeps backward compatibility for all v1.x callers. When a breaking change is needed, bump to v2.0.0; existing callers continue against v1.x until they migrate deliberately. Deprecation notices in the v1 frontmatter point to v2; the registry surfaces the warning in search_skills results.

Is permission-aware RAG built into Claude?

No. You implement it. Claude's tool layer doesn't know about your org's roles. Implement an ACL gate that runs pre-invocation: read agent role + Skill access_level, deny if not allowed, return structured ACL_DENIED. The Skill body never executes if the ACL check fails. This is the same pattern as authorization middleware in any HTTP service. Deterministic, not LLM-judged.

Should sensitive Skills be versioned differently?

No. Same versioning, different access control. Versioning is about backward compatibility; access control is about who can invoke. They're orthogonal. A sensitive Skill ships v1.2.3 just like a public one; the ACL gate gates who can call it, regardless of version.

How do you find the right Skill from 200+?

Two tools, one query. First, search_skills(query, k=5, filters). Embeddings search returns top-k matches by intent. Second, invoke_skill(name, version, payload). Runs the chosen Skill with ACL check. The agent never sees raw access to the registry; it queries through the search tool. This keeps the agent's tool list small (just 2 tools) while exposing the entire Skills library.

What happens to old Skill versions when a new major ships?

They stay queryable for 6 months by default. The deprecation lifecycle: ship v2.0.0 → mark v1.x with a deprecation note in frontmatter → registry serves v1.x to existing callers but flags the deprecation in search results → after 6 months of zero invocations, auto-archive. Active Skills stay forever; truly cold ones get cleaned up.

Help someone build it

Share this scenario.

One share is one less team repeating the same architecture mistake.