raj-demand-driven-context
Skill1 starsChanged 5 months agoMITView on GitHub
Dogfooding loop for vertical AI agents — three providers (Langfuse production-trace + Arize Phoenix agent-runtime self-introspection + Plurai developer eval iteration) plus four agent tools (report_knowledge_gap, list_available_tools, recall_similar_turns, find_resolved_gap) and the gap-scanner CLI, composed as one motion. Run during LIVE dogfooding sessions with a Monitor watching real-time inbound/outbound. Auto-curation crons (Phoenix promote-resolutions + promote-successes) compound the dataset without per-turn human work. STRICT DEV-ONLY at the agent layer (NODE_ENV + VERCEL_ENV + caller gate). Inspired by Raj Kapadia's "Demand-Driven Context" workshop (https://www.youtube.com/watch?v=_QAVExf_1uw).
- Reads credentials
In this repository22 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .agents/skills/vercel-react-best-practices/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- agent-browserSkill
- ai-sdkSkill
- baseline-uiSkill
- chat-sdkSkill
- claude-tenderly-auditorSkill
- code-reviewSkill
- codex-adversarial-review-tenderly-testnetSkill
- codex-adversarial-tenderly-auditorSkill
- deploy-open-harnessSkill
- emil-design-engSkill
- frontend-designSkill
- gateman-analysisSkill
- plan-modeSkill
- remove-demo-limitsSkill
- tenderly-proSkill
- tenderly-testnetSkill
- vercel-react-best-practicesSkill
- web-animation-designSkill
- workflowSkill
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 6 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 141
Read the gap entry that just landed.
- Distinctive: line 147
The agent's next attempt: should either succeed (gap implicitly resolved) or report a _different_ gap (one fix surfaced the next layer of …
- Very specific: line 173
Gap-scan diff IS the session retro: Don't waste time writing one.
- Very specific: line 195
Tenant context: No orphan rows. Refused if ctx.traveler.tenantId is missing.
- Distinctive: line 288
When forking the Sendero template for a new vertical (real estate / legal / healthcare / etc.):
- Distinctive: line 295
Persona slab: Add this to your dispatch routing rules so the agent uses these tools at the right moment:
- Distinctive: line 337
Don't run gaps:scan in CI on every PR: Run it nightly via cron. The gap board reflects real-world traffic.
- Very specific: line 339
Pair with Langfuse regression: Every closed gap should have a paired entry in sendero-golden-turns so a future prompt regression can't …
- Distinctive: line 344
Don't build this for a tiny team with great docs: If your prompt slab is 200 lines and your tool catalog is 8 tools, you don't need this.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Raj's Demand-Driven Context — Sendero implementation
Why this exists
Push-strategy retrieval (build all the MCPs, dump the wiki into a vector DB, hope the agent figures it out) caps at ~30% accuracy on real institutional knowledge. The agent ends up doing data-entry work for you. Raj's thesis: flip to pull. Give the agent a real task, let it fail, let it tell you what it needed to succeed, then fill the gap once and curate the answer back into a structured knowledge base.
Sendero implements the loop across three observability planes with four agent tools and a CLI:
| Plane | Provider | Audience | Purpose |
| Production turn scoring | Langfuse (@sendero/langfuse) | Platform / ops | Prompt management, evaluators (4 LLM-judges per turn fire-and-forget), golden-turn regression, operator dashboards |
| Agent runtime introspection | Arize Phoenix (@sendero/arize-phoenix) | Agent | recall_similar_turns + find_resolved_gap — the agent reads its own past traces + curated resolutions mid-turn |
| Developer eval iteration | Plurai (claude-code plugin evals@plurai-plugins) | Engineers | Vibe-iterate eval rubrics in claude-code; promote locked rubrics into Langfuse / Phoenix |
| Surface | What it does | Mode |
report_knowledge_gap (Sendero tool) | Agent self-reports a missing tool / wrong field name / dead instruction / missing env. Persisted to KnowledgeGap Postgres table, deduped by sha256(kind|tool|hypothesisNorm). | Dev/sandbox only. |
list_available_tools (Sendero tool) | Agent introspects the canonical tool catalog when uncertain. Returns name + scope + description + required/optional inputs. | Dev/sandbox only. |
recall_similar_turns (Sendero tool, @sendero/arize-phoenix) | Agent reads top-N past traces with similar intent for THIS tenant before planning. Returns summary + outcome + evalScore + appliedTools. Fail-soft on Phoenix outage. | Dev/sandbox only. |
find_resolved_gap (Sendero tool, @sendero/arize-phoenix) | Agent looks up sendero-resolved-gaps Phoenix dataset before calling report_knowledge_gap. On hit: returns fixSummary + mustMention tokens; agent applies and retries. Self-heals without a human in the loop. | Dev/sandbox only. |
bun gaps:scan (CLI) | Pulls open gaps, buckets by severity (auto-promotes blocking + repeat-offenders), writes docs/agent-gaps/board.md kanban. Optionally auto-resolves stale rows. | Dev / CI / cron. |
phoenix-promote-resolutions (Vercel cron, daily) | Closed KnowledgeGap rows with resolutionPrUrl get pushed to sendero-resolved-gaps Phoenix dataset → find_resolved_gap reads them. | Production cron, idempotent on metadata.sendero_id. |
phoenix-promote-successes (Vercel cron, every 6h) | Confirmed bookings get pushed to sendero-recall Phoenix dataset → recall_similar_turns reads them. | Production cron, idempotent on metadata.sendero_id. |
This is the missing observability layer for vertical AI agents — and the magic is that the three planes feed each other. Langfuse traces become Phoenix recall data via auto-curation. Plurai-iterated eval rubrics become Langfuse judges. Closed gaps become self-heals on the next traveler turn.
Where each plane feeds the loop
TRAVELER turn fires (any channel)
│
▼
runAgentTurn → traceAgent stamps sendero.tenant_id on OTel span
│
┌────┴─────┐ (one span, two destinations
▼ ▼ via shared NodeTracerProvider)
LANGFUSE PHOENIX
│ │
│ ├─► recall_similar_turns reads past traces
│ │ (tenant-scoped, eval≥0.7, age>1h)
│ │
│ └─► find_resolved_gap reads sendero-resolved-gaps
│ (returns fixSummary + mustMention on hit)
│
└─► LLM-judge evaluators score the turn (fire-and-forget)
│
└─► high-eval traces auto-promoted to Phoenix recall dataset
(every 6h via phoenix-promote-successes cron)
When a tool fails AND no resolved-gap matches:
│
▼
report_knowledge_gap → KnowledgeGap row (Postgres, dedup by sha256)
│
▼ (human triage / PR with resolutionPrUrl)
│
▼
phoenix-promote-resolutions cron (daily) →
pushes resolved gap to sendero-resolved-gaps Phoenix dataset
│
▼
NEXT TIME the same hypothesis fires →
find_resolved_gap returns the fix → agent self-heals
Plurai overlay (developer-side):
When a Langfuse eval flags a regression OR a gap board row needs a
rubric, /evals:eval <description> drafts a new evaluator in claude-code.
Locked rubric promotes back into Langfuse evaluators. The eval rubric
itself becomes a versioned artifact, not a one-time script.The four canonical Sendero evals (Plurai-drafted, against responsible-AI ship gate)
/plugin marketplace add plurai-ai/plurai-plugins
/plugin install evals@plurai-plugins
# Each evaluator maps to a CLAUDE.md responsible-AI dimension
/evals:eval locale fidelity — agent reply must match user's last detected language; switch mid-thread
/evals:eval PII redaction — no full phone numbers, raw passport fields, or PASSPORT_VAULT_KEK material
/evals:eval grounding — tenant-specific claims must reference tool calls; no fabricated trip ids/PNRs
/evals:eval handoff trigger — escalate via request_human_handoff for irreversible payments / settlement / legalFailing rows → report_knowledge_gap → eventual find_resolved_gap self-heal once the rubric stabilizes and a human PR closes the gap. Plurai is the surface where the eval rubric matures; Langfuse/Phoenix is where it runs at scale.
When to use this skill
Invoke /raj-demand-driven-context (this skill) when:
- You're starting a dogfooding session. This is the primary use case — see "Dogfooding workflow" below. The three tools are designed to work together during live testing, not separately after the fact.
- You're spinning up a new vertical AI agent template (real estate / legal / healthcare / freelance ops) and want the same demand-driven layer Sendero has.
- You're debugging a flaky agent and suspect it's missing context — pull the gap board first before manually grepping logs.
- You need to wire the gap-scanner output into an ops workflow (Vercel logs + Langfuse traces + Cloudflare worker logs).
- You're reviewing a PR that adds a new agent tool and want to ensure the description matches the schema (the load-bearing class of bug this layer was designed to catch).
Dogfooding workflow — three tools, one motion
The tools were built to be used together. Using them separately gets you 30% of the value. A live dogfood session combines all three in a tight loop with a Monitor watching real-time events. Run this every time you ship a non-trivial agent change.
Pre-flight (5 min before testing)
# 1. Snapshot the current gap board so you can diff after the session.
bun gaps:scan --output docs/agent-gaps/_pre-session.md --dry-run > /tmp/gaps-before.md
# 2. Pull live env from Vercel so localhost matches prod-shape.
vercel env pull .env.local
# 3. Boot dev server.
bun devOpen three Claude Code shells:
- Shell A — your editor session (this skill loaded).
- Shell B —
Monitorwatching for the inbound traffic source. Examples:- WhatsApp dogfood:
Monitoronbun whatsapp:tailor the Kapso event stream - Slack dogfood:
Monitoron the Slack interactions webhook log - Web dogfood:
Monitoron the dev server's request log
- WhatsApp dogfood:
- Shell C —
Monitoronvercel logs --follow <preview-url>for the deployed surface, ORbun devconsole for local.
The Monitor pattern is the load-bearing piece. It surfaces real-time inbound/outbound events so the agent (Claude) can react to your live test traffic without you typing "what just happened?" each turn.
Live loop (during the session)
Per-turn motion, repeated as you exercise the feature:
- Send a real test request through the channel under test (WhatsApp message, Slack /command, web click).
- Monitor surfaces the event to Shell A automatically.
- Watch what the agent does. Three outcomes:
- Works → move to the next test case.
- Fails recoverably → the agent should call
list_available_tools({ keyword: '<thing it tried>' })to introspect, then retry with the real tool name. Watch the trace. - Fails unrecoverably → the agent calls
report_knowledge_gap({ kind, toolName, errorMessage, hypothesis, suggestedFix?, blockingTraveler: true })and escalates viarequest_human_handoff. The gap is now persisted.
- You walk the debugging chain in Shell A while the next traveler turn is in flight (see
references/integration-vercel-langfuse-cloudflare.md):- Read the gap entry that just landed.
- Pull Langfuse trace via the
langfuseMCP usingtraceIdfrom the gap. - Pull Vercel logs for the failing tool path.
- Identify the root cause + fix.
- Apply the fix. Common shapes: prompt slab edit + Kapso push, env var set + redeploy, schema rename + Prisma migration. Push it live.
- Re-test the same scenario. This is the load-bearing step — without re-test, you don't know if the fix actually closed the gap.
- The agent's next attempt should either succeed (gap implicitly resolved) or report a different gap (one fix surfaced the next layer of failure).
Post-flight (5 min after testing)
# 1. Final gap-scan — what rows opened during the session?
bun gaps:scan
git diff docs/agent-gaps/board.md # the diff IS the session retro
# 2. Auto-resolve anything that didn't recur (signal that the fix held).
bun gaps:scan --resolve-stale-days 1
# 3. For each NEW gap that's still open, decide: ship a real fix, file
# an issue, or mark `wontfix`. Don't leave critical/blocking rows
# undecided — they re-fire on the next live customer.
# 4. For each gap RESOLVED in this session, add the canonical input
# to the Langfuse golden-turns dataset. Closes the loop on Raj's
# "TDD with failed tests" — the prompt edit can't silently regress.
bun langfuse:dataset:seedWhy this loop matters
- Raj's pull-not-push thesis is wrong without the loop. Pull alone is just "the agent fails, you patch, repeat." That's manual. The loop adds: the agent self-reports the failure shape, the scanner aggregates patterns, the regression closes the loop. Each iteration compounds — your prompt slab + tool catalog get smarter every session, not just less broken.
- Monitor is non-optional. Without it, you're context-switching between three terminals + your phone. With it, the agent (Claude in Shell A) has the full session in its context and can debug end-to-end without re-explaining state.
- Gap-scan diff IS the session retro. Don't waste time writing one.
git diff docs/agent-gaps/board.mdbetween pre and post sessions tells the story: which rows opened, which closed, which escalated to high. - The three tools are not interchangeable.
list_available_toolsis the agent's first move when uncertain;report_knowledge_gapis the second move when introspection didn't help;gap-scanis the human's third move to triage what the agent surfaced. Skipping the first two and only running the scanner periodically gets you a static board, not a closed loop.
Canonical dogfood-found bugs (Sendero)
Each of these surfaced via the loop, not via code review or static analysis:
documentImageUrlvsdocumentUrl— prompt slab named a field the schema didn't accept. Caught by the agent retrying twice, thenreport_knowledge_gap({ kind: 'tool_input_mismatch' }). Fix: rename in Story 4.2.request_human_handoffnot registered as Kapso top-level — agent tried to call it directly; runtime returned "Tool not available." Caught by the agent then tryinghandoff_to_human(the foot-gun). Fix: prompt clarification + Kapso default-tools enum + unconditional ban.PASSPORT_VAULT_KEKenv not loaded — Vercel env-add post-dated last deployment; runtime saw no KEK. Caught byreport_knowledge_gap({ kind: 'env_missing' })+ the agent escalating. Fix: redeploy after env change.readKek()is intentionally inside a function (no module-level cache) so each call readsprocess.env.PASSPORT_VAULT_KEKfresh — function instance reuse can't pin stale env.flowKey: 'trip_intake'returning 500 — Meta Flow not configured. Caught by the agent retrying twice and falling through. Fix: prompt rule banning that flow key for passport intake; usescan_passport_inlineinstead.
Each one took ~10–15 minutes start-to-finish through the loop. None would have surfaced in a unit test or PR review — they were prompt-runtime mismatches that only show up under live traffic.
For the full dogfooding playbook, see references/dogfooding-loop.md.
Hard rule: dev-only enforcement
Three independent gates. ALL must pass for the gap-tool to actually persist a row:
- Environment.
NODE_ENV !== 'production'ORVERCEL_ENV ∈ {undefined, 'development'}. Production + preview deploys are dead-zone. - Caller key type.
caller.effectiveKeyType !== 'production'. Production prod-keys are refused regardless of environment — leaked credentials must not become a discovery surface. - Tenant context. No orphan rows. Refused if
ctx.traveler.tenantIdis missing.
Override (operator dashboard only): SENDERO_GAPS_ALLOW_NONDEV=1 bypasses gate #1 but never bypasses gate #2.
Failure mode is silent refusal — the tool returns { status: 'production_refused', message } rather than throwing. The agent reads this and falls back to request_human_handoff (the production-correct escalation path).
Tools surface (canonical)
report_knowledge_gap
report_knowledge_gap({
kind: 'tool_input_mismatch' | 'tool_not_found' | 'tool_error_unrecoverable'
| 'instruction_missing' | 'env_missing' | 'schema_drift'
| 'runtime_constraint' | 'other',
toolName?: string, // "scan_passport_inline"
errorMessage: string, // verbatim from the failed call
attemptedInput?: object, // sanitized — NO PII / passport numbers / phone digits
hypothesis: string, // "I think field is named documentUrl, not documentImageUrl"
suggestedFix?: string, // "Rename in agent-persona.ts Story 4.2"
blockingTraveler: boolean, // true → severity rolls up to high/critical
channelKind?: string, // 'whatsapp' | 'slack' | 'web' | 'mcp'
surface?: string, // 'agent.dispatch' | 'agent.kapso' | 'agent.chat'
})
→ { status: 'reported' | 'duplicate_increment' | 'production_refused', gapId?, occurrenceCount? }Dedup contract. Same sha256(kind|toolName|normalize(hypothesis)) from multiple turns increments occurrenceCount on a single row. last_seen_at updates. Severity escalates but never downgrades.
list_available_tools
list_available_tools({
keyword?: string, // 'passport' → scan_passport_inline + check_visa_requirements
scope?: 'search' | 'bookings' | 'settlement' | 'treasury' | 'documents'
| 'compliance' | 'trip_assistance' | 'utilities',
limit?: number, // default 15
})
→ {
status: 'ok' | 'production_refused',
tools: Array<{ name, scope, description, callMode, requiredInputs, optionalInputs }>,
total, truncated,
}Filters by caller's granted scopes — sandbox sees *, user-minted prod keys see only what they can invoke. Internal tools (internal: true in ToolDef) are hidden from results so the agent doesn't accidentally surface ops-only tools to a customer.
recall_similar_turns (Phoenix-backed, dev/sandbox-only)
recall_similar_turns({
query: string, // verbatim from the user's last message
route?: string, // optional restrictor: 'SFO-LHR'
limit?: number, // default 3, max 10
})
→ { status: 'ok' | 'unavailable' | 'production_refused',
results: Array<{ traceId, summary, outcome, latencyMs, evalScore?,
appliedTools, provenance, occurredAt }>,
message: string }Filters span search by sendero.tenant_id (PR1 stamps), age > 1h (anti-injection), evalScore ≥ 0.7. Fail-soft: Phoenix down → available: false, agent plans cold.
find_resolved_gap (Phoenix-backed, dev/sandbox-only)
find_resolved_gap({
hypothesis: string, // same shape as report_knowledge_gap.hypothesis
toolName?: string,
kind?: KnowledgeGapKind,
})
→ { status: 'found' | 'not_found' | 'unavailable' | 'production_refused',
hit?: { fixSummary, mustMention[], resolutionPrUrl, ... },
message: string }The agent calls this BEFORE report_knowledge_gap. On hit: applies mustMention tokens, retries the original tool, never escalates. On miss: falls through to report_knowledge_gap. Token-overlap match in v0.1 (the 4 seeded bugs each have distinctive identifiers); v0.2 swaps to embedding similarity via Vertex text-embedding-005.
bun gaps:scan CLI
bun gaps:scan # writes docs/agent-gaps/board.md
bun gaps:scan --since 2026-04-01 # custom lower bound on lastSeenAt
bun gaps:scan --resolve-stale-days 14 # auto-resolve rows not seen in 14d (blocking rows excluded)
bun gaps:scan --tenant org_xyz # single-tenant slice
bun gaps:scan --dry-run # print to stdout, don't touch the file
bun gaps:scan --output path/to/board.md # alternate output pathOutput structure: 🚨 Critical → ⚠️ High → 🛠 Medium → 📦 Low → ✅ Recently resolved. Repeat-offender promotion is the load-bearing rule: a row marked severity=low that fires 3+ times AND blocks travelers gets bucketed as high — the scanner is the truth, not the snapshotted column.
How to wire into a NEW vertical AI agent template
When forking the Sendero template for a new vertical (real estate / legal / healthcare / etc.):
- Copy the schema.
KnowledgeGapmodel + 3 enums (KnowledgeGapKind,KnowledgeGapSeverity,KnowledgeGapStatus) — seepackages/database/prisma/schema.prismaand the migration atpackages/database/prisma/migrations/20260505100000_add_knowledge_gap/. - Copy the tools.
packages/tools/src/report-knowledge-gap.ts+packages/tools/src/list-available-tools.ts. The dev-only gate, dedup helper, and severity inference are domain-agnostic — keep them as-is. - Copy the scanner.
scripts/scan-knowledge-gaps.ts+scripts/scan-knowledge-gaps-render.ts. The render layer is split deliberately so unit tests don't pull in Prisma. - Register in
toolList. Both tools must be in the canonicaltoolList(seepackages/tools/src/index.ts) — the AI SDK adapter and MCP server derive their catalogs from it. Never wire them ad-hoc. - Scope to
utilities. Both tools live in theutilitiesscope. Handler-level prod gate enforces dev-only — scope-gated would let a user-minted utilities key write to the gap table from production, which is not what we want. Persona slab. Add this to your dispatch routing rules so the agent uses these tools at the right moment:
### Self-diagnostic tools (dev/sandbox only — silently no-op in prod) When you can't recover from a tool failure on a sandbox/dev turn: - After 2 consecutive 4xx/5xx OR a runtime "Tool X is not available", call list_available_tools({ keyword }) to discover what's registered. - If introspection still doesn't help, call report_knowledge_gap({ kind, toolName, errorMessage, hypothesis, suggestedFix?, blockingTraveler }) with a SPECIFIC hypothesis ("I think field is named X, not Y" — not "tool failed"). Same hypothesis from multiple turns dedups onto one row, so don't worry about spam. - Then escalate via request_human_handoff so the traveler isn't left waiting. - These tools are dev-mode only. In production they return production_refused and you must escalate via request_human_handoff directly.- Add
bun gaps:scantopackage.json. Plus an optional cron entry invercel.jsonto run nightly with--resolve-stale-days 14.
For the full new-vertical playbook see references/wiring-new-vertical.md.
Combine with: Vercel CLI logs + Langfuse MCP + Cloudflare MCP
The gap board is the entry point for an end-to-end debugging chain. When a critical gap appears, walk the chain:
bun gaps:scan— surfaces the gap. Read the hypothesis + suggestedFix.- Langfuse MCP (
/mcpshows it;mcp__langfuse-docs__searchLangfuseDocsetc.) — every gap row carries atraceId. Pull the full trace to see what the agent was actually trying when it failed: input, tool calls, model reasoning. UsegetTraceif available, else search by ID. - Vercel CLI logs —
vercel logs <deployment>(orvercel inspect) for the server-side stack trace of the failing tool. The agent saw the response code + body; you see the throw site. - Cloudflare MCP (
mcp__cloudflare-workers__*) — when the gap is inruntime_constraintor points at the edge worker (sendero-arc-edge), pull worker logs from CF. The edge surfaces things the Vercel function side can't see (request shape, edge cache hits, geo).
Together: gap → trace → server log → edge log. Four-line answer to "why didn't this work" in under five minutes, all from the same Claude Code session.
For the full integration playbook see references/integration-vercel-langfuse-cloudflare.md.
Best practices
- Don't expand the kind enum casually. The 8 kinds (
tool_input_mismatch | tool_not_found | tool_error_unrecoverable | instruction_missing | env_missing | schema_drift | runtime_constraint | other) cover the failure surface for vertical AI agents. New kinds need a corresponding routing rule in the scanner — otherwise they bucket intootherand lose triage signal. - Hypothesis must be specific. "Tool failed" is useless. "I think the field is named
documentUrl, notdocumentImageUrl" closes the loop on its own. The dedup hash uses the hypothesis, so vague hypotheses both triage badly AND dedup poorly. - Don't sanitize PII at the SQL layer. Sanitize at the agent's
attemptedInputpayload — the agent already knows what's PII because it was the one that constructed the call. Pushing this responsibility into Prisma triggers feels nice but loses signal (we WANT to know which fields were misnamed; we DON'T want to know which passport number was attempted). - Resolution is human, not auto.
bun gaps:scan --resolve-stale-days Nonly marks non-blocking rows as resolved when they fall out of the recurring window. A blocking row stays open until a human PR closes it with aresolutionPrUrl. This is intentional — auto-resolving a blocking gap because nobody hit it for 2 weeks is exactly the wrong move. - Don't run gaps:scan in CI on every PR. Run it nightly via cron. The gap board reflects real-world traffic; PR-level scans race against test fixtures and produce noise.
- Never wire
SENDERO_GAPS_ALLOW_NONDEV=1into the agent runtime. It's reserved for the/dashboard/agent-gapsoperator UI's manual "file a gap" button. If you find yourself wanting it in agent code, you're using the wrong tool — escalate viarequest_human_handoffinstead. - Pair with Langfuse regression. Every closed gap should have a paired entry in
sendero-golden-turnsso a future prompt regression can't silently re-open it. The hypothesis text often becomes the rule-matchmustMentionfield. - Scan output is committed.
docs/agent-gaps/board.mdis checked into git. The git history of the board IS the institutional knowledge of "what did our agent struggle with last quarter?" — an artifact you'd otherwise have to scrape from Slack threads.
Anti-patterns (Raj's drawbacks, restated for our stack)
- Don't build this for a tiny team with great docs. If your prompt slab is 200 lines and your tool catalog is 8 tools, you don't need this. The whole point is surfacing what's not documented in a sprawling system.
- Don't try to manually fill gaps for 50 incidents in one sitting. Raj said this is exhausting; he's right. Run the scanner, fix the top 3 critical, ship, let the next 24h of agent traffic surface what actually matters.
- Don't conflate gap severity with bug priority. A
mediumgap on a frequently-used tool is more urgent than acriticalgap on a tool nobody calls. The scanner shows occurrence × severity together for a reason.
Files in this skill
SKILL.md— this filereferences/wiring-new-vertical.md— step-by-step playbook for forking the pattern into a new vertical AI agent templatereferences/integration-vercel-langfuse-cloudflare.md— debugging chain workflow combining Vercel CLI + Langfuse MCP + Cloudflare MCP
Reference
- Raj Kapadia, "Demand-Driven Context for AI Agents", 2026 (workshop video): https://www.youtube.com/watch?v=_QAVExf_1uw
- Sendero implementation:
packages/tools/src/report-knowledge-gap.ts,packages/tools/src/list-available-tools.ts,scripts/scan-knowledge-gaps.ts - Schema:
packages/database/prisma/schema.prisma→model KnowledgeGap - Persona wiring:
apps/app/lib/agent-persona.ts→ "Self-diagnostic tools" section
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

