| name | harvest |
| tier | essential |
| description | Harvest reusable knowledge from a project into the brain - guided, dedup-checked capture of learnings (memory), modules (the lego catalog), and the project archetype. |
| disable-model-invocation | false |
| allowed-tools | ["Read","Write","Edit","Glob","Grep","Bash","mcp__igris-brain__igris_project_register","mcp__igris-brain__igris_catalog_add","mcp__igris-brain__igris_catalog_search","mcp__igris-brain__igris_catalog_update","mcp__igris-brain__igris_memory_recall","mcp__igris-brain__igris_memory_search","mcp__igris-brain__igris_memory_store","mcp__igris-brain__igris_memory_get","mcp__igris-brain__igris_brief_dashboard"] |
| triggers | ["HARVEST","harvest","harvest knowledge","extract learnings","capture knowledge"] |
HARVEST โ Knowledge Capture Skill
Deliberately harvest reusable knowledge from a project into the brain: curated
learnings (memory), reusable modules (the reusable-assets catalog / lego store), and
the project archetype. Every step is operator-guided, never automatic โ
this is the proven principle from the original capture design (revived FR-100):
the model proposes, the operator decides what is worth keeping.
Guided harvest in six phases. Determine the current project slug, name, and
absolute path up front (the project the operator is in) โ Phases 2โ4 key off it.
Degradation (applies to EVERY brain call below): if the igris-brain MCP
server is unavailable, do not block. Continue the operator interview,
collect the same answers, and warn once at the top:
Note: brain MCP unavailable โ capturing the interview locally; the learnings/modules/archetype will not be persisted to the brain this run. Re-run /harvest when the brain is reachable to store them.
Then, for each phase that would have written to the brain, write a clean
capture note to ~/.igris/projects/{project}/context/harvest-capture-{date}.md
(Markdown: the chosen archetype, the module list, and each curated learning in
the same shape Phase 4 would have stored) so the harvest is not lost. This
mirrors the boot/rest skip-on-MCP-unavailable convention โ never error,
never block, warn once.
Phase 1 โ Analysis
Build a picture of the project from ground truth (no brain needed for this scan):
- Tech stack โ Glob + Read the manifest(s):
pubspec.yaml, package.json,
pyproject.toml / requirements.txt, Cargo.toml, go.mod, Gemfile,
pom.xml / build.gradle, etc. Extract framework + key dependency versions
(e.g. scan pubspec.yaml โ get: ^4.6.6 โ "Flutter + GetX").
- Folder structure โ Glob the source tree (e.g.
lib/**, src/**) to map
the architecture (feature-first vs layered, where models/services/views live).
Sample a few representative files (e.g. lib/features/*_view_model.dart) to
confirm the patterns actually in use.
- Completed briefs โ call
igris_brief_dashboard (project = slug,
summary_only: true) for the shipped-work landscape; the completed briefs are
the source references (source_brief) the curated learnings cite.
- Existing context docs โ Read whatever is present under
~/.igris/projects/{project}/context/ (e.g. coding_guidelines.md,
architecture_map.md). Knowing what is already documented prevents
re-capturing it as a "new" learning in Phase 4.
Present a short scan summary to the operator before proceeding.
Phase 2 โ Archetype classification
- From the Phase-1 scan, suggest an archetype (e.g. "enterprise mobile MVVM",
"Flutter design kit", "marketing web", "AI platform").
- Confirm with the operator โ never assume. Let them correct or replace it.
- Persist via
igris_project_register:
igris_project_register({
slug: "<project-slug>",
name: "<project-name>",
path: "<absolute-project-path>",
tech_stack: "<comma-separated stack from Phase 1, e.g. 'Flutter:3.9.2,GetX:4.6.6'>",
archetype: "<confirmed archetype>"
})
(Register upserts by slug and COALESCEs archetype, so this is safe to
re-run; it also refreshes last_session_at.)
Phase 3 โ Module identification (the lego catalog seed)
Catalog reusable, standalone modules so future projects can reuse them
instead of rebuilding (the dark-theme-incident lesson; this is the FR-198 lego
catalog seed).
The mechanics โ what counts as a standalone module, dedup-before-register, and
the exact igris_catalog_add shape (including the source/source_ref/
when_to_use asset-reference fields) โ live in the shared catalog recipe.
Read it and follow it: ~/.igris/core/docs/catalog-recipe.md. This is the
same recipe /reuse follows, so the catalog has one home.
Harvest-specific framing on top of the recipe:
- From the Phase-1 scan, propose an interactive checklist of candidate
standalone modules (the recipe's "what is a standalone module" test decides
what qualifies). The operator confirms which to catalog โ never auto-register.
- For each confirmed candidate, follow the recipe: dedup via
igris_catalog_search (offer skip/update on a strong match), then
register new ones via igris_catalog_add โ set source_project to this
project's slug and capture when_to_use while the context is fresh.
Phase 4 โ Knowledge extraction (3โ8 curated learnings)
The heart of the harvest. The operator picks 3โ8 reusable learnings worth
keeping (resist storing everything โ curation is the value).
-
From the scan + completed briefs, propose a guided checklist of candidate
learnings across the kinds: architecture patterns, tech-stack
decisions, reusable code patterns, project discovery (structure /
conventions), and mistakes (with the fix). For each, draft a title and a
one-line rationale; ask the operator the "why" (e.g. "Why GetX over Provider?
What problem was it solving?") so the stored content captures the reasoning,
not just the fact.
-
CRITICAL โ dedup pre-check (before EVERY store): for each candidate the
operator wants to keep, FIRST call igris_memory_recall:
igris_memory_recall({ project: "<slug>", context: "<candidate title + key terms>" })
(optionally igris_memory_search for an FTS pass, and igris_memory_get to
read a near-match's full content). If a strong near-duplicate already
exists, do not blindly create a new row โ offer the operator:
- skip (the existing learning already covers it),
- merge (fold the new detail into the existing one โ read it, combine,
and re-store the improved version), or
- update (the existing one is stale โ replace it).
This dedup gate is load-bearing: re-creating duplicate learnings is the exact
failure the guided-not-automated design exists to prevent. Never skip it.
-
Store survivors via igris_memory_store โ one call per curated learning:
igris_memory_store({
project: "<slug>",
category: "<pattern | decision | discovery | mistake | optimization>",
title: "<concise, searchable title>",
content: "<the full markdown writeup: overview, code, why, trade-offs, when-to-use, sources>",
tags: "<comma-separated: domain, tech, archetype>",
tech_stack: "<e.g. 'Flutter:3.9.2,GetX:4.6.6'>",
source_brief: "<the brief(s) this came from, e.g. 'BR-008,BR-012'>",
confidence: <0.0-1.0, default 0.8 โ higher = battle-tested>,
source_extractor: "distill"
})
source_extractor: "distill" is mandatory on every Phase-4 store โ it
marks the row as conscious operator-curated harvest (distinct from the
llm/perception channel). The write path already accepts this value.
Do NOT "fix" this to 'harvest': the value is a persisted DB
channel-tag enum (VALID_SOURCE_EXTRACTOR), not the skill name. The skill
was renamed /distill โ /harvest, but the enum value intentionally stays
'distill' โ every learning already stored carries it, and renaming the
enum would orphan those rows and force a DB migration. The invocation NAME
and the channel-tag value are deliberately decoupled.
category MUST be one of the five enum values above (no others are
accepted): pattern, decision, discovery, mistake, optimization.
- These rows land at
review_status: 'approved' by default โ they appear in
recall immediately (operator-curated content needs no perception review).
- For the exact JSON shape of high-quality learnings (the worked examples:
MVVM+GetX
conf 0.85, Fifty-UI decision conf 0.80, WebSocket pattern
0.80, folder-structure discovery 0.75, PM2 mistake 0.85), the
distill_concrete_examples.md research note is the canonical reference.
Phase 5 โ Rebrand checklist (template archetypes only)
Only when the project is a template/starter archetype (something future
projects clone-and-rebrand):
- Produce the rebrand checklist โ the concrete steps to white-label this
template for a new brand (app name, bundle id, color tokens, logo assets,
API endpoints, store metadata, etc.).
- Store it on the relevant catalog module row via
igris_catalog_update
(the rebrand_checklist field), or pass it inline as rebrand_checklist in
the Phase-3 igris_catalog_add call for that module.
Skip this phase entirely for non-template projects.
Phase 6 โ Summary
Report what was captured:
## Harvest complete โ <project-slug>
- Archetype: <confirmed archetype>
- Modules cataloged: <M> (<new>, <updated>, <skipped-as-dup>)
- Learnings stored: <N> (source_extractor: distill)
- <title> [<category>, conf <x>]
- ...
- Dedup: <k> candidate(s) skipped/merged against existing memory
If the run was degraded (brain absent), point the operator at the local capture
note that was written and remind them to re-run when the brain is reachable.
Constraints
- GUIDED, never automatic โ the operator chooses every archetype, module,
and learning. The model proposes; it never silently stores a learning.
- DEDUP before writing โ
igris_memory_recall / igris_catalog_search a
candidate before creating a new row (offer skip/merge/update). This is the
load-bearing guard against duplicate-knowledge drift.
source_extractor: "distill" on every Phase-4 igris_memory_store (the
persisted channel-tag enum โ NOT the skill name; intentionally kept after the
/distill โ /harvest rename, see the Phase-4 note).
- Curate, don't dump โ capture targets 3โ8 learnings; resist storing
everything โ curation is the value.
- Graceful degradation โ brain absent โ continue the interview, warn once,
write a local capture note, never block.
- NEVER modify source code โ harvest catalogs knowledge into the brain; it
does not edit the project's application code.