Knowledge layer - alloy + e11-knowledge
How Foundry talks to the @engineering11/alloy knowledge corpus. One skill, a stable query-key grammar, a deterministic resolution ladder, a corpus manifest that owns the layout AND the vocabulary, and a citation scheme that lets readers trace every claim.
If you want a single page to bookmark while using Foundry, this is it.
What alloy is
@engineering11/alloy is a published npm package that holds the platform's knowledge - SDK docs, patterns, conventions, infrastructure guides, foundation docs, and the selection matrices. It is versioned per project: each project pins the corpus version (and view) it depends on in .alloy/corpus.lock.
Foundry holds zero corpus-layout knowledge. The corpus ships a manifest (meta/corpus-manifest.yaml) that declares its categories, directory layout, subdoc sets, and views. The e11-knowledge skill reads that manifest at query time and derives structure from it - so Alloy can restructure the corpus and Foundry keeps working with no change. You never hardcode a corpus path; you query a key and cite the path the skill resolves.
Under the v2 layout the tree is organised by source and by shared curation, not a flat category list:
@engineering11/alloy/
├── meta/ # corpus-manifest.yaml, how-to-read-this-corpus, matrices
├── shared/ # curated, non-repo-derived categories
│ ├── foundation/ patterns/ conventions/ infrastructure/ integrations/
└── sources/ # one namespace per source repo
├── sdks-nodejs/ # backend-apis/ sdks/ microservices/
├── sdks-react/ # sdks/ (frontend leaves)
└── engineering11-platform/ # services/ app-assembly/ libs/ adapters/ … (v2 platform)The exact category keys, their directories, and which are live under your pinned view are manifest data you discover, never a list to memorise. Two upstream docs describe the corpus for agents - cite them via the skill rather than restating them here: meta/agent-consumption-guide.md (index-first navigation, context-assembly order) and meta/how-to-read-this-corpus.md (frontmatter + the sources//shared/ hierarchy).
Install
The Foundry installer wires alloy for you (brainless install): it runs the corpus install, pins .alloy/corpus.lock only-if-absent, provisions the alloy CLI at @latest, syncs the cache, and registers the alloy-corpus MCP server. You do not type or bump a version - the installer resolves @latest once and records the exact resolved version in the lock.
Only the corpus is pinned. The CLI (and the alloy-corpus MCP server) float @latest on their own release train: they carry the resolver that decides how a pinned corpus is fetched - straight from the npm registry, or cloned from the corpus git repo - and that transport work ships independently of the knowledge itself. Pinning the CLI to the corpus version would strand a project on whatever resolver happened to ship alongside that corpus.
If you ever need to do it by hand inside the project where you've installed Foundry:
npm install -D @engineering11/alloyWithout a corpus reachable on any rung, the skill halts with a fix-per-rung instruction - and any agent that tries to consult it (Architect, UX, Dev, Bootstrapper, Analyst on [TR]) halts too. This is by design: loud absence, never a guessed answer.
The resolution ladder
The skill resolves each query through a strict ladder, falling to the next rung only when a rung is unavailable (never on a rung's NOT FOUND - a reachable rung's answer is authoritative):
- MCP - the
alloy-corpusMCP tools (resolve/search/manifest/matrix), when registered in the session. The only supersession-aware surface. - cache - the machine-global pinned cache (
$ALLOY_CACHE_DIR ?? ~/.alloy/cache/corpus/<version>), populated byalloy corpus sync. - package-source -
{workflow.corpus_root}(default{project-root}/node_modules/@engineering11/alloy). - halt - none reachable: the skill prints the per-rung fix and stops.
The committed .alloy/corpus.lock ({ version, view }) pins which corpus version and view every rung serves. A malformed lock halts with an actionable error; an absent lock resolves the manifest's default view, explicitly marked unpinned.
How agents consult it
Agents don't read alloy files directly. They invoke skill:e11-knowledge with a query key - a colon-separated string like sdk:auth or pattern:multi-tenancy. The skill runs the manifest handshake, resolves the key against the active view, reads the file, and returns the content with a citation header and a marker envelope ([resolved], [pin], [supersession]).
You can do the same thing manually from any agent: pick [QK] Query Knowledge (available on Analyst, Architect, Dev, UX, Bootstrapper) and pass a key.
The V2 scaffolds are corpus consumers too. e11-scaffold-app and e11-scaffold-service generate entirely from platform keys — foundation:v2-app-shape, the app-assembly:canon-app:* leaves, pattern:v2-domain-slice, pattern:v2-authz-catalog-and-seed, and the generated matrix:canon-env / matrix:published-surface contracts. They never clone engineering11-platform; the corpus (extracted and drift-gated in E11's own CI against the CI-booted examples/canon-app referent) is the only channel platform knowledge travels to a consumer machine. An unresolvable key halts the scaffold with the pin command that fixes it.
Discovery-first. You do not need to know the category vocabulary in advance - it is corpus data. Ask the corpus what it holds (the manifest MCP tool, or the meta/corpus-manifest.yaml the skill loads on the file rungs), pick the category that fits, read its list:<category> unit map, then resolve the doc.
Query-key grammar
The manifest owns the vocabulary and layout; the skill owns a small set of grammars. Every prefix that is a manifest category key resolves generically to that category's base directory under the active view. Placeholder forms (supply concrete names from discovery):
| Key form | Resolves to |
|---|---|
sdk:<name>[:<subdoc>] | smart route: the sdk category, falling back to backend-api on a Tier-2 miss |
api:<name>[:<subdoc>] | the backend-api category (Tier 1 explicit; folder-per-name) |
<category>:<name>[:<subdoc>] | that manifest category's base dir (layout flat -> <name>.md; folder -> <name>/<subdoc ?? index>.md) |
meta:<name> | the top-level meta/ dir |
matrix:<name> | meta/<name>-matrix.yaml |
list:<category-or-dir> | that category's unit map (base/index.md) |
Two prefixes are aliases whose spelling differs from their category key: api: -> backend-api, infra: -> infrastructure. Which categories are live depends on your pinned view - discover them; never assume a fixed set.
Subdocs for sdk: are skill-owned (the sdk/backend-api categories declare no manifest docs map): Tier 2 - shared, backend-building, backend-using, frontend-building, frontend-using; Tier 1 - building, using. A folder category that DOES declare a docs map has its subdocs discovered from the manifest, not memorised.
Upstream-resolved keys (four, reserved)
A small set of keys resolve against the sdks-nodejs clone instead of the corpus. They capture material that lives only in the upstream generator-skill set today:
| Key | Resolves to | Cite as |
|---|---|---|
pattern:backend-shared | $CLONE_PATH/.claude/skills/BACKEND-PATTERNS.md | sdks-nodejs-skill://BACKEND-PATTERNS.md |
pattern:backend-standards | $CLONE_PATH/.claude/skills/STANDARDS.md | sdks-nodejs-skill://STANDARDS.md |
pattern:gen-microservice | $CLONE_PATH/.claude/skills/gen-microservice.md | sdks-nodejs-skill://gen-microservice.md |
pattern:gen-sdk | $CLONE_PATH/.claude/skills/gen-sdk.md | sdks-nodejs-skill://gen-sdk.md |
These shadow any future alloy entry with the same key, on purpose. They resolve OUTSIDE the corpus, so they are the skill's own grammar, not corpus vocabulary. The e11-sdks-nodejs skill resolves $CLONE_PATH (clones the upstream repo to a cache if needed).
Smart routing for sdk:
When you query sdk:<name> without specifying a tier, the skill tries Tier 2 first, then Tier 1, using the manifest-derived base dirs:
- Tier-2 candidate:
base(sdk)/<name>/index.md- if it exists, use it. - Otherwise Tier-1 candidate:
base(backend-api)/<name>/index.md. - If neither exists, fall back to package source (see below).
For sdk:<name>:<subdoc>, the subdoc auto-translates between tiers (:backend-using -> base(backend-api)/<name>/using.md, etc.; frontend-only subdocs have no Tier-1 fallback). Use api: and microservice: prefixes to assert a specific tier and skip smart routing.
Fallback to package source
When an alloy doc is missing for an sdk:<name> query inside an in-range corpus, the skill falls back to pointing the agent at the package source on disk:
[alloy:sdk:<name>] NOT FOUND in corpus
Fallback: @engineering11/<name> source at
{project-root}/node_modules/@engineering11/<name>/src
Use Glob/Grep/Read on that tree to inspect the SDK directly.
Likely entry points: package.json, src/index.ts, src/**/index.tsThis is intentional - the platform is the source of truth even when the corpus isn't yet complete. Don't guess an API; read it.
Citation rules
Two citation schemes, depending on where the content came from.
Alloy-resolved content - cite the exact path the skill's Cite as: line returns (alloy://<resolved-relative-path>). The path is taken from the resolution result, never reconstructed from memory of a layout. A citation to a legacy flat V1 path resolves to the v2 redirect tombstone left there; cite where the doc actually resolved (the successor path after a redirect).
Upstream-skill content (the four reserved keys) - cite with the upstream scheme so readers know they need a local sdks-nodejs checkout (or the Foundry cache): sdks-nodejs-skill://BACKEND-PATTERNS.md, …/STANDARDS.md, …/gen-microservice.md, …/gen-sdk.md.
Worked examples
The right-hand paths below are illustrative; always cite the actual Cite as: line the skill returns.
skill:e11-knowledge sdk:auth → the auth SDK index the skill resolves
skill:e11-knowledge sdk:auth:backend-using → the auth backend-using doc
skill:e11-knowledge pattern:multi-tenancy → the multi-tenancy pattern doc
skill:e11-knowledge list:sdks → the domain-SDK unit map for the active view
skill:e11-knowledge matrix:unit → meta/unit-matrix.yaml (matrix:sdk resolves a byte-identical back-compat copy)Hard constraints
The skill enforces these and they're worth knowing:
- No HTTP from the local rungs. The MCP rung's server does its own fetching; the cache and package rungs are pure file reads.
- Bounded roots. It reads from the cache root,
{workflow.corpus_root}(default{project-root}/node_modules/@engineering11/alloy) and SDK-source fallbacks under{project-root}/node_modules/@engineering11/**, the committed.alloy/corpus.lock, the four reserved upstream files, and any roots you declare viaextra_query_keys. Nothing else. - Never guess layout OR vocabulary. In-range corpus -> the manifest says; out-of-range -> halt. There is no memorised category list to fall back on.
- One permitted write. The only write the skill performs is a single appended telemetry line on a local-rung NOT FOUND. No cache writes, no lock writes, no doc edits.
- No fabrication, no truncation. Missing file -> NOT FOUND branch with fallback guidance; retrieved docs are returned verbatim.
Customizing the knowledge layer
e11-knowledge is a skill with a customize.toml surface - overrides live in .foundry/custom/e11-knowledge.toml (team) / .user.toml (personal). Two fields matter:
corpus_root (scalar - override wins). The rung-3 (package-source) corpus location; the MCP and cache rungs precede it. Remap for monorepos that hoist node_modules, vendored corpus checkouts, or a pre-release corpus build:
[workflow]
corpus_root = "{project-root}/../../node_modules/@engineering11/alloy"If an overridden corpus_root doesn't exist, the rung-4 halt names the missing override path instead of telling you to npm install.
extra_query_keys (array of tables keyed by id). Team-extensible query prefixes, checked before the built-in grammar, so a team can add whole corpora without forking the skill:
[[workflow.extra_query_keys]]
id = "runbook" # the query prefix
path_template = "runbooks/<name>.md" # <name>/<subdoc> placeholders
root = "{project-root}/docs/ops" # or "corpus" to resolve under corpus_rootNow any agent can skill:e11-knowledge runbook:rotate-keys. See Customization for the general override mechanics.
The alloy thread, end to end
The knowledge layer isn't just a lookup tool - one platform thread runs through the whole lifecycle, and each stage's output is the next stage's input:
- PRD - Platform Capability Map (
e11-prd, gatee11_platform_capability_map). Discovery surveys the platform (list:sdks,sdk:*) and classifies every MVP feature Covered / Composed / New, withalloy://cites, in a PRD section. - Architecture - SDK composition (
e11-architecture, gatee11_platform_composition). The spine inherits the map: composed SDKs become[ADOPTED]AD-n decisions with citations; the "New" rows become the actual design work; gaps land in an explicit follow-ups list. - Stories - SDK stamps (
e11-create-epics-and-stories, gatee11_platform_sdk_stamp). Every story gets an**E11 SDKs touched:**stamp derived from the map + composition table. - Readiness - cross-artifact check (
e11-check-implementation-readiness, gatee11_platform_alignment). Verifies the three agree via a deterministiccheck-consumerscite sweep: no unmapped stamps, no unstamped mappings, no broken cites. - Dev - capability-driven pre-load (
e11-dev-storystep 2b, gatee11_platform_preload). Before code: derive capabilities (pattern:backend-capability-map), union with the story stamp and imports, load each SDK's:backend-using/:frontend-usingdoc, halt on gaps, and record "Alloy pre-load complete" with counts and cites. The same pre-load runs ine11-spec-flow,e11-dev-flow, ande11-dev-auto. - Review - the alloy auditor layer (
e11-review-alloy-auditor). Checks the diff's conventions against the docs, verifies the pre-load record and citations, audits skip honesty, and resolves everyalloy://cite through the MCPresolvetool (or thecheck-consumersbackstop) - surfacing a valid-but-superseded tombstone cite as an advisory. - Retrospective - platform debt (
e11-retrospective). The epic review surfaces what accumulated: alloy gaps hit during pre-loads, Tier C components from UX, spine follow-ups - the feedback loop that grows the corpus.
Break the thread at any stage and the later stages tell you: that's the design.
Source
e11-knowledge/SKILL.md · e11-sdks-nodejs/SKILL.md · e11-sdks-react/SKILL.md
See also: Query alloy directly (recipe) · Concepts.