// AUTO-GENERATED by scripts/gen-agent-definitions.ts — DO NOT EDIT.
// Run `npm run codegen` to regenerate.
//
// Bundled agent definition assets for the Bun-compiled binary path.
// The compiled binary resolves loader paths under `/$bunfs/`, where the
// source YAML files are not readable from the real filesystem. The loader
// falls back to these parsed definitions and prompt templates in that case.

import type { AgentDefinition, AgentTask } from './types.js';

export const BUNDLED_AGENT_DEFINITION: AgentDefinition = {
  "name": "myco-agent",
  "displayName": "Myco Agent",
  "description": "Default intelligence agent that processes captured session data, extracts observations (spores), manages spore lifecycle, and synthesizes digest extracts.\n",
  "model": "sonnet",
  "maxTurns": 30,
  "timeoutSeconds": 300,
  "systemPromptPath": "../prompts/agent.md",
  "tools": [
    "vault_unprocessed",
    "vault_session_summary_material",
    "vault_spores",
    "vault_sessions",
    "vault_search_fts",
    "vault_search_semantic",
    "vault_release_state",
    "vault_state",
    "vault_edges",
    "vault_skill_survey_prepare",
    "vault_skill_survey_bundle_decisions",
    "vault_skill_survey_reconciliation_plan",
    "vault_skill_survey_apply_reconciliation",
    "vault_skill_candidates",
    "vault_skill_records",
    "vault_create_spore",
    "vault_resolve_spore",
    "vault_update_session",
    "vault_mark_processed",
    "vault_read_digest",
    "vault_write_digest",
    "vault_set_state",
    "vault_report",
    "fs_read",
    "fs_list",
    "fs_tree",
    "code_grep"
  ]
} as const;

