{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Maguyva Blog",
  "home_page_url": "https://maguyva.ai/blog",
  "feed_url": "https://maguyva.ai/feed.json",
  "description": "Technical deep-dives on MCP code intelligence, AI agent architecture, and lessons from building a multi-language code search platform.",
  "language": "en",
  "items": [
    {
      "id": "https://maguyva.ai/blog/context-that-travels",
      "url": "https://maguyva.ai/blog/context-that-travels",
      "title": "Context that travels",
      "summary": "Cursor's indexer is excellent inside Cursor. Maguyva is the hosted MCP map the same agent can query from other editors, CLIs, and CI.",
      "content_html": "<p>Cursor’s indexer is excellent inside Cursor. Tab complete, inline edit, chat, and the agent inside that window already sit on top of a project index Cursor operates for the opened workspace. If Cursor is the only surface you write in, and that index already finds the right files, stay there. That is the honest stay-put case, and it is the right first sentence of this page.</p>\n<p>This piece is about the other half of a common week. The same repository is also opened in Claude Code, asked about from Codex CLI, reviewed on a second machine, or queried by an agent running in CI. The question is not “which indexer is better.” The question is whether the map the agent trusts in one window is the same map it trusts in the next.</p>\n<p>Maguyva is that traveling map. It is a remote MCP codebase-context layer. The agent queries it the same way it queries any other MCP tool. Results come back as ranked paths with line numbers. Cursor stays the editor. The context is what moves.</p>\n<h2 id=\"what-cursors-indexer-is-for\">What Cursor’s indexer is for</h2>\n<p>Cursor’s built-in indexing exists so chat, agent, and search inside the editor can retrieve relevant code instead of relying only on whatever fits in the model’s raw context window. That is the right design for an IDE. The index is native to Cursor. It is not an MCP server and is not reachable from any other client.</p>\n<p>How it works, as described in Cursor’s public docs and Cursor’s own account at time of writing: the primary search path is no longer a cloud-embedding index. Cursor’s team stated on their community forum that dedicated semantic/embedding-based search is being wound down in favor of grep-based retrieval, because current models search a live tree well enough on their own without one. In its place is Instant Grep, a local search index built from n-grams, inverted lists, and bloom filters, kept in a memory-mapped lookup table so queries resolve on the developer’s own machine rather than a server.</p>\n<p>The index itself lives inside the repository’s own <code>.git/cursor/</code> directory, anchored to a specific git commit; edits since that commit layer on top of it instead of triggering a rescan, and the index only rebuilds when local state has drifted far from what it was built against. Because it sits inside <code>.git</code>, it is never tracked and never pushed — delete the folder and the index is gone. <code>.gitignore</code> is respected by construction, since only git-tracked content is eligible, and <code>.cursorignore</code> is enforced on the read path. There is no server-side embedding step and no remote vector database in that path anymore. Earlier docs described a cloud-assisted design — chunk encryption, a Merkle-tree sync, cross-teammate index reuse — and Cursor’s own team has since said that design is being turned down, so this piece no longer describes it as current.</p>\n<p>A standout inside the editor is Cursor’s Explore subagent. It can spawn multiple parallel searches in its own context window on a faster model and return only the relevant findings, so the main conversation does not swell with search hits. That is a genuine in-editor strength. Keep it.</p>\n<p>Multi-root workspaces are supported: each opened folder’s context is available to Agent. Some git-dependent features such as worktrees are disabled in multi-root setups, and Cloud Agents do not support multi-root workspaces at all.</p>\n<p>None of that is a reason to leave Cursor. It is a precise description of a map that is excellent where it lives.</p>\n<h2 id=\"what-travels-actually-means\">What “travels” actually means</h2>\n<p>A map travels when the same questions return the same kind of answer, with citations you can open, from more than one client.</p>\n<ul>\n<li>In Cursor: “Where is <code>parseConfig</code> defined, and who calls it?”</li>\n<li>In Claude Code, on the same repo: the same question.</li>\n<li>In Codex CLI, on a review box that never opened the Cursor window: the same question.</li>\n<li>In a CI agent that speaks MCP: the same question, against the same hosted snapshot.</li>\n</ul>\n<p>If each surface builds its own private index, you do not have one map. You have several caches that drift. The editor index can be current for the tree on disk. The CLI session can be a day behind. The CI job can be looking at a different checkout. The agent will still sound confident.</p>\n<p>Cursor’s indexer is not supposed to solve that. Because it lives inside the editor, the context it builds is for that editor. A reader who also needs a CLI, a CI pipeline, or a different editor needs a separate tool for those surfaces. That is a scope fact, not a defect. Maguyva is the separate tool.</p>\n<p>A published language count for Cursor’s indexer is not stated in the notes this draft is allowed to use. Maguyva publishes 279+ languages and text-based technologies. Pricing for Cursor is likewise not copied here; see their pricing page. Maguyva bills per workspace, not per seat, with published plans at $0, $19, $49, and $149 depending on indexed footprint and workspace size.</p>\n<h2 id=\"one-hosted-map-every-mcp-client\">One hosted map, every MCP client</h2>\n<p>Maguyva is a remote MCP server. You connect GitHub, pick the repositories, and the cloud pipeline builds symbols, graph edges, and a ranked map. You add an API key to the MCP config of the client you already use. Maguyva has setup guides for 24 documented MCP clients — including Cursor — and can connect to other MCP-compatible clients that support standard MCP configuration.</p>\n<p>The <a href=\"https://maguyva.ai/for-cursor\">Cursor setup page</a> is the editor-specific path if that is where you work. The same server answers Claude Code, VS Code, Windsurf, Codex CLI, and the rest. You do not switch editors. You give every agent the same tool surface: 11 customer-facing MCP tools across search, symbols, dependency analysis, file retrieval, repository context, and deterministic utility workflows. Semantic, structural, graph, and text retrieval are fused into ranked results.</p>\n<p>That is the portability benefit. The citations you graded in Cursor this morning are the same shape of citations Codex CLI will return tonight. File path and line number. Open them. If they are wrong, you see it. If they are right, the next edit has a place to land. The approved claim is fewer hallucinated edits, not a promise that every edit is correct.</p>\n<p>Freshness is published. Snapshots are timestamped, so the agent knows which version it is reading. Rebuild cadence is daily on the free plan and hourly on paid plans. The honest limit is un-synced local work: an edit that exists only in a working tree is not in the hosted map yet. That limit is the same no matter which client you query from, which is the point. Drift between clients is no longer a second, hidden limit.</p>\n<p>The <a href=\"https://maguyva.ai/docs\">docs</a> give the activation loop that applies to every client: index one repo you already know, connect the client, ask one question you can verify. Do that once in Cursor. Do it again from the CLI you actually use on review days. If both answers cite the same handler, the map traveled.</p>\n<h2 id=\"how-the-two-maps-sit-next-to-each-other\">How the two maps sit next to each other</h2>\n<p>Use both. They are not alternatives in the comparison-page sense.</p>\n<ol>\n<li>Keep Cursor’s indexer on for the project on disk. Let Explore, Instant Grep, and the in-editor agent use it. That loop is native and fast.</li>\n<li>Add Maguyva as an MCP server in Cursor so the same session can also ask the hosted workspace map. Cursor is a documented Maguyva client. You are not choosing one index and deleting the other.</li>\n<li>Add the same Maguyva server to Claude Code, Codex CLI, or any other MCP client that touches the repo. One API key shape. One workspace.</li>\n<li>If a CI agent is MCP-compatible, point it at the same server. It will read the same timestamped snapshot the laptop did.</li>\n</ol>\n<p>The editor index remains the best tool for “what is on disk in this window, right now.” The hosted map is the best tool for “what does this workspace look like to every agent that will touch it today.” Those sentences do not compete.</p>\n<p>Workspace quotas are published on the <a href=\"https://maguyva.ai/pricing\">pricing page</a>: repos, indexed lines, and users, billed per workspace. Agents and humans share the same user count. Start free on a repo you can already grade. Raise the workspace only after the citations survive contact with the tree.</p>\n<h2 id=\"what-this-page-does-not-claim\">What this page does not claim</h2>\n<p>It does not claim that Cursor’s indexer is weak, incomplete, or a reason to switch editors. The first sentence of this draft is the opposite.</p>\n<p>It does not claim Maguyva replaces Instant Grep or the Explore subagent. Those are Cursor features. They stay in Cursor.</p>\n<p>It does not invent a language count, a latency figure, or a token-savings number for either product. Unknown figures stay unpublished.</p>\n<p>It does not pretend un-pushed local work is in the hosted map. Timestamped snapshots make that limit visible. They do not remove it.</p>\n<p>The test is ordinary. Index one repo you already know. Ask one question you can verify, first in Cursor, then in a second MCP client. Context that travels is the same citation in both places.</p>\n<p><code>// same map, wherever you opened it.</code></p>\n",
      "date_published": "2026-09-07T00:00:00.000Z",
      "tags": [
        "Ecosystem",
        "MCP",
        "Portability"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/map-first-review-second",
      "url": "https://maguyva.ai/blog/map-first-review-second",
      "title": "Map first, review second",
      "summary": "Ground the coding agent in a repo map before it writes. Let Greptile review the pull request after. A complementary pairing, not a swap.",
      "content_html": "<p>Two different jobs sit on either side of a pull request. Before the agent writes, it needs a map of the tree it is about to change. After the agent opens a PR, something should read that change against the rest of the system and leave comments a human can act on.</p>\n<p>Those jobs look similar from a distance because both involve “understanding the codebase.” They are not the same product. One answers “where should this edit land?” The other answers “what did this diff break that a line-by-line linter will miss?” Mixing them up produces a worse first draft and a noisier review.</p>\n<p>This piece is a joint-workflow guide. Maguyva is the map the agent queries first. Greptile is the review agent that comments on the PR second. The pairing is complementary by construction: Maguyva does not review pull requests, and Greptile does not replace the context layer the agent used to write them.</p>\n<h2 id=\"why-the-split-is-useful\">Why the split is useful</h2>\n<p>A coding agent that starts from training priors plus a few pasted files will invent a plausible path and edit it. That is the wrong-file failure, and it is a retrieval problem. Maguyva is a remote MCP codebase-context layer: semantic, structural (AST), graph/dependency, and text retrieval fused into ranked results, plus symbol lookup and file fetch. Grounded answers come back as <code>path/file.ext:line</code> so you can reject a miss before a patch exists. The claim stays modest: fewer hallucinated edits. The model can still guess. The first step stops being a guess.</p>\n<p>Greptile is an AI code review agent. In their own words, it automatically reviews every pull request with complete understanding of the codebase, and it positions that against traditional linters that check files in isolation rather than the whole system. Setup is installing the GitHub or GitLab app and selecting repositories. There is no local index for you to operate. Hosting is Greptile Cloud (they state SOC 2 Type II compliance, with a report available on request), with a self-hosted option offered for enterprises.</p>\n<p>Their own numbered flow is: connect and build a dependency graph of every function, class, and dependency; on every pull request, analyze the change using that full-repo graph and post findings as PR comments with suggested fixes, in about three minutes; each comment can hand the issue to a coding agent the team already uses. They also state they read prior human PR comments over time to learn a team’s coding standards and reduce noisy suggestions. Their learning system is stated to need 2–3 weeks to adapt.</p>\n<p>That is review, not drafting. Greptile’s standout is full-repository graph context on the change that already landed in a PR, then a closed loop that sends the finding to Claude Code, Codex, Conductor, Cursor, or Devin. Maguyva’s standout is the ranked map the agent queried before that change was written. Use both. Do not ask either to do the other’s job.</p>\n<p>A first-party Maguyva–Greptile product integration is not stated. You do not need one. Maguyva talks to the agent over MCP. Greptile talks to GitHub or GitLab through their app. They meet at the pull request. No glue script, no cron that pipes one tool into the other. The pairing is bash-free because each product already sits on the surface it owns.</p>\n<h2 id=\"what-this-is-not\">What this is not</h2>\n<p>This is not a teardown of Greptile. It is not a “switch your reviewer” page. Greptile launched on Hacker News on 5 March 2024 as a Y Combinator W24 company, and that thread is how a lot of people first met the product. If that is how you found them, keep them. This page is the missing front half of that loop: ground the agent so the PR Greptile sees is already aimed at the right files.</p>\n<p>Greptile’s marketing materials lead with review-speed and bug-catch claims. Treat those as Greptile’s own claims, not independently verified numbers. This draft does not repeat them as facts.</p>\n<p>Language coverage is the same kind of honesty. Greptile frames support as covering all programming languages rather than an enumerated list; a precise count is not stated. Maguyva publishes 279+ languages and text-based technologies, with a technical split (parser-backed AST versus text-only) on the site when the question is technical. Those are different products making different claims. Do not blend them.</p>\n<p>Pricing for Greptile is not stated in the notes this draft is allowed to use. Paid plans exist; see their pricing page. Maguyva bills per workspace, not per seat. Plans start free. The <a href=\"https://maguyva.ai/pricing\">pricing page</a> lists the published tiers if you need the workspace numbers.</p>\n<h2 id=\"workflow\">Workflow</h2>\n<p>Three named stages. Run them in this order. Skip none of them the first time you try the pairing.</p>\n<h3 id=\"1-maguyva-context\">1. Maguyva context</h3>\n<p>Index one repository you already know. Connect the MCP client you already write in — Claude Code, Cursor, Codex CLI, VS Code, Windsurf, or another MCP-compatible client. Maguyva has setup guides for 24 documented MCP clients and can connect to other clients that support standard MCP configuration.</p>\n<p>Ask a question you can grade before anyone writes a line. “Where is session expiry handled, and what calls it?” is a better first move than “fix auth.” Demand citations. Open the <code>file.ext:line</code> results. Follow the symbol. Confirm the dependency you are about to touch.</p>\n<p>Maguyva exposes 11 customer-facing MCP tools across search, symbols, dependency analysis, file retrieval, repository context, and deterministic utility workflows. Four retrieval modes are fused into ranked results; <code>find_symbol</code> is a separate tool when you already know the name. The <a href=\"https://maguyva.ai/docs\">docs</a> describe the shortest path: start free, index a repo you already know, connect the client, then ask one question you can verify.</p>\n<p>Snapshots are timestamped, so the agent can tell which version of the tree it is reading. The honest limit is un-synced local work. If the edit exists only in a working tree and has not been pushed, the hosted map does not contain it yet. Instruction files (<code>CLAUDE.md</code>, <code>AGENTS.md</code>) still belong here for conventions and what not to touch. They are not a live map. Use them for behavior. Use Maguyva for facts.</p>\n<p>Do not let the agent open a PR until the citations survive contact with the repo. That gate is the whole point of this stage.</p>\n<h3 id=\"2-agent-pr\">2. Agent PR</h3>\n<p>The same agent now writes the change in the client you already pay for. Maguyva is not an editor and not a reviewer. The agent still produces the diff. You still open the pull request on GitHub or GitLab the way you already do.</p>\n<p>What should be different is the first file. The PR should name the handler that actually implements the behavior, the caller that will break, and the test that will fail if the change is wrong. If stage 1 was skipped, stage 3 will spend its comments on a change that landed in the wrong package. Greptile can still find systemic issues. It should not have to also recover from a hallucinated path.</p>\n<p>Keep the PR scoped. A grounded first file is not a license to rewrite the module. The complementary pairing works when the agent did one job with a map, then asked a reviewer to do a different job on a bounded diff.</p>\n<h3 id=\"3-greptile-review\">3. Greptile review</h3>\n<p>Greptile is already connected to the repository through the GitHub or GitLab app. On the new pull request it analyzes the change using the full-repo graph it built and posts findings as comments with suggested fixes. Their own materials put that pass at about three minutes.</p>\n<p>Read the comments the way you would read a careful teammate: open the cited location, decide whether the finding is real, then act. Where Greptile offers “Fix with your Agent,” it sends the issue — file paths, line numbers, suggested code — to Claude Code, Codex, Conductor, Cursor, or Devin. “Fix All” sends every issue in the review at once. They also ship a Greptile MCP and a Claude Code plugin for that hand-off. Maguyva is not on that named target list; that absence is not a problem. Maguyva already did its work in stage 1. The coding agent that wrote the PR is the one that should receive the fix payload.</p>\n<p>Expect noise for the first 2–3 weeks while Greptile’s learning system adapts to the comments your team actually leaves. That is their stated timeline, not a defect in the pairing. Human review stays in the loop. Greptile is the automated first pass, not the merge button.</p>\n<p>If a Greptile comment points at a file the agent never queried in stage 1, that is useful signal. Either the map missed a caller, or the agent skipped a citation. Fix the draft against the comment. Do not disable the reviewer.</p>\n<h2 id=\"how-to-keep-the-complement-honest\">How to keep the complement honest</h2>\n<ul>\n<li>Maguyva first, always. A review of a wrong-file PR is still a review of the wrong file.</li>\n<li>Greptile second, always. A well-cited draft still needs a whole-system read of the diff.</li>\n<li>Do not ask Maguyva to post PR comments. It does not.</li>\n<li>Do not ask Greptile to be the agent’s first retrieval layer while it is still choosing a path. That is not the job their GitHub or GitLab app is wired to do.</li>\n<li>Do not invent a bash pipeline that “syncs” them. The PR is the interface.</li>\n<li>Verify both sides independently. Index one repo you already know. Ask one question you can verify. Then open a small PR and read what Greptile actually comments.</li>\n</ul>\n<p>The loop is ordinary once it is named. Map first. Agent PR. Review second. Each product stays on the side of the pull request it is good at.</p>\n<p><code>// map first. review second. in that order.</code></p>\n",
      "date_published": "2026-09-07T00:00:00.000Z",
      "tags": [
        "Ecosystem",
        "Workflow",
        "Code Review"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/large-repo-context-without-a-local-indexer",
      "url": "https://maguyva.ai/blog/large-repo-context-without-a-local-indexer",
      "title": "Give an AI agent context of a large repo without a local indexer",
      "summary": "How to give a coding agent a queryable map of a large repository from the cloud, without running a local indexer on your laptop.",
      "content_html": "<p>A large repository doesn’t fit in a context window, and if you’ve ever pointed a laptop indexer at a real monorepo you know it doesn’t fit comfortably there either — the RAM spikes, the first index takes an hour, and your agent still starts the next session guessing which files matter.</p>\n<p>The usual answer is to run an indexer next to the editor, and for a repo that fits comfortably on one machine, it’s a good one. If your monorepo already indexes fast in Cursor and that’s the only place you need the map, this post has nothing to add — skip it.</p>\n<p>This post is about the other case — when you need an agent to have a queryable map of a large repo, and you don’t want to run a local indexer to get it.</p>\n<h2 id=\"when-a-local-indexer-is-the-wrong-tool\">When a local indexer is the wrong tool</h2>\n<p>A local index assumes the code lives on the machine that will query it, and at real monorepo scale that assumption strains even inside a single editor. The repo is simply bigger than you want to keep warm on a laptop: you work in one package while the blast radius lives three directories over, and a cold first index of a two-million-line tree is not something you want to sit through twice — on your machine, or on a CI runner that never cloned the tree before. Or a teammate should be querying the same map you are, without waiting for their own machine to grind through the same index first.</p>\n<p>None of that is a reason to throw away a good editor indexer. It’s a reason to also have a hosted map that any of your agents can query over MCP.</p>\n<p>And the scale problem runs deeper than “too many files to paste.” On a large tree, the interesting question is almost never “show me this file” — it’s which file, which symbol, which callers, which tests. An agent that starts by listing <code>src/</code> and reading the first three hits will happily miss the handler in <code>apps/api</code> and the generated client in <code>packages/sdk</code>. What you need is retrieval that was built from the whole tree, then ranked, then cited.</p>\n<h2 id=\"what-context-of-a-large-repo-actually-means\">What “context of a large repo” actually means</h2>\n<p>Dumping files into the prompt isn’t context — it’s a smaller, worse copy of the tree. What your agent actually needs is to ask questions and get cited answers back: where is this symbol defined and who calls it, what depends on the module I’m about to change, which test file covers this behavior, and what does the tree look like <em>now</em>, not last quarter.</p>\n<p>Those answers have to come from an index built from your repo rather than from the model’s memory of other people’s repos, and the index has to live somewhere other than the agent’s context window. For this problem, it should also live somewhere other than your laptop.</p>\n<p>One more thing instruction files can’t do for you: <code>CLAUDE.md</code> and <code>AGENTS.md</code> are the right place for conventions and behavior, but they are not a live, ranked, queryable map of a two-million-line tree. Use rules for behavior; use repo intelligence for facts.</p>\n<h2 id=\"build-the-map-in-the-cloud-query-it-from-any-client\">Build the map in the cloud, query it from any client</h2>\n<p>Maguyva is a remote MCP codebase context layer. You connect GitHub, pick your repositories, and walk away while cloud pipelines parse the tree, build the symbols and graph edges, and keep a ranked map — no local indexer, ever.</p>\n<p>When you push code, changed files are parsed incrementally, and the graph and ranking layers rebuild on a schedule: daily on the free plan, hourly on paid ones. Every snapshot is timestamped, so your agent can tell which version of the tree it’s reading. The honest limit here is un-synced local work — an edit that exists only in your working tree, never pushed, isn’t in the hosted map yet.</p>\n<p>Then you wire up whichever client you already use by adding an API key to its MCP config. There are setup guides for 24 documented MCP clients, and any other MCP-compatible client that supports standard configuration can connect too. If Cursor is where you live, the <a href=\"https://maguyva.ai/for-cursor\">Cursor page</a> walks that path; the same server answers Claude Code, VS Code, Windsurf, Codex CLI, and the rest.</p>\n<p>You don’t switch editors. You give your agent a tool surface — 11 MCP tools across search, symbols, dependency analysis, file retrieval, and repository context — with coverage across 279+ languages and text-based technologies, which matters more than you’d think on a monorepo that stopped being one language years ago.</p>\n<p>Answers come back grounded, as file paths with line numbers. Semantic, structural, graph, and text retrieval are fused into ranked results, so a question like “what depends on parseConfig” gets you neither a grep dump nor a single semantic chunk, but the handful of locations that actually matter.</p>\n<h2 id=\"a-concrete-how-to\">A concrete how-to</h2>\n<p>Don’t start by indexing the whole company. Here’s the path that works:</p>\n<ol>\n<li>Pick one repository you already know well — a package you can grade by hand beats the largest tree you have.</li>\n<li>Start free: 3 repos, 50k indexed lines, all 11 tools, no monthly query quota. If your representative repo is bigger than that, the <a href=\"https://maguyva.ai/pricing\">pricing page</a> lists the workspace tiers ($0, $19, $49, $149) by indexed footprint — not by seat count.</li>\n<li>Connect GitHub and wait for the first index to finish. You’re not compiling anything locally.</li>\n<li>Wire the MCP client — a few lines of config. Maguyva is a remote MCP server, so there are no plugins, no extensions, and no second editor to adopt.</li>\n<li>Ask one question you can verify. “What depends on parseConfig?” or “Where is login session expiry handled?” Then open the cited <code>file.ext:line</code> results and check them against the tree in front of you.</li>\n<li>Only after the citations survive that contact do you let the agent edit.</li>\n</ol>\n<p>If the first repo is a good fit and your tree is large, raise the workspace to match your indexed lines and rebuild cadence. Humans and agents share the same user count — Maguyva bills per workspace, not per seat — so adding a third agent to the loop costs you nothing.</p>\n<p>The activation test is the same one the <a href=\"https://maguyva.ai/docs\">docs</a> recommend for any first run: index one repo you already know, ask one question you can verify. A large repo doesn’t change the test; it only makes a wrong first file more expensive.</p>\n<h2 id=\"what-to-watch-after-its-wired\">What to watch after it’s wired</h2>\n<p>Keep an eye on three things. Freshness: paid plans rebuild hourly, free rebuilds daily, and un-pushed local work will not be in the map — that’s the trade you’re making. Scope: index a representative set of repos, not every archived fork; the free tier is deliberately sized for finding out whether the answers are worth keeping. And verification: a large-repo map that can’t cite paths and line numbers is just a slower guessing engine, so make your agent show you the location before it ships the patch.</p>\n<p>Then run the same test you’d run on a small repo. Index one repo you already know. Ask one question you can verify. If the map is real, your agent stops starting from a cold tree.</p>\n<p><code>// no laptop got hot building this map.</code></p>\n",
      "date_published": "2026-08-14T00:00:00.000Z",
      "tags": [
        "AI Agents",
        "MCP",
        "Indexing",
        "Monorepos"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/why-ai-coding-agents-hallucinate-file-paths",
      "url": "https://maguyva.ai/blog/why-ai-coding-agents-hallucinate-file-paths",
      "title": "Why your AI coding agent hallucinates file paths",
      "summary": "AI coding agents invent file paths when they have no real map of the repo. Here is why it happens, and how grounding leads to fewer hallucinated edits.",
      "content_html": "<p>The tell is not a wrong function body. It is a confident edit to a file that does not exist, or to a file that exists but is not the one that implements the behavior.</p>\n<p>You asked for a session-expiry fix. The agent opened <code>src/auth/session.ts</code>. That path is plausible. It is also wrong. The real handler lives in <code>apps/api/src/middleware/expiry.ts</code>, renamed two refactors ago. The agent did not lie to you. It completed a path-shaped string from training priors plus whatever was already in the context window.</p>\n<p>This is the common failure mode on a real repository. The model can write code. The miss is choosing the wrong place to write it.</p>\n<h2 id=\"why-agents-invent-paths\">Why agents invent paths</h2>\n<p>A coding agent is a next-token model with tools. When you say “fix session expiry”, it has to name a file before it can read or patch anything. If it does not already have a grounded map, it constructs a path from:</p>\n<ol>\n<li>Naming conventions it has seen in other repositories. <code>src/auth/session.ts</code> is a frequent shape.</li>\n<li>Files already in the conversation, which may be the ones you pasted last week, not the ones that matter now.</li>\n<li>Directory listings it happened to run, which are incomplete on a large tree.</li>\n<li>Instruction files. <code>CLAUDE.md</code> and <code>AGENTS.md</code> tell the agent how to behave. They are not a live index of symbols, callers, or current paths.</li>\n</ol>\n<p>None of those sources is a map of this repo, today. The model fills the gap the way it fills any gap: with a high-probability continuation. That continuation often looks like a real path. Sometimes the file exists and is adjacent to the right one. Sometimes it existed on a branch that merged last month. Sometimes it never existed.</p>\n<p>Grep does not save you here if the agent never searches for the right string. The agent guessed a path, then read whatever that path returned, then edited it. The first wrong step was the path, not the patch.</p>\n<p>Reading files is also not the same as finding the right ones. Claude Code, Cursor, Codex, and similar tools can open whatever you point them at. The question is whether they reliably find the right files, the important symbols, the dependencies, the tests, and the blast radius before they edit. File access without a map still starts with a guess.</p>\n<h2 id=\"the-wrong-file-edit-is-a-retrieval-problem\">The wrong-file edit is a retrieval problem</h2>\n<p>Treat the invented path as a retrieval miss, not a personality flaw.</p>\n<p>If the agent had to return <code>path/file.ext:line</code> before it was allowed to edit, two things would happen. First, you could open the citation and reject the work in ten seconds. Second, the agent would have to query something that actually knows the tree.</p>\n<p>That is the job of a codebase context layer. Semantic search alone is not enough. A chunk that “sounds like session expiry” can still land in a deprecated package. You also need exact text when you know the string, symbol lookup when you know the name, structural search when you know the shape, and a dependency graph when you need callers and blast radius.</p>\n<p>Maguyva is that layer for MCP-compatible coding agents. It is not an editor. Claude Code, Cursor, Codex CLI, VS Code, Windsurf, and other MCP clients stay where they are. The agent queries a ranked map before it touches a line.</p>\n<p>The claim is modest on purpose: fewer hallucinated edits. Maguyva does not remove the model’s ability to guess. It changes the default first step from “invent a plausible path” to “ask for ranked, cited locations.”</p>\n<h2 id=\"what-a-grounded-answer-looks-like\">What a grounded answer looks like</h2>\n<p>A useful answer to “where is session expiry handled” is not a paragraph. It is a short list of locations:</p>\n<ul>\n<li><code>apps/api/src/middleware/expiry.ts:48</code> - the handler</li>\n<li><code>apps/web/src/lib/auth-client.ts:112</code> - the caller</li>\n<li><code>apps/api/tests/expiry.test.ts:20</code> - the test that will fail if the change is wrong</li>\n</ul>\n<p>You can open those lines. If they are wrong, you stop. If they are right, the agent may edit. The verification is the point, not a slogan.</p>\n<p>Maguyva exposes 11 customer-facing MCP tools across search, symbols, dependency analysis, file retrieval, repository context, and deterministic utility workflows. Four retrieval modes (semantic, structural, graph/dependency, and text) are fused into ranked results; symbol lookup is a separate MCP tool (<code>find_symbol</code>). Grounded answers come back with file paths and line numbers so you can grade them against the tree in front of you.</p>\n<p>The <a href=\"https://maguyva.ai/docs\">docs</a> describe the shortest path: start free, index a repo you already know, connect the client, then ask one question you can verify.</p>\n<h2 id=\"a-loop-that-changes-the-first-edit\">A loop that changes the first edit</h2>\n<p>You do not need a new workflow religion. You need one extra step before the first write.</p>\n<ol>\n<li>Ask a question you can already grade. “What code handles login and session expiry?” is better than “fix auth.”</li>\n<li>Demand citations. File path and line number, not a summary of “the auth module.”</li>\n<li>Open the cited files. Follow the symbol. Confirm the dependency you are about to break.</li>\n<li>Only then let the agent patch.</li>\n</ol>\n<p>If step 2 returns nothing useful, the agent does not get to improvise a path. It searches again, or you point it. That single gate is what produces fewer hallucinated edits. The model is the same model. The map is what changed.</p>\n<p>Instruction files still matter. Keep them. Use them for conventions, review rules, and what not to touch. Do not ask them to be the index. A <code>CLAUDE.md</code> that lists three important directories will be stale the week after a package split. A queryable map updates when the repo updates.</p>\n<p>A related failure is the near-miss file: the agent opens <code>auth.ts</code> when the behavior lives in <code>auth-client.ts</code>, or patches a generated file instead of the source, or edits the copy in <code>packages/legacy</code> because the name matched. Citations do not make those mistakes impossible. They make them visible before the diff lands.</p>\n<h2 id=\"what-a-map-wont-fix-for-you\">What a map won’t fix for you</h2>\n<p>Be clear-eyed about what you’re getting. A grounded map won’t make every edit correct — your agent can still write a bad patch in exactly the right file. If your codebase leans on dynamic dispatch, reflection, or monkey-patching, some symbol lookups will come back thinner than you’d like, because that’s what runtime indirection does to any static index. And if you’re hoping for a percentage — “hallucinated paths down by X%” — you won’t find one here, because nobody can honestly measure that number for your repo but you.</p>\n<p>What you can expect is narrower and more useful: the agent stops opening its edits with a guessed path. That first step gets grounded in a real map, and that is where fewer hallucinated edits comes from. Everything after the citation — reading the diff, judging the patch — is still your job, the same as it ever was.</p>\n<p>The test costs you almost nothing: index one repo you already know and ask one question you can verify. Start with a path you have been burned by. If the citations are wrong, you’ll see it immediately. If they are right, your agent’s next edit has a better place to land.</p>\n<p><code>// it doesn't know the file. it knows how to find it.</code></p>\n",
      "date_published": "2026-08-14T00:00:00.000Z",
      "tags": [
        "AI Agents",
        "Hallucination",
        "Retrieval",
        "MCP"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/upgrading-code-search-to-voyage-4-large",
      "url": "https://maguyva.ai/blog/upgrading-code-search-to-voyage-4-large",
      "title": "Why We Upgraded Code Search to voyage-4-large",
      "summary": "We moved our code embeddings to voyage-4-large — currently top of the public RTEB code retrieval leaderboard. The honest version: the trade we make, what we actually index, and why we pay for premium embeddings.",
      "content_html": "<blockquote>\n<p><em>Benchmark numbers in this post reflect the RTEB leaderboards at publication (June 2026). Leaderboards move; treat the rankings as a snapshot, not a permanent fact.</em></p>\n</blockquote>\n<p>Semantic search is only as good as the embeddings underneath it.</p>\n<p>When an agent asks Maguyva “where do we handle retries,” it is not grepping for the word “retry.” It is asking for the <em>meaning</em> — the backoff loop, the circuit breaker, the thing that wraps a flaky call. That question gets answered by a vector model that turns code into a point in space and finds the neighbors. Pick a better model and every semantic query in the product gets quietly sharper.</p>\n<p>So we changed ours. As of June 2026, Maguyva’s code embeddings run on <strong><code>voyage-4-large</code></strong>, replacing <code>voyage-code-3</code>.</p>\n<h2 id=\"the-benchmark\">The Benchmark</h2>\n<p>We did not make this call on vibes. The public <a href=\"https://embedding-benchmark-rteb.hf.space/code\">Retrieval Embedding Benchmark (RTEB)</a> ranks embedding models on real retrieval tasks, and on its <strong>Code</strong> leaderboard <code>voyage-4-large</code> sits at <strong>#1 overall (90.86)</strong> — ahead of <code>gemini-embedding-2-preview</code> (90.26) and, notably, ahead of the model we were already using, <code>voyage-code-3</code> (89.73, #3).</p>\n<p>That is a small absolute gap. But it is a gap in the right direction, on a public benchmark, on the exact task we care about: retrieving code by meaning.</p>\n<h2 id=\"the-trade-we-accept-binary-quantization\">The Trade We Accept: Binary Quantization</h2>\n<p>Here is the part most “we upgraded our model” posts leave out.</p>\n<p>Maguyva does not store full-precision vectors. We store <strong>binary-quantized</strong> embeddings: each 2048-dimensional vector collapses to a 2048-bit signature — <strong>256 bytes per vector</strong>. Those signatures are searched with Hamming distance, indexed and partitioned per tenant.</p>\n<p>That is a deliberate trade. Binary quantization gives up some retrieval precision in exchange for dramatically smaller storage and fast, cheap distance math with no separate vector database to operate. For a product that indexes whole repositories per workspace, that economics matters more than squeezing out the last fraction of a benchmark point.</p>\n<p><code>voyage-4-large</code> fits this design without forcing a migration of the storage layer: it produces 2048-dimensional output, same as <code>voyage-code-3</code>, so our <code>bit(2048)</code> columns and Hamming search path did not change. The model got better; the schema stayed put.</p>\n<h2 id=\"code-was-just-the-start\">Code Was Just the Start</h2>\n<p>Maguyva is a code-intelligence tool. But we’re also customer zero, and we point it at something else: the markdown that lives in our repos alongside the code. Architecture decision records, runbooks, contracts, finance and policy docs — all of it version-controlled in Git, all of it behind the same MCP server, a semantic index over the <em>documents</em>, not just the source.</p>\n<p>That is exactly why voyage-4-large’s breadth matters. On the same RTEB family of leaderboards it is <strong>#1 on finance, #1 on healthcare, and #1 on overall text retrieval</strong> — ahead of Google’s Gemini Embedding, Cohere’s Embed v4, and OpenAI’s text-embedding-3-large. (Voyage is a co-creator of RTEB, so we read it as a strong public signal rather than a perfectly neutral referee — but it is benchmarked head-to-head against every major commercial model, on private hold-out sets.) The same index that finds the right function for an agent finds the right clause in a contract or the right line in a policy — and on those domains, voyage-4-large isn’t a compromise, it’s the leader.</p>\n<h2 id=\"why-we-pay-for-premium-embeddings\">Why We Pay for Premium Embeddings</h2>\n<p>There’s a cheaper way to do search, and a lot of it is free. Lexical search — BM25 and its kin — matches keywords, runs locally, and costs nothing. Open-source embedding models like BGE, Nomic, and embeddinggemma give genuinely <em>decent</em> semantic retrieval, and you can self-host them for the price of a GPU. Maguyva uses the free side too: every query fuses text, AST, graph, and semantic search. What we don’t cheap out on is the semantic layer.</p>\n<p>We pay per token for premium embeddings — <code>voyage-4-large</code> — instead of self-hosting a free model, for two reasons. First, keyword search alone can’t answer “where do we handle retries” when the code says <code>backoff</code> and <code>circuit breaker</code> and never says the word “retry” — meaning is the whole point of the embedding, and on the domains we serve the open models trail the premium ones: a couple of points behind on general text, and further behind in niches like code, contracts, and finance. Second, in our experience retrieval quality shapes the final answer more than the model on the other end does — a strong agent handed the wrong context still answers wrong, and it never sees the document it was never given.</p>\n<p>So premium embeddings are a per-token bill that scales with every repo and document we index — and we pay it on purpose. For the outcome our users get, the right function or the right clause, we think that trade is worth it.</p>\n<h2 id=\"the-honest-part\">The Honest Part</h2>\n<p>Voyage’s own documentation still labels <code>voyage-code-3</code> as the code-optimized model. So why move?</p>\n<p>Because we read the public benchmark, not just the vendor’s model table, and the benchmark put <code>voyage-4-large</code> on top for code retrieval. This was a forward-looking call: take the newer, generally stronger model and validate it against a public leaderboard on the tasks that matter. We’re comfortable making that bet because the evidence is broad — voyage-4-large doesn’t just win on code, it leads on finance, healthcare, and overall retrieval too.</p>\n<h2 id=\"the-quiet-floor\">The Quiet Floor</h2>\n<p>Every tool we expose — semantic search, task-context gathering, grounded Q&amp;A — bottoms out in retrieval. When the retriever improves, the agent on the other end gets better evidence, makes fewer wrong turns, and grounds its answers in the right code — or the right clause, or the right policy. A sharper embedding model is not a flashy feature. It is the floor under everything else, and we just raised it. You won’t notice. That’s the point.</p>\n",
      "date_published": "2026-06-09T00:00:00.000Z",
      "tags": [
        "Embeddings",
        "Search",
        "Architecture"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/autonomous-quality-loops-language-grind",
      "url": "https://maguyva.ai/blog/autonomous-quality-loops-language-grind",
      "title": "Language Recursive Self-Improvement: Grinding Code Intelligence Across ~280 Languages",
      "summary": "We support code intelligence for ~280 languages. No human can hand-audit that. So we built a language recursive self-improvement loop — spot-check, LLM-as-judge, fix one thing, re-validate — and run it with a fleet of isolated agents until extraction is actually right, not just green.",
      "content_html": "<blockquote>\n<p><em>Numbers in this post reflect the system at publication (May 2026). See our <a href=\"https://maguyva.ai/team\">team page</a> for current figures.</em></p>\n</blockquote>\n<p>Maguyva extracts symbols, references, and a dependency graph from source code in roughly 280 languages. Each language is a custom tree-sitter handler — queries, heuristics, edge cases — and every handler can be subtly wrong in its own way. A method call emitted as a read. A function attributed to the wrong enclosing scope. A relationship that simply isn’t there.</p>\n<p>You cannot hand-audit that. No team can read extraction output across 280 grammars and spot the bad edges. So the interesting question isn’t “is our extraction correct” — it’s “how do you <em>find out</em> that it’s wrong, at this breadth, without a human in every loop.” Our answer is language recursive self-improvement: a quality loop driven by language agents, an LLM acting as judge, and one rule we keep relearning: green is not the same as correct.</p>\n<h2 id=\"green-is-not-correct\">Green is not correct</h2>\n<p>Every language has a fixture suite, and a release gate scores it across five dimensions — accuracy, structural integrity, completeness, quality, and performance. A language goes <strong>GREEN</strong> only when, on its fixtures, precision ≥ 0.95, recall ≥ 0.99, and F1 ≥ 0.97, with at least 20 expected edges for statistical confidence. Below that it’s YELLOW or RED, and it doesn’t ship.</p>\n<p>That gate is necessary and not sufficient. Fixtures validate against fixtures <em>we wrote</em>. They encode the cases we already thought of. A handler can be flawless on its fixtures and still mangle a pattern that only shows up in real code — a macro idiom, a generic-bound method, a language feature nobody wrote a fixture for. GREEN means the fixtures pass. It does not mean a real repository extracts cleanly. So the loop has to leave the fixtures behind and look at the wild.</p>\n<h2 id=\"the-inner-loop-spot-check-judge-fix-prove\">The inner loop: spot-check, judge, fix, prove</h2>\n<p>The core loop runs one language at a time:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"text\"><code><span class=\"line\"><span>        ┌──────────────────────────────────────────────────────────┐</span></span>\n<span class=\"line\"><span>        │                                                          │</span></span>\n<span class=\"line\"><span>        ▼                                                          │</span></span>\n<span class=\"line\"><span>  1. corpus run ── clone real-world repos, extract relationships   │</span></span>\n<span class=\"line\"><span>        │                                                          │</span></span>\n<span class=\"line\"><span>        ▼                                                          │</span></span>\n<span class=\"line\"><span>  2. spot-check 100 edges (seed 42, then seed 123 to cross-check)  │</span></span>\n<span class=\"line\"><span>        │                                                          │</span></span>\n<span class=\"line\"><span>        ▼                                                          │</span></span>\n<span class=\"line\"><span>  3. LLM judge classifies every sampled edge:                      │</span></span>\n<span class=\"line\"><span>        CORRECT · FALSE_POSITIVE · TYPE_ERROR ·                    │</span></span>\n<span class=\"line\"><span>        SCOPE_ERROR · METADATA_ERROR                               │</span></span>\n<span class=\"line\"><span>        │                                                          │</span></span>\n<span class=\"line\"><span>        ▼                                                          │</span></span>\n<span class=\"line\"><span>  4. fix ONE thing — handler .py, .scm query, or config           │</span></span>\n<span class=\"line\"><span>        │                                                          │</span></span>\n<span class=\"line\"><span>        ▼                                                          │</span></span>\n<span class=\"line\"><span>  5. re-validate — F1 + re-classify + manifest diff (no regressions)│</span></span>\n<span class=\"line\"><span>        │                                                          │</span></span>\n<span class=\"line\"><span>   better? ──no──► revert, try a different fix ────────────────────┤</span></span>\n<span class=\"line\"><span>        │ yes                                                       │</span></span>\n<span class=\"line\"><span>        ▼                                                           │</span></span>\n<span class=\"line\"><span>  6. promote the fix into fixtures (a permanent regression guard) ──┘</span></span></code></pre>\n<p>A few things make this work rather than thrash.</p>\n<p><strong>The judge is the agent, not an API call.</strong> When we say “LLM-as-judge,” we mean the language agent itself reads each sampled edge against the real source and classifies it with a fixed five-category rubric: is this edge correct, a false positive, the right relationship with the wrong type, attached to the wrong scope, or carrying wrong metadata? That rubric is the whole game — “23% error rate” is meaningless until you know whether those are real defects or the judge miscounting.</p>\n<p><strong>Fix one thing, then prove it.</strong> Each iteration changes exactly one editable asset, then re-runs against a fixed harness and keeps the change only if F1 improves and the re-classification looks better. If it doesn’t, it reverts. No batch of speculative edits, no “should be better.” A change earns its place or it’s gone. And when a fix sticks, it’s promoted into the fixture suite — so the bug it fixed can never silently come back. That promotion step is what makes the loop <em>recursive</em> rather than merely repetitive: every pass hardens the oracle the next pass validates against.</p>\n<h2 id=\"the-lesson-we-keep-relearning-metrics-over-report\">The lesson we keep relearning: metrics over-report</h2>\n<p>Here’s the trap, and we walked straight into it. The secondary corpus metrics — how often an extracted target has no resolvable symbol, how many symbols look “orphaned,” and so on — massively over-report problems. They are mostly <em>paradigm artifacts</em>, not bugs.</p>\n<p>The cleanest example: <code>llvm</code> once showed a 73% “source-without-symbol” rate and got branded catastrophic. We dug in. Real accuracy was <strong>98.5%</strong>. The “missing symbols” were almost all legitimate external references — calls into the standard library, into frameworks, into code that lives outside the repo. The metric was measuring a property of the language, not a defect in the handler. Languages like Zig, COBOL, and Odin show 65–70% “orphan” rates and are entirely correct; COBOL had zero real errors.</p>\n<p>If we had let those numbers drive the work, we’d have spent weeks “fixing” handlers that were already right and ignoring the languages with quiet, real bugs. The conclusion is blunt: the aggregate metrics are a rough triage signal at best. <strong>The real quality signal is the spot-check with edge classification</strong> — looking at actual edges in actual repositories and judging them one by one. Data over intuition, but only once you know which data is telling the truth.</p>\n<h2 id=\"the-outer-loop-a-fleet-not-a-marathon\">The outer loop: a fleet, not a marathon</h2>\n<p>One language at a time would take forever across 280 of them, so the inner loop is wrapped in an outer one that runs many in parallel.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"text\"><code><span class=\"line\"><span>   pick a wave of near-GREEN / high-error languages</span></span>\n<span class=\"line\"><span>        │</span></span>\n<span class=\"line\"><span>        ▼</span></span>\n<span class=\"line\"><span>   fan out 10–15 agents, each ISOLATED in its own git worktree,</span></span>\n<span class=\"line\"><span>   each grinding ONE language, committing to its own branch</span></span>\n<span class=\"line\"><span>        │</span></span>\n<span class=\"line\"><span>        ▼</span></span>\n<span class=\"line\"><span>   orchestrator integrates serially: file-scoped apply, then</span></span>\n<span class=\"line\"><span>   `manifest diff` — any cross-language regression blocks the batch</span></span>\n<span class=\"line\"><span>        │</span></span>\n<span class=\"line\"><span>        ▼</span></span>\n<span class=\"line\"><span>   gated push (reviewed and confirmed) ──► rotate to the next wave</span></span></code></pre>\n<p>Each agent works in a throwaway worktree so they can’t step on each other. The orchestrator integrates their fixes one at a time, each behind a full-manifest regression check: a change that helps its own language but quietly breaks three others doesn’t land. Integration is gated and confirmed before anything is pushed — the regression gate decides what’s <em>safe</em>, a human still decides what <em>ships</em>. Then the pool rotates to the next set of languages and the whole thing runs again.</p>\n<h2 id=\"whats-still-imperfect\">What’s still imperfect</h2>\n<p>The judge can be wrong, and wrongness has a direction: an agent running with too little context <em>over-reports</em>. In one batch, eight languages were flagged at 5–20% error; on inspection only one was a real per-language bug — the rest were judge mistakes from missing the language’s own semantics (one source line legitimately emitting several edges, parameter bindings modeled as assignments, reference-per-identifier languages). That’s why we sample with two seeds and cross-check, and why a disagreement between the judge and the fixtures is treated as the <em>most</em> interesting signal, not a settled verdict — sometimes the fixture is the thing that’s wrong.</p>\n<p>We’re also honest about the target. The goal is zero real errors, full stop — but “zero” is a direction we grind toward, language by language, not a box that’s checked. There is always another repo with another idiom.</p>\n<h2 id=\"earned-not-asserted\">Earned, Not Asserted</h2>\n<p>Everything Maguyva does for an agent — finding a symbol, tracing a dependency, answering a question with cited code — rests on the extraction underneath being right. Across 280 languages, “right” can’t be asserted; it has to be continuously <em>earned</em> against real code. The loop is how we earn it: an autonomous spot-check-and-fix cycle that treats its own metrics with suspicion, proves every change, and turns each fix into a guard against the next regression. It’s not glamorous. It’s the work that lets us say “we support your language” and mean it. Green is easy. Correct is earned.</p>\n",
      "date_published": "2026-05-26T00:00:00.000Z",
      "tags": [
        "Architecture",
        "Languages",
        "Agents"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/multi-modal-fusion-search",
      "url": "https://maguyva.ai/blog/multi-modal-fusion-search",
      "title": "Multi-Modal Fusion Search: Picking the Right Retriever For Every Query",
      "summary": "A query like 'where is parseConfig defined' wants a different search than 'how does auth work'. Maguyva classifies the intent, weights four retrieval modalities accordingly, and fuses the results with weighted Reciprocal Rank Fusion.",
      "content_html": "<blockquote>\n<p>Historical design note: this April 2026 article describes the routing design at that time, not the current default behavior. The September correction below addresses a measurement claim only. For current routing, presets, and explicit modality controls, see <a href=\"https://maguyva.ai/docs/how-it-works\">How It Works</a>.</p>\n</blockquote>\n<p>A search query is not one thing.</p>\n<p>“where is <code>parseConfig</code> defined” wants an exact symbol — one precise location, fast. “how does authentication work” wants meaning — the spread of related code that explains a concept. “what breaks if I change this function” wants the dependency graph. “find the string <code>ECONNREFUSED</code>” wants a literal match, nothing clever.</p>\n<p>Grep is excellent for literal matches and useful for some reference hunts, but it is not a dependency graph and it does not understand meaning. Embeddings cover the semantic side, but they are the wrong tool for exact strings and impact analysis. Most code search tools pick one engine and make every query live with that choice. Maguyva doesn’t pick. It works out what kind of question you asked, then blends four retrievers in the proportion that question deserves.</p>\n<h2 id=\"four-modalities\">Four modalities</h2>\n<p>Under the hood there are four independent ways to find code:</p>\n<ul>\n<li><strong>semantic</strong> — vector search over Voyage binary embeddings; finds code by meaning.</li>\n<li><strong>text</strong> — trigram matching; finds literals, error strings, exact identifiers.</li>\n<li><strong>structural</strong> — AST queries; finds definitions, signatures, and language constructs.</li>\n<li><strong>graph</strong> — the dependency graph; finds callers, callees, and blast radius.</li>\n</ul>\n<p>Each is strong on a different class of question. The trick is deciding how much to trust each one for the query in front of you.</p>\n<h2 id=\"intent-classification\">Intent classification</h2>\n<p>Before any retrieval runs, a lightweight classifier sorts the query into one of six intents, with a confidence score. It’s deliberately cheap — ordered heuristics, first match wins — because it runs on the hot path and adds only a millisecond or two:</p>\n<ul>\n<li>starts with <code>def </code>, <code>class </code>, <code>func </code>, <code>import </code>… → <strong>find_definition</strong> (confidence 0.95)</li>\n<li>“who calls”, “usages of”, “references to” → <strong>find_references</strong> (0.90)</li>\n<li>“impact”, “blast radius”, “what depends on” → <strong>impact_analysis</strong> (0.90)</li>\n<li>a quoted <code>\"string\"</code> or an error token like <code>traceback</code> → <strong>exact_match</strong> (0.85–0.90)</li>\n<li>a <code>CamelCase</code> or <code>snake_case</code> identifier → <strong>find_definition</strong> (0.60–0.80)</li>\n<li>“how”, “why”, “explain”, “architecture” → <strong>understand_code</strong> (0.75)</li>\n<li>nothing matches → <strong>understand_code</strong>, low confidence (0.40)</li>\n</ul>\n<p>Each intent carries a weight profile across the four modalities. These are the real numbers:</p>\n<table>\n<thead>\n<tr>\n<th>Intent</th>\n<th>semantic</th>\n<th>text</th>\n<th>structural (AST)</th>\n<th>graph</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>find_definition</td>\n<td>0.2</td>\n<td>0.1</td>\n<td><strong>0.6</strong></td>\n<td>0.1</td>\n</tr>\n<tr>\n<td>find_references</td>\n<td>0.1</td>\n<td>0.2</td>\n<td>0.2</td>\n<td><strong>0.5</strong></td>\n</tr>\n<tr>\n<td>understand_code</td>\n<td><strong>0.5</strong></td>\n<td>0.2</td>\n<td>0.2</td>\n<td>0.1</td>\n</tr>\n<tr>\n<td>find_similar</td>\n<td><strong>0.4</strong></td>\n<td>0.3</td>\n<td>0.2</td>\n<td>0.1</td>\n</tr>\n<tr>\n<td>impact_analysis</td>\n<td>0.1</td>\n<td>0.1</td>\n<td>0.1</td>\n<td><strong>0.7</strong></td>\n</tr>\n<tr>\n<td>exact_match</td>\n<td>0.0</td>\n<td><strong>0.9</strong></td>\n<td>0.1</td>\n<td>0.0</td>\n</tr>\n</tbody>\n</table>\n<p>So “where is <code>parseConfig</code> defined” leans hard on AST (0.6). “how does auth work” leans on semantic vectors (0.5). “what depends on this” is almost all graph (0.7). “find <code>ECONNREFUSED</code>” is almost all trigram (0.9), with the embedding model switched off entirely — because semantic similarity is exactly the wrong tool for an exact string.</p>\n<h2 id=\"the-fast-path-and-the-fused-path\">The fast path, and the fused path</h2>\n<p>When the classifier is confident — score ≥ 0.85 — and the query is a normal one, Maguyva skips fusion entirely and routes straight to the single dominant modality. “where is X defined” doesn’t need four retrievers; it needs the AST index, now. That direct path is reported back as <code>fusion_strategy: \"direct\"</code>.</p>\n<p>Everything ambiguous goes through fusion. The four (or three, on the default preset) modalities run in parallel, each returning its own ranked list, and we combine them.</p>\n<h2 id=\"weighted-reciprocal-rank-fusion\">Weighted Reciprocal Rank Fusion</h2>\n<p>Fusing heterogeneous retrievers is harder than it sounds: a cosine similarity of 0.82 and a trigram score of 137 and a graph centrality of 0.004 are not on the same scale, so you cannot just add them. Reciprocal Rank Fusion sidesteps the problem by throwing away the raw scores and keeping only the <strong>rank</strong> each engine assigned. A result’s contribution from one modality is:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"text\"><code><span class=\"line\"><span>contribution = weight × 1 / (k + rank + 1)</span></span></code></pre>\n<p>where <code>rank</code> is its position in that modality’s list and <code>k</code> is a smoothing constant. Contributions are summed across modalities for any result that more than one engine found — agreement between retrievers naturally floats to the top. We use <strong>k = 40</strong> on the default preset and 60 on <code>thorough</code> (<code>quick</code> runs semantic-only, so fusion never kicks in there). The original RRF work landed on k = 60 for general-purpose retrieval; we default slightly sharper, which gives top-ranked agreement between modalities a bit more weight — and we don’t recommend hand-tuning it.</p>\n<p>On top of that, results carry a <strong>graph-importance boost</strong>. A hub — a function the whole codebase leans on — should outrank an obscure leaf even at the same textual relevance, so we multiply each contribution by:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"text\"><code><span class=\"line\"><span>boost = min(1 + 0.3 × ln(1 + centrality), 1.5)</span></span></code></pre>\n<p>Centrality comes from the pipeline’s precomputed PageRank/degree metrics, and the boost is clamped at 1.5× so a popular function can’t completely bury a more relevant obscure one. Finally we demote results from vendor, build, and archive paths, and dedupe to the best chunk per file.</p>\n<h2 id=\"whats-still-imperfect\">What’s still imperfect</h2>\n<p>The intent classifier is a stack of regexes, not a learned model. It handles common query shapes with heuristics, and an ambiguous query falls through to <code>understand_code</code> and a semantic-leaning blend. An earlier version of this post described a zero-result reduction from roughly 15% to under 5% as achieved. The December 2025 proposal actually listed an estimated baseline and a target; no supporting query set or measurement receipt is supplied. We withdraw that achieved-improvement claim; see the <a href=\"https://maguyva.ai/evidence/search-quality.md\">source evidence and correction</a>. We haven’t replaced the classifier with a trained model because the cheap version is fast and good enough for its intended routing role, and because a wrong-but-confident classifier is worse than an honest fallback. The weights themselves are hand-chosen priors, not learned from click data we don’t collect.</p>\n<h2 id=\"ask-the-question-not-the-tool\">Ask the Question, Not the Tool</h2>\n<p>An agent shouldn’t have to know whether to reach for grep or embeddings or the call graph — it should ask its question in plain terms and get the right answer. Multi-modal fusion is what lets <code>find_symbol</code>, semantic search, and dependency analysis sit behind one query surface: the system reads the shape of the question and quietly assembles the right retriever for it. The model that scores the embeddings matters, but so does knowing when <em>not</em> to use them. Picking the right tool for each query is its own kind of quality, and it’s one we’d rather own than push onto the caller.</p>\n<p><code>// you bring the question. it brings the tools.</code></p>\n",
      "date_published": "2026-04-15T00:00:00.000Z",
      "date_modified": "2026-09-06T00:00:00.000Z",
      "tags": [
        "Search",
        "Architecture"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/agent-observability-hooks-alloy-grafana",
      "url": "https://maguyva.ai/blog/agent-observability-hooks-alloy-grafana",
      "title": "Agent Observability: Hooks, Alloy, and Grafana",
      "summary": "We wired Claude Code and Codex into one Grafana stack with OpenTelemetry and Alloy, then used traces and logs to find and fix agent behavior issues at the source.",
      "content_html": "<p>Agent systems fail in weird ways.</p>\n<p>Sometimes the model is the problem. Sometimes the tool is the problem. Sometimes your MCP server is fine, but the agent chose the wrong specialist, or spent half the session doing shell work you did not expect, or silently burned cost in a loop that looked productive from the outside.</p>\n<p>If you cannot see the difference, you are not really operating an agent system. You are guessing.</p>\n<p>So we built an observability stack for our own workflow: Claude Code, Codex, Claude hook events, Codex notify events, native OpenTelemetry, Grafana Alloy, and Grafana Cloud on the other side.</p>\n<p>The interesting part is not “we made a dashboard.” The interesting part is that we had to split telemetry into two different streams because no single feed gave us the whole picture.</p>\n<h2 id=\"the-problem-agent-telemetry-is-fragmented\">The Problem: Agent Telemetry Is Fragmented</h2>\n<p>Modern coding agents already emit some telemetry. That helps, but it is not enough.</p>\n<p>Native OTEL is good at answering questions like:</p>\n<ul>\n<li>How many requests did we make?</li>\n<li>How much did a session cost?</li>\n<li>Where are the spans and traces?</li>\n<li>Did latency spike?</li>\n</ul>\n<p>It is much worse at answering questions like:</p>\n<ul>\n<li>Which MCP server did the agent lean on?</li>\n<li>Was this failure in <code>Bash</code>, a built-in file tool, or an MCP call?</li>\n<li>Which skill actually activated?</li>\n<li>Which subagent type got dispatched?</li>\n<li>Was the session doing useful work, or just thrashing?</li>\n</ul>\n<p>That second class of question lives closer to hooks than traces.</p>\n<p>But the inverse is also true: some of the most important performance questions live closer to traces than hooks.</p>\n<p>If you want to know where latency actually accumulated, which spans were slow, or whether the session burned time in model calls versus tool execution, you need trace data as well as semantic events.</p>\n<h2 id=\"the-architecture-we-ended-up-with\">The Architecture We Ended Up With</h2>\n<p>We run two telemetry paths side by side.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"text\"><code><span class=\"line\"><span>Claude Code</span></span>\n<span class=\"line\"><span>  native OTEL -&gt; Alloy -&gt; Grafana Cloud</span></span>\n<span class=\"line\"><span>  hooks        -&gt; send_event.py -&gt; Grafana Cloud Loki</span></span>\n<span class=\"line\"><span></span></span>\n<span class=\"line\"><span>Codex</span></span>\n<span class=\"line\"><span>  native OTEL -&gt; Alloy -&gt; Grafana Cloud</span></span>\n<span class=\"line\"><span>  notify hook -&gt; codex_notify.py -&gt; shared Loki schema</span></span></code></pre>\n<p>That split is deliberate.</p>\n<p>It is also asymmetric. Claude Code gives us a much richer lifecycle hook surface. Codex gives us native OTEL plus a notify surface, so we normalize thinner turn-completion events into the same log schema instead of pretending both runtimes expose the same controls.</p>\n<p><strong>Native OTEL</strong> gives us the baseline stream: logs and traces from the runtime itself, plus metrics where the runtime actually emits them.</p>\n<p><strong>Hook and notify events</strong> give us the semantic layer: things like <code>PreToolUse</code>, <code>PostToolUse</code>, <code>PostToolUseFailure</code>, <code>UserPromptSubmit</code>, <code>SubagentStop</code>, <code>SkillActivated</code>, and the classified metadata we actually care about when debugging agent behavior. Claude Code contributes the richer event stream here. Codex contributes a thinner but still useful normalized stream.</p>\n<h2 id=\"why-hooks-exist-at-all\">Why Hooks Exist At All</h2>\n<p>Our hook pipeline enriches events before they hit Loki.</p>\n<p>Instead of just saying “a tool ran,” we classify the event into fields like:</p>\n<ul>\n<li><code>tool_type</code>: builtin, mcp, skill, agent, bash</li>\n<li><code>mcp_server</code>: which MCP backend handled the call</li>\n<li><code>bash_cli</code>: the shell command family</li>\n<li><code>subagent_type</code>: what kind of specialist got dispatched</li>\n<li><code>agent_tool</code>: whether the source was Claude Code or Codex</li>\n</ul>\n<p>That means we can ask questions that matter operationally:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"text\"><code><span class=\"line\"><span>{service_name=\"claude-code-hooks\"} | agent_tool=\"codex-cli\"</span></span>\n<span class=\"line\"><span>{service_name=\"claude-code-hooks\"} | tool_type=\"mcp\"</span></span>\n<span class=\"line\"><span>{service_name=\"claude-code-hooks\"} | json | bash_cli=\"git\"</span></span></code></pre>\n<p>Those are not vanity fields. They are the difference between “the agent felt slow” and “the agent spent the last ten minutes in shell-heavy git operations with a high tool failure rate.”</p>\n<p>One implementation detail that looks stranger than it is: the shared Loki stream still uses <code>service_name=\"claude-code-hooks\"</code> as the label even when the event came from Codex. The real split between runtimes happens on <code>agent_tool</code>.</p>\n<h2 id=\"why-alloy-sits-in-the-middle\">Why Alloy Sits In The Middle</h2>\n<p>Grafana Alloy is not just a forwarder in this setup. It is the policy boundary.</p>\n<p>We point the native OTEL stream from Claude Code and Codex at a local Alloy proxy on <code>localhost:4318</code>, then let Alloy clean up the payload before forwarding it to Grafana Cloud.</p>\n<p>That matters because raw agent telemetry is full of high-cardinality fields that are useful for analysis but terrible as indexed labels:</p>\n<ul>\n<li><code>session_id</code></li>\n<li><code>prompt_id</code></li>\n<li>token counts</li>\n<li>durations</li>\n<li>tool parameter blobs</li>\n</ul>\n<p>If you index everything, you get a label explosion and a bad day.</p>\n<p>So Alloy does three things for us:</p>\n<ol>\n<li>Keeps a very small set of low-cardinality labels indexed.</li>\n<li>Moves noisy but useful fields into structured metadata.</li>\n<li>Drops pure noise entirely.</li>\n</ol>\n<p>The important idea is simple: <strong>observe more, index less</strong>.</p>\n<h2 id=\"why-the-hook-stream-bypasses-alloy\">Why The Hook Stream Bypasses Alloy</h2>\n<p>The hook stream is already shaped for Loki.</p>\n<p>By the time <code>send_event.py</code> pushes an event, we have already decided which fields deserve label treatment and which belong in the structured JSON body. That stream goes straight to Grafana Cloud’s OTLP gateway instead of taking another pass through Alloy.</p>\n<p>So the system has a clear division of labor:</p>\n<ul>\n<li><strong>Alloy</strong> tames the raw native OTEL stream.</li>\n<li><strong>Hook enrichment</strong> makes semantic events queryable.</li>\n</ul>\n<p>That keeps the architecture simpler than trying to force everything through one path.</p>\n<h2 id=\"what-the-dashboard-actually-shows\">What The Dashboard Actually Shows</h2>\n<p>The screenshot below is from one of the observability dashboards behind our agent workflow. It is not a benchmark, and the numbers are just a point-in-time slice. The point is the shape of the data: activity feed, tool calls, failures, prompts, and breakdowns by agent, built-in tools, MCP usage, shell commands, and skills.</p>\n<p>The useful part is that this dashboard lives on the same Grafana stack as the rest of the agent telemetry. We can filter by source agent and tool family and look across runtimes without inventing a different observability story for each system.</p>\n<figure class=\"feature-figure feature-figure--wide\">\n  <a\n    href=\"https://maguyva.ai/blog/agent-observability-dashboard.png\"\n    target=\"_blank\"\n    rel=\"noreferrer\"\n    aria-label=\"Open the observability dashboard screenshot at full resolution\"\n  >\n    <img\n      src=\"https://maguyva.ai/blog/agent-observability-dashboard.png\"\n      alt=\"Grafana dashboard showing an activity feed, tool call counts, failures, prompts, and breakdowns by agents, built-in tools, MCP usage, CLI commands, and skills for an agent workflow.\"\n    />\n  </a>\n  <figcaption>\n    One of the live dashboards behind our agent workflow. This screenshot is just one slice of a shared Grafana stack that also receives telemetry from our other agent runtimes and systems. Click the image for the full-resolution version.\n  </figcaption>\n</figure>\n<h2 id=\"why-traces-matter-more-than-they-first-appear\">Why Traces Matter More Than They First Appear</h2>\n<p>Logs tell us what category of work happened. Traces tell us how the work unfolded over time.</p>\n<p>That distinction matters in agent systems because “slow” is too blunt to be useful.</p>\n<p>A trace can tell us whether the pain came from:</p>\n<ul>\n<li>model latency</li>\n<li>tool execution time</li>\n<li>repeated retries</li>\n<li>one especially expensive MCP interaction</li>\n<li>a long tail of small operations that looked harmless in isolation</li>\n</ul>\n<p>In practice we use the hook stream and Tempo traces together.</p>\n<ul>\n<li><strong>Hook logs</strong> answer: what kind of thing happened?</li>\n<li><strong>Traces</strong> answer: where did the time go?</li>\n</ul>\n<p>The combination is what turns observability from a dashboard into an explanation.</p>\n<h2 id=\"where-codex-fits\">Where Codex Fits</h2>\n<p>Codex is part of the same stack, but it is not identical to Claude Code.</p>\n<p>For Codex we wire two pieces:</p>\n<ul>\n<li>Native OTEL from Codex into Alloy</li>\n<li>A notify webhook into <code>codex_notify.py</code>, which maps turn completions into the same Loki schema we use for hook events</li>\n</ul>\n<p>That gives us a unified filter like <code>agent_tool=\"codex-cli\"</code> inside the same log stream.</p>\n<p>The honest caveat: Codex’s notify payload is currently thinner than Claude Code’s hook payload because it is not the same kind of integration surface. In our setup today, Codex turn completions can be normalized into the shared schema, but rich tool-by-tool extraction is still better in the native OTEL stream than in the notify bridge.</p>\n<p>That is not a reason to avoid the post. It is the point of the post. Real observability systems are assembled from imperfect signals.</p>\n<h2 id=\"grafana-over-mcp-changes-the-game\">Grafana Over MCP Changes The Game</h2>\n<p>The bigger shift is that Grafana is not only a place humans visit in a browser.</p>\n<p>In this repo we also expose Grafana through MCP. That means an agent can query Loki, Prometheus, and Tempo directly instead of waiting for a human to manually inspect the dashboards first.</p>\n<p>That turns observability into an active input to the workflow.</p>\n<p>An agent can ask:</p>\n<ul>\n<li>Which tool families failed most in the last hour?</li>\n<li>Which MCP server dominated a session?</li>\n<li>Did recent changes reduce tool failures or just move the work into more shell-heavy paths with the same mistakes?</li>\n<li>Which traces show the highest latency or repeated retries?</li>\n</ul>\n<p>Once you have that, you are very close to a self-improvement loop.</p>\n<h2 id=\"from-dashboard-to-feedback-loop\">From Dashboard To Feedback Loop</h2>\n<p>This is the part we find most interesting.</p>\n<p>Once the observability stack is queryable from the agent layer, telemetry stops being a passive reporting surface and becomes a control signal.</p>\n<p>The loop looks like this:</p>\n<ol>\n<li>Agent activity emits traces, metrics, and enriched hook logs.</li>\n<li>Grafana stores the evidence in Loki, Tempo, and Prometheus where metrics exist.</li>\n<li>Agents query that evidence through Grafana MCP.</li>\n<li>The system identifies bad tool mix, brittle skills, weak routing, or shell-heavy workflows that keep producing avoidable mistakes.</li>\n<li>Agents or operators adjust prompts, agent configs, skill descriptions, routing rules, or tool access.</li>\n<li>The next session produces a new telemetry shape, and the cycle repeats.</li>\n</ol>\n<p>That is how you move from “interesting dashboard” to “measurable improvement system.”</p>\n<p>The goal is not to maximize one tool category. It is to land on the right mix of CLI, built-in tools, MCP calls, and skills for the work actually being done.</p>\n<h2 id=\"what-this-lets-us-answer\">What This Lets Us Answer</h2>\n<p>Once both runtimes land in the same Grafana stack, we can answer operational questions much faster:</p>\n<ul>\n<li>Are failures concentrated in one tool family?</li>\n<li>Are shell-heavy workflows creating avoidable mistakes where a higher-level tool should exist?</li>\n<li>Which MCP servers are carrying the workload?</li>\n<li>Are we paying for agent activity that is not producing meaningful progress?</li>\n<li>Is a session unhealthy because of the model, the tools, or the orchestration layer?</li>\n</ul>\n<p>This is especially useful in multi-agent workflows, where “the agent was busy” tells you almost nothing.</p>\n<p>If one specialist keeps getting dispatched and producing high failure rates, that is a routing or prompt-shaping problem.</p>\n<p>If one MCP server dominates all calls, that may be good architecture or a sign that everything else is dead weight.</p>\n<p>If tool failures spike while cost stays high, you have an operational problem, not a quality problem.</p>\n<p>If shell work keeps failing in predictable, avoidable ways where a higher-level tool should exist, that is a product signal.</p>\n<p>If one skill activates constantly but does not improve outcomes, that is a prompt or routing signal.</p>\n<h2 id=\"the-real-lesson\">The Real Lesson</h2>\n<p>The deeper lesson here is that agent observability needs both <strong>runtime telemetry</strong> and <strong>workflow telemetry</strong>.</p>\n<p>Runtime telemetry tells you what the system did.</p>\n<p>Workflow telemetry tells you what the agent thought it was doing.</p>\n<p>We need both.</p>\n<p>If you only keep traces and counters, you miss the semantic layer. If you only keep hook events, you miss latency, spans, and the broader runtime picture.</p>\n<p>And if you keep both but never feed them back into the agent layer, you have monitoring, not adaptation.</p>\n<p>The combination is what makes the system explainable enough to operate and tunable enough to improve.</p>\n<h2 id=\"whats-still-imperfect\">What’s Still Imperfect</h2>\n<p>There are still rough edges.</p>\n<ul>\n<li>Not every hook event includes the duration and token data we would like.</li>\n<li>Some of the best timing views still come from Tempo traces, not the hook logs.</li>\n<li>Codex today is less semantically rich than Claude Code in the enriched event stream.</li>\n<li>The dashboard screenshot is a live operations surface, not a polished marketing artifact.</li>\n</ul>\n<p>That last point is intentional. We would rather show the real instrument panel than pretend agent systems are magically self-explanatory.</p>\n<h2 id=\"why-this-matters-for-maguyva\">Why This Matters For Maguyva</h2>\n<p>Maguyva is about giving agents better code intelligence. But once agents are actually doing useful work, a new requirement appears immediately: you need to see how they are behaving.</p>\n<p>Search quality, routing quality, tool selection, and context efficiency all become observable problems.</p>\n<p>That is why we think this is worth writing about. The future agent stack is not just prompts and tools. It is prompts, tools, and the instrumentation layer that tells you whether the whole thing is working.</p>\n<p>If you are building serious agent workflows, observability is not optional infrastructure. It is part of the product.</p>\n",
      "date_published": "2026-03-24T00:00:00.000Z",
      "tags": [
        "Observability",
        "Grafana",
        "OpenTelemetry",
        "Architecture"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/mining-workflow-closing-the-loop",
      "url": "https://maguyva.ai/blog/mining-workflow-closing-the-loop",
      "title": "Mining the Loop: How Changes Become Institutional Memory",
      "summary": "Git commits become structured changelog entries and architectural decision records, then feed back into AI agents as queryable institutional memory.",
      "content_html": "<blockquote>\n<p><em>Numbers in this post reflect the system at publication (February 2026). See our <a href=\"https://maguyva.ai/team\">team page</a> for current figures.</em></p>\n</blockquote>\n<p>Every engineering team faces the same challenge: changes happen constantly, but the <em>why</em> behind those changes disappears. Six months later, someone asks “why did we adopt DuckDB for pipeline stages?” and the answer lives only in the head of whoever made that call—if they’re still around.</p>\n<p>We built a mining workflow that closes this loop. Changes flow through git commits, get processed by our mining pipeline, become structured changelog entries and architectural decision records, and then feed back into our AI agents through CLI queries. The result: institutional memory that both humans and AI can access.</p>\n<h2 id=\"the-problem-decisions-evaporate\">The Problem: Decisions Evaporate</h2>\n<p>Consider a typical scenario. A developer commits:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>feat(canonical): add DuckDB runtime for pipeline stages</span></span></code></pre>\n<p>This commit represents a significant architectural choice. The team evaluated options, considered trade-offs, and landed on DuckDB for specific reasons. But all that context lives in:</p>\n<ul>\n<li>A Slack thread (probably deleted)</li>\n<li>Someone’s memory (definitely fading)</li>\n<li>A comment in the code (maybe, if you’re lucky)</li>\n</ul>\n<p>Three months later, a new team member asks: “Should I use DuckDB or SQLite for this new stage?” Without institutional memory, they either reinvent the wheel or make inconsistent choices.</p>\n<h2 id=\"the-loop-from-commits-to-context\">The Loop: From Commits to Context</h2>\n<p>Our mining workflow transforms git history into queryable knowledge:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>Git Commits</span></span>\n<span class=\"line\"><span>    │</span></span>\n<span class=\"line\"><span>    ▼</span></span>\n<span class=\"line\"><span>┌─────────────────────┐</span></span>\n<span class=\"line\"><span>│  mine sync          │  ← Build index from git history</span></span>\n<span class=\"line\"><span>└─────────────────────┘</span></span>\n<span class=\"line\"><span>    │</span></span>\n<span class=\"line\"><span>    ▼</span></span>\n<span class=\"line\"><span>┌─────────────────────┐</span></span>\n<span class=\"line\"><span>│  mine candidates    │  ← Surface commits for review</span></span>\n<span class=\"line\"><span>└─────────────────────┘</span></span>\n<span class=\"line\"><span>    │</span></span>\n<span class=\"line\"><span>    ▼</span></span>\n<span class=\"line\"><span>┌─────────────────────┐</span></span>\n<span class=\"line\"><span>│  Classification     │  ← Human or LLM assessment</span></span>\n<span class=\"line\"><span>│  (changelog or ADR) │</span></span>\n<span class=\"line\"><span>└─────────────────────┘</span></span>\n<span class=\"line\"><span>    │</span></span>\n<span class=\"line\"><span>    ├──────────────────────┐</span></span>\n<span class=\"line\"><span>    ▼                      ▼</span></span>\n<span class=\"line\"><span>┌─────────────┐    ┌───────────────┐</span></span>\n<span class=\"line\"><span>│ Changelog   │    │ Decisions     │</span></span>\n<span class=\"line\"><span>│ Ledger      │    │ Registry      │</span></span>\n<span class=\"line\"><span>│ (JSONL)     │    │ (YAML files)  │</span></span>\n<span class=\"line\"><span>└─────────────┘    └───────────────┘</span></span>\n<span class=\"line\"><span>    │                      │</span></span>\n<span class=\"line\"><span>    ▼                      ▼</span></span>\n<span class=\"line\"><span>┌─────────────┐    ┌───────────────┐</span></span>\n<span class=\"line\"><span>│ CHANGELOG.md│    │ orkestra CLI  │</span></span>\n<span class=\"line\"><span>│ per package │    │ queries       │</span></span>\n<span class=\"line\"><span>└─────────────┘    └───────────────┘</span></span>\n<span class=\"line\"><span>    │                      │</span></span>\n<span class=\"line\"><span>    └──────────────────────┘</span></span>\n<span class=\"line\"><span>              │</span></span>\n<span class=\"line\"><span>              ▼</span></span>\n<span class=\"line\"><span>      ┌───────────────┐</span></span>\n<span class=\"line\"><span>      │ AI Agents     │</span></span>\n<span class=\"line\"><span>      │ (via CLI)     │</span></span>\n<span class=\"line\"><span>      └───────────────┘</span></span></code></pre>\n<p>The key insight: both changelogs and architectural decisions flow from the same git history, processed through a unified pipeline. This ensures nothing falls through the cracks.</p>\n<h2 id=\"how-mining-works\">How Mining Works</h2>\n<h3 id=\"step-1-sync-the-index\">Step 1: Sync the Index</h3>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> mine</span><span style=\"color:#9ECBFF\"> sync</span></span></code></pre>\n<p>This command scans git history and builds an index of all commits. It extracts structured signals from each commit:</p>\n<ul>\n<li>Conventional commit type (<code>feat</code>, <code>fix</code>, <code>chore</code>, <code>docs</code>)</li>\n<li>Scope (which package or area)</li>\n<li>Breaking change markers</li>\n<li>Files touched and complexity metrics</li>\n</ul>\n<h3 id=\"step-2-check-coverage-status\">Step 2: Check Coverage Status</h3>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> mine</span><span style=\"color:#9ECBFF\"> status</span></span></code></pre>\n<p>Here’s what our current status looks like:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>Mining Status</span></span>\n<span class=\"line\"><span>=============</span></span>\n<span class=\"line\"><span></span></span>\n<span class=\"line\"><span>Decisions</span></span>\n<span class=\"line\"><span>---------</span></span>\n<span class=\"line\"><span>  Coverage:        100.0%</span></span>\n<span class=\"line\"><span>    Processed:     15637  (of 15637)</span></span>\n<span class=\"line\"><span>    Extracted:       476</span></span>\n<span class=\"line\"><span>    Skipped:       15161</span></span>\n<span class=\"line\"><span></span></span>\n<span class=\"line\"><span>Changelog</span></span>\n<span class=\"line\"><span>---------</span></span>\n<span class=\"line\"><span>  Coverage:        100.0%</span></span>\n<span class=\"line\"><span>    Processed:     15637  (of 15637)</span></span>\n<span class=\"line\"><span>    Released:       6799</span></span>\n<span class=\"line\"><span>    Skipped:        8838</span></span></code></pre>\n<p>15,637 commits processed. 476 became architectural decisions. 6,799 became changelog entries. Every commit classified.</p>\n<h3 id=\"step-3-get-candidates-for-review\">Step 3: Get Candidates for Review</h3>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> mine</span><span style=\"color:#9ECBFF\"> candidates</span><span style=\"color:#79B8FF\"> --limit</span><span style=\"color:#79B8FF\"> 50</span><span style=\"color:#79B8FF\"> --full</span></span></code></pre>\n<p>This surfaces commits that haven’t been processed yet, with full context for classification:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"json\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"sha\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"90571786d99166c0039ca2e80e4d9cd96184bd85\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"date\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"2026-01-26\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"subject\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"feat(canonical): add DuckDB runtime for pipeline stages\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"signals\"</span><span style=\"color:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"commit_type\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"feat\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"scope\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"canonical\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"breaking\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">false</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"is_releasable_type\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"domains_affected\"</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">\"pipeline\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">\"data-architecture\"</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  },</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"body\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Establishes DuckDB as canonical in-process analytical database...\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"files_changed\"</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">\"packages/canonical/pipelines/stages/duckdb_runtime.py\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">\"...\"</span><span style=\"color:#E1E4E8\">],</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"stats\"</span><span style=\"color:#E1E4E8\">: {</span><span style=\"color:#79B8FF\">\"files\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">8</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#79B8FF\">\"insertions\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">450</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#79B8FF\">\"deletions\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">120</span><span style=\"color:#E1E4E8\">}</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n<p>The signals help guide classification: <code>is_releasable_type: true</code> suggests this should appear in the changelog. The large insertion count and infrastructure files suggest it might also be an architectural decision.</p>\n<h3 id=\"step-4-classify-commits\">Step 4: Classify Commits</h3>\n<p>Two paths diverge here: changelog entries and architectural decisions.</p>\n<p><strong>For changelog entries:</strong></p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> mine</span><span style=\"color:#9ECBFF\"> classify</span><span style=\"color:#9ECBFF\"> abc123</span><span style=\"color:#79B8FF\"> --changelog</span><span style=\"color:#9ECBFF\"> added</span></span></code></pre>\n<p>This records that commit <code>abc123</code> should appear in the changelog under the “Added” category.</p>\n<p><strong>For architectural decisions:</strong></p>\n<p>First, get a real decision ID:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> registry</span><span style=\"color:#9ECBFF\"> decisions</span><span style=\"color:#9ECBFF\"> new</span><span style=\"color:#79B8FF\"> --domain</span><span style=\"color:#9ECBFF\"> pipeline</span><span style=\"color:#79B8FF\"> --dry-run</span></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Returns: DEC-PL-143</span></span></code></pre>\n<p>Then classify with the decision ID:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> mine</span><span style=\"color:#9ECBFF\"> classify</span><span style=\"color:#9ECBFF\"> abc123</span><span style=\"color:#79B8FF\"> --decision</span><span style=\"color:#9ECBFF\"> DEC-PL-143</span></span></code></pre>\n<p>This links the commit to a decision record that will be created or updated.</p>\n<p><strong>For batch processing (what we actually do):</strong></p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#959da5\"># Generate classifications file with LLM assistance</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> mine</span><span style=\"color:#9ECBFF\"> commit</span><span style=\"color:#79B8FF\"> --input</span><span style=\"color:#9ECBFF\"> classifications.jsonl</span></span></code></pre>\n<p>The JSONL format supports both domains in one pass:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"jsonl\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">{</span><span style=\"color:#79B8FF\">\"sha\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"abc123\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"domain\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"changelog\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"action\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"release\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"category\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"added\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"summary\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"Add DuckDB runtime for pipeline stages\"</span><span style=\"color:#E1E4E8\">}</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">{</span><span style=\"color:#79B8FF\">\"sha\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"abc123\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"domain\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"decisions\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"action\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"extract\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"decision_id\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"DEC-PL-142\"</span><span style=\"color:#E1E4E8\">}</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">{</span><span style=\"color:#79B8FF\">\"sha\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"def456\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"domain\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"changelog\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"action\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"skip\"</span><span style=\"color:#E1E4E8\">,</span><span style=\"color:#79B8FF\">\"reason\"</span><span style=\"color:#E1E4E8\">:</span><span style=\"color:#9ECBFF\">\"Chore: dependency update\"</span><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n<h3 id=\"step-5-render-outputs\">Step 5: Render Outputs</h3>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> registry</span><span style=\"color:#9ECBFF\"> changelog</span><span style=\"color:#9ECBFF\"> render</span><span style=\"color:#79B8FF\"> --package</span><span style=\"color:#F97583\"> &lt;</span><span style=\"color:#9ECBFF\">pk</span><span style=\"color:#E1E4E8\">g</span><span style=\"color:#F97583\">&gt;</span></span></code></pre>\n<p>This generates per-package <code>CHANGELOG.md</code> files from the ledger. The changelogs are derived artifacts—delete them and they regenerate perfectly from the source ledger.</p>\n<h2 id=\"the-decision-record-structure\">The Decision Record Structure</h2>\n<p>Extracted decisions become YAML files with rich metadata:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">DEC-PL-142</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">title</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">Adopt DuckDB as Canonical Processing Runtime for Pipeline Stages</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">domain</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">pipeline</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">status</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">active</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">created</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">'2026-01-26'</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">summary</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">  Establishes DuckDB as the canonical in-process analytical database for pipeline</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">  stage transformations. Provides a shared runtime module that resolves settings</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">  from pipeline defaults with stage-level overrides.</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#85E89D\">context</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">  Pipeline stages performing data transformations each independently configured</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">  DuckDB connections. This led to inconsistent settings, duplicated configuration</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">  code, and no way to tune DuckDB globally for a pipeline run.</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#85E89D\">rationale</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">DuckDB provides efficient in-process OLAP with zero configuration deployment</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">Centralized runtime module eliminates duplicated DuckDB setup across stages</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">Hierarchical settings enable global tuning with stage-level overrides</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">Memory limits and thread counts can be adjusted per-pipeline</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#85E89D\">impact</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  positive</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Consistent DuckDB configuration across all pipeline stages</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Single point of control for memory/thread tuning</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Reduced code duplication in conversion and export stages</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  negative</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Adds dependency on shared runtime module</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Stages must adopt new configuration pattern</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#85E89D\">source_commits</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">sha</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">90571786d99166c0039ca2e80e4d9cd96184bd85</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    message</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">'feat(canonical): add DuckDB runtime for pipeline stages'</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    date</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">'2026-01-26'</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    role</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">primary</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#85E89D\">files</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">packages/canonical/pipelines/stages/duckdb_runtime.py</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">packages/canonical/pipelines/runner.py</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">packages/canonical/pipelines/stages/convert_hdx_admin_boundaries_to_geoparquet.py</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#85E89D\">related</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">DEC-DA-014</span><span style=\"color:#959da5\">  # Data architecture decisions that influenced this</span></span></code></pre>\n<p>Every decision links back to its source commits. Every decision specifies which files it affects. Relationships between decisions are explicit.</p>\n<h2 id=\"cli-integration-querying-institutional-memory\">CLI Integration: Querying Institutional Memory</h2>\n<p>This is where the loop closes. Agents can query decisions through the CLI:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#959da5\"># Search by topic</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> registry</span><span style=\"color:#9ECBFF\"> decisions</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#79B8FF\"> --query</span><span style=\"color:#9ECBFF\"> \"retry\"</span></span></code></pre>\n<p>Returns decisions about retry logic, error handling, recovery patterns.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#959da5\"># Get full details on a specific decision</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> registry</span><span style=\"color:#9ECBFF\"> decisions</span><span style=\"color:#9ECBFF\"> info</span><span style=\"color:#9ECBFF\"> DEC-PL-142</span></span></code></pre>\n<p>Returns the complete decision record with context, rationale, and impact.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#959da5\"># List recent decisions for context</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> registry</span><span style=\"color:#9ECBFF\"> decisions</span><span style=\"color:#9ECBFF\"> list</span><span style=\"color:#79B8FF\"> --limit</span><span style=\"color:#79B8FF\"> 15</span></span></code></pre>\n<p>Shows what architectural choices were made recently.</p>\n<h3 id=\"how-agents-use-this\">How Agents Use This</h3>\n<p>Our orchestrator’s baseline instructions include:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"markdown\"><code><span class=\"line\"><span style=\"color:#E1E4E8;font-weight:bold\">**Essential CLI commands:**</span></span>\n<span class=\"line\"><span style=\"color:#FFAB70\">-</span><span style=\"color:#79B8FF\"> `orkestra registry decisions search \"X\"`</span><span style=\"color:#E1E4E8\"> — Find architectural decisions</span></span></code></pre>\n<p>When an agent is asked to implement something related to DuckDB, it can first check:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> registry</span><span style=\"color:#9ECBFF\"> decisions</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#79B8FF\"> --query</span><span style=\"color:#9ECBFF\"> \"DuckDB\"</span></span></code></pre>\n<p>And discover DEC-PL-142, learning:</p>\n<ul>\n<li>Why we chose DuckDB (context)</li>\n<li>How to use it correctly (agent_guidance)</li>\n<li>What files to look at (files)</li>\n<li>What related decisions exist (related)</li>\n</ul>\n<p>The agent doesn’t reinvent the wheel. It builds on established patterns.</p>\n<h2 id=\"the-three-questions-test\">The Three Questions Test</h2>\n<p>Not every commit deserves a decision record. We use the Three Questions Test to filter:</p>\n<ol>\n<li><strong>Was this hard to make?</strong> Did it require significant analysis, trade-off evaluation, or debate?</li>\n<li><strong>Is it costly to change?</strong> Would reversing this decision require significant rework?</li>\n<li><strong>Does it have system-wide impact?</strong> Does it affect multiple packages or establish patterns others will follow?</li>\n</ol>\n<p>If a commit answers “yes” to at least one of these questions, it’s a candidate for decision extraction. Our typical rate: 1-4 decisions per 100 commits (about 1-4%).</p>\n<p>For changelog entries, the bar is lower: any user-facing change (features, fixes, improvements) gets recorded. Internal chores, documentation updates, and refactors typically get skipped. Our typical rate: 30-50 changelog entries per 100 commits.</p>\n<h2 id=\"data-storage-append-only-ledgers\">Data Storage: Append-Only Ledgers</h2>\n<p>The mining system uses append-only JSONL ledgers for conflict-free multi-agent operation:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>packages/orchestration/ai_assets/reference/changelog/</span></span>\n<span class=\"line\"><span>├── commits_processed.jsonl  # Classification ledger (both domains)</span></span>\n<span class=\"line\"><span>├── release_notes.jsonl      # Changelog entries</span></span>\n<span class=\"line\"><span>└── commits_index.yaml       # Derived index (gitignored)</span></span>\n<span class=\"line\"><span></span></span>\n<span class=\"line\"><span>packages/orchestration/ai_assets/reference/decisions/</span></span>\n<span class=\"line\"><span>├── registry.yaml            # Decision index</span></span>\n<span class=\"line\"><span>└── records/</span></span>\n<span class=\"line\"><span>    ├── DEC-AD-001.yaml</span></span>\n<span class=\"line\"><span>    ├── DEC-AD-002.yaml</span></span>\n<span class=\"line\"><span>    └── ...</span></span></code></pre>\n<p>The JSONL format with <code>merge=union</code> in <code>.gitattributes</code> means multiple agents can classify commits simultaneously without merge conflicts. Each line is independent.</p>\n<h2 id=\"validation-gates\">Validation Gates</h2>\n<p>Before any mining session, we run validation:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> mine</span><span style=\"color:#9ECBFF\"> validate</span><span style=\"color:#79B8FF\"> --quick</span></span></code></pre>\n<p>This checks:</p>\n<ul>\n<li>SHA format validity</li>\n<li>Decision ID format compliance</li>\n<li>No duplicate entries for the same SHA</li>\n<li>Referenced decisions actually exist</li>\n</ul>\n<p>After classification, we validate again before committing changes.</p>\n<h2 id=\"why-this-matters\">Why This Matters</h2>\n<p>The feedback loop we’ve built solves several problems:</p>\n<p><strong>For new team members:</strong> Instead of asking “why did we do X?”, they can search the decisions registry. The context is preserved.</p>\n<p><strong>For AI agents:</strong> They don’t operate in a vacuum. They can query institutional knowledge before making recommendations. When asked to add a new pipeline stage, they can discover the DuckDB pattern and follow it.</p>\n<p><strong>For architectural consistency:</strong> Decisions are explicit and searchable. When someone proposes an approach that contradicts an existing decision, the system can surface the conflict.</p>\n<p><strong>For changelog generation:</strong> Release notes aren’t a last-minute scramble. They’re a byproduct of continuous classification during development.</p>\n<p><strong>For onboarding:</strong> New agents inherit the full context of the codebase. They don’t just see the code—they see the decisions that shaped it.</p>\n<h2 id=\"current-state\">Current State</h2>\n<p>As of today:</p>\n<ul>\n<li><strong>15,637 commits</strong> processed through the pipeline</li>\n<li><strong>476 architectural decisions</strong> extracted and documented</li>\n<li><strong>6,799 changelog entries</strong> recorded</li>\n<li><strong>100% coverage</strong> across both domains</li>\n</ul>\n<p>Every commit since we started has been classified. The institutional memory is complete and queryable.</p>\n<h2 id=\"getting-started\">Getting Started</h2>\n<p>If you want to implement something similar:</p>\n<ol>\n<li>\n<p><strong>Start with conventional commits.</strong> The mining pipeline works best when commits have structured prefixes (<code>feat:</code>, <code>fix:</code>, <code>chore:</code>).</p>\n</li>\n<li>\n<p><strong>Define your domains.</strong> We use domains like <code>pipeline</code>, <code>agent-design</code>, <code>observability</code>, <code>data-modeling</code>. These organize decisions by area.</p>\n</li>\n<li>\n<p><strong>Build the classification habit.</strong> Mining works when teams regularly classify commits. Batch processing with LLM assistance helps scale.</p>\n</li>\n<li>\n<p><strong>Make decisions queryable.</strong> The value compounds when agents can search decisions via CLI. Structure your output for machine consumption.</p>\n</li>\n<li>\n<p><strong>Close the loop.</strong> Decisions should influence future work. Include decision references in agent instructions and code review checklists.</p>\n</li>\n</ol>\n<p>The goal isn’t perfect documentation. It’s making the <em>why</em> behind changes accessible to both humans and AI, today and six months from now. When changes become institutional memory, teams build on established patterns instead of reinventing them.</p>\n<hr>\n<p><em>The mining workflow is part of our orchestration engine, specifically the context engine module in our orchestration package.</em></p>\n",
      "date_published": "2026-02-03T00:00:00.000Z",
      "tags": [
        "Architecture",
        "Workflows"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/skill-mining-3500-and-counting",
      "url": "https://maguyva.ai/blog/skill-mining-3500-and-counting",
      "title": "Skill Mining: From 3,500 Candidates to 466 Capabilities",
      "summary": "We screened 3,500 skill candidates and adopted 466. A systematic mining and ingestion loop for building a coherent AI agent skill library at scale.",
      "content_html": "<blockquote>\n<p><em>Numbers in this post reflect the system at publication (January 2026). See our <a href=\"https://maguyva.ai/team\">team page</a> for current figures.</em></p>\n</blockquote>\n<h2 id=\"the-3500-skill-problem\">The 3,500 Skill Problem</h2>\n<p>When we started building an agent orchestration system, we faced an interesting challenge: there are thousands of potential skills scattered across the AI ecosystem. GitHub repositories, vendor documentation, community projects, internal patterns - skills exist everywhere. But which ones matter? Which ones work? And how do you maintain a coherent skill library that agents can actually use?</p>\n<p>Our answer: a systematic mining and ingestion loop.</p>\n<h2 id=\"the-numbers-today\">The Numbers Today</h2>\n<p>Just over three months after Anthropic launched Agent Skills on October 16, 2025, here’s where we stood when this post was published on January 27, 2026:</p>\n<table>\n<thead>\n<tr>\n<th>Metric</th>\n<th>Count</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Candidates identified</td>\n<td>3,500+</td>\n</tr>\n<tr>\n<td>Skills adopted</td>\n<td>466</td>\n</tr>\n<tr>\n<td>Vendor skills</td>\n<td>373</td>\n</tr>\n<tr>\n<td>Internal skills</td>\n<td>93</td>\n</tr>\n<tr>\n<td>Active vendors</td>\n<td>25+</td>\n</tr>\n<tr>\n<td>Average tokens per skill</td>\n<td>2,834</td>\n</tr>\n<tr>\n<td>Tools referenced</td>\n<td>89</td>\n</tr>\n<tr>\n<td>Unique tags</td>\n<td>635</td>\n</tr>\n</tbody>\n</table>\n<p>We’ve reviewed over 3,500 skill candidates. We’ve adopted 466. That’s a 13% adoption rate - and that selectivity is by design.</p>\n<h2 id=\"the-knowledge-tier-system\">The Knowledge Tier System</h2>\n<p>Not all skills are created equal. We organize them into five knowledge layers (K0-K4), each representing a different scope of applicability:</p>\n<h3 id=\"k0-foundations-universal\">K0: Foundations (Universal)</h3>\n<p>Skills every agent should have. These represent “good thinker” capabilities that work anywhere.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>foundations/</span></span>\n<span class=\"line\"><span>├── test-first-discipline       # TDD: Red-Green-Refactor</span></span>\n<span class=\"line\"><span>├── evidence-based-completion   # Verify before claiming done</span></span>\n<span class=\"line\"><span>├── systematic-debugging        # Root cause methodology</span></span>\n<span class=\"line\"><span>├── structured-planning         # Break work into tasks</span></span>\n<span class=\"line\"><span>└── context-budget-awareness    # Manage token consumption</span></span></code></pre>\n<p>K0 skills are portable to any project, any domain, any stack. They encode universal cognitive patterns.</p>\n<h3 id=\"k1-identities-discipline\">K1: Identities (Discipline)</h3>\n<p>“Good engineer” or “good researcher” skills that apply across projects within a discipline.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>identities/</span></span>\n<span class=\"line\"><span>├── research-workflows          # Multi-source research</span></span>\n<span class=\"line\"><span>├── web-extraction-playbook     # Content extraction</span></span>\n<span class=\"line\"><span>├── code-review                 # PR review patterns</span></span>\n<span class=\"line\"><span>└── cli-interface-standards     # CLI design patterns</span></span></code></pre>\n<h3 id=\"k2-domains-subject-expertise\">K2: Domains (Subject Expertise)</h3>\n<p>“Good database expert” or “good security engineer” skills portable within a field.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>domains/</span></span>\n<span class=\"line\"><span>├── schema-migration-workflow   # Safe migration patterns</span></span>\n<span class=\"line\"><span>├── rpc-validation-checklist    # RPC health checks</span></span>\n<span class=\"line\"><span>├── auth-validation-checklist   # JWT/OAuth patterns</span></span>\n<span class=\"line\"><span>└── secrets-audit-checklist     # Credential scanning</span></span></code></pre>\n<h3 id=\"k3-stacks-technology\">K3: Stacks (Technology)</h3>\n<p>“Good Supabase user” or “good Cloudflare developer” skills for specific technology stacks.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>stacks/</span></span>\n<span class=\"line\"><span>├── maguyva-quickstart          # Our semantic search patterns</span></span>\n<span class=\"line\"><span>├── cloudflare-deployment       # Workers/Pages deployment</span></span>\n<span class=\"line\"><span>└── mcp-tool-best-practices     # MCP tool selection</span></span></code></pre>\n<h3 id=\"k4-project-organization\">K4: Project (Organization)</h3>\n<p>Skills specific to our organization and workflows.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>project/</span></span>\n<span class=\"line\"><span>├── agent-creation-workflow     # How we build agents</span></span>\n<span class=\"line\"><span>├── skill-authoring-workflow    # How we write skills</span></span>\n<span class=\"line\"><span>├── mining-session-workflow     # This very process</span></span>\n<span class=\"line\"><span>└── vendor-skill-evaluation     # Evaluation rubrics</span></span></code></pre>\n<h2 id=\"the-mining-loop\">The Mining Loop</h2>\n<h3 id=\"phase-1-discovery\">Phase 1: Discovery</h3>\n<p>Skills come from everywhere:</p>\n<p><strong>Vendor Repositories</strong>: AWS, Anthropic, Cloudflare, Supabase, and community contributors publish skill collections. We track 25+ vendor roots.</p>\n<p><strong>Community Projects</strong>: GitHub is full of Claude Code templates, agent patterns, and workflow definitions.</p>\n<p><strong>Internal Patterns</strong>: As our team solves problems, patterns emerge. These get formalized into skills.</p>\n<p><strong>Documentation Mining</strong>: Technical documentation often contains implicit skills - procedures, checklists, decision trees.</p>\n<p>Discovery is continuous. We use a skill backlog to track candidates before formal evaluation.</p>\n<h3 id=\"phase-2-evaluation\">Phase 2: Evaluation</h3>\n<p>Every candidate goes through the same rubric:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">adoption_criteria</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">fills_real_gap</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#959da5\">      # We lack this capability</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">well_structured</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#959da5\">     # Progressive disclosure</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">actively_maintained</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#959da5\"> # Commits in last 6 months</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">portable</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#959da5\">            # Not hyper-specific</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">tested</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#959da5\">              # Evidence of usage</span></span></code></pre>\n<p>All five product criteria must pass. This is why 87% of candidates are rejected.</p>\n<p>Then every candidate goes through a separate trust review. We do not treat an official vendor repository, a well-known community maintainer, and a random GitHub repo as equivalent sources of truth.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">trust_review</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  vendor_credibility</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">ownership_verified</span><span style=\"color:#959da5\">       # Official vendor, known maintainer, or internal source</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">maintenance_signal</span><span style=\"color:#959da5\">       # Recent commits, issue response, release history</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">adoption_signal</span><span style=\"color:#959da5\">          # Evidence of real use, stars alone are not enough</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">provenance_clear</span><span style=\"color:#959da5\">         # We can trace where the skill came from</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  prompt_injection_scan</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">hidden_instruction_check</span><span style=\"color:#959da5\"> # Buried \"ignore previous instructions\" patterns</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">exfiltration_check</span><span style=\"color:#959da5\">       # Prompts that try to leak files, secrets, or context</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">authority_check</span><span style=\"color:#959da5\">          # Claims of priority over system or developer rules</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  script_audit</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">inspect_scripts</span><span style=\"color:#959da5\">          # Read shell/python/js helpers before adoption</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">network_and_exec_review</span><span style=\"color:#959da5\">  # curl|bash, remote downloads, subprocess execution</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">file_and_secret_review</span><span style=\"color:#959da5\">   # Env vars, credential access, broad file writes</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">destructive_action_check</span><span style=\"color:#959da5\"> # rm, reset, overwrite, or unsafe automation</span></span></code></pre>\n<p>Trusted vendors get a lighter provenance review, but not a free pass. Untrusted or unknown sources get a deeper manual audit, and we do not execute bundled scripts until they have been read, scoped, and classified as safe.</p>\n<p><strong>Gap Analysis</strong>: Before adopting, we search our registry:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> skills</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#9ECBFF\"> \"&lt;capability&gt;\"</span></span></code></pre>\n<p>If we already have it, we don’t need it. If we have something close, we might merge rather than adopt.</p>\n<p><strong>Depth and Standards Scoring</strong>: We also score how fully a candidate uses the agent-skill model. A lone <code>SKILL.md</code> can still be useful, but deeper skills are more valuable when they separate instructions from references, scripts, and assets in the way <code>agentskills.io</code> encourages.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">skill_depth</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">level_1</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">SKILL.md only</span><span style=\"color:#959da5\">                     # Single instruction file</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">level_2</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">SKILL.md + strong description</span><span style=\"color:#959da5\">     # Clear triggers and scope</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">level_3</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">adds references/</span><span style=\"color:#959da5\">                  # Load docs only when needed</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">level_4</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">adds atomic scripts/</span><span style=\"color:#959da5\">              # Small, reviewable helpers</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">level_5</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">adds assets/examples/templates</span><span style=\"color:#959da5\">    # Full progressive disclosure</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">depth_signals</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">standards_adherence</span><span style=\"color:#959da5\">        # Structure aligns with agentskills.io conventions</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">reference_quality</span><span style=\"color:#959da5\">          # Curated references, not giant context dumps</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">script_atomicity</span><span style=\"color:#959da5\">           # Focused helpers, not opaque monoliths</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">tool_boundary_clarity</span><span style=\"color:#959da5\">      # Clear limits on what the skill can execute</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">community_signal</span><span style=\"color:#959da5\">           # Stars/forks/users help, but only as a weak boost</span></span></code></pre>\n<p>GitHub stars can elevate a credibility score a bit, but they never rescue a shallow or unsafe skill. A high-star repo with one vague <code>SKILL.md</code> and opaque scripts scores below a smaller repo with a precise description, curated <code>references/</code>, and atomic helpers that actually leverage the full skill capability.</p>\n<p><strong>Structural Analysis</strong>: We check skill quality:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">wc</span><span style=\"color:#79B8FF\"> -l</span><span style=\"color:#9ECBFF\"> vendor/</span><span style=\"color:#F97583\">&lt;</span><span style=\"color:#9ECBFF\">rep</span><span style=\"color:#E1E4E8\">o</span><span style=\"color:#F97583\">&gt;</span><span style=\"color:#9ECBFF\">/</span><span style=\"color:#F97583\">&lt;</span><span style=\"color:#9ECBFF\">skil</span><span style=\"color:#E1E4E8\">l</span><span style=\"color:#F97583\">&gt;</span><span style=\"color:#9ECBFF\">/SKILL.md</span><span style=\"color:#959da5\">  # Size check</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">ls</span><span style=\"color:#9ECBFF\"> vendor/</span><span style=\"color:#F97583\">&lt;</span><span style=\"color:#9ECBFF\">rep</span><span style=\"color:#E1E4E8\">o</span><span style=\"color:#F97583\">&gt;</span><span style=\"color:#9ECBFF\">/</span><span style=\"color:#F97583\">&lt;</span><span style=\"color:#9ECBFF\">skil</span><span style=\"color:#E1E4E8\">l</span><span style=\"color:#F97583\">&gt;</span><span style=\"color:#9ECBFF\">/scripts/</span><span style=\"color:#959da5\">     # Supporting files</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">ls</span><span style=\"color:#9ECBFF\"> vendor/</span><span style=\"color:#F97583\">&lt;</span><span style=\"color:#9ECBFF\">rep</span><span style=\"color:#E1E4E8\">o</span><span style=\"color:#F97583\">&gt;</span><span style=\"color:#9ECBFF\">/</span><span style=\"color:#F97583\">&lt;</span><span style=\"color:#9ECBFF\">skil</span><span style=\"color:#E1E4E8\">l</span><span style=\"color:#F97583\">&gt;</span><span style=\"color:#9ECBFF\">/references/</span><span style=\"color:#959da5\">  # Bundled docs</span></span></code></pre>\n<p>If a candidate includes scripts, that review gets more stringent. A good skill is not just useful; it has to be legible, bounded, and safe to hand to an agent. That safety filter alone disqualifies a meaningful slice of otherwise interesting candidates.</p>\n<h3 id=\"phase-3-ingestion\">Phase 3: Ingestion</h3>\n<p>When a skill passes evaluation, it enters the registry. But skills are never adopted unchanged. They’re modified to fit our system.</p>\n<p><strong>Modifications on Adoption</strong>:</p>\n<ol>\n<li><strong>Metadata Normalization</strong>: Every skill gets our frontmatter schema</li>\n<li><strong>K-Tier Assignment</strong>: Skills are placed in the appropriate knowledge layer</li>\n<li><strong>Tag Enrichment</strong>: Tags are added for discovery</li>\n<li><strong>Tool Declaration</strong>: Allowed tools are explicitly declared</li>\n<li><strong>Section Alignment</strong>: Content is restructured to match our template</li>\n</ol>\n<p>A typical skill YAML after ingestion:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">metadata</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  identifier</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">vendor-skill-evaluation</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  name</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">vendor-skill-evaluation</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  description</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">Systematic evaluation of vendor skills for adoption.</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  type</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">workflow</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  layer</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">K4</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  semantic_folder</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">project</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  source</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">core</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  last_updated</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">'2026-01-17'</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#85E89D\">frontmatter</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  tags</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">agents</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">meta</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">skill-adoption</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">vendor</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  allowed_tools</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Bash</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Read</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Write</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Edit</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Grep</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Glob</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">Task</span></span></code></pre>\n<h3 id=\"phase-4-scope-assignment\">Phase 4: Scope Assignment</h3>\n<p>Skills are assigned to scopes - categories that determine which agents load which skills:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">scopes</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  database</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    primary_skills</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">domains/schema-migration-workflow</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">domains/rpc-validation-checklist</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">vendor/supabase/supabase-database</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">vendor/supabase/supabase-auth</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  research</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    primary_skills</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">identities/research-workflows</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">identities/web-extraction-playbook</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">identities/dataset-discovery-quickstart</span></span></code></pre>\n<p>Agents declare their scopes, and skills are automatically assigned:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#959da5\"># Agent definition</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">scopes</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">database</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">research</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Gets: all database skills + all research skills + universal skills</span></span></code></pre>\n<h3 id=\"phase-5-materialization\">Phase 5: Materialization</h3>\n<p>Skills don’t live as YAML in production. They’re rendered into SKILL.md files that Claude Code can load:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> sync</span></span></code></pre>\n<p>This command:</p>\n<ol>\n<li>Reads all skill YAML definitions</li>\n<li>Renders them through Jinja templates</li>\n<li>Writes SKILL.md files to <code>.claude/skills/</code></li>\n<li>Organizes by K-tier (foundations/, identities/, domains/, stacks/, project/)</li>\n</ol>\n<p>The final output structure:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>.claude/skills/</span></span>\n<span class=\"line\"><span>├── foundations/     # K0: Universal</span></span>\n<span class=\"line\"><span>├── identities/      # K1: Discipline</span></span>\n<span class=\"line\"><span>├── domains/         # K2: Subject</span></span>\n<span class=\"line\"><span>├── stacks/          # K3: Technology</span></span>\n<span class=\"line\"><span>├── project/         # K4: Organization</span></span>\n<span class=\"line\"><span>└── vendor/          # External skills</span></span></code></pre>\n<h2 id=\"the-dormant-scope-pattern\">The Dormant Scope Pattern</h2>\n<p>One of our most powerful patterns is “adopted-but-not-loaded” skills. We call these dormant scopes.</p>\n<p>Consider scientific computing skills from the k-dense-scientific repository. We’ve adopted 120+ skills covering bioinformatics, chemistry, quantum computing, and clinical informatics. But most of our agents don’t need molecular docking or gene expression analysis.</p>\n<p>Instead of loading all 120 skills into every agent (bloating context windows), we:</p>\n<ol>\n<li><strong>Adopt</strong> the skills with a specific scope (e.g., <code>bioinformatics</code>)</li>\n<li>Keep them <strong>dormant</strong> - registered but not loaded</li>\n<li><strong>Enable</strong> them only when an agent declares that scope</li>\n</ol>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#959da5\"># In scopes.yaml - dormant scope</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">bioinformatics</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  description</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Bioinformatics and genomics\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  primary_skills</span><span style=\"color:#E1E4E8\">: []  </span><span style=\"color:#959da5\"># Empty - skills exist but aren't loaded</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#959da5\"># When an agent needs bioinformatics:</span></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Agent YAML</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">scopes</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">research</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">bioinformatics</span><span style=\"color:#E1E4E8\">]  </span><span style=\"color:#959da5\"># Now loads bioinformatics skills</span></span></code></pre>\n<p>This pattern lets us have 466 skills in the registry while typical agents load only 40-60 relevant ones.</p>\n<h2 id=\"skill-types\">Skill Types</h2>\n<p>Skills come in three cognitive patterns:</p>\n<h3 id=\"workflow\">Workflow</h3>\n<p>Ordered procedural steps: “1. Do X, 2. Then Y, 3. Finally Z”</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">type</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">workflow</span></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Examples: schema-migration-workflow, mining-session-workflow</span></span></code></pre>\n<h3 id=\"discipline\">Discipline</h3>\n<p>Behavioral guardrails: “Always X”, “Never Y”, “Prefer Z”</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">type</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">discipline</span></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Examples: test-first-discipline, evidence-based-completion</span></span></code></pre>\n<h3 id=\"checklist\">Checklist</h3>\n<p>Verification criteria: “Confirm X”, “Verify Y”, “Check Z”</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">type</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">checklist</span></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Examples: auth-validation-checklist, secrets-audit-checklist</span></span></code></pre>\n<h2 id=\"quality-gates\">Quality Gates</h2>\n<p>Every skill must pass validation before it ships:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">validation</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  file_exists</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#959da5\">           # Skill file at declared path</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  frontmatter_valid</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#959da5\">     # Frontmatter parses correctly</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  sections_complete</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#959da5\">     # Expected sections present</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  tools_registered</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span><span style=\"color:#959da5\">      # Declared tools exist in registry</span></span></code></pre>\n<p>Descriptions must be 50-400 characters with trigger phrases (“Use when…”, “When you need…”) so Claude Code knows when to suggest them.</p>\n<p>We validate continuously:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> validate</span><span style=\"color:#79B8FF\"> --show-warnings</span></span></code></pre>\n<h2 id=\"the-vendor-ecosystem\">The Vendor Ecosystem</h2>\n<p>Our 373 vendor skills come from:</p>\n<table>\n<thead>\n<tr>\n<th>Provider</th>\n<th>Skills</th>\n<th>Domain</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>AWS Agent</td>\n<td>19</td>\n<td>Cloud services</td>\n</tr>\n<tr>\n<td>Anthropic</td>\n<td>12</td>\n<td>Document generation</td>\n</tr>\n<tr>\n<td>Cloudflare</td>\n<td>8</td>\n<td>Edge computing</td>\n</tr>\n<tr>\n<td>Supabase</td>\n<td>5</td>\n<td>Database</td>\n</tr>\n<tr>\n<td>k-dense</td>\n<td>100+</td>\n<td>Scientific computing</td>\n</tr>\n<tr>\n<td>silvainfm</td>\n<td>4</td>\n<td>Data science</td>\n</tr>\n<tr>\n<td>Java Developer Kit</td>\n<td>45+</td>\n<td>Spring/Java</td>\n</tr>\n<tr>\n<td>Vercel</td>\n<td>1</td>\n<td>Browser automation</td>\n</tr>\n</tbody>\n</table>\n<p>Each vendor root is declared in metadata.yaml:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">vendor_roots</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">path</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">vendor/aws-agent-skills</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    provider</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">aws</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">path</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">vendor/k-dense-scientific/scientific-skills</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    provider</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">k-dense</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">path</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">vendor/supabase-skills</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    provider</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">supabase</span></span></code></pre>\n<p>When <code>orkestra sync</code> runs, vendor skills are symlinked into <code>.claude/skills/vendor/</code> with their provider namespace.</p>\n<h2 id=\"what-weve-learned\">What We’ve Learned</h2>\n<p><strong>Selectivity pays off.</strong> It’s tempting to adopt everything that looks useful. But each skill costs tokens. With 2,834 average tokens per skill, bloat hurts fast. Our 13% adoption rate keeps agents lean.</p>\n<p><strong>Structure enables discovery.</strong> The K-tier system isn’t just organization - it’s about portability. K0 skills can be reused anywhere. K4 skills are intentionally project-specific. This clarity helps both humans and agents find what they need.</p>\n<p><strong>Dormant scopes scale.</strong> You can adopt hundreds of skills without loading them all. Scopes let you build a comprehensive registry while keeping individual agent context windows manageable.</p>\n<p><strong>Modification on adoption is essential.</strong> Raw vendor skills rarely fit your system. The ingestion process - adding metadata, assigning tiers, enriching tags - makes external skills work internally.</p>\n<p><strong>Mining is continuous.</strong> The 3,500 number keeps growing. New vendor repos appear. Community patterns emerge. Internal workflows solidify. The loop never stops.</p>\n<h2 id=\"whats-next\">What’s Next</h2>\n<p>We’re working on several improvements:</p>\n<ol>\n<li><strong>Automated gap detection</strong>: Alert when common agent failures could be addressed by an unadopted skill</li>\n<li><strong>Skill deprecation workflows</strong>: Formal process for retiring skills that are superseded or unused</li>\n<li><strong>Cross-skill dependencies</strong>: Explicit declaration of skill prerequisites</li>\n<li><strong>Usage analytics</strong>: Track which skills agents actually invoke vs. just load</li>\n</ol>\n<p>The skill mining loop is infrastructure. It’s not glamorous. But it’s what makes 41 agents work coherently with 466 capabilities while staying within context limits.</p>\n<p>That’s the story of how 3,500 becomes 466. Not by ignoring 3,000 - by evaluating them systematically and adopting only what works.</p>\n<hr>\n<p><em>Want to see the skill system in action? Check out <code>uv run orkestra skills list</code> to explore our current registry.</em></p>\n",
      "date_published": "2026-01-27T00:00:00.000Z",
      "tags": [
        "Architecture",
        "Skills"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/progressive-disclosure-cli-into-agents",
      "url": "https://maguyva.ai/blog/progressive-disclosure-cli-into-agents",
      "title": "Progressive Disclosure: CLI Windows into Agent Systems",
      "summary": "Agent systems are opaque by default. Progressive disclosure gives operators layered CLI views from quick status checks to full agent internals and decision traces.",
      "content_html": "<blockquote>\n<p><em>Numbers in this post reflect the system at publication (January 2026). See our <a href=\"https://maguyva.ai/team\">team page</a> for current figures.</em></p>\n</blockquote>\n<p>Agent systems are opaque by design. They make decisions, invoke tools, and coordinate work across dozens of specialists. But when something goes wrong—or when you simply want to understand what’s happening—where do you look?</p>\n<p>The answer is progressive disclosure: a layered interface that reveals exactly as much complexity as you need, exactly when you need it.</p>\n<h2 id=\"the-opacity-problem\">The Opacity Problem</h2>\n<p>A modern agent orchestration system might have:</p>\n<ul>\n<li>40+ specialist agents, each with distinct capabilities</li>\n<li>700+ skills spanning internal automation and vendor integrations</li>\n<li>470+ architectural decisions shaping behavior</li>\n<li>Dozens of MCP tool servers providing external capabilities</li>\n</ul>\n<p>This complexity is intentional. Agents need access to rich context—domain knowledge, code intelligence, database schemas—to make good decisions. But that same richness creates a visibility problem.</p>\n<p>How do you know which agent handles database migrations? What decisions shaped the search system’s ranking behavior? Which tools does the architecture advisor have access to?</p>\n<p>Without structured access, you’re left reading source code or hoping the documentation is current.</p>\n<h2 id=\"progressive-disclosure-as-architecture\">Progressive Disclosure as Architecture</h2>\n<p>Progressive disclosure isn’t just a UI pattern. It’s an architectural principle: organize information in layers, each deeper than the last, so users can stop at the level that answers their question.</p>\n<p>For agent systems, this translates to CLI commands at increasing depths:</p>\n<table>\n<thead>\n<tr>\n<th>Level</th>\n<th>Command</th>\n<th>Question Answered</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td><code>orkestra system status</code></td>\n<td>Is everything healthy?</td>\n</tr>\n<tr>\n<td>2</td>\n<td><code>orkestra agents list</code></td>\n<td>What agents exist?</td>\n</tr>\n<tr>\n<td>3</td>\n<td><code>orkestra agents info &lt;name&gt;</code></td>\n<td>What does this agent do?</td>\n</tr>\n<tr>\n<td>4</td>\n<td><code>orkestra decisions search</code></td>\n<td>Why does it work this way?</td>\n</tr>\n<tr>\n<td>5</td>\n<td>Maguyva MCP tools</td>\n<td>Show me the code.</td>\n</tr>\n</tbody>\n</table>\n<p>Each level answers a natural follow-up question. You rarely need to jump straight to level 5.</p>\n<h2 id=\"level-1-system-health\">Level 1: System Health</h2>\n<p>The first question is always: is everything working?</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">$</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> system</span><span style=\"color:#9ECBFF\"> status</span></span></code></pre>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"json\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"agents\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">40</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"skills_internal\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">466</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"skills_vendor\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">240</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"skills_total\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">706</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"commands\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">17</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n<p>One command. Four numbers. Enough to know the system is configured and the registries are populated.</p>\n<p>If an agent count drops unexpectedly or skills fail to load, you see it here first. No log diving required.</p>\n<h2 id=\"level-2-agent-inventory\">Level 2: Agent Inventory</h2>\n<p>Once you know the system is healthy, the next question is: what’s available?</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">$</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> agents</span><span style=\"color:#9ECBFF\"> list</span></span></code></pre>\n<p>This returns structured data—agent names, descriptions, model preferences, domain coverage. The output is JSON by default, making it easy to pipe into <code>jq</code> for filtering:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">$</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> agents</span><span style=\"color:#9ECBFF\"> list</span><span style=\"color:#F97583\"> |</span><span style=\"color:#B392F0\"> jq</span><span style=\"color:#9ECBFF\"> '.agents[] | select(.model == \"opus\") | .name'</span></span></code></pre>\n<p>Want agents that handle database work? The search command narrows it down:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">$</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> agents</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#9ECBFF\"> \"database\"</span></span></code></pre>\n<p>This scans names, descriptions, and capabilities. You find the right specialist without reading 40 agent definitions.</p>\n<h2 id=\"level-3-agent-deep-dive\">Level 3: Agent Deep Dive</h2>\n<p>Found an agent that looks relevant? The <code>info</code> command reveals everything:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">$</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> agents</span><span style=\"color:#9ECBFF\"> info</span><span style=\"color:#9ECBFF\"> architecture-advisor</span></span></code></pre>\n<p>The output includes:</p>\n<ul>\n<li><strong>Metadata</strong>: Name, category, model preference, description</li>\n<li><strong>Domains</strong>: Which knowledge areas this agent covers</li>\n<li><strong>Identity</strong>: Character traits (architect, strategist, knowledge-architect)</li>\n<li><strong>Tool guides</strong>: Which tool documentation is injected into context</li>\n<li><strong>Tools</strong>: The full list of MCP tools available to this agent</li>\n</ul>\n<p>Here’s a sample of what you see:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"jsonc\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"metadata\"</span><span style=\"color:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"name\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"architecture-advisor\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"model\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"opus\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"description\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Strategic decision-making and architectural guidance...\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  },</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"domains\"</span><span style=\"color:#E1E4E8\">: [</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    \"product\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    \"development/architecture\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    \"meta/strategy\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  ],</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"tools\"</span><span style=\"color:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"mcp_tools\"</span><span style=\"color:#E1E4E8\">: [</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">      \"mcp__maguyva__intelligent_search\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">      \"mcp__maguyva__analyze_dependencies\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">      \"mcp__supabase__execute_sql\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#FDAEB7;font-style:italic\">      ...</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    ]</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n<p>This tells you exactly what the agent can do. No source code required.</p>\n<h2 id=\"level-4-decision-archaeology\">Level 4: Decision Archaeology</h2>\n<p>Agents behave according to documented decisions. When you need to understand <em>why</em> something works a particular way, the decisions registry is the source of truth.</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">$</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> decisions</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#9ECBFF\"> \"agent\"</span></span></code></pre>\n<p>This returns matching architectural decisions:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"json\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"results\"</span><span style=\"color:#E1E4E8\">: [</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    {</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">      \"id\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"DEC-SR-049\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">      \"title\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"AI-Agent-First Defaults with Graph Intelligence\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">      \"domain\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"search\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">      \"status\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"active\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  ]</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n<p>Each decision has full provenance—when it was made, why, what trade-offs were considered, which commits implemented it:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">$</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> decisions</span><span style=\"color:#9ECBFF\"> info</span><span style=\"color:#9ECBFF\"> DEC-SR-049</span></span></code></pre>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"json\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"id\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"DEC-SR-049\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"title\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"AI-Agent-First Defaults with Graph Intelligence\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"summary\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Changes default values for search tools to AI-agent-optimal behavior...\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"rationale\"</span><span style=\"color:#E1E4E8\">: [</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    \"AI agents work better with pre-ranked, importance-weighted results\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    \"Graph metrics already computed by pipeline - leverage them\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    \"Community context helps agents understand feature scope in single query\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  ],</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"source_commits\"</span><span style=\"color:#E1E4E8\">: [</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    {</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">      \"sha\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"156a880d05eae295669ef7c194b039023f245511\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">      \"message\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"feat(maguyva): enable boost_by_importance...\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  ]</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n<p>This is architectural documentation that stays current because it’s mined from commits, not manually maintained.</p>\n<h2 id=\"level-5-direct-code-intelligence\">Level 5: Direct Code Intelligence</h2>\n<p>When you need to see the actual implementation—not metadata about it—Maguyva’s MCP tools provide direct access.</p>\n<p>From within an agent session:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>mcp__maguyva__intelligent_search</span></span>\n<span class=\"line\"><span>  query: \"agent context loading\"</span></span></code></pre>\n<p>This auto-routes across semantic, text, and AST search to find relevant code. For specific symbols:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>mcp__maguyva__find_symbol</span></span>\n<span class=\"line\"><span>  symbol_name: \"load_agent_context\"</span></span></code></pre>\n<p>For dependency analysis:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>mcp__maguyva__analyze_dependencies</span></span>\n<span class=\"line\"><span>  target: \"packages/orchestration/core/agents.py\"</span></span></code></pre>\n<p>These aren’t just grep replacements. They’re graph-aware, semantically indexed, and integrated with the same code intelligence that powers the agents themselves.</p>\n<h2 id=\"unified-search-across-registries\">Unified Search Across Registries</h2>\n<p>Sometimes you don’t know which registry holds the answer. The unified search spans everything:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">$</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#9ECBFF\"> \"database\"</span><span style=\"color:#79B8FF\"> --summary</span></span></code></pre>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"json\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"query\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"database\"</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"total\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">254</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">  \"counts\"</span><span style=\"color:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"agents\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">40</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"skills\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">59</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"decisions\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">476</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"truths\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">2</span><span style=\"color:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    \"packages\"</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">1</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}</span></span></code></pre>\n<p>254 matches across five registries. The summary tells you where to drill down. Remove <code>--summary</code> for detailed results, or add <code>--limit 5</code> to keep output manageable.</p>\n<h2 id=\"why-this-matters\">Why This Matters</h2>\n<p>Progressive disclosure isn’t just about convenience. It changes how you interact with complex systems.</p>\n<p><strong>Debugging becomes tractable.</strong> When an agent makes an unexpected decision, you don’t grep through logs. You check which tools it has access to (<code>agents info</code>), what decisions shape its behavior (<code>decisions search</code>), and trace the implementation if needed (<code>intelligent_search</code>).</p>\n<p><strong>Onboarding accelerates.</strong> New team members don’t need to read the entire codebase. They start with <code>system status</code>, explore with <code>agents list</code>, and go deeper only when they hit something they don’t understand.</p>\n<p><strong>Documentation stays current.</strong> Because the CLI reads from the same registries that configure the agents, the output is always accurate. There’s no drift between what the docs say and what the system does.</p>\n<h2 id=\"the-cli-as-interface\">The CLI as Interface</h2>\n<p>We could have built a web dashboard. We could have written extensive documentation. Instead, we built a CLI that reads from the source of truth.</p>\n<p>The CLI has advantages:</p>\n<ul>\n<li><strong>Composable</strong>: Pipe output through <code>jq</code>, integrate with scripts</li>\n<li><strong>Scriptable</strong>: Automate checks, generate reports</li>\n<li><strong>Fast</strong>: No page loads, no authentication flows</li>\n<li><strong>Accurate</strong>: Reads the actual configuration, not a cached representation</li>\n</ul>\n<p>For systems where correctness matters more than aesthetics, CLI wins.</p>\n<h2 id=\"building-your-own-progressive-disclosure\">Building Your Own Progressive Disclosure</h2>\n<p>If you’re building agent systems, consider how users will inspect them:</p>\n<ol>\n<li><strong>Start with health checks.</strong> One command that tells you if things are working.</li>\n<li><strong>Provide inventory views.</strong> List what exists before explaining what it does.</li>\n<li><strong>Enable targeted queries.</strong> Search beats browsing at scale.</li>\n<li><strong>Expose provenance.</strong> Let users trace decisions to their origins.</li>\n<li><strong>Connect to code intelligence.</strong> Eventually, users need to see the implementation.</li>\n</ol>\n<p>Each layer answers a follow-up question. Build them in order of frequency—most users stop at layer 2 or 3. Only power users reach layer 5.</p>\n<p>The goal isn’t to expose everything. It’s to expose exactly what’s needed, exactly when it’s needed. That’s progressive disclosure applied to agent architecture.</p>\n",
      "date_published": "2026-01-20T00:00:00.000Z",
      "tags": [
        "Architecture",
        "CLI",
        "Tooling"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/ground-truths-anchoring-ai-to-reality",
      "url": "https://maguyva.ai/blog/ground-truths-anchoring-ai-to-reality",
      "title": "Ground Truths: Anchoring AI Agents to Reality",
      "summary": "AI agents hallucinate confidently. Ground truths are versioned, scoped facts that anchor agent behavior to reality. Here is how we built and enforce them.",
      "content_html": "<blockquote>\n<p><em>Numbers in this post reflect the system at publication (January 2026). See our <a href=\"https://maguyva.ai/team\">team page</a> for current figures.</em></p>\n</blockquote>\n<p>AI agents are remarkably capable. They can reason, synthesize, and generate. But they have a fundamental weakness: they make things up. Not maliciously, but confidently. An agent might invent API parameters that do not exist, reference configurations that were never defined, or apply patterns from its training data that contradict your actual architecture.</p>\n<p>The standard mitigation is “give the agent more context.” But context can be contradictory. Documentation drifts from implementation. Comments lie. Even code can mislead when read without understanding intent.</p>\n<p>We needed something more explicit. Something that could not be ignored or misinterpreted. Something that would anchor agents to verifiable reality.</p>\n<p>We call them Ground Truths.</p>\n<h2 id=\"what-is-a-ground-truth\">What is a Ground Truth?</h2>\n<p>A ground truth is an explicit, versioned statement of fact that agents must respect. It is not documentation. It is not a comment. It is a first-class entity in the system with:</p>\n<ul>\n<li><strong>A unique identifier</strong> (like <code>GT-MAG-015</code> or <code>GT-MAG-036</code>)</li>\n<li><strong>A lifecycle status</strong> (current, tentative, or deprecated)</li>\n<li><strong>A scope</strong> (platform-wide, package-specific, or domain-bound)</li>\n<li><strong>Evidence</strong> (file paths, URLs, or references that prove the statement)</li>\n<li><strong>Agent guidance</strong> (explicit do/avoid instructions)</li>\n</ul>\n<p>Here is an example from our Maguyva code intelligence platform:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">- </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-015</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  status</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">current</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  scope</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">package</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  statement</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Fuzzy symbol matching is opt-in via `find_similar=true`.</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Default behavior returns empty results for non-existent symbols;</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    `exact_match=true` enforces strict matching and disables all fuzzy fallbacks.</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  rationale</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Deterministic defaults prevent agents from receiving misleading results.</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Typos should fail explicitly rather than silently returning unrelated symbols.</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  evidence</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">\"packages/maguyva/server/src/maguyva/services/code_analysis_service.py\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">\"packages/maguyva/server/docs/quick_reference/parameters.md\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  last_verified</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"2026-01-25\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  tags</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">product</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">ai_first</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">principle</span></span></code></pre>\n<p>This is not prose. It is a contract. When an agent encounters this ground truth, it knows:</p>\n<ol>\n<li>The default is deterministic (empty results, not fuzzy guesses)</li>\n<li>There are specific parameters (<code>find_similar</code>, <code>exact_match</code>) with defined behaviors</li>\n<li>Evidence exists in specific files that can be verified</li>\n<li>The statement was verified on a specific date</li>\n</ol>\n<h2 id=\"the-anatomy-of-a-ground-truth-registry\">The Anatomy of a Ground Truth Registry</h2>\n<p>Ground truths live in YAML registries under <code>ai_assets/reference/ground_truths.yaml</code>. Each package or domain can have its own registry. The structure is:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">metadata</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  title</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Maguyva Ground Truths\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  summary</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Foundational constraints and principles that guide Maguyva.\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  last_updated</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"2026-01-26\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  owner</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"maguyva\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  render</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    include_statuses</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">current</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">tentative</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    show_deprecated</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    groups</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#85E89D\">title</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Product Principles\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">        tags</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">product</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">principle</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">brand</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#85E89D\">title</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Architecture &amp; Boundaries\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">        tags</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">architecture</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">boundaries</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">cqrs</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#85E89D\">statements</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-001</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    status</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">current</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    scope</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">package</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    statement</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Maguyva is read-only with respect to user repositories...\"</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    ...</span></span></code></pre>\n<p>The registry includes metadata about the collection itself, render configuration for documentation generation, and the statements themselves. Each statement follows a strict schema validated by Pydantic models:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"python\"><code><span class=\"line\"><span style=\"color:#F97583\">class</span><span style=\"color:#B392F0\"> GroundTruthStatement</span><span style=\"color:#E1E4E8\">(</span><span style=\"color:#B392F0\">BaseModel</span><span style=\"color:#E1E4E8\">):</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF\">    id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">str</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    status: GTStatus  </span><span style=\"color:#959da5\"># current, tentative, deprecated</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    source: GTSource </span><span style=\"color:#F97583\">|</span><span style=\"color:#79B8FF\"> None</span><span style=\"color:#959da5\">  # claude-code, orkestra, discipline</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    scope: GTScope  </span><span style=\"color:#959da5\"># platform, package, domain</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    statement: </span><span style=\"color:#79B8FF\">str</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    rationale: </span><span style=\"color:#79B8FF\">str</span><span style=\"color:#F97583\"> |</span><span style=\"color:#79B8FF\"> None</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    evidence: list[</span><span style=\"color:#79B8FF\">str</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    last_verified: </span><span style=\"color:#79B8FF\">str</span><span style=\"color:#F97583\"> |</span><span style=\"color:#79B8FF\"> None</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    tags: list[</span><span style=\"color:#79B8FF\">str</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    agent_guidance: AgentGuidance </span><span style=\"color:#F97583\">|</span><span style=\"color:#79B8FF\"> None</span></span></code></pre>\n<h2 id=\"how-agents-access-ground-truths\">How Agents Access Ground Truths</h2>\n<p>Ground truths are exposed through multiple channels:</p>\n<h3 id=\"1-rendered-documentation\">1. Rendered Documentation</h3>\n<p>The <code>orkestra sync</code> command transforms YAML registries into readable markdown:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> sync</span></span></code></pre>\n<p>This generates <code>GROUND_TRUTHS.md</code> files that are included in agent context. The rendered output groups statements by status and category:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"markdown\"><code><span class=\"line\"><span style=\"color:#79B8FF;font-weight:bold\">## Current</span></span>\n<span class=\"line\"><span style=\"color:#79B8FF;font-weight:bold\">### Product Principles</span></span>\n<span class=\"line\"><span style=\"color:#FFAB70\">-</span><span style=\"color:#E1E4E8\"> Maguyva is read-only with respect to user repositories... (GT-MAG-001)</span></span>\n<span class=\"line\"><span style=\"color:#FFAB70\">-</span><span style=\"color:#E1E4E8\"> Design tool responses for AI agents first... (GT-MAG-009)</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#79B8FF;font-weight:bold\">### Architecture &amp; Boundaries</span></span>\n<span class=\"line\"><span style=\"color:#FFAB70\">-</span><span style=\"color:#E1E4E8\"> Pipeline and Maguyva boundaries are intentional... (GT-MAG-006)</span></span></code></pre>\n<h3 id=\"2-cli-search\">2. CLI Search</h3>\n<p>Agents with shell access can search ground truths programmatically:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> registry</span><span style=\"color:#9ECBFF\"> truths</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#9ECBFF\"> \"embedding\"</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> registry</span><span style=\"color:#9ECBFF\"> truths</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#79B8FF\"> --tag</span><span style=\"color:#9ECBFF\"> security</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">uv</span><span style=\"color:#9ECBFF\"> run</span><span style=\"color:#9ECBFF\"> orkestra</span><span style=\"color:#9ECBFF\"> registry</span><span style=\"color:#9ECBFF\"> truths</span><span style=\"color:#9ECBFF\"> list</span><span style=\"color:#79B8FF\"> --status</span><span style=\"color:#9ECBFF\"> current</span></span></code></pre>\n<p>The search function scores matches across multiple fields with weighted relevance:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"python\"><code><span class=\"line\"><span style=\"color:#F97583\">def</span><span style=\"color:#B392F0\"> truth_fields</span><span style=\"color:#E1E4E8\">(gt: GroundTruthStatement) -&gt; list[FieldSpec]:</span></span>\n<span class=\"line\"><span style=\"color:#F97583\">    return</span><span style=\"color:#E1E4E8\"> [</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        FieldSpec(</span><span style=\"color:#FFAB70\">name</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">\"id\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">weight</span><span style=\"color:#F97583\">=</span><span style=\"color:#79B8FF\">6</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">values</span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\">[gt.id]),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        FieldSpec(</span><span style=\"color:#FFAB70\">name</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">\"statement\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">weight</span><span style=\"color:#F97583\">=</span><span style=\"color:#79B8FF\">5</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">values</span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\">[gt.statement]),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        FieldSpec(</span><span style=\"color:#FFAB70\">name</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">\"rationale\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">weight</span><span style=\"color:#F97583\">=</span><span style=\"color:#79B8FF\">4</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">values</span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\">[gt.rationale] </span><span style=\"color:#F97583\">if</span><span style=\"color:#E1E4E8\"> gt.rationale </span><span style=\"color:#F97583\">else</span><span style=\"color:#E1E4E8\"> []),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        FieldSpec(</span><span style=\"color:#FFAB70\">name</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">\"tags\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">weight</span><span style=\"color:#F97583\">=</span><span style=\"color:#79B8FF\">3</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">values</span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\">gt.tags </span><span style=\"color:#F97583\">or</span><span style=\"color:#E1E4E8\"> []),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">        FieldSpec(</span><span style=\"color:#FFAB70\">name</span><span style=\"color:#F97583\">=</span><span style=\"color:#9ECBFF\">\"evidence\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">weight</span><span style=\"color:#F97583\">=</span><span style=\"color:#79B8FF\">2</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#FFAB70\">values</span><span style=\"color:#F97583\">=</span><span style=\"color:#E1E4E8\">gt.evidence </span><span style=\"color:#F97583\">or</span><span style=\"color:#E1E4E8\"> []),</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    ]</span></span></code></pre>\n<h3 id=\"3-context-composition\">3. Context Composition</h3>\n<p>When agents are rendered from YAML definitions, their context can reference ground truth registries:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">context_composition</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  domain_knowledge</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">packages/maguyva/ai_assets/reference/ground_truths.yaml</span></span></code></pre>\n<p>This ensures relevant ground truths are loaded before the agent begins work.</p>\n<h2 id=\"categories-of-ground-truths\">Categories of Ground Truths</h2>\n<p>Looking across our registries, ground truths cluster into several patterns:</p>\n<h3 id=\"product-principles\">Product Principles</h3>\n<p>Constraints on what the product is and is not:</p>\n<blockquote>\n<p>“Maguyva is read-only with respect to user repositories; the only non-rebuildable asset is the paid embeddings cache.” (GT-MAG-001)</p>\n</blockquote>\n<h3 id=\"architecture-boundaries\">Architecture Boundaries</h3>\n<p>Where responsibilities live and why:</p>\n<blockquote>\n<p>“Pipeline and Maguyva boundaries are intentional: pipeline is reusable, Maguyva holds code-specific logic, and CQRS separates stage writes from server reads.” (GT-MAG-006)</p>\n</blockquote>\n<h3 id=\"anti-hallucination-rules\">Anti-Hallucination Rules</h3>\n<p>Explicit mandates that keep tool contracts deterministic instead of inferred:</p>\n<blockquote>\n<p>“Fuzzy symbol matching is opt-in via <code>find_similar=true</code>. Default behavior returns empty results for non-existent symbols; <code>exact_match=true</code> enforces strict matching and disables all fuzzy fallbacks.” (GT-MAG-015)</p>\n</blockquote>\n<h3 id=\"quality-gates\">Quality Gates</h3>\n<p>Standards that must be maintained:</p>\n<blockquote>\n<p>“Changes to shared infrastructure (post_filters.py, relationship extractors, shared handlers) MUST be validated against ALL supported languages via full manifest generation before commit. A single-language validation is insufficient for shared code.” (GT-MAG-036)</p>\n</blockquote>\n<h3 id=\"code-patterns\">Code Patterns</h3>\n<p>Implementation requirements:</p>\n<blockquote>\n<p>“Use <code>asyncio.to_thread()</code> for CPU-bound work in async contexts; the deprecated <code>loop.run_in_executor()</code> pattern should not be used in new code.” (GT-MAG-018)</p>\n</blockquote>\n<h2 id=\"the-lifecycle-of-a-ground-truth\">The Lifecycle of a Ground Truth</h2>\n<p>Ground truths are not static. They evolve through a defined lifecycle:</p>\n<h3 id=\"tentative\">Tentative</h3>\n<p>A proposed truth under evaluation. The statement is recorded but may change:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">- </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-044</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  status</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">tentative</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  statement</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    get_file with include_metadata=false may still return metadata in the</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    response because middleware may re-inject it for AI agent disambiguation.</span></span></code></pre>\n<h3 id=\"current\">Current</h3>\n<p>A verified truth that agents must respect. Evidence has been validated:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">- </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-017</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  status</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">current</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  last_verified</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"2026-01-26\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  evidence</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    - </span><span style=\"color:#9ECBFF\">\"packages/maguyva/server/src/maguyva/services/supabase.py\"</span></span></code></pre>\n<h3 id=\"deprecated\">Deprecated</h3>\n<p>A truth that no longer applies. Kept for historical reference with a pointer to what replaced it:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">- </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-099</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  status</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">deprecated</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  superseded_by</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-015</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  notes</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"Replaced when we moved to explicit matching behavior\"</span></span></code></pre>\n<h2 id=\"why-not-just-documentation\">Why Not Just Documentation?</h2>\n<p>Documentation serves a different purpose. It explains. It teaches. It can be vague, can use qualifiers like “generally” or “typically.”</p>\n<p>Ground truths cannot be vague. They are assertions. They either apply or they do not.</p>\n<p>Consider the difference:</p>\n<p><strong>Documentation:</strong> “The API generally returns empty results when a symbol is not found, though fuzzy matching may be enabled in some configurations.”</p>\n<p><strong>Ground Truth:</strong> “Default behavior returns empty results for non-existent symbols; <code>exact_match=true</code> enforces strict matching and disables all fuzzy fallbacks.”</p>\n<p>The first is helpful for humans learning the system. The second is actionable for agents making decisions.</p>\n<h2 id=\"agent-guidance-do-and-avoid\">Agent Guidance: Do and Avoid</h2>\n<p>Some ground truths include explicit agent guidance:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">- </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-022</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  statement</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Accuracy fixes must happen at extraction time via production code,</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    never via validator filters.</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  agent_guidance</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    do</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">\"Fix extraction bugs in YAML config, handlers, or tree-sitter queries\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">\"Add test cases at the layer where the fix lives\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    avoid</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">\"Adding validator filters to mask production bugs\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#9ECBFF\">\"Creating test-only workarounds for extraction issues\"</span></span></code></pre>\n<p>This removes ambiguity. An agent reading this knows not just what is true, but what actions that truth implies.</p>\n<h2 id=\"verification-and-maintenance\">Verification and Maintenance</h2>\n<p>Ground truths require maintenance. We track:</p>\n<ul>\n<li><strong>last_verified</strong>: When someone confirmed the statement still holds</li>\n<li><strong>evidence</strong>: Files that prove the statement (can be checked for existence)</li>\n<li><strong>source</strong>: Where the truth originated (CLI inspection, architecture review, post-incident learning)</li>\n</ul>\n<p>A ground truth with stale verification dates or broken evidence links is a signal to investigate. Either the truth is still valid and needs re-verification, or reality has changed and the truth needs updating.</p>\n<h2 id=\"real-examples-from-production\">Real Examples from Production</h2>\n<h3 id=\"security-boundary\">Security Boundary</h3>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">- </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-014</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  statement</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Maguyva queries are search patterns, not executable code.</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    SQL injection prevention is handled by PostgREST parameterization;</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    application-layer SQL keyword blocking must never be added.</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  rationale</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Blocking SQL keywords breaks legitimate code search. Users search FOR</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    code containing patterns like 'DROP TABLE', they don't execute them.</span></span></code></pre>\n<p>This ground truth prevents a class of misguided “security improvements” that would break the product.</p>\n<h3 id=\"extraction-time-accuracy\">Extraction-Time Accuracy</h3>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">- </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-022</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  statement</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Accuracy fixes must happen at extraction time via production code</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    (YAML config, handlers, queries), never via validator filters.</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  rationale</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Validator filters only run during tests. They can hide extractor bugs</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    while production responses remain wrong.</span></span></code></pre>\n<p>This came from painful experience. Agents would patch failing language packs by adding validator-only filters that made the test harness look greener, while the live Maguyva extractor still emitted the wrong edges. The rule forces fixes back into the real path: YAML config, queries, or handlers.</p>\n<h3 id=\"multi-tier-filtering\">Multi-Tier Filtering</h3>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#E1E4E8\">- </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">GT-MAG-023</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  statement</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Language engine uses three-tier filtering: external_method_patterns</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    (builtins/stdlib), allowlists (legitimate idioms), and expected_call_targets</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    (validation-time deduplication). Each tier serves a distinct purpose.</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  rationale</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#F97583\">|</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    Conflating filter purposes leads to either over-filtering (missing real</span></span>\n<span class=\"line\"><span style=\"color:#9ECBFF\">    relationships) or under-filtering (noise).</span></span></code></pre>\n<p>This prevents agents from adding filters in the wrong place, a common mistake that caused accuracy regressions.</p>\n<h2 id=\"integration-with-the-orchestration-system\">Integration with the Orchestration System</h2>\n<p>Ground truths are one layer of a broader context system:</p>\n<ol>\n<li><strong>Architectural Decisions (ADRs)</strong> - Record why we chose approach A over B</li>\n<li><strong>Ground Truths</strong> - State what is definitively true right now</li>\n<li><strong>Domain Patterns</strong> - Describe how to do things correctly</li>\n<li><strong>Anti-Patterns</strong> - Describe what to avoid and why</li>\n</ol>\n<p>An agent working in the system has access to all four. Ground truths provide the factual anchor, while decisions explain history, patterns guide implementation, and anti-patterns warn of pitfalls.</p>\n<h2 id=\"measuring-impact\">Measuring Impact</h2>\n<p>Since introducing ground truths, we have observed:</p>\n<ul>\n<li>Fewer “fix the hallucinated fix” cycles</li>\n<li>More confident agent decision-making when facts are clear</li>\n<li>Better PR reviews because expectations are explicit</li>\n<li>Reduced onboarding time for new agents (and humans)</li>\n</ul>\n<p>The investment in maintaining ground truths pays off in reduced debugging and clearer system boundaries.</p>\n<h2 id=\"getting-started\">Getting Started</h2>\n<p>To add a ground truth to your system:</p>\n<ol>\n<li>Create a <code>ground_truths.yaml</code> in your package’s <code>ai_assets/reference/</code> directory</li>\n<li>Define metadata and render configuration</li>\n<li>Add statements following the schema</li>\n<li>Run <code>uv run orkestra sync</code> to generate documentation</li>\n<li>Include the registry in agent context composition</li>\n</ol>\n<p>Start with the facts that cause the most confusion or the constraints that get violated most often. Those are your highest-value ground truths.</p>\n<h2 id=\"conclusion\">Conclusion</h2>\n<p>AI agents will hallucinate. That is their nature. But we can create environments where hallucination is constrained, where certain facts are non-negotiable, where agents can check their assumptions against verified reality.</p>\n<p>Ground truths are not a complete solution. They require maintenance. They can become stale. They add overhead to the development process.</p>\n<p>But they provide something valuable: a shared vocabulary of facts that both humans and agents can trust. In a world where agents increasingly participate in software development, that shared foundation becomes essential.</p>\n<p>The alternative is endless cycles of agents making confident mistakes and humans correcting them. Ground truths break that cycle by making the corrections explicit and durable.</p>\n<p>Your agents deserve to know what is true. Tell them.</p>\n",
      "date_published": "2026-01-13T00:00:00.000Z",
      "tags": [
        "Architecture",
        "Grounding"
      ]
    },
    {
      "id": "https://maguyva.ai/blog/orkestra-agent-orchestration",
      "url": "https://maguyva.ai/blog/orkestra-agent-orchestration",
      "title": "Orkestra: Orchestrating AI Agents at Scale",
      "summary": "One orchestrator routes work to specialist AI agents, each with distinct skills and memory. How Orkestra coordinates 46 agents and 466 skills in production.",
      "content_html": "<blockquote>\n<p><em>Numbers in this post reflect the system at publication (January 2026). See our <a href=\"https://maguyva.ai/team\">team page</a> for current figures.</em></p>\n</blockquote>\n<p>When we started building with Claude Code, we ran into a problem that every team using AI coding assistants eventually faces: a single agent cannot do everything well.</p>\n<p>You can prompt an agent to be a database specialist. Or a security auditor. Or a frontend engineer. But the moment you ask it to be all three at once, quality suffers. Context gets diluted. Instructions conflict. The agent becomes a generalist that is mediocre at everything.</p>\n<p>So we built Orkestra.</p>\n<h2 id=\"what-is-orkestra\">What is Orkestra?</h2>\n<p>Orkestra is an agent orchestration system for Claude Code and similar AI coding tools. It coordinates multiple specialized agents, each with distinct expertise, under a single orchestrator that routes work to the right specialist.</p>\n<p>Think of it as a staffing agency for AI agents. The orchestrator receives a task, identifies which specialist should handle it, and delegates with the right context. When the work is done, results flow back to the orchestrator for synthesis.</p>\n<p>The numbers tell the story:</p>\n<table>\n<thead>\n<tr>\n<th>Component</th>\n<th>Count</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Specialist agents</td>\n<td>46</td>\n</tr>\n<tr>\n<td>Reusable skills</td>\n<td>466</td>\n</tr>\n<tr>\n<td>Identity archetypes</td>\n<td>27</td>\n</tr>\n<tr>\n<td>Mindsets</td>\n<td>11</td>\n</tr>\n<tr>\n<td>Communication styles</td>\n<td>10</td>\n</tr>\n<tr>\n<td>Knowledge domains</td>\n<td>21</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"the-character-system-dd-for-agents\">The Character System: D&amp;D for Agents</h2>\n<p>The core insight behind Orkestra is that agent behavior emerges from three composable primitives:</p>\n<p><strong>Identity</strong> defines <em>what</em> the agent is. An architect designs system structures. A debugger traces failures to root causes. A guardian enforces compliance and security boundaries. We have 27 identity archetypes that can be mixed.</p>\n<p><strong>Mindset</strong> defines <em>how</em> the agent thinks. An analytical mindset grounds assertions in evidence and quantifies uncertainty. A skeptical mindset questions assumptions and seeks disconfirming evidence. An exploratory mindset embraces ambiguity and tries multiple approaches.</p>\n<p><strong>Style</strong> defines <em>how</em> the agent communicates. A technical style includes exact values and references specific files. A concise style cuts fluff and leads with the answer. A diplomatic style balances honesty with tact.</p>\n<p>An agent combines these primitives:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#959da5\"># architecture-advisor.yaml</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">identity</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">knowledge-architect</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">architect</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#9ECBFF\">strategist</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">mindset</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">analytical</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">style</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">concise</span></span></code></pre>\n<p>This composition creates an agent that designs systems (architect), connects knowledge across domains (knowledge-architect), sets strategic direction (strategist), thinks in evidence and data (analytical), and communicates without fluff (concise).</p>\n<p>The power is in combinatorial explosion. 27 identities times 11 mindsets times 10 styles yields nearly 3,000 possible agent personalities. But you only define the combinations that matter for your work.</p>\n<h2 id=\"skills-reusable-capability-modules\">Skills: Reusable Capability Modules</h2>\n<p>Skills are the knowledge and workflows that agents can invoke. They follow a tiered system based on scope:</p>\n<table>\n<thead>\n<tr>\n<th>Tier</th>\n<th>Name</th>\n<th>Scope</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>K0</td>\n<td>Foundations</td>\n<td>Universal methodology</td>\n<td>Test-first discipline, evidence-based completion</td>\n</tr>\n<tr>\n<td>K1</td>\n<td>Identities</td>\n<td>Role-based workflows</td>\n<td>CLI interface standards, performance playbook</td>\n</tr>\n<tr>\n<td>K2</td>\n<td>Domains</td>\n<td>Domain-specific knowledge</td>\n<td>Database migration patterns, authentication validation</td>\n</tr>\n<tr>\n<td>K3</td>\n<td>Stacks</td>\n<td>Technology-specific</td>\n<td>Cloudflare deployment, Supabase operations</td>\n</tr>\n<tr>\n<td>K4</td>\n<td>Project</td>\n<td>This codebase only</td>\n<td>Project-specific workflows and conventions</td>\n</tr>\n</tbody>\n</table>\n<p>Skills are lazy-loaded. An agent sees skill names and descriptions at startup, but full skill content only loads when triggered. This keeps context lean while making hundreds of skills discoverable.</p>\n<p>Each skill includes:</p>\n<ul>\n<li>Clear trigger conditions (“Use when migrating database schemas”)</li>\n<li>Step-by-step guidance</li>\n<li>Allowed tools for the workflow</li>\n<li>Success criteria and failure recovery paths</li>\n</ul>\n<p>The 466 skills in our registry cover everything from git worktree isolation to web research workflows to deployment health validation.</p>\n<h2 id=\"why-orchestration-matters\">Why Orchestration Matters</h2>\n<p>Single-agent architectures hit walls quickly:</p>\n<p><strong>Context dilution.</strong> A 200k token context window sounds large until you load database schemas, API docs, test fixtures, and domain knowledge. Specialists can work with targeted context.</p>\n<p><strong>Instruction conflicts.</strong> Telling an agent to “be thorough but fast” and “verify everything but don’t over-engineer” creates tension. Specialists resolve these by having clear scope.</p>\n<p><strong>Expertise depth.</strong> A generalist agent knows a little about everything. A specialist agent, composed with the right identity and skills, knows its domain deeply.</p>\n<p>Orkestra implements flat orchestration: one orchestrator coordinates multiple specialists. Specialists cannot spawn sub-specialists. This prevents complexity explosion while enabling parallel work.</p>\n<p>The orchestrator has access to 2.2 million tokens of effective capacity: its own 200k window plus 10 concurrent subagents with 200k each. Work that would exhaust a single agent runs comfortably across the fleet.</p>\n<h2 id=\"the-rendering-pipeline\">The Rendering Pipeline</h2>\n<p>Agent definitions live in YAML. Claude Code reads Markdown. Orkestra bridges this gap with a deterministic rendering pipeline:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>YAML Registries → Jinja Templates → .claude/agents/*.md</span></span></code></pre>\n<p>Operators edit YAML source. Run <code>orkestra sync</code>. Rendered Markdown appears in <code>.claude/agents/</code>. Claude Code picks up the changes.</p>\n<p>This separation serves different audiences:</p>\n<ul>\n<li><strong>YAML source</strong> includes lifecycle metadata, tags, validation rules, and deprecation notes for tooling</li>\n<li><strong>Rendered Markdown</strong> includes only what the model needs: description, tools, skills, and behavioral guidance</li>\n</ul>\n<p>The pipeline composes identities, mindsets, styles, and skills into a single coherent prompt. An architect-analytical-concise agent gets a very different system prompt than a debugger-skeptical-technical agent, even if they share some underlying skills.</p>\n<h2 id=\"domain-knowledge-the-four-file-pattern\">Domain Knowledge: The Four-File Pattern</h2>\n<p>Every knowledge domain follows a consistent structure:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>domain-name/</span></span>\n<span class=\"line\"><span>  decisions.md      # Key choices, rationale, consequences</span></span>\n<span class=\"line\"><span>  patterns.md       # Step-by-step guidance and examples</span></span>\n<span class=\"line\"><span>  anti-patterns.md  # Failure modes and remediation</span></span>\n<span class=\"line\"><span>  evolution.md      # Dated log of changes</span></span></code></pre>\n<p>This structure serves agent context loading. An agent working on authentication loads <code>authentication/patterns.md</code> for guidance and <code>authentication/anti-patterns.md</code> to avoid known pitfalls. The files are sized for efficient context loading: focused enough to be useful, comprehensive enough to be authoritative.</p>\n<p>We maintain 21 top-level domains including analytics, authentication, data science, infrastructure, machine learning, performance, security, and more. Each domain can have sub-domains for finer granularity.</p>\n<h2 id=\"values-the-operating-system\">Values: The Operating System</h2>\n<p>All agents share a base layer of values that define how they operate:</p>\n<p><strong>Simplicity first.</strong> Use the simplest solution that works. Add complexity only when justified.</p>\n<p><strong>Fix root causes.</strong> Never patch around failures. If a pipeline fails, debug the pipeline. If a test fails, fix the code or the test.</p>\n<p><strong>Evidence-based.</strong> Label claims as “verified” (with benchmarks) or “estimated” (with assumptions). Pattern detected does not equal problem confirmed.</p>\n<p><strong>Context economics.</strong> MCP tools cost 0.1% of context. File reads cost 2% each. Apply domain expertise before exploring code.</p>\n<p>These values propagate to every specialist through the rendering pipeline. An agent cannot bypass them by composition.</p>\n<h2 id=\"cli-the-control-plane\">CLI: The Control Plane</h2>\n<p>Orkestra ships with a CLI for managing the agent ecosystem:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"color:#959da5\"># Discovery</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">orkestra</span><span style=\"color:#9ECBFF\"> agents</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#9ECBFF\"> \"database\"</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">orkestra</span><span style=\"color:#9ECBFF\"> agents</span><span style=\"color:#9ECBFF\"> info</span><span style=\"color:#9ECBFF\"> database-architect</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Validation</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">orkestra</span><span style=\"color:#9ECBFF\"> validate</span><span style=\"color:#79B8FF\"> --show-warnings</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Rendering</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">orkestra</span><span style=\"color:#9ECBFF\"> sync</span><span style=\"color:#79B8FF\"> --dry-run</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">orkestra</span><span style=\"color:#9ECBFF\"> sync</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Skills</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">orkestra</span><span style=\"color:#9ECBFF\"> skills</span><span style=\"color:#9ECBFF\"> list</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">orkestra</span><span style=\"color:#9ECBFF\"> skills</span><span style=\"color:#9ECBFF\"> info</span><span style=\"color:#9ECBFF\"> schema-migration-workflow</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#959da5\"># Decisions</span></span>\n<span class=\"line\"><span style=\"color:#B392F0\">orkestra</span><span style=\"color:#9ECBFF\"> decisions</span><span style=\"color:#9ECBFF\"> search</span><span style=\"color:#9ECBFF\"> \"authentication\"</span></span></code></pre>\n<p>The CLI is the source of truth for what agents exist, what skills they have, and whether the system is healthy. It runs validation before sync to catch problems early.</p>\n<h2 id=\"open-source-considerations\">Open Source Considerations</h2>\n<p>We built Orkestra to solve our own problem: coordinating AI agents at scale for a complex codebase. The patterns we discovered are not specific to our domain.</p>\n<p>The character composition system (identity + mindset + style) applies to any team defining agent personalities.</p>\n<p>The skill tier system (K0-K4) provides a mental model for organizing reusable capabilities by scope.</p>\n<p>The rendering pipeline pattern (YAML source + templates + generated artifacts) separates concerns between tooling and model consumption.</p>\n<p>The flat orchestration model (one coordinator, many specialists) avoids complexity while enabling parallelism.</p>\n<p>Whether Orkestra becomes open source depends on whether these patterns have value for others building with Claude Code. If you are hitting the walls we described, the architecture might help.</p>\n<h2 id=\"what-we-learned\">What We Learned</h2>\n<p>Building Orkestra taught us that orchestration is not about making agents smarter. It is about making them more focused.</p>\n<p>A single agent with perfect instructions still runs out of context. A single agent with all the skills still gets confused about which to apply. A single agent trying to be everything produces mediocre results everywhere.</p>\n<p>Forty specialists, each excellent in their domain, coordinated by an orchestrator that knows when to delegate: that is how we ship.</p>\n<p>The numbers matter less than the architecture. You might need five agents or fifty. The principle remains: composition over capability, specialization over generalization, coordination over individual heroics.</p>\n<hr>\n<p><em>Orkestra powers the agent ecosystem behind Maguyva, our code intelligence platform. Want to learn more? Reach out to the team.</em></p>\n",
      "date_published": "2026-01-06T00:00:00.000Z",
      "tags": [
        "Architecture",
        "Open Source"
      ]
    }
  ]
}