Smart Enrichment: How We Taught Our AI to Speak the Right Tech Language
We faced a curious problem: our AI-powered code enrichment was pulling Go patterns into our TypeScript/Next.js projects. Here's how we built a stack-aware filtering system to keep our wisdom relevant and our development workflows clean.
Ever felt like your AI assistant was speaking a different language than you? Not literally, but perhaps offering suggestions or patterns from a completely unrelated technology stack? That's exactly the kind of cross-stack confusion we encountered recently, leading to a significant (and frustrating) pollution of our AI-driven code enrichment and workflow planning.
Our internal CodeMCP (Code Memory Cache Provider) is designed to learn from our existing repositories and provide relevant code patterns to assist in feature planning. The goal is to accelerate development by offering "wisdom" tailored to the task at hand. However, a critical flaw emerged: Go patterns, pulled from our backend Go services, were inadvertently bleeding into our frontend TypeScript/Next.js feature planning. Imagine trying to build a React component and being suggested goroutines or go.mod file structures! It was a clear case of good intentions, bad context.
The Problem: Cross-Stack Code Pattern Pollution
The core issue was that our enrichment and workflow wisdom loading mechanisms weren't context-aware enough. When generating implementation plans for a TypeScript/Next.js feature, the system would pull general code patterns without first confirming their relevance to the target technology stack. This meant:
- Irrelevant Suggestions: Our AI was "hallucinating" Go-specific constructs into TypeScript plans.
- Wasted Time: Developers had to manually filter out these irrelevant suggestions, slowing down the planning phase.
- Reduced Trust: The utility of the AI-powered assistance was diminished when it frequently provided unhelpful information.
This wasn't just a minor annoyance; it was a systemic issue undermining the very purpose of our intelligent development pipeline.
Our Solution: Building a Stack-Aware Filtering System
To combat this cross-stack confusion, we introduced a two-pronged approach centered around intelligent stack detection and filtering. The goal was simple: ensure that only code patterns relevant to the target technology stack are considered during enrichment and wisdom loading.
Here's how we tackled it:
1. Dynamic Stack Detection
First, we needed a way to identify the target technology stack from freeform text. We added a new utility function:
src/server/services/stack-detector.ts: detectTargetStackFromContent()
This function scans input text (like a feature description, a user story, or a project note) for technology-specific keywords. For instance:
- Presence of "React", "tRPC", "Prisma", "Zod" points strongly to
TypeScript. - Keywords like "goroutine", "channels", "go.mod", "Gin" indicate
Go. - We can extend this to detect other stacks like Python, Java, Rust, etc., as needed.
This allows our system to dynamically understand the context of the current development task.
2. Intelligent Repository Filtering
With the target stack identified, the next step was to filter out irrelevant code pattern sources. We introduced a generic helper:
src/server/services/stack-detector.ts: filterReposByTargetStack()
This function takes a list of code repositories (our sources for CodeMCP patterns) and a detected target stack. It then intelligently prunes the list, keeping only those repositories whose primary language or detected stack matches the target. This prevents, for example, our Go backend repositories from contributing patterns when we're working on a TypeScript frontend.
3. Integrating the Fix into Our Workflow
The new detection and filtering capabilities were then integrated into the critical parts of our development pipeline:
- Note Enrichment (
src/server/services/note-enrichment.ts): When enriching a developer's notes with code patterns, the system now first detects the target stack from the note's content. Then, it usesfilterReposByTargetStack()to ensure that only stack-relevant patterns are considered and injected. - Project Wisdom Loading (
src/server/services/workflow-engine.ts: loadProjectWisdom()): Similarly, when loading "project wisdom" (a collection of common patterns and practices for a project), the system now analyzes the 5 most recent project notes to determine the predominant stack. This stack is then used to filter the code pattern repositories, ensuring the loaded wisdom is always contextually appropriate.
Finally, we updated our internal documentation (docs/reports/2026-03-15-image-to-implementation-pipeline-poc.md) to reflect this crucial fix, detailing the cross-stack issue and its resolution.
Lessons Learned & Challenges
While this particular session was smooth, it highlighted some critical lessons from previous experiences:
- Database Migrations are Serious Business: A recurring pain point is the danger of using
db pushordb push --accept-data-losson production environments. These commands can irrevocably drop specialized column types, such as ourpgvector embedding vector(1536)columns, leading to data loss. The absolute golden rule: always use carefully crafted, safe migration scripts (like our./scripts/db-migrate-safe.sh) to preserve data integrity, especially for AI-related vector embeddings. - External API Dependencies: Our reliance on the Anthropic API for certain Synthesis review steps means that running out of credits can halt critical parts of our workflow. This is a constant reminder to monitor API usage and maintain sufficient credit balances for uninterrupted operation.
The Immediate Impact and What's Next
With the stack filtering fix implemented, typechecks clean, and documentation updated, we're ready to deploy.
The immediate next steps are crucial to realizing the full benefits of this change:
- Commit & Push: Get the stack filtering fix into
main. - Deploy to Production: Roll out the changes to our live environment.
- Re-enrich: The most exciting part! We'll re-enrich our
project-onboardingnote. This time, with the Go patterns filtered out, we expect to see much cleaner, TypeScript-focused suggestions. - New Action Points & Workflow: Based on this clean enrichment, we'll generate new, relevant action points and create a new workflow.
- Top Up Anthropic Credits: Address the API credit issue to ensure our Synthesis review steps function correctly.
- Start Implementing: Finally, with clean, stack-appropriate implementation plans, we can dive back into building features with greater confidence and efficiency.
This seemingly small architectural change is expected to have a profound impact on developer productivity and the quality of our AI-assisted workflows. By teaching our system to speak the right tech language, we're making our "wisdom" truly wise and relevant.