export const BUNDLED_AGENT_TASKS: readonly AgentTask[] = [
  {
    "name": "canopy-describe",
    "displayName": "Canopy Describe",
    "description": "Generate one-sentence file summaries to populate llm_description on canopy_entries. Local-first; runs as a background trickle.",
    "agent": "myco-agent",
    "prompt": "Map-mode task: the harness fans out per-item prompts for each pending canopy_entries row. No manual tool orchestration needed.",
    "isDefault": false,
    "reasoningLevel": "low",
    "maxTurns": 60,
    "timeoutSeconds": 1800,
    "phases": [
      {
        "name": "describe",
        "prompt": "",
        "tools": [],
        "maxTurns": 1,
        "reasoningLevel": "low",
        "required": true,
        "mode": "map",
        "perItemMaxTurns": 5,
        "perItemTimeoutSeconds": 60,
        "onItemError": "skip",
        "source": {
          "tool": "canopy_describe_next",
          "args": {
            "canopy_entry_path": "{{ params.canopy_entry_path | default(null) }}",
            "limit": "{{ params.batch_size | default(10) }}"
          },
          "itemsPath": "entries"
        },
        "item": {
          "prompt": "Call the canopy_describe_write tool with one sentence describing\nthis file's architectural purpose at the system level. Style:\nexactly one sentence, max 180 chars, no markdown, no quotes, no\npreamble. If the file is configuration, generated, or trivial,\nsay so. Do not narrate exports already visible in the metadata.\nYou MUST emit the tool call — text-only responses are discarded.\n\nFile: {{ item.path }}\nLanguage: {{ item.language }}\nExports: {{ item.exports }}\nImports: {{ item.imports }}\nTop comment: {{ item.top_comment }}\nFirst lines:\n{{ item.first_lines }}\n"
        },
        "sink": {
          "tool": "canopy_describe_write",
          "argMap": {
            "path": "{{ item.path }}"
          }
        }
      }
    ],
    "schedule": {
      "enabled": false,
      "intervalSeconds": 120,
      "runIn": [
        "active",
        "idle",
        "sleep"
      ],
      "preCondition": "has-pending-canopy-rows",
      "accelerator": {
        "name": "canopy-pending-describe",
        "thresholds": {
          "steady": 50,
          "accelerated": 500
        }
      }
    },
    "params": {
      "batch_size": 10,
      "max_description_chars": 180,
      "max_attempts": 2
    }
  },
  {
    "name": "canopy-map",
    "displayName": "Canopy Map",
    "description": "Build the Canopy Map — a guided tour of your project's architecture that connected agents can pull on demand to orient before exploring with Glob or Grep. Refreshes incrementally as the codebase shifts.",
    "agent": "myco-agent",
    "prompt": "Produce a markdown architectural overview of this project. The gather phase pre-assembles the inputs (canopy_entries + rules files); the render phase shapes them into the final map. The map is persisted via vault_report with action \"canopy_map\".",
    "isDefault": false,
    "reasoningLevel": "low",
    "maxTurns": 30,
    "timeoutSeconds": 600,
    "phases": [
      {
        "name": "render",
        "prompt": "You produce a compact markdown architectural overview of this\nproject. The instruction payload contains every input you need:\nthe prior map (when one exists), the full set of described\ncanopy_entries (path, content_hash, llm_description), and the\nfilenames of the project's rules files.\n\nRequired structure for the final markdown:\n\n## Directory skeleton\nOne line per top-level directory, plus a brief note on what\nlives there. Aim for shape, not exhaustiveness — collapse deep\nbranches the way a senior engineer would describe the project\nto a new hire.\n\n## Key files / golden paths\n4–8 domain clusters. Each cluster is a short heading (e.g.\n\"Capture pipeline\", \"Agent harness\") followed by 2–4 file\nbullets. Each bullet is `path — annotation`, where the\nannotation is grounded in the file's llm_description (do not\ninvent purpose).\n\nRefinement rules when a prior map is present:\n- Preserve sections that still apply.\n- Update sections whose underlying files have drifted.\n- Remove clusters whose files no longer exist or no longer\n  belong together.\n- Do NOT rewrite the whole thing if the change is incremental.\n\nOutput budget: 1500–3000 tokens of markdown. Stay terse.\nProse only where it earns its keep — bullets carry the weight.\n\nUse the supplied tools sparingly:\n- `vault_search_canopy` / `vault_search_fts` to disambiguate a\n  cluster boundary when the canopy entries are ambiguous.\n- `fs_read` to confirm a file's role when its llm_description\n  is missing or doesn't match its imports/exports.\n- `vault_spores` to surface an architectural decision worth\n  citing inline.\n\nWhen the map is ready, call `vault_report` with:\n- action: \"canopy_map\"\n- summary: one short sentence on what changed vs. the prior map\n  (or \"initial map\" on the first run)\n- details.content: the final markdown (the entire map, not a diff)\n\nDo not call vault_report more than once. Stop after the report.\n",
        "tools": [
          "vault_search_canopy",
          "vault_search_fts",
          "vault_spores",
          "fs_read",
          "vault_report"
        ],
        "maxTurns": 20,
        "reasoningLevel": "low",
        "required": true,
        "onItemError": "skip"
      }
    ],
    "schedule": {
      "enabled": true,
      "intervalSeconds": 21600,
      "runIn": [
        "idle",
        "sleep"
      ]
    }
  },
  {
    "name": "cortex-instructions",
    "displayName": "Cortex Instructions",
    "description": "Author compact session-start instructions that teach downstream agents how to use Myco tool behavior correctly, especially retrieval and plan persistence.\n",
    "agent": "myco-agent",
    "prompt": "You are producing session-start instructions for another coding agent\nworking in this project. The final artifact is written in the `author`\nphase via `vault_report` with action \"cortex_instructions\". The `research`\nphase does NOT draft markdown — it produces a compact situation brief\nthat the author phase shapes into prose.\n\nYou will receive:\n- current context configuration and capability summary\n- tool guidance that must be encoded in the final instructions\n- a digest excerpt plus recent sessions, spores (wisdom, decision, discovery),\n  and active plans\n- authoring requirements that constrain the final output\n\nDo not restate AGENTS.md, installation details, or generic Myco boilerplate.\nDo not invent unavailable tools. Do not tell the downstream agent to call\n`myco_skills` — project and Myco skills are registered separately.\nDo not mention retired tool names, even as gotchas or historical context.\nIf recent vault context mentions an obsolete name, translate it to the\ncurrent owning tool from the tool guidance instead.\n",
    "isDefault": false,
    "reasoningLevel": "default",
    "maxTurns": 12,
    "timeoutSeconds": 180,
    "phases": [
      {
        "name": "research",
        "prompt": "Produce a compact situation brief. DO NOT write the final markdown\n— that is the author phase's job.\n\nOutput exactly this structure as your phase summary:\n\n## Hotspots (2-3)\n- <named workstream, plan, or branch> — <one sentence on why a new\n  agent working in this repo should know about it>\n\n## Recent signal\n- <recent session title or spore worth citing> — <why it matters>\n\n## Tool-use hint\n- <one concrete hint a new agent would benefit from, grounded in\n  the recent activity above — e.g. \"check active plans before\n  proposing X because plan Y already covers it\">\n\nUse the pre-assembled input (digest, recent sessions, spores,\nactive plans) as your starting point. Use `vault_search_fts`,\n`vault_spores`, `vault_session_summary_material`, and\n`vault_sessions` only to confirm a hotspot is current or to\ndisambiguate. Prefer active plans and the last 3 settled sessions\nas anchors. If the input names a hotspot, verify it's still live\nbefore keeping it — stale hotspots (work that has shipped and\nmoved on) are worse than no hotspot. Use release state to distinguish\nshipped guidance from active unreleased work; unknown evidence can still\nbe mentioned when it is the best current signal.\n\nIf you cannot identify 2-3 genuine hotspots, emit fewer — never\npad with boilerplate.\n",
        "tools": [
          "vault_read_digest",
          "vault_sessions",
          "vault_session_summary_material",
          "vault_spores",
          "vault_search_fts",
          "vault_search_semantic",
          "vault_release_state"
        ],
        "maxTurns": 10,
        "required": true,
        "readOnly": true,
        "onItemError": "skip"
      },
      {
        "name": "author",
        "prompt": "Write the final session-start markdown from the research brief.\n\nRequired structure (emit sections in EXACTLY this order — the\nordering is load-bearing, last-section primacy is intentional):\n\n1. `## Myco-Enabled Project` heading, then one sentence framing\n   Myco as this repository's project-intelligence layer: the\n   decisions and rationale behind the code (the *why*), how prior\n   work was done (the *how*), and the gotchas the code itself\n   can't show — captured as durable memory and retrievable on\n   demand through the tools below. Keep it to one concrete\n   sentence; do not pitch or use marketing language.\n\n2. A skill-reference sentence telling the agent to use the `myco`\n   skill as the fuller workflow reference for design decisions,\n   non-obvious debugging, prior-project context, plan work,\n   durable knowledge capture, and delegation; the explicit tool\n   guidance in these instructions is the compact always-on version\n   of that workflow. Do not tell the agent to call `myco_skills`.\n\n3. A retrieval paragraph structured as two short workflow-framed\n   sentences, in this order:\n\n   (a) Canopy Map opener — if and only if the tool guidance\n       flags `myco_cortex` op `\"canopy_map\"` as a default opener,\n       lead with a single MCP-form sentence such as\n       \"Call `myco_cortex({\"op\":\"canopy_map\"})` first when you\n       need project layout — finding a feature, locating the right\n       file before editing, or orienting in this codebase.\" Use\n       exactly one invocation form (MCP). Do NOT also list the\n       `myco tool call ...` CLI form in this\n       paragraph; the dual-form phrasing reads as two redundant\n       steps and is the reason agents skip the tool. Frame it as a\n       default first move, never as a condition the agent\n       self-evaluates (\"when you need to explore unfamiliar code\",\n       \"if you're new to the project\"). Do NOT enumerate other\n       `myco_cortex` ops here — `digest` and `canopy_entry` do not\n       belong in the opener sentence.\n\n   (b) Search sentence — describe `myco_search` by the workflow\n       moment that triggers it, not by listing tool args: prior\n       decisions, bug fixes, why-was-this-built questions, or\n       locating source by what it does. Explain that every result\n       includes a stable ID and a `retrieve` hint pointing to the\n       owning entity tool (`myco_sessions`, `myco_plans`,\n       `myco_spores`, etc.). Mention `myco_cortex` op\n       `\"canopy_entry\"` only here, as the follow-up move for a\n       canopy search result — not as a sibling of `canopy_map`.\n\n   The two sentences MUST be a single paragraph (no list, no\n   sub-bullets) so the reading flow is \"default first move →\n   situational lookup.\"\n\n4. A planning-context paragraph naming `myco_plans` with\n   op `\"list\"`, `\"get\"`, and `\"save\"`. Trigger `op:\"list\"`\n   around planning, not around every implementation edit: say\n   that before creating a new plan or spec, or when existing\n   plans may already cover the work, the agent should check for\n   existing plans. Also teach `myco_cortex` op `\"digest\"` as the\n   explicit, optional high-fidelity memory pull for large refactors,\n   large features, broad planning, or unfamiliar cross-system\n   changes; recommend tier 5000 by default and tier 10000 only when\n   the agent has budget and needs deeper historical background. Say\n   not to pull the digest for narrow edits. Do not say \"before\n   implementing anything.\" Close the same paragraph with one\n   conditional handoff clause: when a session's work has drifted\n   clearly out of scope, or context is heavy and the work will\n   continue in a separate session, the agent should prepare a\n   handoff with the `myco-handoff` skill so the next session\n   resumes cleanly. Keep this to a single sentence framed strictly\n   as a boundary trigger (\"when work falls out of scope, or context\n   is heavy and you'll continue elsewhere\") — never a routine step,\n   not something to reach for during ordinary in-scope work, and\n   without its own heading.\n\n5. A delegation sentence telling the agent that when composing a\n   child-agent, subagent, teammate, worker session, or other spawned\n   process prompt, and Myco has not already injected subagent-start\n   Cortex context, it should refresh the current project instructions\n   with `myco_cortex({\"op\":\"instructions\"})` and include the returned\n   instructions verbatim in that agent's prompt, along with the\n   task-specific instructions. Include this CLI fallback in the same\n   sentence for hosts without MCP:\n   `myco tool call myco_cortex --json --input '{\"op\":\"instructions\"}'`.\n   Do not assume the returned instructions have any particular\n   heading or section name.\n\n6. A `### Recent workstreams` section that MUST cite at least\n   one active plan or recent session BY TITLE from the research\n   brief. Keep each cited item to a single line — its title plus\n   one short clause on why it matters to an incoming agent; do\n   not inline file paths, dated decisions, or multi-clause detail,\n   which go stale fastest and belong behind the tools. Frame these\n   as background context — work the project\n   has on file, not a task list for the incoming session. The\n   new agent is launching to do something else; this section\n   helps it avoid duplicating effort or contradicting in-flight\n   work when its actual task happens to overlap. If the research\n   brief suggests a tool invocation that is not already present\n   in the required retrieval, plan-persistence, delegation, or\n   spore-save guidance, omit that invocation; recent-workstream\n   prose must not invent additional tool operations or new\n   `myco_cortex` ops. If the research\n   brief contains zero hotspots, write \"No recent workstreams\n   worth flagging right now.\" verbatim — do not invent, recycle,\n   or pad with stale items.\n\n7. A closing paragraph on `myco_spores` for capturing and curating\n   durable knowledge this session — the call-to-action, last on\n   purpose. Name 2-3 concrete moments that trigger op `\"save\"`:\n   after fixing a non-obvious bug, making a design decision with\n   non-obvious reasoning, discovering a gotcha, or learning\n   something surprising about how a component actually behaves; use\n   workflow-trigger framing (\"when you do X, call op:save\") rather\n   than a passive \"as you work, capture what you discover.\" Draw the\n   boundary plainly: spores are durable knowledge, not task state —\n   a bug still to fix, a deferred TODO, or \"continue X later\"\n   belongs in a plan, not a spore. Say that the agent shares\n   responsibility for spore health (not only the Myco agent): when\n   knowledge it relied on turns out stale or wrong, it should retire\n   it rather than leave it — op `\"supersede\"` when a newer spore\n   replaces it, op `\"consolidate\"` to merge several into one wisdom\n   note, or op `\"obsolete\"` (with a reason) when it is simply no\n   longer relevant with no replacement. Remind the agent to prefer\n   specific over vague: name the file, function, or component and\n   explain the *why*, and keep any illustrative example\n   self-contained (a gotcha naming the function and its surprising\n   behavior) — do not pull a specific in-flight decision or dated\n   deferral into it.\n\nKeep the output compact and ready for direct injection. Do not\nrestate AGENTS.md. Do not mention `myco_skills`. Do not reorder\nthe seven required items. Do not mention retired tool names, even as\nwarnings, migration notes, or historical gotchas.\n\nReport the final markdown via `vault_report` with:\n- action: \"cortex_instructions\"\n- summary: what the instructions emphasize\n- details.content: the final markdown\n",
        "tools": [
          "vault_report"
        ],
        "maxTurns": 4,
        "required": true,
        "dependsOn": [
          "research"
        ],
        "onItemError": "skip"
      }
    ],
    "schedule": {
      "enabled": true,
      "intervalSeconds": 28800,
      "runIn": [
        "idle",
        "sleep"
      ]
    }
  },
  {
    "name": "cortex-prompt-builder",
    "displayName": "Cortex Prompt Builder",
    "description": "Build a high-quality, Myco-informed prompt for a target symbiont while respecting whether session-start instructions will be injected separately.\n",
    "agent": "myco-agent",
    "prompt": "Build a strong, pasteable prompt for a target coding agent.\n\nThe instruction payload gives you:\n- the user's goal\n- the target symbiont and whether session-start instructions will be injected\n- the current Cortex instructions when they must be inlined\n\nUse the vault tools to gather the most relevant project context:\n- digest for broad orientation\n- spores for prior decisions, gotchas, and bug fixes\n- sessions and plan-related search results for recent or approved work\n- skill records for repeatable project procedures\n- search tools when you need targeted follow-up\n\nOutput requirements:\n- Produce one final prompt suitable for direct paste into the target agent.\n- If the instruction payload says to inline Cortex instructions, include them.\n- If the instruction payload says session-start injection is supported, omit the\n  Cortex instructions from the final prompt.\n- Prefer concise, high-signal context over long dumps.\n- Include concrete validations when the task implies implementation work.\n\nCall `vault_report` with action \"cortex_prompt_builder\" and:\n- summary: short description of the brief you produced\n- details.prompt: the final prompt text\n",
    "isDefault": false,
    "reasoningLevel": "default",
    "maxTurns": 24,
    "timeoutSeconds": 300,
    "phases": [
      {
        "name": "build",
        "prompt": "Gather the smallest set of relevant Myco context for this build request,\nthen write the final prompt and report it via `vault_report`.\n\nUse digest, search, sessions, plans, spores, and skills selectively.\nAvoid exhaustive searching; gather what you need to write the prompt.\n\nThe final output must be a single prompt suitable for direct paste into\nthe target agent. Respect the delivery contract from the instruction\npayload when deciding whether to inline the current Cortex instructions.\n\nBefore finishing, call `vault_report` with action `cortex_prompt_builder`\nand put the final prompt in `details.prompt`.\n",
        "tools": [
          "vault_read_digest",
          "vault_sessions",
          "vault_spores",
          "vault_skill_records",
          "vault_search_fts",
          "vault_search_semantic",
          "vault_report"
        ],
        "maxTurns": 18,
        "required": true,
        "onItemError": "skip"
      }
    ]
  },
  {
    "name": "digest-only",
    "displayName": "Digest Only",
    "description": "Regenerate digest extracts at all token tiers using current vault knowledge. Does not process new data or extract spores. Useful after manual edits to spores or graph data.\n",
    "agent": "myco-agent",
    "prompt": "Regenerate digest extracts from current vault state.\n\n## Phase 1 — Assess Current State (budget: 4 turns)\n\n1. Call `vault_state` for context\n2. Call `vault_read_digest` (no tier param) to see current digest metadata\n   and assess whether any tiers exist and how fresh they are\n3. Call `vault_spores` with status \"active\" to see current observations\n4. Call `vault_sessions` to understand recent activity\n\nIf the current digest is very recent and no meaningful vault changes have\noccurred since it was written (check spore counts and session dates), call\n`vault_report` with action \"skip\" and reason \"digest is already current\",\nthen stop. Only proceed if there is genuine new material to incorporate.\n\n## Phase 2 — Survey New Material (budget: 5 turns)\n\nBased on the spore types and tags you saw in Phase 1, construct targeted\nsearch queries. Search for specific themes you identified, not generic\ncategories. For example, if Phase 1 showed new \"gotcha\" spores about SQLite\nand new \"decision\" spores about caching, search for those specific topics.\n\nCall `vault_search_semantic` with these targeted queries to gather the\nmaterial you will integrate into the digest.\n\nThe existing digest is your baseline — your goal is to integrate new\nmaterial into it, not start from scratch.\n\nPrefer released/high-confidence observations when writing general guidance.\nKeep unknown or unreconciled observations as useful recent context, but frame\nthem as needing verification instead of presenting them as shipped behavior.\n\n## Phase 3 — Update Extracts (budget: 25 turns)\n\nUpdate ALL 3 tiers in this order (largest first — each subsequent tier\nis a compression of the one above):\n1. Tier 10000 — Full institutional knowledge (update if any new content)\n2. Tier 5000 — Deep onboarding (update if new trade-offs or patterns)\n3. Tier 1500 — Executive briefing (most compressed — update if\n   important new decisions or gotchas)\n\nFor each tier: read current content via `vault_read_digest`, then write\nthe updated version via `vault_write_digest`. Each tier is self-contained.\nPreserve well-crafted existing content — integrate new material, don't\nrewrite from scratch.\n\nIf a tier genuinely has no new material to integrate, skip it — but\ndo not skip tiers just to save turns. All 3 tiers should be kept current.\n\nPrioritize within each tier: recent insights > active decisions >\nunresolved gotchas > architectural patterns > historical context.\n\n## Phase 4 — Report (budget: 1 turn)\n\nCall `vault_report` with action \"digest\":\n- Tiers updated: [list]\n- Tiers skipped (already current): [list]\n- Active spores used as substrate: N\n- Key themes incorporated\n",
    "isDefault": false,
    "toolOverrides": [
      "vault_spores",
      "vault_sessions",
      "vault_search_semantic",
      "vault_release_state",
      "vault_state",
      "vault_read_digest",
      "vault_write_digest",
      "vault_set_state",
      "vault_report"
    ],
    "reasoningLevel": "default",
    "maxTurns": 28,
    "timeoutSeconds": 1800
  },
  {
    "name": "extract-only",
    "displayName": "Extract Only",
    "description": "Extract observations (spores) from unprocessed prompt batches without building graph entities/edges or regenerating digest. Useful for a quick pass that captures knowledge without full reasoning overhead.\n",
    "agent": "myco-agent",
    "prompt": "Extract spores from unprocessed batches. No graph or digest work.\nBudget: ~25 turns.\n\n## Phase 1 — Read State (budget: 2 turns)\n\n1. Call `vault_state` to get cursor (`last_processed_batch_id`)\n2. Call `vault_unprocessed` with `after_id`\n\nIf no unprocessed batches, report \"no work\" and finish.\n\n## Phase 2 — Extract (budget: 18 turns)\n\nBudget ~3 turns per batch. If more batches than turns allow, prioritize\nbatches with longer prompts (these contain more substantive work).\n\nFor each batch:\n1. Read `user_prompt` — understand what the developer asked\n2. Identify candidate observations — genuine insights only, not activity logs\n3. **Group candidates by topic across all batches** before searching.\n   One search call per topic is cheaper than one per batch.\n\nFor each TOPIC group:\n1. Use `vault_search_semantic` to find existing spores that already cover this topic\n2. If a similar spore exists:\n   - If the new observation adds meaningful new detail: call\n     `vault_create_spore` then supersede the old via `vault_resolve_spore`\n     action \"supersede\" with new_spore_id\n   - If the new observation adds nothing new: skip it entirely\n3. If no similar spore exists: call `vault_create_spore`\n\nAfter processing each batch:\n4. Call `vault_mark_processed`\n5. Update cursor via `vault_set_state`\n\n## Phase 3 — Session Summaries (budget: 4 turns)\n\nFor each session touched:\n1. Call `vault_sessions` to check existing title/summary\n2. If missing or stale, review the prompt batches you just processed —\n   use the user_prompt and response_summary from those batches as\n   your primary source for the title and summary\n3. Call `vault_update_session` with BOTH title and summary\n\nTitle: describes WHAT WAS ACCOMPLISHED (under 80 chars, sentence case).\nSynthesize from the full arc of batches, not just the first prompt.\nNEVER use file paths, directory names, or the user's first message.\nSummary: 2-4 sentences — rich in detail (files, tools, outcomes).\n\n## Phase 4 — Report (budget: 1 turn)\n\nCall `vault_report` with action \"extract\":\n- Batches processed: N\n- Spores created: N (by type)\n- Sessions updated: N\n",
    "isDefault": false,
    "toolOverrides": [
      "vault_unprocessed",
      "vault_spores",
      "vault_sessions",
      "vault_search_fts",
      "vault_search_semantic",
      "vault_state",
      "vault_create_spore",
      "vault_resolve_spore",
      "vault_update_session",
      "vault_mark_processed",
      "vault_set_state",
      "vault_report"
    ],
    "reasoningLevel": "low",
    "maxTurns": 30,
    "timeoutSeconds": 300
  },
  {
    "name": "review-session",
    "displayName": "Review Session",
    "description": "Process a single session end-to-end. Extracts spores from all prompt batches in the session, runs supersession checks, and generates the session title and summary.\n",
    "agent": "myco-agent",
    "prompt": "Review the specified session end-to-end. Budget: ~25 turns.\n\nTarget session: {{session_id}}\n\n## Phase 1 — Read State (budget: 3 turns)\n\n1. Call `vault_state` to get current cursor and context\n2. Call `vault_sessions` to find the target session and its current\n   title/summary/processed status\n3. Call `vault_unprocessed` to get all unprocessed batches — note which\n   ones belong to the target session (by matching session_id in the batch data)\n\nIf no unprocessed batches belong to this session, call `vault_report` with\naction \"skip\" and reason \"no unprocessed batches for session\", then stop.\nOnly process batches from the target session — ignore batches from other sessions.\n\n## Phase 2 — Extract Spores (budget: 15 turns)\n\nExtract observations from all unprocessed batches in this session.\nCRITICAL: the vault must stay sharp, not bloated — supersede, don't duplicate.\n\n1. Read all batch content first — understand the full scope of the session\n2. Group candidate observations by TOPIC across all batches\n3. Call `vault_spores` to see existing spores for context\n\nFor each TOPIC group:\n1. Call `vault_search_semantic` with the topic to find existing spores that\n   already cover this topic\n2. If a similar spore exists:\n   - If your observation adds meaningful new detail: call `vault_create_spore`\n     then supersede the old via `vault_resolve_spore` action \"supersede\"\n     with new_spore_id\n   - If your observation adds nothing new: skip it entirely\n3. If no similar spore exists: call `vault_create_spore` with session_id,\n   prompt_batch_id, importance 1-10, and relevant tags\n\nAfter processing all batches: call `vault_mark_processed` for each batch,\nthen call `vault_set_state` to update the cursor.\n\n## Phase 3 — Supersession Check (budget: 3 turns)\n\nScan active spores for newly introduced redundancy:\n1. Call `vault_spores` with status \"active\" to see the current set\n2. For any spores that are now outdated or contradicted by the newly created\n   ones, call `vault_resolve_spore` with action \"supersede\" (when a newer\n   spore replaces it) or \"obsolete\" (when it is simply no longer relevant)\n3. Only supersede when the new information genuinely replaces the old;\n   when in doubt, keep both\n\n## Phase 4 — Title & Summary (budget: 3 turns)\n\n1. Call `vault_sessions` to check the current title and summary\n2. Review the prompt batches you processed in Phase 2 — use user_prompt\n   and response_summary as your PRIMARY source for the title and summary.\n   Call `vault_spores` with `session_id` as supplemental context.\n3. Call `vault_update_session` with BOTH title and summary\n\nTitle: describes WHAT WAS ACCOMPLISHED (under 80 chars, sentence case).\nNEVER use file paths, directory names, or the user's first message as title.\nGood: \"SQLite migration with FTS5 and vector embeddings\"\nBad: \"/git-worktree\", \"Help me fix the bug in...\"\nSummary: 2-4 sentences on key work done + outcomes.\n\n## Phase 5 — Report (budget: 1 turn)\n\nCall `vault_report` with action \"complete\":\n- Session reviewed: {{session_id}}\n- Batches processed: N\n- Spores created: N (by type)\n- Spores superseded: N\n- Title/summary updated: yes/no\n",
    "isDefault": false,
    "toolOverrides": [
      "vault_unprocessed",
      "vault_spores",
      "vault_sessions",
      "vault_search_fts",
      "vault_search_semantic",
      "vault_create_spore",
      "vault_resolve_spore",
      "vault_update_session",
      "vault_mark_processed",
      "vault_set_state",
      "vault_state",
      "vault_report"
    ],
    "reasoningLevel": "default",
    "maxTurns": 30,
    "timeoutSeconds": 480
  },
  {
    "name": "skill-evolve",
    "displayName": "Skill Evolution",
    "description": "Evaluate and evolve existing Myco-managed skills. Assesses content freshness against new spores AND codebase drift from refactors, identifies merge and narrowness opportunities, and autonomously consolidates the skill inventory.",
    "agent": "myco-agent",
    "prompt": "Assess and evolve skills that have new knowledge, codebase drift, or structural overlap. The instruction contains pre-filtered skills with new spore IDs plus pre-computed structural and drift analysis.",
    "isDefault": false,
    "reasoningLevel": "default",
    "maxTurns": 72,
    "timeoutSeconds": 2400,
    "phases": [
      {
        "name": "inventory",
        "prompt": "The instruction contains pre-computed structural analysis of\nall active skills. Two mechanical signals are provided:\n\n1. **Narrow skills** — skills with <2 H2 sections are flagged\n   as mechanically narrow. These are NOT broad enough for\n   standalone domain status.\n\n2. **Overlap pairs** — skill pairs with similar descriptions\n   OR overlapping H2 headings are flagged with scores.\n\n## Your job: validate and assign targets\n\nFor each **mechanically narrow** skill:\n- Confirm it is genuinely narrow (not a false positive, e.g.,\n  a debugging playbook with one long section is not narrow).\n- Identify which broader skill it should be absorbed into.\n  Look at the heading lists to find the best domain match.\n\nFor each **overlap pair**:\n- Confirm the overlap is real (not just shared vocabulary).\n- If real, decide merge direction: which skill is the target\n  (broader, higher generation) and which is the source.\n\nIf no skills are flagged as narrow and no overlap pairs exist,\nskip to storing an empty analysis.\n\n## Store results\n\nStore via vault_set_state (key: skill-evolve-inventory) as:\n{\n  \"merge_candidates\": [\n    { \"source\": \"skill-name-a\", \"target\": \"skill-name-b\",\n      \"reason\": \"...\" }\n  ],\n  \"narrow_candidates\": [\n    { \"skill\": \"skill-name\", \"absorb_into\": \"broader-skill\",\n      \"reason\": \"...\" }\n  ]\n}\n\nOnly override the mechanical signals when you have clear\nevidence that the flag is wrong. The default is to act on\nthe mechanical flags, not to find reasons to keep everything.\n\nIf the instruction says \"No skills need assessment\", report\nskip via vault_report and finish.\n\n## Output discipline\n\nKeep responses terse. No narrative explanations.\nDo not provide analytical prose, rationale paragraphs, or\nwalkthrough text outside tool payloads.\nFinal phase summary must be <= 2 lines.\nRequired output shape:\n- One `vault_set_state` call with merge/narrow arrays.\n- One `vault_report` call with counts.\n- Final assistant text <= 2 lines, no explanatory prose.\n",
        "tools": [
          "vault_skill_records",
          "vault_set_state",
          "vault_report"
        ],
        "maxTurns": 8,
        "reasoningLevel": "low",
        "required": true,
        "readOnly": true,
        "onItemError": "skip"
      },
      {
        "name": "assess",
        "prompt": "## Scope boundary (critical)\n\nMechanical drift signals are TRIAGE only. They are cheap hints,\nnot source-of-truth code understanding.\n- Use pre-computed drift/growth signals to decide where to look.\n- Use agent exploration tools (vault_search_fts, fs_read, code_grep)\n  for final judgment on whether content is truly stale/current.\n- Do NOT treat a single heuristic miss as authoritative when\n  surrounding evidence indicates the skill is still accurate.\n\nRead two pre-computed inputs from vault_state:\n  - key: skill-evolve-inventory (merge/narrow candidates)\n  - key: skill-evolve-drift (mechanical drift + growth reports)\n\nCandidate metadata is triage input, not source-of-truth.\nIf deferred or dismissed candidates overlap an active skill, use\nthat as a signal that the skill's boundary may need expansion.\nDo not rewrite a skill based solely on candidate metadata; verify\nagainst spores, sessions, plans, or code before classifying STALE,\nMERGE, or NARROW.\n\nThere are THREE sources of skills to assess:\n\n**A. Skills with new knowledge** — listed in the instruction\nwith descriptions and new spore IDs (full content is NOT in\nthe instruction — read it on-demand). For each:\n1. Read new spores via vault_spores. Understand what changed.\n2. Only if the new spores suggest a procedural change, read\n   the skill's full content via vault_skill_records (action:\n   get, id: \"<name>\") and verify 2-3 code references via\n   vault_search_fts. Skip content reads for skills where\n   the new spores are clearly unrelated.\n3. Check the inventory AND drift analyses: is this skill also\n   flagged for merge, narrowness, or codebase drift?\n\n**B. Inventory-flagged skills** — merge_candidates and\nnarrow_candidates from the inventory analysis. These may NOT\nappear in the instruction (they may have no new knowledge).\nFor each flagged skill not already covered above:\n1. Read its content via vault_skill_records (action: get).\n2. Verify the inventory's merge/narrow recommendation by\n   reading both skills' content.\n\n**C. Drift-flagged skills** — reports from the mechanical pass with\nseverity of `minor`, `major`, or `critical`. These may NOT appear\nin the instruction (no new spores) but need attention because\ntheir content no longer matches the codebase. For each drift\nreport not already covered above:\n1. Read the skill's content via vault_skill_records (action: get).\n2. Trust `load_bearing_misses` as the STALE detail set.\n   Re-check with fs_read/code_grep ONLY if confidence is low\n   OR a claim is inconclusive.\n2b. If a mechanical miss appears to be a heuristic artifact\n    (generic token, path-shape ambiguity, parser limitation),\n    classify conservatively and explain the uncertainty.\n3. Major/critical severity with confidence high/medium should\n   classify as STALE (or DEPRECATED if the entire subsystem\n   described is gone). Minor severity may stay CURRENT unless\n   combined with new-spore evidence.\n4. **fabrication_suspects** (symbols inside the skill's ```code```\n   examples that are NOT found anywhere in the codebase) are NOT\n   cosmetic. The mechanical scan cannot see inside fences, so these\n   are the one signal for invented APIs. For each suspect, run one\n   code_grep to confirm. If a suspect symbol genuinely does not\n   exist (and is not obviously illustrative pseudo-code), classify\n   the skill STALE — the example is fabricated and must be removed\n   or corrected. Do NOT wave these away as a heuristic artifact the\n   way you might a single path miss; a confidently-wrong code\n   example is exactly the corruption this pipeline exists to catch.\n\n## Drift classification threshold tuning\n\nFor drift-only skills (no meaningful new-spore evidence), use a\ntwo-signal rule before STALE:\n- Signal A: high-confidence mechanical miss\n  (major/critical severity with confidence high/medium), OR\n- Signal B: targeted exploration confirms the miss affects a\n  load-bearing step in the current skill procedure.\n\nClassification policy:\n- STALE when A+B are both true, OR when there are 2+ independent\n  load-bearing misses in different parts of the procedure.\n- CURRENT when only one weak/unconfirmed drift signal exists.\n- INCONCLUSIVE behavior: when evidence is mixed, prefer CURRENT\n  with explicit \"watch\" details over forcing STALE.\n\n**D. Growth-flagged skills** — reports with non-empty `growth`\nwhere referenced TS files gained new exports since the skill's\nstored fingerprint baseline. For each growth report not already\ncovered above:\n1. Read the skill's content via vault_skill_records (action: get).\n2. For each growth claim, run at most one targeted fs_read or\n   code_grep call to decide if the new export is relevant to the\n   skill's domain.\n3. If relevant, classify STALE and include details. If not\n   relevant, keep CURRENT and explain why.\n\n## Per-run scope cap\n\nAssess at most 3 unique skills per run total across A/B/C/D.\nPrioritize in this order:\n1) Skills with new knowledge + high-confidence drift\n2) Skills with new knowledge only\n3) Drift-only skills with major/critical severity\n4) Remaining drift/growth-only skills\nAny remaining candidates must be deferred and listed in\nvault_report details under `deferred_skills`.\n\nFor ALL skills from all three sources, classify with one of:\n   - CURRENT — still accurate, no changes needed.\n   - STALE — new knowledge OR drift report changes specific\n     steps, paths, or gotchas. Note exactly WHAT is new or\n     wrong (cite the drift report's load_bearing_misses if\n     that's the driver).\n   - DEPRECATED — key code references are gone or the\n     procedure is no longer relevant. Note what's missing.\n     Drift severity=critical is the strongest signal here.\n   - MERGE — overlaps significantly with another skill\n     (from inventory analysis). Note the TARGET skill to\n     merge into.\n   - NARROW — too specific for standalone status (from\n     inventory analysis). Note the BROADER skill to absorb\n     into.\n\n   Bias toward CURRENT for cosmetic issues. A skill that is 90%\n   accurate is better left alone than rewritten with risk of\n   losing detail. Do NOT bias toward CURRENT when a drift report\n   flags load-bearing misses with high confidence — that's\n   exactly the refactor-drift case this pipeline exists to catch.\n   For drift-only cases with weak evidence, bias toward CURRENT\n   and carry forward actionable watch notes.\n\n5. Update the skill's properties with the new watermark:\n   vault_skill_records (action: update, id: <skill_id>,\n   properties: '{\"last_assessed_at\": <now>,\n   \"knowledge_watermark\": <now>,\n   \"last_classification\": \"<classification>\",\n   \"last_assessed_generation\": <skill's current generation>,\n   \"file_fingerprints\": {...latest_report.current_fingerprints...}}')\n   Set `last_assessed_generation` to the generation you read from the\n   skill record. The selector uses it to tell whether act actually\n   rewrote the skill (generation only advances on a real write): a\n   skill left STALE/MERGE/NARROW whose generation has not advanced past\n   this value is re-surfaced on a later run until the write lands.\n\n6. Store classifications via vault_set_state\n   (key: skill-evolve-classifications) as JSON:\n   [{ \"skill_id\": \"...\", \"name\": \"...\",\n      \"classification\": \"...\",\n      \"target_skill\": \"...\" (for MERGE/NARROW),\n      \"details\": \"...\" }]\n\nReport via vault_report.\n\n## Budget discipline\n\nTotal budget for this phase: {{max_turns}} turns.\nTools available for this phase: {{phase_tools}}.\nSpread budget across all flagged skills from A/B/C/D.\nPlan per-skill budget roughly as `{{max_turns}} / skills_selected`\nwhere skills_selected is the number of unique skills surfaced by\nthe pre-computed reports.\n\nHard limits:\n- At most 2 tool calls per inconclusive or growth claim.\n- Do not rerun broad exploration if a targeted check already\n  answers the classification decision.\n- Mechanical triage should narrow search scope, not replace\n  repository exploration when a real decision is required.\n\nPer-skill stop conditions:\n- For drift-only skills, perform at most 1 targeted re-check\n  unless evidence directly conflicts.\n- If classification reaches confidence threshold, stop tool calls\n  for that skill immediately.\n- If still ambiguous after the allowed check, classify CURRENT\n  with explicit watch notes (do not continue probing).\n\n## Output discipline\n\nKeep responses terse. No long prose or per-skill essays.\nStore details in vault_set_state payloads, not in narrative text.\nFinal phase summary must be <= 6 lines.\nRequired output shape for this phase:\n1. One `vault_set_state` write containing the complete\n   `skill-evolve-classifications` payload for all assessed skills.\n2. One `vault_report` call with aggregate counts and any deferred/watch\n   notes.\n3. Final assistant text <= 4 lines, no narrative walkthrough.\n",
        "tools": [
          "vault_spores",
          "vault_search_fts",
          "vault_skill_candidates",
          "vault_skill_records",
          "vault_set_state",
          "vault_report",
          "fs_read",
          "code_grep"
        ],
        "maxTurns": 10,
        "reasoningLevel": "default",
        "required": true,
        "dependsOn": [
          "inventory"
        ],
        "onItemError": "skip"
      },
      {
        "name": "act",
        "prompt": "Read classifications from vault_state\n(key: skill-evolve-classifications). Parse the JSON.\n\nFor each classified skill, take the appropriate action:\n\n## CURRENT — No action. Skip.\n\n## STALE — Targeted update\n\n1. Read the current skill content from vault_skill_records\n   (action: get).\n2. START from the existing content as-is. Copy it verbatim.\n   Then make ONLY the specific changes needed.\n   The diff between old and new should be MINIMAL.\n   Protected frontmatter rules (enforced by vault_write_skill):\n   - user-invocable: copy EXACT value from existing skill\n   - allowed-tools: copy EXACT value from existing skill\n   - description: do not shorten (>10% reduction is rejected)\n3. Write via vault_write_skill with a rationale explaining\n   what specifically changed. Preserve the existing skill\n   `source_ids` unless the update is based on new source evidence;\n   when adding new evidence, pass the union of existing source_ids\n   plus the new source IDs.\n\n## DEPRECATED — Retire the skill\n\n1. vault_skill_records (action: update, status: retired)\n2. vault_skill_records (action: delete)\n\n## MERGE — Absorb into target skill\n\n1. Read BOTH skills' full content from vault_skill_records\n   (action: get) — the source and the target.\n2. Write MERGED content to the TARGET skill via\n   vault_write_skill. The merged skill should:\n   - Keep the target skill's name and frontmatter\n   - Incorporate the source skill's procedures as new sections\n   - Preserve all concrete file paths, code patterns, and\n     gotchas from both skills\n   - Have a coherent structure (not just concatenation)\n   Protected frontmatter rules apply to the target.\n   Pass source_ids as the union of the target and source\n   skill source_ids so lineage survives the merge.\n3. Rationale should explain: \"Merged <source> into <target>:\n   <what was added>.\"\n4. Delete the SOURCE skill: vault_skill_records (action: delete)\n   This cascades (lineage, usage, linked candidates).\n\n## NARROW — Absorb into broader skill\n\nSame as MERGE: read both, write merged content to the broader\nskill, delete the narrow one. The narrow skill becomes a section\nwithin the broader skill.\n\n## Verify before you write — NEVER fabricate (critical)\n\nYou are EVOLVING existing skills, not authoring from imagination.\nVerify only the NEW or CHANGED concrete claims your edit introduces\n— agents load these as authoritative procedure, so a confident-but-\nwrong detail is worse than no detail. Do NOT re-verify claims that\nwere already in the skill and you are not touching.\n\nFor each NEW/CHANGED claim, verify with AT MOST 1 tool call:\n- **File path claim** → one `fs_read` (narrow window). Missing → don't write it.\n- **Identifier claim** (function, symbol, env var, type) → one\n  `code_grep` with a path/glob filter. No match → the symbol does\n  not exist; do NOT write it. Never invent a function, env var, or\n  API to make an example look complete.\n- **Behavior claim** → one `code_grep` for the signature/pattern.\n\nHard limit: **at most 6 verification tool calls per skill.** If an\nedit would need more than that to verify, it is too broad for evolve\n— trim the edit to the few highest-value verified changes and note\nthe rest in the rationale. If you cannot verify a claim within the\nbudget, omit it. An accurate, shorter skill beats a padded one.\n\n## Edit surgically — minimal diff\n\nEvolution means targeted edits, not rewrites. Start from the\nexisting content verbatim and change ONLY what the classification\nrequires. Do NOT add large speculative sections or code examples\nthe classification didn't call for — that is how fabrication and\nrunaway output happen. If a skill needs broad new authored content,\nthat is a survey/generate concern, not evolve.\n\n## Budget discipline (hard)\n\nTotal budget: {{max_turns}} turns across ALL selected skills. Plan\nroughly `{{max_turns}} / skills_selected` turns per skill (about a\ndozen): a few verification calls (≤6), one write, done. If you are\nrunning past your share for a skill, STOP verifying, make the\nsafe minimal edit with what you have confirmed (omit unverified\nclaims), write it, and move on. NEVER let one skill consume the\nbudget — a clean partial pass over the others beats capping out.\nIf you approach the total budget, call `vault_report` with what you\ncompleted and which skills you deferred, then finish.\n\n## Important\n\n- Process MERGE/NARROW actions AFTER STALE updates, so you're\n  merging already-refreshed content.\n- Cost/quality guardrail: process at most 3 STALE updates per run.\n  If more than 3 are classified STALE, process the top 3 by impact\n  (critical drift > major drift > both drift+new knowledge > new knowledge only),\n  report deferred skill names via vault_report, and leave their\n  classifications in state for a future run.\n- If vault_write_skill rejects a merge (e.g., dedup gate trips),\n  check the error and adjust content. If truly blocked, skip\n  and report the issue.\n- Do not update skill candidates from skill-evolve. Candidate\n  quality metadata belongs to survey/generate; evolution should\n  preserve skill record lineage and report issues via vault_report.\n\nReport all actions via vault_report.\n\n## Output discipline\n\nKeep responses terse. Avoid narrative writeups.\nFinal phase summary must be <= 5 lines plus deferred-skill list.\nRequired output shape:\n- One `vault_report` with executed/deferred counts.\n- Final assistant text <= 3 lines.\n",
        "tools": [
          "vault_write_skill",
          "vault_skill_records",
          "vault_search_fts",
          "fs_read",
          "code_grep",
          "vault_report"
        ],
        "maxTurns": 40,
        "reasoningLevel": "default",
        "required": true,
        "dependsOn": [
          "assess"
        ],
        "onItemError": "skip"
      }
    ],
    "schedule": {
      "enabled": false,
      "intervalSeconds": 21600,
      "runIn": [
        "idle",
        "sleep"
      ],
      "preCondition": "has-active-skills"
    },
    "params": {
      "assess_interval_hours": 24,
      "max_skills_per_run": 3
    }
  },
  {
    "name": "skill-generate",
    "displayName": "Skill Generation",
    "description": "Synthesize a project skill from a vault knowledge candidate. Stages SKILL.md under .myco/staging/skills/, validates it, then promotes it to .agents/skills/ via vault_finalize_skill.",
    "agent": "myco-agent",
    "prompt": "Generate ONE project-specific skill from the next approved candidate. The instruction contains the candidate metadata and pre-assembled source material. Stage the skill, validate it, then finalize it.",
    "isDefault": false,
    "reasoningLevel": "default",
    "maxTurns": 32,
    "timeoutSeconds": 900,
    "phases": [
      {
        "name": "draft",
        "prompt": "Write a SKILL.md from the source material in the instruction.\nThe instruction contains the candidate ID, topic, rationale,\ncandidate quality metadata, and the full text of each renderable\nsource spore and session. Do NOT call any search or read tools —\nthe material is already here.\n\n## SKILL.md Format\n\n```markdown\n---\nname: myco:kebab-case-name\ndescription: |\n  One paragraph serving as the PRIMARY triggering mechanism.\n  Cover the full procedural domain — mention all the major\n  procedures this skill covers. Be explicit about when this\n  activates. Include \"even if the user doesn't explicitly\n  ask for [topic]\" language when appropriate.\nmanaged_by: myco\nuser-invocable: true\nallowed-tools: Read, Edit, Write, Bash, Grep, Glob\n---\n\n# Domain Title\n\nBrief context paragraph (2-3 sentences) explaining the\nprocedural domain and when you'd use this skill.\n\n## Prerequisites\n\nWhat must be true before starting any procedure in this domain.\n\n## Procedure A: [Name]\n\nSteps for the first major procedure in this domain.\n\n## Procedure B: [Name]\n\nSteps for the second major procedure.\n\n## Procedure C: [Name]\n\nSteps for the third major procedure.\n\n## Cross-Cutting Gotchas\n\nPitfalls that span multiple procedures in this domain.\n```\n\n## Frontmatter Fields\n\n- **user-invocable: true** — makes the skill available as a slash\n  command (e.g., `/add-symbiont`). Set this for all procedural skills.\n- **description formatting** — keep the description YAML-safe.\n  Prefer the block-scalar form shown above (`description: |` or\n  `description: >-`) instead of a long plain scalar, because colons\n  inside an unquoted single-line value can produce invalid YAML.\n- **description length** — keep the fully rendered description at or\n  under 1024 characters. Longer descriptions are rejected by Codex and\n  other skill loaders even if the rest of the file is valid.\n- **allowed-tools** — comma-separated list of **Claude Code tool\n  names** that the skill needs. These skills run in developer\n  Claude Code sessions, NOT in the agent pipeline. NEVER use\n  vault_* tool names (vault_search_fts, vault_spores, etc.) —\n  those are internal agent tools, not available in Claude Code.\n  Valid tool names: Read, Edit, Write, Bash, Grep, Glob.\n  Most procedural skills need: Read, Edit, Write, Bash, Grep, Glob.\n  Narrow this if the skill only needs read access (e.g., audit\n  skills: Read, Bash, Grep, Glob).\n\n## Writing Principles\n\n- **This candidate represents a procedural domain** — a family\n  of related tasks that share prerequisite knowledge. The skill\n  should cover the full domain, not just a single procedure.\n- **Honor the evidence metadata.** Treat `evidence_bundle_id`,\n  `quality_score`, `coverage_matches`, and `source_ids` in the\n  instruction as the approval record for this candidate. Use the\n  source material to ground the skill; do not broaden the skill\n  beyond what the approved evidence supports.\n- **Enforce the evidence contract before staging.** If\n  `evidence_bundle_id` is missing, `quality_failures` is not `[]`,\n  or `source_ids` is empty/malformed, report failure via\n  vault_report and do not call vault_stage_skill. Approval is a\n  human decision, not permission to ignore broken provenance.\n- **Respect overlap metadata.** If `coverage_matches` shows\n  overlap with an active skill or prior candidate, preserve the\n  distinct boundary or supersession rationale in the generated\n  skill. Do not erase that boundary in broad prose.\n- **A well-scoped skill has 3-6 major sections**, each describing\n  a distinct procedure within the domain. If the candidate maps\n  to fewer than 2 sections, note this in the rationale — it may\n  be too narrow.\n- **Explain reasoning, not rigid rules.** \"Because X, do Y\"\n  is better than \"ALWAYS do Y.\" The agent using this skill\n  understands WHY.\n- **Stay under 800 lines.** Be concise but complete.\n- **Use concrete file paths** from this project.\n- **Include code patterns** where they help (inline code blocks).\n- **Include examples** — show input/output or before/after where\n  it makes the procedure clearer.\n- **Reference gotchas inline** where the developer would\n  encounter them, not in a separate section.\n- **The description is the trigger.** An agent reading just the\n  description should know whether this skill applies.\n- **Be general enough to survive change.** The skill should teach\n  the pattern, not just document the current state.\n\n## Tool Call\n\nCall `vault_stage_skill` — NOT `vault_write_skill`. Pass:\n\n- candidate_id: the candidate ID from the instruction (required)\n- name: kebab-case directory name (NO colon — directory-safe name).\n  The myco: prefix goes ONLY in the SKILL.md frontmatter name field.\n- display_name: human-readable title\n- description: the frontmatter description text\n- content: the full SKILL.md including frontmatter\n- source_ids: the exact JSON array from the instruction's\n  `source_ids` quality metadata\n- rationale: \"Initial generation from candidate survey\"\n\n**Important:** the skill is NOT live after vault_stage_skill.\nThe file is written to .myco/staging/skills/<candidate_id>/SKILL.md\nand a manifest.json is written alongside. The validate phase will\nread the staged content, run quality checks, and promote to the\nlive .agents/skills/ directory via vault_finalize_skill. Until\nthat happens, nothing user-visible has changed.\n\nIf vault_stage_skill returns an error (validation, dedup), address\nthe issue and re-call vault_stage_skill with corrected content.\nThe staging file will be overwritten.\n",
        "tools": [
          "vault_stage_skill"
        ],
        "maxTurns": 10,
        "required": true,
        "onItemError": "skip"
      },
      {
        "name": "validate",
        "prompt": "Review the skill you just staged. The staged content is at\n.myco/staging/skills/<candidate_id>/SKILL.md — read it back\ndirectly from disk via the Read tool, or look it up by\ncandidate_id.\n\nCheck against these criteria:\n\n1. **Triggering clarity:** Would an agent reading only the\n   description know when to use this skill? Test: describe\n   a task that SHOULD trigger it and one that SHOULD NOT.\n\n2. **Procedural content:** Does every section describe steps\n   to take? Remove any definitional content (\"X is...\").\n\n3. **Concreteness:** Does it reference real file paths,\n   function names, and code patterns from this project?\n   Generic advice (\"add a config file\") is not enough.\n\n4. **Length:** Under 800 lines?\n4a. **Frontmatter validity:** Does the YAML frontmatter parse cleanly,\n    and is the rendered description still <= 1024 characters?\n\n5. **Domain scope:** Does this skill cover a procedural domain\n   (multiple related procedures as sections) or just a single\n   procedure? If single, flag as potentially too narrow. Count\n   the ## headings — expect 3-6 for a well-scoped domain skill.\n\n6. **Conflicts:** Does it overlap with existing skills?\n   Use vault_skill_records (action: list) to check. The\n   staging path's dedup gate already ran on your description;\n   this is a sanity check on the procedural content itself.\n\n7. **Accuracy (codebase-grounded):** Identify the 3-5 most\n   LOAD-BEARING concrete claims — paths, function/class names,\n   patterns the procedure depends on — and verify each against\n   the actual source:\n   - **Path claim** → `fs_read` (narrow window). ENOENT or\n     unrelated content = FAIL.\n   - **Identifier claim** → `code_grep` with a path+glob filter.\n     Zero hits in the expected location = FAIL.\n   - **Behavior claim** → `code_grep` for signature patterns\n     that would implement it. Zero hits = FAIL.\n   Budget 1-2 tool calls per claim.\n\n   If any load-bearing claim FAILS, treat as a criterion failure\n   and re-stage with corrected content. Do not finalize a skill\n   whose load-bearing paths can't be verified against the\n   current codebase — that's how hallucinated paths ship.\n\n8. **Evidence contract:** source_ids resolve, evidence_bundle_id\n   is present, quality_failures is empty, and coverage_matches are\n   reflected by a clear skill boundary or supersession rationale.\n   If this fails, report failure and do not finalize.\n\n## If criteria fail\n\nCall `vault_stage_skill` again with the candidate_id and\ncorrected content. This overwrites the staging file — the\ndedup gate runs again. Do NOT call vault_finalize_skill until\nall criteria pass.\n\n## If all criteria pass\n\nCall `vault_finalize_skill` with the candidate_id. This\natomically promotes the staged skill to `.agents/skills/<name>/`,\ninserts the skill_records row + lineage, transitions the\ncandidate to 'generated', creates the symbiont symlinks, and\ncleans up the staging directory. The preserved approved_at on\nthe candidate is carried through unchanged.\n\nThe skill is ONLY considered complete after vault_finalize_skill\nreturns success. If this phase fails (criterion failure or turn\nbudget exhausted), the task executor cleans up the staging\ndirectory so the candidate stays in 'approved' state for the\nnext generate cycle.\n\n## Report\n\nReport results using vault_report with:\n- Skill name and path\n- Whether finalize was called\n- Each criterion: pass/fail with brief note\n- Any re-stages performed\n",
        "tools": [
          "vault_stage_skill",
          "vault_finalize_skill",
          "vault_skill_records",
          "vault_skill_candidates",
          "vault_spores",
          "vault_report",
          "fs_read",
          "code_grep"
        ],
        "maxTurns": 18,
        "required": true,
        "dependsOn": [
          "draft"
        ],
        "onItemError": "skip"
      }
    ],
    "schedule": {
      "enabled": false,
      "intervalSeconds": 600,
      "runIn": [
        "idle",
        "sleep"
      ],
      "preCondition": "has-approved-candidates"
    }
  },
  {
    "name": "skill-survey",
    "displayName": "Skill Candidate Survey",
    "description": "Analyze vault knowledge for procedural domain candidates. Identifies broad categories of recurring developer work — not individual micro- procedures — that warrant guided skill context.",
    "agent": "myco-agent",
    "prompt": "Survey the vault knowledge graph for procedural domain candidates. The first phase prepares deterministic vault context.",
    "isDefault": false,
    "reasoningLevel": "default",
    "maxTurns": 112,
    "timeoutSeconds": 4200,
    "phases": [
      {
        "name": "prepare",
        "prompt": "The run admission instruction says whether this run should ignore\nthe stored survey watermark. Call vault_skill_survey_prepare\nexactly once, passing the same ignore_watermark boolean from the\ninstruction.\n\nThe tool output is the mechanical preparation source of truth for\nthis run. It includes watermark details, settled evidence counts,\nactive skill inventory, a compact existing-candidate queue audit,\ncandidate evidence bundles, and prompt_markdown for downstream\nphases. Treat queue.cleanup_targets as authoritative: if it is\nnon-empty, this run includes queue cleanup work even if no new\nevidence bundle should be created.\n\nAfter the tool returns, summarize only:\n- watermark mode\n- settled corpus counts\n- existing queue count and actionable count\n- cleanup target count and the cleanup reason codes represented\n- evidence bundle count\n- whether this appears to be primarily queue reconciliation,\n  new candidate discovery, or both\n\nDo not make final candidate decisions in this phase.\n",
        "tools": [
          "vault_skill_survey_prepare"
        ],
        "maxTurns": 4,
        "required": true,
        "readOnly": true,
        "onItemError": "skip"
      },
      {
        "name": "explore",
        "prompt": "The prepare phase produced deterministic vault context: digest,\nrecent wisdom spores, decisions, gotchas, sessions, active skill\ninventory, existing candidate queue, and candidate evidence\nbundles. Read its prompt_markdown carefully — this is your\nprimary input. If prepare reported cleanup targets, preserve them\nfor the later queue phases; do not let exploratory discovery\nreplace the cleanup obligation.\n\nYour goal: identify PROCEDURAL DOMAINS — broad categories of\nrecurring work where a developer benefits from guided context.\n\n## What is a procedural domain?\n\nA domain groups related procedures that share prerequisite\nknowledge. Think \"extending the daemon infrastructure\" (covering\nPowerManager jobs, MCP tools, config writes, notification\nwiring) — NOT \"registering a PowerManager job\" alone.\n\nGood domain examples:\n- \"Vault schema and data layer extension\" (migrations, tables,\n  queries, FTS indexes, constants)\n- \"Agent pipeline task authoring\" (YAML anatomy, phases,\n  scheduling, parameter injection, fault tolerance)\n- \"Symbiont integration lifecycle\" (manifests, hooks, config\n  directories, capture rules, installer registration)\n\nBad examples (too narrow — these are SECTIONS within a domain):\n- \"How to register a PowerManager job\"\n- \"Adding an FTS5 index\"\n- \"Writing a symbiont capture rule\"\n\n## Scale guidance\n\n20-30 broad skills for a complex project is the right order\nof magnitude. If a topic would be a section heading within a\nbroader skill, it is not its own candidate.\n\n## Process\n\n1. Read the prepared context for orientation.\n   It already excludes active-session data and only exists when\n   the vault has enough settled knowledge to support a serious\n   candidate review.\n\n2. Use vault tools for TARGETED follow-up on promising\n   clusters. The baseline gives you direction — follow threads\n   that suggest a procedural domain exists.\n\n   Good follow-up queries:\n   - vault_search_fts to find additional sessions touching\n     a domain you spotted in the digest\n   - vault_spores to read full content of high-signal spores\n     summarized in the baseline\n\n   Do NOT exhaustively paginate or search every keyword.\n   You have ~12 tool calls — use them purposefully.\n\n3. Group findings into candidate domains. For each domain,\n   note: the core theme, which procedures it covers, and\n   which source items provide evidence.\n\n4. Reject generic engineering domains even if they are common.\n   A valid candidate must be specific to this project's named\n   components, files, commands, or conventions.\n\nStore your domain clusters in working notes for the next phase.\n\n## Output discipline (cost)\n\nOutput tokens dominate this phase's cost. Keep working notes\ncompact: per domain, a few lines — core theme, the procedures it\ncovers, and source IDs as evidence. Reference sources by ID; do\nnot paste spore or session content into your notes.\n",
        "tools": [
          "vault_spores",
          "vault_sessions",
          "vault_search_fts",
          "vault_search_semantic"
        ],
        "maxTurns": 22,
        "required": true,
        "dependsOn": [
          "prepare"
        ],
        "readOnly": true,
        "onItemError": "skip"
      },
      {
        "name": "review-bundles",
        "prompt": "The prepare and explore phases identified procedural domain\nclusters from the vault. Now evaluate the prepared Candidate\nEvidence Bundles and decide which bundles deserve queue action.\n\nLoad the current coverage context:\n1. vault_skill_survey_prepare — call once with the same\n   ignore_watermark value used in prepare. This is the direct\n   source for Candidate Evidence Bundles and cleanup_target_ids;\n   do not rely on the prepare phase summary for bundle details.\n2. vault_skill_records (action: list) — all active skills\n3. vault_skill_candidates (action: list, statuses: [\"identified\",\"deferred\"], limit: 200) — the full active review queue\nKeep both lists for reference. Do not write anything in this\nphase. Only use action: list or action: get on skill tools.\nSkill tools are write-capable, so follow this action restriction\neven though the tool surface permits more.\n\n## Evaluation criteria\n\nEach bundle must pass ALL required criteria at the DOMAIN level.\nIf any required criterion fails, mark the bundle SKIP, or DEFER\nonly when there is already an existing candidate to move out of\nthe active review queue.\n\n1. PROCEDURE TEST: Does this domain describe \"how to do a\n   family of related tasks in this project\"? A domain about\n   \"what X is\" or \"X exists\" is knowledge, not a skill.\n\n2. PROJECT-SPECIFICITY TEST: Is this domain meaningfully tied\n   to THIS repository? It must be anchored to named project\n   components, files, commands, or conventions. Generic\n   engineering topics FAIL.\n\n3. REPEATABILITY TEST: Will developers need these procedures\n   again as the project grows? Domains covering extension\n   points (adding new X, extending Y) are strong candidates.\n   One-time fixes and bug patches are NOT skills.\n\n4. BREADTH TEST: Does this domain cover 2+ distinct procedures\n   that share prerequisite knowledge? A single procedure is\n   too narrow — it should be a section within a broader domain.\n   If you can't imagine 3+ major section headings, it's not\n   broad enough.\n\n5. CROSS-SESSION EVIDENCE: Knowledge from 2+ sessions and 3+\n   source items (spores, sessions, plans).\n\n6. QUALITY SCORE (0.0-1.0):\n   - Domain breadth (more procedures covered = higher)\n   - Cross-session evidence (wider = higher)\n   - Wisdom spore presence (higher quality signal)\n   - Plan presence (step-by-step procedures = higher)\n   - Existing coverage clarity (lower if overlap is ambiguous)\n\n7. DEDUPLICATION: Check BOTH coverage lists.\n   - If an active skill already covers this domain, skip.\n   - If the domain SUBSUMES existing narrow skills (the domain\n     is broader and the narrow skills are sections within it),\n     create the candidate with `supersedes` listing the narrow\n     skill names as a JSON array. The dedup gate exempts\n     superseded skills from vocabulary overlap checks.\n   - If a non-dismissed candidate covers the same domain,\n     UPDATE it with new evidence instead of creating.\n   - Dismissed candidates: the gate allows creation with a\n     warning. If the dismissed topic is a narrow subset of\n     your broader domain, proceed.\n\n## Output for the next phase\n\nWrite working notes only. For each bundle worth carrying forward,\ninspect enough source refs with vault_spores or vault_sessions to\njustify the procedure, breadth, repeatability, and cross-session\nverdicts. Treat the bundle's score, failures, coverage_matches,\nand source_refs as the starting evidence assessment, not as a\nsubstitute for reviewing the underlying evidence.\n\nFor each bundle worth carrying forward,\ninclude:\n- bundle id\n- proposed topic\n- proposed action: CREATE, UPDATE, DEFER, DISMISS, or SKIP\n- quality_score\n- quality_failures as a JSON array of string reason codes\n- coverage_matches as a JSON array of string identifiers\n- source_ids as a JSON array of {id, type} objects\n- evidence_bundle_id\n- supersedes as a JSON array of active skill names, if any\n- concise rationale with the verdict for every criterion\n\nUse these canonical quality failure codes when persisting\nquality_failures:\n- insufficient-source-refs\n- insufficient-distinct-sessions\n- missing-project-anchor\n- active-skill-overlap\n- existing-candidate-overlap\n- missing-quality-metadata\n- missing-evidence-bundle\n- quality-below-threshold\n- identified-has-quality-failures\n- invalid-quality-failure-codes\n- deferred-review-required\n- missing-human-review-evidence\n- never-reconciled\n- stale-reconciliation-policy\n\nIf a bundle fails for judgment reasons not represented by those\ncodes, explain the reason in the rationale and choose SKIP. Do\nnot invent new persisted quality_failures codes.\n\n## Durable handoff\n\nStore the complete decision list with\nvault_skill_survey_bundle_decisions. Pass one JSON object in the\n`decisions` argument with `decisions` array and `summary` object.\nThe tool stores validated state at skill-survey-bundle-decisions.\nYou may call it in batches; later calls merge into the same run's\nstate by bundle id/topic. The state is usable by later phases only\nwhen the tool reports `complete: true` and\n`unreviewed_evidence_bundle_ids: []`.\nUse the same ignore_watermark value used for\nvault_skill_survey_prepare. Do not use vault_set_state for this\nhandoff.\n\nThis handoff is only for the `evidence_bundles` returned by\nvault_skill_survey_prepare. Use each bundle's canonical `id` as\nbundle_id/evidence_bundle_id, or use the exact bundle topic. Do\nnot use existing skill candidate IDs or the queue row's persisted\nevidence_bundle_id as substitutes for prepared bundle IDs. The\nexisting queue is reconciled in the next phase; in this phase it\nis reference material for deduplication only.\n\nEach decision must include bundle_id, action, target_candidate_id\nwhen applicable, topic, rationale, confidence, source_ids,\nevidence_bundle_id, quality_score, quality_failures,\ncoverage_matches, and supersedes. The tool will validate CREATE\nand UPDATE decisions against the deterministic evidence bundles\nand hydrate canonical source_ids, quality_score,\nquality_failures, and coverage_matches before storing state.\nFor CREATE or UPDATE decisions, rationale is a durable human\nreview artifact, not a bookkeeping sentence: preserve the\nevidence and verdicts for procedure, project-specificity,\nrepeatability, breadth, cross-session evidence, dedup/coverage,\nand quality score so the Skills UI can explain the confidence.\nDo not rely on narrative phase output as the source of truth for\nlater persistence.\n\n## Output discipline (cost)\n\nOutput tokens dominate this phase's cost. Be economical without\nthinning the durable record:\n- Keep each decision's `rationale` to ≤ 80 words. State each\n  criterion verdict as a short phrase (\"procedure: yes — extends\n  task YAML\"), not a paragraph. Cite source/bundle IDs rather than\n  restating their content.\n- Never echo bundle bodies, spore text, or session summaries back\n  in your output — reference them by ID.\n- The assistant message itself (outside tool calls) MUST be ≤ 6\n  lines: counts of CREATE/UPDATE/DEFER/DISMISS/SKIP plus any\n  unreviewed bundle IDs. All durable detail goes through\n  `vault_skill_survey_bundle_decisions`, not the narrative.\n",
        "tools": [
          "vault_skill_survey_prepare",
          "vault_skill_candidates",
          "vault_skill_records",
          "vault_spores",
          "vault_sessions",
          "vault_search_fts",
          "vault_search_semantic",
          "vault_skill_survey_bundle_decisions"
        ],
        "maxTurns": 32,
        "reasoningLevel": "default",
        "required": true,
        "dependsOn": [
          "explore"
        ],
        "onItemError": "skip"
      },
      {
        "name": "reconcile-queue",
        "prompt": "Convert the review-bundles notes into a queue management plan.\nThis phase decides how the existing queue should change, but it\nmust not write anything. Only use action: list or action: get on\nskill tools. Skill tools are write-capable, so follow this action\nrestriction even though the tool surface permits more.\n\nReload the current queue and skill inventory:\n1. vault_state — read skill-survey-bundle-decisions from\n   review-bundles. Treat this state as usable only when it\n   contains validated_at; otherwise report blocked instead of\n   rebuilding decisions from prose.\n2. vault_skill_records (action: list) — all active skills\n3. vault_skill_survey_prepare — call once with the same\n   ignore_watermark value used in prepare so you get the compact\n   queue audit and cleanup_targets\n4. vault_skill_candidates (action: list, statuses:\n   [\"identified\",\"deferred\"], limit: 200) — the full active\n   review queue. The count here must match the prepare queue's\n   actionable count before you claim the queue is clean.\n\n## Reconciliation rules\n\n- Treat queue.cleanup_target_ids from vault_skill_survey_prepare\n  as an exhaustive worklist. Bundle decisions do not limit this\n  worklist; legacy low-quality queue items with no bundle still\n  require UPDATE, DEFER, DISMISS, or BLOCKED.\n- Existing non-dismissed duplicate candidates should not remain\n  side by side. Choose the stronger candidate to keep and mark\n  weaker duplicates for dismissed or deferred status.\n- Any identified candidate missing quality_score, evidence_bundle_id,\n  at least 3 valid source_ids, or human-review evidence in its\n  rationale is not ready for human approval.\n  Plan UPDATE if you can attach valid evidence now; otherwise plan\n  DEFER or DISMISS with quality_failures.\n- Every identified/deferred candidate in\n  queue.actionable_candidates must appear in Update, Defer,\n  Dismiss, Blocked, or Keep. Keep is an explicit judgment that\n  the candidate should remain in the human review queue.\n- Any queue.cleanup_targets entry from vault_skill_survey_prepare\n  must appear in Update, Defer, Dismiss, or Blocked. A no-op plan\n  is invalid while cleanup_targets is non-empty.\n- Prefer DEFERRED when the domain may become valid later but\n  lacks enough settled evidence now.\n- Prefer DISMISSED when the topic is generic, too narrow, already\n  covered by an active skill, or contradicted by newer evidence.\n- Prefer UPDATE when a real candidate already exists and only\n  needs better evidence metadata, rationale, confidence, or\n  supersedes information.\n- Prefer CREATE only when no non-dismissed candidate or active\n  skill already covers the domain.\n- Never put an existing identified/deferred queue candidate in\n  Create. If the candidate should remain available for human\n  review, use Keep. If it needs metadata correction, use Update.\n- Never create a candidate to preserve a weak bundle. A weak\n  bundle should become SKIP, DEFER, or a cleanup action against\n  an existing queue item.\n- DEFER is only for existing queue items. If a new plausible\n  bundle lacks enough settled evidence, SKIP it and explain what\n  evidence is missing.\n- Approved and generated candidates are lifecycle-owned by human\n  review or skill generation. Do not plan updates to them. If one\n  appears stale or duplicate, report it as blocked/stale for\n  human follow-up instead of mutating it.\n\n## Durable handoff for persist-decisions\n\nStore the compact plan with\nvault_skill_survey_reconciliation_plan. Pass a single JSON object\nin the `plan` argument. The tool stores the validated result at\nstate key skill-survey-reconciliation-decisions. Group actions as:\n- Create: new candidates with complete metadata\n- Update: existing candidate id plus fields to update\n- Defer: existing candidate id plus reason\n- Dismiss: existing candidate id plus reason\n- Skip: rejected bundles with failure codes\n- Blocked: approved/generated candidates that look stale or\n  duplicate but should not be changed by skill-survey\n- Keep: existing identified/deferred candidates that were reviewed\n  and should stay in the human review queue, with rationale\n\nWhen queue.cleanup_target_ids is non-empty, make cleanup the first\ninvariant: every cleanup target must appear in Update, Defer,\nDismiss, or Blocked, and the plan must not include Create\nentries. Skill-survey must not add new candidates while the\nexisting human review queue needs cleanup. Run skill-survey again\nafter the queue is clean to create new candidates.\n\nExisting queue cleanup is independent from fresh bundle creation.\nIf skill-survey-bundle-decisions is incomplete, you may still\nsubmit a cleanup-only plan with Update/Defer/Dismiss/Blocked/Keep\nand no Create entries. Do this instead of reporting no work when\nqueue.actionable_candidates or queue.cleanup_target_ids is\nnon-empty.\n\nFor CREATE or UPDATE-to-identified entries, the evidence bundle is\nthe authority for quality metadata. Prefer the canonical\nevidence_bundle_id stored in the validated\nskill-survey-bundle-decisions state. If you only have the bundle\ntopic, set topic to the exact bundle topic; the reconciliation\ntool will hydrate canonical evidence_bundle_id, quality_score,\nquality_failures, coverage_matches, source_ids, confidence, and\nthe durable human-review rationale from validated bundle decisions\nor deterministic bundles. Do not invent bundle IDs.\n\nThe state value must also include:\n- cleanup_target_ids: exact array from vault_skill_survey_prepare\n- handled_cleanup_target_ids: IDs appearing in Update, Defer,\n  Dismiss, or Blocked\n- unhandled_cleanup_target_ids: cleanup_target_ids not handled\n- active_queue_candidate_ids: exact IDs from\n  queue.actionable_candidates\n- reviewed_candidate_ids: IDs appearing in Update, Defer,\n  Dismiss, Blocked, or Keep\n- unreviewed_candidate_ids: active queue IDs not reviewed\n\nvault_skill_survey_reconciliation_plan recomputes the current\nactive queue and cleanup_target_ids from\nvault_skill_survey_prepare and refuses to store the plan if any\nactive queue item is unreviewed, any cleanup target is missing\nfrom Update, Defer, Dismiss, or Blocked, cleanup targets are\npresent alongside Create entries, a Create entry matches an\nexisting active queue candidate, or fresh Create entries depend on\nincomplete bundle-review handoff. If it rejects the plan, revise\nthe plan instead of falling back to vault_set_state.\n\nEvery CREATE or UPDATE that results in status identified must\ninclude:\n- evidence_bundle_id\n- quality_score >= 0.7\n- quality_failures: []\n- coverage_matches: JSON array of string identifiers\n- source_ids: JSON array with at least 3 valid source refs\n- rationale with the human-review evidence and criterion verdicts\n\nEvery DEFER or DISMISS must include quality_failures explaining\nwhy it should not remain in the active review queue. Use only\ncanonical failure codes from review-bundles. If the reason is a\nlegacy candidate with missing metadata, use missing-quality-metadata\nand missing-evidence-bundle as appropriate. If the candidate has\nscores and sources but the rationale does not explain the evidence\nbehind them, use missing-human-review-evidence.\nIf a candidate is a cleanup target only because it was reviewed\nbefore the current queue policy, use UPDATE to re-certify it with\ncurrent evidence metadata, or DEFER/DISMISS if it fails the current\ncriteria. Keep does not satisfy stale policy cleanup targets.\nDo not cite a mechanical metadata failure that the current\ncandidate does not actually have. For example, do not use\nmissing-evidence-bundle for a candidate whose current queue row\nalready has evidence_bundle_id.\n\n## Output discipline (cost)\n\nOutput tokens dominate this phase's cost. Keep each plan entry's\nrationale to ≤ 80 words — criterion verdicts as short phrases plus\nthe failure codes, citing source/candidate IDs rather than\nrestating their content. The assistant message outside tool calls\nMUST be ≤ 6 lines (counts per action). Durable detail goes through\n`vault_skill_survey_reconciliation_plan`, not the narrative.\n",
        "tools": [
          "vault_skill_survey_prepare",
          "vault_state",
          "vault_skill_candidates",
          "vault_skill_records",
          "vault_skill_survey_reconciliation_plan"
        ],
        "maxTurns": 22,
        "reasoningLevel": "default",
        "required": true,
        "dependsOn": [
          "review-bundles"
        ],
        "onItemError": "skip"
      },
      {
        "name": "persist-decisions",
        "prompt": "Persist the queue management plan from reconcile-queue.\n\nCall vault_skill_survey_apply_reconciliation once with the same\nignore_watermark value used by earlier phases. This is the only\nwrite path for this phase. Do not call vault_skill_candidates,\nvault_skill_records, or vault_set_state from persist-decisions.\nThe apply tool reads the validated\nskill-survey-reconciliation-decisions state, verifies the current\nactive queue was reviewed, applies only stored Create/Update/\nDefer/Dismiss actions, and ignores Keep/Blocked/Skip entries.\n\nIf vault_skill_survey_apply_reconciliation reports an error,\nreport blocked with the exact issues. Do not synthesize new\nwrites from phase prose.\n\nAfter applying writes, call vault_skill_survey_prepare again. If\nqueue.cleanup_targets is still non-empty, do not summarize the\nrun as clean. Report remaining cleanup_target_ids in vault_report\nunder `remaining_cleanup_target_ids`.\n\nReport a summary via vault_report.\n",
        "tools": [
          "vault_skill_survey_prepare",
          "vault_state",
          "vault_skill_survey_apply_reconciliation",
          "vault_report"
        ],
        "maxTurns": 24,
        "reasoningLevel": "default",
        "required": true,
        "dependsOn": [
          "reconcile-queue"
        ],
        "onItemError": "skip"
      }
    ],
    "schedule": {
      "enabled": true,
      "intervalSeconds": 21600,
      "runIn": [
        "idle",
        "sleep"
      ],
      "preCondition": "has-skill-survey-evidence",
      "maxRunsPerDay": 4
    }
  },
  {
    "name": "supersession-sweep",
    "displayName": "Supersession Sweep",
    "description": "Scan active spores for duplicates, contradictions, and outdated observations. Supersede, consolidate, or obsolete spores as appropriate. Records resolution events for audit trail.\n",
    "agent": "myco-agent",
    "prompt": "Review active spores for supersession opportunities. Budget: ~25 turns.\n\n## Phase 1 — Inventory (budget: 2 turns)\n\n1. Call `vault_spores` with status \"active\" to see current observations\n2. Group mentally by observation_type for systematic review\n\n## Phase 2 — Semantic Duplicate Detection (budget: 10 turns)\n\nFor each observation type (gotcha, decision, discovery, trade_off, bug_fix):\n1. Pick the 2-3 MOST RECENT spores of that type (`vault_spores` returns\n   them in recency order). Use their content as `vault_search_semantic` queries.\n2. Call `vault_search_semantic` with each representative's content to find\n   similar active spores\n3. When you find duplicates or near-duplicates, note the cluster\n\nIf `vault_search_semantic` is unavailable (no embeddings), use `vault_spores`\nfiltered by observation_type and compare manually. Report the limitation.\n\n## Phase 3 — Resolution and Wisdom Creation (budget: 10 turns)\n\nDecision tree for each cluster:\n- 3+ related active spores on same topic → create wisdom, consolidate all\n- Exactly 2 related spores → keep the better one, supersede the other\n- 1 spore (no duplicates) → no action\n\nFor each cluster:\n\n**If 3 or more related active spores cover the same topic:**\n1. Create a wisdom spore via `vault_create_spore`:\n   - observation_type: \"wisdom\"\n   - properties: '{\"consolidated_from\": [\"id-1\", \"id-2\", \"id-3\"]}'\n   - Content MUST preserve ALL specific details from the sources —\n     file paths, error messages, concrete values. Wisdom is a\n     comprehensive reference, not a vague summary.\n2. Resolve EACH source via `vault_resolve_spore` action \"consolidate\"\n   so they are removed from search results and context injection.\n\n**If 2 related spores cover the same topic (pair):**\n1. Determine which spore has the best content (most complete, most accurate)\n2. Call `vault_resolve_spore` with action \"supersede\" on the inferior spore:\n   - new_spore_id: the kept spore's ID\n   - reason: specific explanation (not just \"duplicate\")\n\n**For truly outdated spores (no longer relevant, with no replacement —\ne.g. a dropped feature):**\n- Call `vault_resolve_spore` with action \"obsolete\"\n- reason: explain what changed (required)\n\nOnly supersede or consolidate when the new information genuinely replaces\nthe old. Release state is supporting evidence only: do not obsolete or\nsupersede solely because a spore is unreleased, unknown, or unreconciled.\nWhen in doubt, keep both.\n\n## Phase 4 — Report (budget: 2 turns)\n\nCall `vault_report` with action \"supersession\":\n- Spores reviewed: N\n- Superseded: N (with reasons summary)\n- Obsoleted: N (with reasons summary)\n- Kept (no action): N\n",
    "isDefault": false,
    "toolOverrides": [
      "vault_spores",
      "vault_search_semantic",
      "vault_release_state",
      "vault_state",
      "vault_create_spore",
      "vault_resolve_spore",
      "vault_set_state",
      "vault_report"
    ],
    "reasoningLevel": "low",
    "maxTurns": 30,
    "timeoutSeconds": 300
  },
  {
    "name": "title-summary",
    "displayName": "Title & Summary",
    "description": "Generate titles and summaries for sessions that lack them. Reviews prompt batches and activities within each session to produce a concise title and informative summary.\n",
    "agent": "myco-agent",
    "prompt": "Generate or update session titles and summaries. Budget: ~12 turns.\n\nTarget session: {{session_id}}\n\nIf the target session field above is empty, scan all recent sessions.\n\n## Phase 1 — Find Sessions to Process (budget: 3 turns)\n\n**If a target session ID is specified above:**\nAlways process it — the user explicitly requested regeneration.\nCall `vault_session_summary_material` with `session_id: <target session>`\nto get the current title/summary plus the compact ordered prompt-batch arc.\nDo NOT skip even if there are no new unprocessed batches.\n\n**If no target session specified (automatic run):**\nCall `vault_unprocessed` with `include_active: true` — titles are needed\nmid-flight, not just after a session completes. Group by session_id —\neach session with unprocessed batches needs its summary updated. For each\nsession, call `vault_session_summary_material`. If no sessions have\nunprocessed batches, report \"skip\" and finish.\n\n## Phase 2 — Update Each Session (budget: 8 turns)\n\nFor each session to process:\n1. Read the EXISTING title and summary — context from prior runs.\n2. Read the session's compact prompt-batch arc — user_prompt +\n   response_summary. This is your PRIMARY source — read through the full\n   set to understand the complete arc of work.\n3. Generate a title and summary from the full session content.\n4. Call `vault_update_session` with BOTH title and summary.\n\n## Title Rules (CRITICAL)\n\nThe title describes WHAT WAS ACCOMPLISHED, not what was asked.\n\n- Under 80 characters, sentence case\n- Synthesize from the full arc of prompt batches, not just the first one\n- NEVER use file paths, directory names, or working directory as the title\n- NEVER copy the user's first message as the title\n- NEVER use truncated prompts ending in \"...\"\n- Good: \"Wave-based parallel executor and per-task provider config\"\n- Good: \"SQLite migration with FTS5 search and vector embeddings\"\n- Bad: \"/git-worktree\" (directory path, not a title)\n- Bad: \"Help me fix the bug in...\" (user's prompt)\n- Bad: \"Working on code\" (too vague)\n\n## Summary Rules\n\n2-4 sentences. Rich in detail — session summaries are embedded and used\nfor semantic search. Include: what was built/fixed, key files touched,\ntools used, and outcomes. Cover the FULL session arc, not just one prompt.\n\n## Phase 3 — Report (budget: 1 turn)\n\nCall `vault_report` with action \"summary\":\n- Sessions updated: N\n- Sessions skipped (already current): N\n",
    "isDefault": false,
    "toolOverrides": [
      "vault_unprocessed",
      "vault_session_summary_material",
      "vault_update_session",
      "vault_report"
    ],
    "reasoningLevel": "low",
    "maxTurns": 15,
    "timeoutSeconds": 300
  },
  {
    "name": "vault-evolve",
    "displayName": "Vault Evolve",
    "description": "Complete intelligence pass over all unprocessed session data. Extracts observations as spores, updates session summaries, consolidates related spores into wisdom, and regenerates digest extracts. Runs automatically on a schedule once sessions have settled.\n",
    "agent": "myco-agent",
    "prompt": "You are executing one phase of a multi-phase intelligence pipeline. Each phase has its own scoped tools — only use the tools available to you. Do NOT report on tools or work outside your current phase. Focus on quality over quantity — one precise observation is worth more than ten vague ones. Use release state as conservative context: released/high-confidence knowledge is strongest for general guidance, while unknown, unreconciled, or unreleased knowledge can still be useful in-flight evidence.\n",
    "isDefault": true,
    "reasoningLevel": "default",
    "maxTurns": 150,
    "timeoutSeconds": 1800,
    "phases": [
      {
        "name": "read-state",
        "prompt": "Read the current vault state to determine what needs processing.\n\n1. Call `vault_state` to get your cursor (`last_processed_batch_id`)\n2. Call `vault_unprocessed` with `after_id` set to your cursor\n\nIf no unprocessed batches exist, report via `vault_report` with\naction \"skip\" and reason \"no unprocessed batches\".\n",
        "tools": [
          "vault_state",
          "vault_unprocessed",
          "vault_spores",
          "vault_release_state",
          "vault_report"
        ],
        "maxTurns": 20,
        "reasoningLevel": "low",
        "required": true,
        "readOnly": true,
        "onItemError": "skip"
      },
      {
        "name": "extract",
        "prompt": "Extract observations from unprocessed batches as spores.\nCRITICAL: the vault must stay sharp, not bloated. Supersede, don't duplicate.\n\nIf the prior phase reported no unprocessed batches, call `vault_report`\nwith action \"skip\" and reason \"no unprocessed batches\" and finish.\n\n## Step 1: Read batches and identify observations (budget: ~10 turns)\n\nPASS 1: Call `vault_unprocessed` with `after_id` set to the cursor from\nthe prior phase AND `limit: 40`. This is a hard per-run cap — process at\nmost 40 batches. The cursor advances by what you process, so any larger\nbacklog drains across subsequent scheduled runs rather than overheating\none. For each batch, note candidate insights as a mental list. Focus on\ngenuine insights, not activity logs.\n\nPASS 2: Group similar insights into topics. Batches often repeat the same\ntheme — group before searching to minimize tool calls.\n\n## Step 2: Search and create/supersede (budget: ~20 turns)\n\nFor each TOPIC you identified (not each batch — group first):\n1. Call `vault_search_semantic` with the topic to check existing coverage\n2. If a similar spore exists:\n   - If your observation adds meaningful new detail: create the new\n     spore, then supersede the old via `vault_resolve_spore`\n     action \"supersede\" with new_spore_id\n   - If your observation adds nothing new: skip it entirely\n3. If no similar spore exists: create it as new\n4. Mark the source batches as processed via `vault_mark_processed`\n\n## Step 3: Update cursor (budget: 1 turn)\n\nCall `vault_set_state` to update `last_processed_batch_id`.\n\n## Quality rules\n- One observation per spore — specific, not vague\n- Include session_id, prompt_batch_id, importance 1-10, tags\n- Supersede rather than duplicate — the vault gets sharper, not bigger\n- Group batches by topic to minimize search calls\n- If approaching the turn budget or the 40-batch cap, stop and move on\n\nFinal summary MUST be ≤ 6 lines: batches processed, spores created (by\ntype), and supersedes applied. No per-spore retelling.\n",
        "tools": [
          "vault_unprocessed",
          "vault_spores",
          "vault_search_fts",
          "vault_search_semantic",
          "vault_release_state",
          "vault_create_spore",
          "vault_resolve_spore",
          "vault_mark_processed",
          "vault_set_state",
          "vault_report"
        ],
        "maxTurns": 35,
        "reasoningLevel": "default",
        "required": true,
        "dependsOn": [
          "read-state"
        ],
        "onItemError": "skip"
      },
      {
        "name": "summarize",
        "prompt": "Update session titles and summaries for sessions touched during extraction.\n\n## Step 1: Find sessions with new activity (budget: 2 turns)\n\n1. Call `vault_unprocessed` — group batches by session_id. Each session\n   with unprocessed batches needs its summary updated.\n2. Call `vault_sessions` to get existing titles/summaries for those sessions.\n\nIf no sessions have new activity, report \"skip\" and finish.\n\n## Step 2: Update each session (budget: 5 turns)\n\nFor each session with new batches:\n1. Read the EXISTING title and summary — context from prior runs.\n2. Read the NEW prompt batches (from Step 1) — user_prompt + response_summary.\n   This is your PRIMARY source. Understand the full arc of new work.\n3. Generate an UPDATED title and summary incorporating both existing\n   context and new activity.\n\n## Step 3: Write updates (budget: 2 turns)\n\nCall `vault_update_session` with BOTH title and summary.\n\n### Title Rules (CRITICAL)\n\nThe title describes WHAT WAS ACCOMPLISHED, not what was asked.\n- Under 80 chars, sentence case\n- Synthesize from the full arc of prompt batches, not just the first one\n- NEVER use file paths, directory names, or working directory\n- NEVER copy the user's first message as the title\n- Good: \"Wave-based parallel executor and per-task provider config\"\n- Bad: \"/git-worktree\" (directory path, not a title)\n\n### Summary Rules\n\n2-4 sentences. Rich in detail — session summaries are embedded and used\nfor semantic search. Include: what was built/fixed, key files touched,\ntools used, outcomes. Focus on what was accomplished across the FULL\nsession, not just the first or last prompt.\n\nReport via `vault_report` with action \"summary\" for each update.\nIf no updates needed, report action \"skip\" with reason.\n",
        "tools": [
          "vault_sessions",
          "vault_unprocessed",
          "vault_spores",
          "vault_release_state",
          "vault_update_session",
          "vault_report"
        ],
        "maxTurns": 10,
        "reasoningLevel": "low",
        "required": false,
        "dependsOn": [
          "read-state"
        ],
        "onItemError": "skip"
      },
      {
        "name": "consolidate-shortlist",
        "prompt": "Find consolidation candidates. This is the cheap retrieval pass —\na later phase (`consolidate-write`) does any actual wisdom creation\nor supersession based on your shortlist.\n\nStay focused on recent or high-signal active spores; do not perform\nan exhaustive crawl if the first few targeted searches show no action.\n\n## Step 1: Search for clusters (budget: 6 turns)\n\n1. Run targeted `vault_search_semantic` queries for themes touched by\n   the current extract phase and other likely consolidation targets.\n2. For any candidate you need to inspect in full, call `vault_spores`\n   with `ids: [...]` — never bulk-read an entire high-volume type.\n3. Skip spores with status \"consolidated\", \"superseded\", or \"obsolete\"\n   to prevent cycles (only active spores are consolidation candidates).\n\n## Step 2: Emit a STRUCTURED shortlist (budget: 2 turns)\n\nYour final message MUST be parseable by the next phase. Use this\nexact format. If no clusters meet the bar, emit only the SKIP line\nand call `vault_report` with action \"skip\".\n\n```\nSHORTLIST v1\ncluster: <one-line topic name>\n  action: wisdom           # 3+ related active spores on same topic\n  source_ids: [id1, id2, id3, ...]\n  rationale: <why these belong together — 1 line>\n\ncluster: <topic>\n  action: supersede        # exactly 2 spores; the newer/richer wins\n  keep_id: <id of winner>\n  old_id: <id to supersede>\n  rationale: <1 line>\n```\n\nHard cap: emit at most 2 clusters per run. The downstream write\nphase has a small budget; over-feeding it produces nothing extra.\nPick the highest-signal candidates first.\n\nIf `vault_search_semantic` returns no results (embedding unavailable),\nreport action \"skip\" and finish.\n\nFinal summary MUST be ≤ 25 lines (the shortlist block plus a brief\nheader). No prose recap of what you searched.\n",
        "tools": [
          "vault_spores",
          "vault_search_semantic",
          "vault_release_state",
          "vault_report"
        ],
        "maxTurns": 18,
        "reasoningLevel": "low",
        "required": false,
        "dependsOn": [
          "extract"
        ],
        "readOnly": true,
        "preCondition": "has-recent-consolidatable-spores",
        "onItemError": "skip"
      },
      {
        "name": "consolidate-write",
        "prompt": "Execute the shortlist from `consolidate-shortlist`. The judgment\nwork — content synthesis, preserving specific details — needs the\ndefault tier; cheap retrieval already happened upstream.\n\nIf the shortlist was empty or marked SKIP, call `vault_report` with\naction \"skip\" and finish immediately.\n\n## Budget discipline\n\nThe shortlist may contain up to 2 clusters. Each cluster needs\nroughly 4-6 turns (1 optional read + 1 create + 1-3 resolves).\nProcess clusters in order. If you're past turn 11 and still have\na cluster pending, STOP — call `vault_report` summarizing what\nyou completed and which clusters you skipped, then finish. A clean\npartial result beats a failed full run.\n\n## For each `action: wisdom` cluster\n\n1. (Optional, 1 turn) Re-read the source spores in full via\n   `vault_spores(ids: [...])` if the shortlist didn't include enough\n   body text to synthesize from. Skip if you already have what you need.\n2. Create a wisdom spore via `vault_create_spore`:\n   - observation_type: \"wisdom\"\n   - properties: '{\"consolidated_from\": [<source_ids>]}'\n   - Content MUST preserve ALL specific details from sources —\n     file paths, error messages, concrete values. Wisdom is a\n     comprehensive reference, not a vague summary.\n3. Resolve EACH source via `vault_resolve_spore` action \"consolidate\"\n   — this removes them from search and context injection.\n\n## For each `action: supersede` cluster\n\n1. (Required) Read the keep spore in full via `vault_spores(ids: [<keep_id>])`\n   to confirm it actually subsumes the old one. Never supersede on\n   the shortlist's word alone.\n2. Call `vault_resolve_spore` action \"supersede\" with new_spore_id =\n   keep_id and old_spore_id = old_id.\n\nFinal summary MUST be ≤ 5 lines: how many wisdom spores created, how\nmany supersedes applied, anything skipped. No retelling of the shortlist.\n",
        "tools": [
          "vault_spores",
          "vault_release_state",
          "vault_create_spore",
          "vault_resolve_spore",
          "vault_report"
        ],
        "maxTurns": 15,
        "reasoningLevel": "default",
        "required": false,
        "dependsOn": [
          "consolidate-shortlist"
        ],
        "preCondition": "has-recent-consolidatable-spores",
        "onItemError": "skip"
      },
      {
        "name": "digest-assess",
        "prompt": "Gather material for AT MOST ONE digest tier update per run. The\nrotation decision is made by the `vault_read_digest` tool, not\nby you — the tool returns which tier needs attention (or tells\nyou to skip). Over 3 runs every tier gets one deep pass.\n\nTotal budget: {{max_turns}} turns.\n\n## Step 1: Get the rotation decision (1 turn)\n\nCall `vault_read_digest` with:\n  pick: \"rotate_oldest\"\n  min_staleness_seconds: 1800\n\nThe tool returns one of two shapes:\n\n**Skip shape** — `{mode:\"rotate_oldest\", skip:true, reason, all_tiers}`.\nEvery tier was generated within the last 30 minutes. Commit the\nskip via the metadata channel:\n\n  phase_emit_metadata({ key: \"selectedTier\", value: null })\n\nThen call `vault_report` with action \"skip\" passing the reason\nthrough. STOP — do not run steps 2-3. The downstream digest-N\nsibling phases gate on `selectedTier` and will short-circuit in\nzero LLM turns when the value is null or doesn't match their tier.\n\n**Rotate shape** — `{mode:\"rotate_oldest\", selected_tier,\nselected_generated_at, selected_content, rotation_reason, all_tiers}`.\nProceed to step 2, scoped to `selected_tier`.\n\n## Step 2: Gather material for `selected_tier` (budget: half\nof remaining)\n\nScope the search to what belongs at the selected tier:\n- **1500 (executive briefing):** only critical decisions,\n  reversals, state-of-system changes.\n- **5000 (deep onboarding):** trade-offs, patterns, active\n  decisions, unresolved gotchas.\n- **10000 (full archive):** any new content worth preserving.\n\nUse `vault_search_semantic` for themes from new/superseded spores,\n`vault_spores` for specific content, `vault_sessions` for recent\nsession context. Make each call count — do not repeatedly search\nfor variations of the same theme. Accept \"good enough\" findings\nand move on.\n\n## Step 3: Produce findings AND commit the rotation choice\n\nYour final response is the per-tier phases' primary context\n(they cannot call vault_spores or vault_sessions). Structure it:\n\n**Chosen tier for this run: <selected_tier>**\nInclude the rotation_reason verbatim from the tool so readers\ncan audit the decision.\n\n**New material to integrate (scoped to the chosen tier):**\n- List each insight with enough detail that the tier writer can\n  incorporate it without re-searching\n- Include specific spore content, not just spore counts\n\n**Themes and connections** relevant to the chosen tier.\n\n## Step 4: Commit the rotation via metadata (REQUIRED, last call)\n\nBefore finishing, you MUST call:\n\n  phase_emit_metadata({ key: \"selectedTier\", value: <number> })\n\nwhere `<number>` is the integer 1500, 5000, or 10000 matching the\ntier you selected. The downstream digest-N sibling phases gate on\nthis — non-selected tiers skip in zero LLM turns. If you forget\nthis call, all three digest phases skip and the rotation stalls\nfor this run.\n\nTools available: {{phase_tools}}.\n",
        "tools": [
          "vault_spores",
          "vault_sessions",
          "vault_search_semantic",
          "vault_release_state",
          "vault_read_digest",
          "vault_report",
          "phase_emit_metadata"
        ],
        "maxTurns": 12,
        "reasoningLevel": "default",
        "required": true,
        "dependsOn": [
          "consolidate-write"
        ],
        "onItemError": "skip"
      },
      {
        "name": "digest-10000",
        "prompt": "Update digest tier 10000 — Full institutional knowledge.\nBudget: {{max_turns}} turns.\n\nYou only reach this phase when digest-assess committed\n`selectedTier: 10000` — no STOP-FIRST check needed; the phase loop\ngate already filtered the rotation. The digest-assess phase\nsummary in your context contains the material to integrate.\n\n1. Call `vault_read_digest` with tier 10000 to get current content\n2. Call `vault_search_semantic` for themes identified in the assess\n   findings — gather specific details to weave in\n3. Integrate new material into the existing digest\n4. Call `vault_write_digest` with the updated content\n\nThe existing digest is your baseline — integrate new material, don't\nrewrite from scratch. Preserve well-crafted existing content.\n\nPrioritize: recent insights > active decisions > unresolved gotchas >\narchitectural patterns > historical context.\n\nFinal summary MUST be ≤ 5 lines.\n",
        "tools": [
          "vault_search_semantic",
          "vault_release_state",
          "vault_read_digest",
          "vault_write_digest",
          "vault_report"
        ],
        "maxTurns": 9,
        "reasoningLevel": "low",
        "required": true,
        "dependsOn": [
          "digest-assess"
        ],
        "gateOnPriorMetadata": {
          "phase": "digest-assess",
          "key": "selectedTier",
          "equals": 10000
        },
        "onItemError": "skip"
      },
      {
        "name": "digest-5000",
        "prompt": "Update digest tier 5000 — Deep onboarding.\nBudget: {{max_turns}} turns.\n\nYou only reach this phase when digest-assess committed\n`selectedTier: 5000`. This tier (~5,000 tokens) focuses on\ntrade-offs and patterns. The digest-assess phase summary in your\ncontext contains the material to integrate.\n\n1. Call `vault_read_digest` with tier 5000 to get current content\n2. Optionally call `vault_search_semantic` for additional context\n3. Integrate new material from the assess findings\n4. Call `vault_write_digest` with the updated content\n\nThe existing digest is your baseline — integrate new material, don't\nrewrite from scratch. Preserve well-crafted existing content.\n\nPrioritize: recent insights > active decisions > unresolved gotchas >\narchitectural patterns > historical context.\n\nFinal summary MUST be ≤ 5 lines.\n",
        "tools": [
          "vault_search_semantic",
          "vault_release_state",
          "vault_read_digest",
          "vault_write_digest",
          "vault_report"
        ],
        "maxTurns": 7,
        "reasoningLevel": "low",
        "required": true,
        "dependsOn": [
          "digest-assess"
        ],
        "gateOnPriorMetadata": {
          "phase": "digest-assess",
          "key": "selectedTier",
          "equals": 5000
        },
        "onItemError": "skip"
      },
      {
        "name": "digest-1500",
        "prompt": "Update digest tier 1500 — Executive briefing.\nBudget: {{max_turns}} turns.\n\nYou only reach this phase when digest-assess committed\n`selectedTier: 1500`. This is the most compressed tier\n(~1,500 tokens). Only update if\nimportant new decisions, gotchas, or critical changes were found.\nThe digest-assess phase summary in your context contains the material\nto integrate.\n\n1. Call `vault_read_digest` with tier 1500 to get current content\n2. Integrate new material from the assess findings — be very selective,\n   only critical changes belong at this tier\n3. Call `vault_write_digest` with the updated content\n\nThe existing digest is your baseline — integrate new material, don't\nrewrite from scratch. Preserve well-crafted existing content.\n\nPrioritize: recent insights > active decisions > unresolved gotchas >\narchitectural patterns > historical context.\n\nFinal summary MUST be ≤ 5 lines.\n",
        "tools": [
          "vault_read_digest",
          "vault_write_digest",
          "vault_report"
        ],
        "maxTurns": 5,
        "reasoningLevel": "low",
        "required": true,
        "dependsOn": [
          "digest-assess"
        ],
        "gateOnPriorMetadata": {
          "phase": "digest-assess",
          "key": "selectedTier",
          "equals": 1500
        },
        "onItemError": "skip"
      },
      {
        "name": "report",
        "prompt": "Summarize what was done across all phases.\n\nCall `vault_report` with action \"complete\" and these details:\n- Batches processed: N\n- Spores created: N (by type)\n- Sessions updated: N\n- Wisdom created: N\n- Digest tiers written: N\n\nThis report MUST be the last tool call of the run.\n",
        "tools": [
          "vault_report"
        ],
        "maxTurns": 3,
        "reasoningLevel": "low",
        "required": true,
        "dependsOn": [
          "extract",
          "summarize",
          "consolidate-shortlist",
          "consolidate-write",
          "digest-assess",
          "digest-10000",
          "digest-5000",
          "digest-1500"
        ],
        "onItemError": "skip"
      }
    ],
    "contextQueries": {
      "pre-planning": [
        {
          "tool": "vault_unprocessed",
          "queryTemplate": "",
          "limit": 5,
          "purpose": "Check if there are unprocessed batches",
          "required": false
        },
        {
          "tool": "vault_state",
          "queryTemplate": "",
          "limit": 10,
          "purpose": "Get agent cursor state",
          "required": false
        },
        {
          "tool": "vault_spores",
          "queryTemplate": "",
          "limit": 20,
          "purpose": "Review recent spores for consolidation candidates",
          "required": false
        }
      ]
    },
    "orchestrator": {
      "enabled": true,
      "reasoningLevel": "default",
      "maxTurns": 3
    },
    "schedule": {
      "enabled": true,
      "intervalSeconds": 21600,
      "runIn": [
        "idle",
        "sleep"
      ],
      "preCondition": "has-unprocessed-batches",
      "accelerator": {
        "name": "unprocessed-settled-batches",
        "thresholds": {
          "steady": 25,
          "accelerated": 100
        }
      },
      "maxRunsPerDay": 6
    }
  },
  {
    "name": "vault-seed",
    "displayName": "Vault Seed",
    "description": "One-shot seeding pass for a brownfield codebase. Explores the project with filesystem and grep tools, identifies architectural patterns, conventions, and gotchas, then populates the vault with an initial spore set and a starter digest. Manual trigger only — no session data required.\n",
    "agent": "myco-agent",
    "prompt": "You are running a one-shot seeding pass over a brownfield codebase. There are no session transcripts to process — infer knowledge directly from source. Focus on architectural patterns, conventions, trade-offs, and gotchas that a new developer or agent onboarding to this code would benefit from. Quality over quantity — one precise observation is worth more than ten vague ones.\nIMPORTANT: the pipeline is phased, and each phase has a different tool surface. Early phases explore source with filesystem tools; later phases write observations to the vault using vault_* tools. Each phase's prompt lists the tools it has. Trust that list and call those tools directly. Do not rationalize that a declared tool is \"unavailable\" based on what earlier phases used.\n",
    "isDefault": false,
    "reasoningLevel": "default",
    "maxTurns": 300,
    "timeoutSeconds": 3600,
    "phases": [
      {
        "name": "orient",
        "prompt": "**Your ONLY job this phase: produce a 3-8 item theme list from\nsurface signals.** You are NOT verifying themes, NOT reading\nimplementation, and NOT building a comprehensive understanding.\nThat work belongs to the next phase (explore-themes), which has\na much larger budget and is designed for it.\n\n**Hard turn budget: {{max_turns}}.** Each tool call costs one\nturn. If you exhaust the budget before calling `vault_report`\nwith the theme list, this phase fails and blocks the rest of\nthe pipeline. Treat the budget as a constraint, not a suggestion\n— finish well under it.\n\n**Scope guard:** if you find yourself opening a file under\n`packages/*/src/**`, `src/**`, `lib/**`, or any implementation\ndirectory, STOP. That is explore-themes's job. Orient reads\ntop-level metadata and docs only.\n\n## Exact tool plan (budget: ~8 tool calls total)\n\nCall ONLY these tools, in this order. Do NOT add calls.\n\n1. `fs_tree` at `.` with depth=1 — 1 call, 1 turn.\n2. `fs_read` the README (no line window) — 1 call, 1 turn.\n3. `fs_read` the primary manifest (package.json / pyproject.toml /\n   Cargo.toml / go.mod / Gemfile / pom.xml — pick the one that\n   exists, skip if unclear) — 0 or 1 call.\n4. `fs_list` at `.` — 1 call, 1 turn. After this call you have\n   seen every top-level tooling signal. DO NOT list additional\n   directories in this phase; recursive layout exploration is\n   explore-themes's job.\n5. (Optional) `fs_list` on `docs/` — 0 or 1 call. If you do, then\n   `fs_read` AT MOST 2 files that clearly look like architecture\n   or overview docs — max 2 more calls.\n6. `vault_report` with action \"orient\" and the theme list — 1\n   call. This is your last tool call. The phase ends here.\n\nSkipping steps is fine. Adding steps is not. If you are tempted\nto list a subdirectory to \"see what's inside it,\" resist —\nexplore-themes will do that with more budget.\n\n**Frugality:** every tool response comes back as tokens on your\nnext turn's input. Narrow calls keep the budget healthy.\n\n## Output: theme outline\n\nFrom those surface signals alone, name 3-8 themes worth deeper\nexploration in the next phase. Name them confidently even if you\ndon't have full evidence yet — the next phase will verify them.\nGood themes:\n- major architectural layers (\"agent harness\", \"daemon\", \"UI\")\n- cross-cutting domain concepts (\"team sync\", \"session lifecycle\")\n- notable integration points (\"MCP server\", \"SQLite vault\")\n- conventions worth surfacing (testing style, error handling)\n\nAvoid generic themes like \"TypeScript code\" or \"tests exist\".\n\nCall `vault_report` with action \"orient\" and the structured theme\nlist. This is your final tool call for this phase.\n",
        "tools": [
          "fs_tree",
          "fs_list",
          "fs_read",
          "vault_report"
        ],
        "maxTurns": 25,
        "reasoningLevel": "default",
        "required": true,
        "readOnly": true,
        "onItemError": "skip"
      },
      {
        "name": "explore-themes",
        "prompt": "For each theme identified in the orient phase, drill down with\n`code_grep` and targeted `fs_read` calls. Collect specific,\nconcrete observations that would survive the code evolving.\n\n## Strategy (budget: 4-6 turns per theme)\n\nFor each theme:\n1. `code_grep` for signature patterns — class/interface names,\n   distinctive function names, keywords. Use a `glob` filter when\n   the language is known (e.g., `*.ts`, `*.py`).\n2. `fs_read` the 2-4 most informative files you find. Prefer\n   cross-cutting modules over leaf files.\n3. Note 3-6 concrete observations for the theme. Anchor each to\n   file paths or function names.\n\n## What makes a good observation\n\n- Anchored to specific file paths, function names, or patterns\n- Captures trade-offs, gotchas, or non-obvious invariants\n- Explains WHY when the reasoning is evident from the code\n- Would be useful to an agent or developer onboarding\n\n## What to skip\n\n- Boilerplate (standard manifest fields, generated code)\n- Implementation details that change frequently\n- Things obvious from the README\n- Generic advice (\"use TypeScript\") — only observations specific to\n  THIS codebase belong in the vault\n\n## Output\n\nProduce a structured summary grouped by theme, focused on\nOBSERVATIONS (the conclusions) rather than a log of what you did.\nWrite the summary as if a separate agent will read it cold and\nturn each observation into a durable note. Avoid phrases like\n\"I ran fs_tree on…\" or \"I read the README\" — name the observation\nand anchor it to specific paths. The seed-spores phase runs with\na different tool surface and should not be primed to expect\nfilesystem access.\n\nCall `vault_report` with action \"explore\" and the structured result.\n",
        "tools": [
          "fs_tree",
          "fs_list",
          "fs_read",
          "code_grep",
          "vault_report"
        ],
        "maxTurns": 120,
        "reasoningLevel": "default",
        "required": true,
        "dependsOn": [
          "orient"
        ],
        "readOnly": true,
        "onItemError": "skip"
      },
      {
        "name": "seed-spores",
        "prompt": "Create spores for the observations from the explore phase.\n\n**Hard turn budget: {{max_turns}}.** Each tool call costs one\nturn. Every observation needs one `vault_create_spore` call;\nbudget your work accordingly.\n\n## Your tools this phase\n\nYou have these tools and ONLY these tools: {{phase_tools}}.\nThey are registered and available. Call them directly. Do NOT\nverify or second-guess. Filesystem tools from earlier phases\nare not needed here — the explore-themes summary in your\ncontext contains everything you need to create spores.\n\n## Step 1: Re-seed check (1 tool call)\n\nThis phase runs on cold vaults AND on vaults that have been\nseeded before. Call `vault_search_semantic` ONCE with a broad\nquery derived from the strongest theme (e.g. the name of the\nhighest-signal architectural layer from the explore summary).\n\n- If the search returns several high-similarity results (many\n  scores > 0.85), the vault is already populated. Call\n  `vault_report` with action \"skip\" and reason \"vault already\n  populated\" and STOP. Do not create duplicate spores.\n- If the search returns nothing or only low-similarity results\n  (typical for a cold vault with no embeddings, or a vault with\n  unrelated prior content), proceed to Step 2.\n\nDo NOT run per-observation similarity searches — dedup across\nexisting spores is the job of the separate consolidation task,\nnot seed-spores. One broad re-seed check is enough.\n\n## Step 2: Create spores (the bulk of your budget)\n\nFor each observation in the explore summary, call\n`vault_create_spore` with:\n- observation_type: \"decision\", \"pattern\", \"wisdom\", \"gotcha\",\n  or \"architecture\" based on what the observation captures\n- content: the full observation — concrete and specific\n- importance: 1-10 (10 = load-bearing architectural invariant,\n  3 = minor stylistic preference)\n- tags: 2-4 tags covering theme and domain\n- file_path: the primary source file when the observation\n  anchors to one specific location\n- session_id: null (no session provenance — this is seed data)\n- prompt_batch_id: null\n- context: \"Seeded from vault-seed exploration pass\"\n\nSeed spores have no session provenance. Do not invent release\nconfidence for them; use release state only when file or package\nevidence has already been reconciled.\n\n## Quality rules\n\n- One observation per spore — specific, not vague\n- Prefer fewer, higher-signal spores over many low-signal ones\n- Target: 10-40 spores per seed run. If the exploration produced\n  far more candidates, prioritize by importance and drop the rest\n  rather than creating everything\n- Observations anchored to specific file paths are stronger than\n  abstract statements\n",
        "tools": [
          "vault_search_semantic",
          "vault_release_state",
          "vault_create_spore",
          "vault_report"
        ],
        "maxTurns": 80,
        "reasoningLevel": "default",
        "required": true,
        "dependsOn": [
          "explore-themes"
        ],
        "onItemError": "skip"
      },
      {
        "name": "digest-10000",
        "prompt": "Write digest tier 10000 — Full institutional knowledge (~10k tokens).\n\n## Your tools this phase\n\nYou have these tools and ONLY these tools:\n`vault_spores`, `vault_search_semantic`, `vault_release_state`,\n`vault_read_digest`, `vault_write_digest`, `vault_report`. They are registered and\navailable. Call them directly. Filesystem tools from earlier\nphases are NOT in scope here — the spores created in seed-spores\ncontain everything you need.\n\nIf the seed-spores phase short-circuited with \"vault already populated\",\ncall `vault_report` with action \"skip\" for tier 10000 and finish.\n\n1. Call `vault_read_digest` with tier 10000 to see any existing content.\n   If this is a first seed run, it will be empty.\n2. Call `vault_spores` with status \"active\" to read the freshly seeded\n   observations.\n3. Organize the digest around the themes from the explore phase.\n   Include concrete file paths and function names. A reader should\n   come away with a thorough picture of the architecture, key\n   decisions, and gotchas.\n4. Call `vault_write_digest` with tier 10000.\n\nIf the existing digest already contains comparable content (re-seed\ncase), integrate rather than overwrite — preserve well-crafted text.\n",
        "tools": [
          "vault_spores",
          "vault_search_semantic",
          "vault_release_state",
          "vault_read_digest",
          "vault_write_digest",
          "vault_report"
        ],
        "maxTurns": 15,
        "reasoningLevel": "default",
        "required": false,
        "dependsOn": [
          "seed-spores"
        ],
        "onItemError": "skip"
      },
      {
        "name": "digest-5000",
        "prompt": "Write digest tier 5000 — Deep onboarding (~5k tokens).\n\n## Your tools this phase\n\nYou have these tools and ONLY these tools:\n`vault_spores`, `vault_read_digest`, `vault_write_digest`,\n`vault_report`. They are registered and available. Call them\ndirectly. Filesystem tools from earlier phases are NOT in scope.\n\nIf the seed-spores phase short-circuited, call `vault_report` with\naction \"skip\" for tier 5000 and finish.\n\nThis tier focuses on trade-offs and patterns — what a developer\nneeds after the README but before diving into code.\n\n1. Call `vault_read_digest` with tier 5000 for the baseline.\n2. Call `vault_spores` as the primary source (digest-10000 may still\n   be in-flight — don't depend on it).\n3. Call `vault_write_digest` with tier 5000. Trim and synthesize;\n   this tier is a compression of tier 10000's material.\n",
        "tools": [
          "vault_spores",
          "vault_read_digest",
          "vault_write_digest",
          "vault_report"
        ],
        "maxTurns": 12,
        "reasoningLevel": "default",
        "required": false,
        "dependsOn": [
          "seed-spores"
        ],
        "onItemError": "skip"
      },
      {
        "name": "digest-1500",
        "prompt": "Write digest tier 1500 — Executive briefing (~1.5k tokens).\n\n## Your tools this phase\n\nYou have these tools and ONLY these tools:\n`vault_spores`, `vault_read_digest`, `vault_write_digest`,\n`vault_report`. They are registered and available. Call them\ndirectly. Filesystem tools from earlier phases are NOT in scope.\n\nIf the seed-spores phase short-circuited, call `vault_report` with\naction \"skip\" for tier 1500 and finish.\n\nThe tightest tier: what someone needs to know in 2 minutes.\nArchitectural overview in 1-2 sentences, 2-3 load-bearing decisions,\nthe critical gotchas. Ruthlessly selective.\n\n1. Call `vault_spores` filtered to importance >= 8 to find the\n   top-signal observations.\n2. Call `vault_write_digest` with tier 1500.\n",
        "tools": [
          "vault_spores",
          "vault_read_digest",
          "vault_write_digest",
          "vault_report"
        ],
        "maxTurns": 8,
        "reasoningLevel": "default",
        "required": false,
        "dependsOn": [
          "seed-spores"
        ],
        "onItemError": "skip"
      },
      {
        "name": "report",
        "prompt": "Summarize the seeding pass.\n\nYour only tool this phase is `vault_report`. Call it — it is\nregistered and available.\n\nCall `vault_report` with action \"complete\" and these details:\n- Themes explored: N\n- Spores created: N (by type)\n- Spores superseded: N\n- Digest tiers written: [list]\n- Thin coverage: any themes where the exploration surfaced fewer than\n  3 observations — surface these so the user can follow up with a\n  targeted review-session or additional manual curation\n\nThis report MUST be the last tool call of the run.\n",
        "tools": [
          "vault_report"
        ],
        "maxTurns": 5,
        "reasoningLevel": "low",
        "required": true,
        "dependsOn": [
          "seed-spores",
          "digest-10000",
          "digest-5000",
          "digest-1500"
        ],
        "onItemError": "skip"
      }
    ]
  }
] as const;

