Context/Patterns-For-Skills.md
PRISM Patterns for Skill Refactoring
What the Algolia Search Audit skills should learn from PRISM's 20-module implementation. Read this before refactoring any skill. See also: Module-Catalog, Module-Spec-Template.
The Core Insight
PRISM and the Algolia skills do the same 20 jobs. The difference is runtime: - Skills run in Claude's context window (single LLM session, file I/O) - PRISM runs in Temporal (Python async, PostgreSQL, httpx)
Both should follow the same module spec. The spec says WHAT. The runtime says HOW.
Pattern 1: Collector / Enricher / Validator Separation
In PRISM: Every module has three files:
- collector.py -- gathers raw data from external APIs
- enricher.py (or parser.py) -- structures raw data via LLM or parsing
- validator.py -- runs 8-10 quality checks on output
In Skills: These three steps should be explicit sections in SKILL.md: 1. Collection step -- call MCP tools, WebSearch, WebFetch to gather raw data 2. Enrichment step -- use Claude to structure the raw data into the output schema 3. Validation step -- verify gate before writing output files
Why this matters: Skills that mix collection and enrichment in one giant prompt produce worse output. Separating them means the LLM gets clean data to structure, and the validation catches errors before they propagate.
Pattern 2: Typed Output Schemas (Not Freeform JSON)
PRISM learned this the hard way. Early modules used output: dict.
Templates rendered blank fields because the module wrote search_vendor
but the template expected detected_search_vendor.
The fix: Every module spec defines the exact output schema. Field names are canonical. Both the skill .json output and the PRISM Pydantic model use the same field names from the spec.
For skills: Each SKILL.md should include the exact JSON schema the module must produce. Not "generate a JSON file with the research." Instead:
{
"legal_name": "string, required",
"industry": "string, required",
"executives": [{"name": "string", "title": "string"}],
"competitors": [{"company_name": "string", "domain": "string"}]
}
This prevents each skill invocation from inventing its own field names.
Pattern 3: Evidence Tiers on Every Data Point
In PRISM: Every field has an evidence tier (VERIFIED/WEBFETCH/WEBSEARCH/ESTIMATE/NO_SOURCE) and a Source object with URL, method, and retrieval date.
In Skills: Each output .json should include a _sources array:
{
"legal_name": "Dell Technologies Inc.",
"_sources": [
{
"field": "legal_name",
"tier": "VERIFIED",
"source_label": "SEC EDGAR",
"source_url": "https://efts.sec.gov/..."
}
]
}
Why: The factcheck skill and the report skill both need to know WHERE data came from. Without evidence tiers, the factcheck is guessing, and the report can't cite sources. This is the single biggest quality improvement skills can adopt from PRISM.
Pattern 4: 8-10 Validation Rules Per Module
In PRISM: Every module has a validator.py with numbered quality checks. If checks fail, the module returns "partial" status.
In Skills: Every SKILL.md should end with a Verification Gate:
## Verification Gate
Before writing output files, verify ALL of these:
1. legal_name is populated and not "Unknown"
2. At least 3 executives with name + title
3. At least 1 competitor with domain
4. business_model is at least 50 characters
5. At least 1 source URL in _sources array
6. No field sourced from NO_SOURCE tier
If any check fails, retry the enrichment step.
Why: Without validation, skills silently produce shallow or broken output. The downstream report skill then works with garbage data and produces a garbage report. Validation catches it early.
Pattern 5: Public vs Private Company Branching
In PRISM: intel-financial-public and intel-financial-private are separate
modules. The workflow checks is_private and skips the wrong one.
In Skills: The financial skills should do the same: - If public (has ticker): run algolia-intel-financial-public - If private (no ticker): run algolia-intel-financial-private - Never run both. Never force a private company through the public path.
The intel-investor module also branches: Public path reads earnings transcripts and SEC filings. Private path reads conference presentations and CEO interviews.
Pattern 6: Said vs Found Matrix
PRISM's most valuable deliverable. The intel-investor module extracts executive quotes from earnings calls. synth-business-case maps each quote to an Algolia value proposition.
SAID (by CEO): "We're investing heavily in search personalization this year"
FOUND (by PRISM): Algolia Personalization feature matches this priority exactly
SALES ANGLE: "Your CEO committed to search personalization. Algolia delivers
this out of the box. Here's how [customer] achieved 37% conversion lift."
For skills: The investor skill and business-case skill should produce
this same mapping. It requires:
1. intel-investor extracts verbatim executive quotes
2. synth-business-case maps quotes to Algolia angles
3. Both use the same SaidVsFoundMapping schema
Pattern 7: Competitor Fan-Out
In PRISM: intel-techstack detects tech for prospect AND all competitors. intel-traffic gets traffic for prospect AND all competitors. intel-competitors synthesizes the comparison.
In Skills: Each intelligence skill should collect competitor data in the same pass, not as a separate skill invocation. The competitor data goes into the same output .json:
{
"prospect_traffic": { ... },
"competitor_traffic": [
{"domain": "competitor1.com", ... },
{"domain": "competitor2.com", ... }
],
"comparative_summary": "..."
}
Pattern 8: Golden Angle Detection
In PRISM: intel-techstack checks if any competitor uses Algolia (a "Golden Angle" opportunity). This is flagged immediately and flows into sales plays and the business case.
For skills: algolia-intel-techstack should check the BuiltWith results for each competitor against a known list of Algolia technology signatures. If found, flag it in the output:
{
"golden_angle_competitors": ["competitor2.com"],
"golden_angle_detected": true
}
Pattern 9: ICP Tier Classification in Hiring
In PRISM: intel-hiring classifies every open role by ICP tier: - Tier 1: Economic Buyer (CTO, VP Eng, CDO) - Tier 2: Technical Buyer (Search Engineer, ML Engineer) - Tier 3: Champion (Product Manager, UX Lead) - Tier 4: Other (unrelated roles)
It also computes: build-vs-buy signal, hiring velocity, and buying committee.
For skills: algolia-intel-hiring should classify roles the same way and include the structured buying_committee in output.
Pattern 10: GAN-Inspired Factcheck
In PRISM: audit-factcheck is an independent evaluator (not the same LLM session that generated the data). It reads ALL module outputs, extracts claims, and verifies them in 8 batched categories.
For skills: algolia-audit-factcheck should: 1. Read ALL research .json files (not .md files) 2. Extract factual claims per category 3. Cross-check for internal contradictions 4. Produce a verdict: PROCEED / WARN / BLOCKED 5. Never modify upstream data (advisory only)
15 of the 20 factcheck dimensions are mechanical (field presence, format consistency, source citation). These should be Python script checks, not LLM evaluations. Only 5 dimensions need LLM judgment.
Pattern 11: Cost-Conscious LLM Assignment
In PRISM: Each module declares its LLM tier in the module spec: - Haiku for pure data structuring (cheapest) - Sonnet for structured extraction + light synthesis - Opus for deep reading, creative generation, evaluation
For skills: Each SKILL.md should declare the execution tier in frontmatter:
execution_tier: haiku | sonnet | opus
Skills that only structure API data (techstack, traffic, hiring data pull)
should run on Haiku. Skills that do deep synthesis (investor intel, sales
plays, reports) should run on Opus. This affects which model the harness
invokes via claude -p.
Pattern 12: Module Spec as Single Source of Truth
The most important pattern.
Every module has a spec in the vault at Projects/PRISM/Modules/.
The spec defines: input/output schemas, collection strategy, enrichment
prompts, validation rules, evidence requirements.
When you improve a module in PRISM (better validation, better prompts), update the spec. When you refactor a skill, read the spec first.
The spec is the bridge between runtimes. It prevents drift.
Skill-Specific Issues to Fix (from SESSION.md)
These are known issues in the current skills that PRISM has already solved:
| Issue | PRISM Solution | Skill Fix |
|---|---|---|
| Context exhaustion by skill #3 | Each module runs in its own Temporal activity (isolated context) | Python harness with subprocess claude -p per skill |
| No schemas (field name drift) | Pydantic models per module | Include JSON schema in each SKILL.md |
| Report reads .md not .json | Reads structured JSON from module_executions | Skill should read .json files, not .md scratchpads |
| ROI calculator unused | Python function in synth-business-case | Wire calculate-roi.py into the business case skill |
| Partner intel has no .json | Structured PartnerOutput Pydantic model | Add .json output to intel-partner skill |
| ABX mutates audit-data.json | Separate CampaignOutput, never touches upstream | Write to separate campaign.json, never modify audit-data.json |
| SEC data fetched twice (1E + 1G) | Shared SECEdgarAdapter, data cached in DB | Shared sec-fetch utility or cache the first result |
| 15/20 factcheck dims are mechanical | Python validator functions | Python script for mechanical checks, LLM for 5 judgment dims |
| No observability | duration_ms, llm_calls, llm_cost_usd tracked per module | JSONL progress log with timing + status per skill |
Related
- Module-Catalog -- all 20 modules in detail
- Module-Spec-Template -- the template for writing module specs
- Evidence-Tier-Spec -- the evidence system to adopt
- Validation-Patterns -- how to write validation rules
- Context -- current skill state (if exists)