Context Assembly
Before any specialist starts work, Guild assembles a tight context bundle: exactly the skills and project knowledge that specialist needs for this task, capped at 6 k tokens. No project-wide dumps. No sibling lanes unless the plan declares an upstream dependency.
This is what keeps your runs fast, reproducible, and debuggable: each specialist works from a known, diffable brief — not from whatever happened to be in the session.
Three layers, 3k target, 6k cap
A specialist’s authoritative task brief is the union of three layers:
| Layer | Content | Size |
|---|---|---|
| Universal | guild-principles + wiki/context/project-overview.md + wiki/context/goals.md | ~400 tokens |
| Role-dependent | wiki/standards/*.md for the role + 2–4 most-relevant entity pages | ~800–1500 tokens |
| Task-dependent | The specialist’s lane from the plan + named refs (concepts, decisions, products) + upstream depends-on: contracts + active decisions touching the task domain | ~800–1500 tokens |
- Target total: ~3k tokens.
- Hard cap: 6k tokens.
- Overflow policy:
guild:context-assemblesummarizes the lowest-weighted layer (usually task-dependent refs beyond 2 pages) until the bundle fits.
Role mapping
Which wiki/standards/ pages load per role group:
| Role group | Standards loaded | Products loaded |
|---|---|---|
| Engineering (architect, researcher, backend, devops, qa, mobile, security) | standards/coding-standards.md | products/<component>.md when explicitly named |
| Writing (copywriter, technical-writer) | standards/writing-voice.md + standards/branding.md | products/<feature>.md if user-facing |
| Social / SEO (social-media, seo) | standards/writing-voice.md + standards/branding.md + standards/seo-rules.md | products/<feature>.md if user-facing |
| Commercial (marketing, sales) | standards/branding.md + standards/pricing-policy.md | products/*.md for any referenced product |
Missing standards/ files are not an error — the assembler skips them silently and logs the omission to .guild/runs/<run-id>/context-warnings.md.
Output path
guild:context-assemble writes one file per specialist task before the Agent dispatch:
.guild/context/<run-id>/<specialist>-<task-id>.md
The invocation passes this file path as the primary task brief. The specialist then works in its worktree with that context plus the T1/T5 skills listed in its agents/<name>.md frontmatter.
When an output is wrong, diff .guild/context/<run-id>/ against a prior run to see exactly what the specialist was working from.
Ambient-context caveat
The bundle is a context contract, not a hard isolation boundary.
Claude Code loads, independent of Guild’s bundle:
- The consuming repo’s
CLAUDE.md(and user-global~/.claude/CLAUDE.md) - Plugin skills declared in
.claude-plugin/plugin.json - MCP servers declared in
.mcp.json - Claude Code auto-memory if enabled
Guild instructs every specialist to privilege the bundle over ambient context. The specialist may cite ambient information but must treat the bundle as the authoritative task brief. When ambient context contradicts the bundle, the bundle wins and the contradiction surfaces in the handoff receipt.
Agent-team backend note. When a subagent definition runs as an agent-team teammate, its skills and mcpServers frontmatter are not applied the same way as in standard agent dispatch — teammates load skills and MCPs from the normal project/user/plugin environment. The tmux launcher therefore restates the bundle path and any required skill playbooks explicitly in the spawn prompt.
Recall-before-read
Before a specialist opens a file, it queries the project wiki for its task description. This is recall-before-read: if the wiki returns ≥1 chunk with a relevance score ≥ models.recallScoreThreshold (default 0.4), the specialist receives the chunk(s) and skips the full file read. Full reads are permitted only when recall returns 0 hits or the task requires source-of-truth verification.
Two implementation paths, selected at runtime by scripts/lib/wiki-recall.ts:
Path A — SQLite FTS5
Activated when:
defaults.index.enabledistrue(default), and- the wiki file count exceeds
defaults.index.wiki_file_threshold(default500)
ensureWikiFtsIndex populates the wiki_fts table on first crossing (lazy, never eager). Subsequent calls skip re-population when the wiki is unchanged. Queries run FTS5 bm25() over wiki_fts, returning up to 10 hits ordered by relevance.
On a cache hit, wikiRecall() returns { source: "sqlite-wiki_fts", hits[], dbPath }. Empty hits[] means the index exists but no FTS5 matches — distinct from null.
Path B — guild-memory MCP BM25 (fallback)
wikiRecall() returns null when:
defaults.index.enabledisfalse- Wiki file count is at or below the threshold
- Index not yet populated or population failed silently
- Any error during DB open or FTS5 query
On null, the caller falls through to the guild-memory MCP BM25 path — the same grep-backed path used before the SQLite index. The fallback is byte-identical to pre-index behavior: no index.sqlite written, no side effects.
The 6k hard cap applies regardless of which path supplies the recall result.
Why this design
| Benefit | How context assembly delivers it |
|---|---|
| Specialists stay on task | Short authoritative brief — no drift into unrelated project history |
| Runs are reproducible | Same task produces the same bundle; evals are meaningful |
| Failures are debuggable | Diff .guild/context/<run-id>/ against a prior run to find the difference |
| Costs stay low | No redundant project-wide prose loaded into every specialist invocation |
See also
- Architecture & Lifecycle — where context assembly sits in the lifecycle.
- Project Memory & Wiki Pattern — the wiki categories the assembler reads from.
- Cost-Aware Model Tiering — recall-score threshold and tier auto-score config.
- Configuration reference —
defaults.index.*andmodels.recallScoreThresholdkeys.