export const BUNDLED_AGENT_PROMPTS: Readonly<Record<string, string>> = {
  "agent.md": "# Myco Intelligence Agent\n\nYou are the Myco intelligence agent. You process captured developer session data to build institutional knowledge. Your job is to read raw session activity, extract meaningful observations, maintain spore lifecycle, and synthesize digest context.\n\nYou operate on a vault database. The capture layer writes raw data (sessions, prompt batches, activities) without any intelligence. You provide the intelligence — deciding what matters, what connects, and what has changed.\n\n## Your Tools\n\n### Read Tools\n\n- **vault_state** — Get your key-value state (cursor position, preferences). Call this first on every run.\n- **vault_unprocessed** — Get prompt batches not yet processed, ordered by ID. Supports cursor-based pagination via `after_id`.\n- **vault_spores** — List existing spores with filters: `observation_type`, `status` (active/superseded/consolidated/obsolete), `agent_id`, `session_id`, or fetch exact spores by `ids` when you need full content for a semantic shortlist.\n- **vault_sessions** — List sessions with optional `status` filter, ordered by most recent.\n- **vault_session_summary_material** — Get compact title/summary material for one session in a single read: current title/summary plus the ordered prompt-batch arc with only user prompts and assistant summaries.\n- **vault_search_fts** — Full-text search across prompt batches and activities using FTS5. Best for keyword matches and finding session content. Params: `query`, `type` (prompt_batch, activity), `limit`.\n- **vault_search_semantic** — Semantic similarity search across embedded vault content (spores, sessions, plans, artifacts). Best for finding conceptually related content and shortlist candidates before reading exact records. Params: `query`, `namespace` (spores, sessions, plans, artifacts — omit to search all), `limit`.\n- **vault_release_state** — Read derived release-state classifications for sessions, prompt batches, spores, plans, artifacts, skills, and Canopy entries. Use it when deciding whether knowledge is shipped, merged-unreleased, unknown, or unreconciled. Do not treat unreleased as false or unknown as unimportant.\n- **vault_read_digest** — Read current digest extracts. Call with no params for metadata, or with a `tier` number (1500/5000/10000) to read that tier's content.\n- **vault_edges** — List lineage edges between sessions, prompt batches, and spores. Use for provenance walks: `FROM_SESSION` (spore→session), `EXTRACTED_FROM` (spore→batch), `HAS_BATCH` (session→batch), `DERIVED_FROM` (wisdom→source spores), `SUPERSEDED_BY` (spore→spore). Filters: `source_id`, `target_id`, `type`.\n\n### Write Tools\n\n- **vault_create_spore** — Create a new observation. Requires `observation_type` and `content`. Optional: `session_id`, `prompt_batch_id`, `importance` (1-10), `tags`, `context`, `file_path`, `properties` (JSON string, e.g., `'{\"consolidated_from\": [\"id1\", \"id2\"]}'`).\n- **vault_resolve_spore** — Resolve a spore's lifecycle. Requires `spore_id` and `action`: `supersede` (a newer spore replaces it; pass `new_spore_id`), `consolidate` (merged into a wisdom note; pass `new_spore_id`), or `obsolete` (no longer relevant, no replacement). Optional: `new_spore_id`, `reason`, `session_id`.\n- **vault_update_session** — Set a session's `title` and/or `summary`.\n- **vault_set_state** — Store a key-value pair for your cursor and preferences.\n- **vault_write_digest** — Write a digest extract at a token `tier`. Upserts on tier.\n- **vault_mark_processed** — Mark a prompt batch as processed so it won't appear in `vault_unprocessed` again.\n\n### Observability\n\n- **vault_report** — Record a report for the current run. Requires `action` and `summary`. Optional: `details` object. Use this to log what you did and why.\n\n## Observation Types\n\nWhen extracting spores, classify each observation. The canonical kinds are split between direct extraction (what you produce from session activity) and synthesis (what consolidation and seed phases produce).\n\n**Direct-extraction kinds:**\n\n- **gotcha** — A surprising behavior or hidden pitfall that caught the developer off guard. Something that would save the next person time if they knew it in advance.\n- **decision** — An architectural or implementation choice, including the rationale. Why was option A chosen over option B?\n- **discovery** — A new understanding about the codebase, a tool, a library, or an approach. An \"aha\" moment that changed how the developer thinks about the system.\n- **trade_off** — A deliberate compromise where the developer weighed pros and cons. What was gained and what was given up?\n- **bug_fix** — A bug found and fixed, including the root cause and the fix. What was wrong and why?\n- **cross-cutting** — An observation that spans multiple subsystems and doesn't belong to any single one.\n\n**Synthesized kinds** (use these only during consolidation or seed phases):\n\n- **wisdom** — A higher-order observation synthesized from 3+ related spores. Always includes `properties.consolidated_from` listing source spore IDs.\n- **pattern** — A recurring shape across the codebase: a layout, naming convention, or interaction style that appears in multiple places.\n- **architecture** — A load-bearing invariant of the system. Use sparingly — these are the spores that explain *why* the design works the way it does.\n\n## Extraction Quality\n\nA good spore is specific and captures insight, not activity.\n\n**Do:**\n- Reference files, components, and functions by name\n- Capture the WHY — rationale, root cause, reasoning\n- Include enough context that the spore is useful without reading the full session\n- Assign importance honestly: 1-3 for local fixes, 4-6 for meaningful patterns, 7-9 for architectural insights, 10 for fundamental design decisions\n- One observation per spore — if you find a compound insight, split it\n\n**Do not:**\n- Extract trivial operations (file reads, basic searches, routine edits)\n- Repeat what the code does — capture what was learned\n- Create vague spores like \"worked on authentication\" — be precise about what was discovered or decided\n- Inflate importance scores — most spores should be 3-6\n\n## Lineage Edges (read-only, daemon-created)\n\nThe daemon maintains a lineage graph automatically — you do not create edges. Use `vault_edges` to walk provenance:\n\n- **FROM_SESSION** — spore → session (which session produced this observation)\n- **EXTRACTED_FROM** — spore → batch (which prompt batch surfaced it)\n- **HAS_BATCH** — session → batch (structural containment)\n- **DERIVED_FROM** — wisdom spore → source spore (consolidation provenance)\n- **SUPERSEDED_BY** — spore → spore (supersession link)\n\n## Skill Lifecycle Tools\n\n### vault_skill_candidates\n\nQuery and manage skill candidates — observations that may become project skills.\n\n- **list**: Browse pending/approved/dismissed candidates. Filter with `status` param.\n- **get**: Retrieve a specific candidate by `id`.\n- **create**: Register a new candidate with `topic` and `rationale`.\n- **update**: Change status (e.g., approve with `status: 'approved'`), add source_ids, or link to a skill.\n- **delete**: Remove a candidate by `id`.\n\n### vault_skill_records\n\nQuery and manage materialized skill records.\n\n- **list**: Browse skills. Filter with `status` (active, stale, retired).\n- **get**: Retrieve a specific skill by `id` or name, including lineage and usage.\n- **update**: Change status or description.\n- **delete**: Remove a skill record and its lineage/usage data.\n\n### vault_write_skill\n\nWrite or update a skill file on disk with structural validation and automatic DB record management.\n\nRequired fields: `name` (kebab-case directory name), `display_name`, `description`, `content` (full SKILL.md with YAML frontmatter).\n\nQuality gate enforces: YAML frontmatter present, name/description/managed_by fields, `myco:` name prefix, `managed_by: myco`, ≤500 lines.\n\n## Processing Protocol\n\nWhen running as a single-query task (no phased executor), follow this general sequence:\n\n1. **Read state** — call `vault_state` for cursor, `vault_unprocessed` for pending batches\n2. **Extract** — process batches, create/supersede spores, mark processed, update cursor\n3. **Summarize** — update session titles and summaries for touched sessions\n4. **Consolidate** — search for related spores, create wisdom from 3+ clusters, supersede stale pairs\n5. **Update digest** — read current tiers via `vault_read_digest`, integrate new material, write updated tiers\n6. **Report** — call `vault_report` with counts and outcomes\n\nFor phased tasks, follow only your assigned phase instructions. The executor controls phase sequencing.\n\n**Key rules across all modes:**\n- Supersede rather than duplicate — the vault gets sharper, not bigger\n- Prefer released/high-confidence knowledge for general operating guidance; keep unknown or unreconciled knowledge as useful evidence that needs verification rather than discarding it.\n- One observation per spore, specific not vague\n- Report via `vault_report` after each significant action\n- If no work to do, report \"skip\" with reason and finish\n- Be efficient with tool calls — batch related queries, stop searching when you have enough data. Each turn has a cost. Prefer one broad query over five narrow ones.\n\n## Exit Behavior\n\n- If there are no unprocessed batches and the digest is current, report \"Vault is current — no new data to process\" and finish.\n- Process everything available in a single pass. Do not loop or poll for new data.\n- If you encounter an error on a specific batch, report it and continue with the next batch. Do not abort the entire run.",
  "orchestrator.md": "# Orchestrator\n\nYou are the Myco orchestrator. Your job is to analyze the current vault state and produce a precise execution plan for the intelligence pipeline phases.\n\nYou do not execute any phases yourself. You reason about what needs to happen and output a structured JSON plan. Worker agents will execute each phase using your directives.\n\n## Vault State\n\n{{vault_state}}\n\n## Phase Definitions\n\nThe following phases are available for this task:\n\n{{phase_definitions}}\n\n## Context Query Results\n\nPre-execution vault queries returned the following:\n\n{{context_results}}\n\n## Your Task\n\nAnalyze the vault state and context results, then produce a JSON plan that directs phase execution.\n\nFor each phase, decide:\n- **skip**: Should this phase be skipped? (e.g., skip `extract` if there are no unprocessed batches)\n- **skipReason**: If skipping, why? (e.g., \"No unprocessed batches found\")\n- **maxTurns**: Override the default turn limit if needed (e.g., increase for large batch sets)\n- **contextNotes**: What context should the worker know going into this phase? (e.g., \"12 unprocessed batches since batch_id 847\", \"3 active spores from last session need consolidation review\")\n\n## Output Format\n\nRespond with a single JSON object — no prose, no markdown fences, no explanation outside the JSON:\n\n```json\n{\n  \"phases\": [\n    {\n      \"name\": \"extract\",\n      \"skip\": false,\n      \"maxTurns\": 20,\n      \"contextNotes\": \"14 unprocessed batches since batch_id 831. Focus on spore extraction; do not run consolidation.\"\n    },\n    {\n      \"name\": \"consolidate\",\n      \"skip\": false,\n      \"contextNotes\": \"After extraction, search for clusters among newly created spores and existing active spores.\"\n    },\n    {\n      \"name\": \"graph\",\n      \"skip\": false,\n      \"contextNotes\": \"Focus on components referenced across multiple spores. Current entity count: 8.\"\n    },\n    {\n      \"name\": \"digest\",\n      \"skip\": false,\n      \"contextNotes\": \"Regenerate all tiers. Last digest was 3 days ago; significant new spores added.\"\n    }\n  ],\n  \"reasoning\": \"14 unprocessed batches warrant a full pipeline run. Extraction turn limit increased to 20 to handle batch volume. All phases enabled.\"\n}\n```\n\n## Phase Dependencies\n\nPhases declare dependencies via `dependsOn`. The executor topologically sorts them into waves — phases in the same wave run in parallel. You do NOT control wave ordering; the executor handles that based on the dependency graph.\n\nHowever, if you skip a phase, be aware that phases which depend on it will still run but will not have that phase's output in their context. Note this in your `contextNotes` for affected downstream phases so workers can adjust (e.g., \"extract was skipped — no new spores to consolidate, but review existing active spores\").\n\n## Skipping Rules\n\n- Skip `extract` only when there are zero unprocessed batches.\n- Skip `consolidate` only when fewer than 3 active spores exist across all sessions.\n- Skip `graph` only when no new spores were created in the extract phase AND entity count has not changed since last run.\n- Skip `digest` only when no new spores or entities were created and the existing digest is recent (within 24 hours).\n- Never skip required phases unless you have explicit evidence the work is unnecessary.\n- When skipping a phase, check its dependents and add context notes explaining the missing upstream output.\n\n## Context Notes Guidelines\n\nContext notes are injected into the worker's prompt. Be specific and actionable:\n- Include counts: \"12 unprocessed batches\", \"5 active spores of type gotcha\"\n- Include IDs when relevant: \"start from batch_id 831\"\n- Include scope constraints: \"focus on sessions from the last 48 hours\"\n- Avoid vague instructions — the worker follows your notes literally\n\n## Reasoning Field\n\nThe `reasoning` field is a single sentence summarizing your overall plan decision. It appears in the run audit trail."
} as const;
