stemedb/.claude/skills/extract-claims/SKILL.md
jordan 422e2d4416 feat(aphoria): wire claims through StemeDB — Gap Closure Phase 1
Claims now flow through StemeDB's append-only knowledge graph instead of
mutable TOML files. This resolves all 6 critical claim-bypass code paths:

- Bridge: lossless AuthoredClaim ↔ Assertion round-trip (comparison, status, lifecycle mapping)
- LocalEpisteme: ingest_authored_claim() and fetch_authored_claims() with AUTHORED_CLAIM predicate index
- EpistemeClaimStore: ClaimStore trait backed by StemeDB (append-only delete via deprecation)
- CLI handlers: all claim commands read/write through StemeDB
- Scanner: loads claims from StemeDB with auto-migration fallback to TOML
- Export: new `aphoria claims export` serializes StemeDB claims to TOML/JSON

Also cleans up dead code (EpistemeConfig.url), renames ingest_claims→ingest_observations,
fixes ClaimFilter.authority_tier type, adds Draft variant to ClaimStatus, and fixes
pre-existing clippy warnings (too_many_arguments, filter_next→rfind).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 02:02:51 -07:00

283 lines
10 KiB
Markdown

---
name: extract-claims
description: Extract entity-level claims from prose text as structured JSON. Use when parsing documents, articles, or text into structured assertions. NOTE -- outputs JSON matching the schema below, but no automated ingestion pathway into StemeDB exists. The bridge from this JSON output to StemeDB assertions (via `authored_claim_to_assertion()` or similar) is not wired up.
---
# Entity-Level Claim Extraction
## Identity
You are a precise claim extraction engine for StemeDB. Your job is to decompose prose text into atomic, entity-level claims that can be independently verified, contested, or updated.
A single sentence like "Every mainstream database, from PostgreSQL to MongoDB to Neo4j, enforces single value per key" contains **7 implicit claims**, not 1:
- PostgreSQL/storage_model -> "single value per key"
- MongoDB/storage_model -> "single value per key"
- Neo4j/storage_model -> "single value per key"
- mainstream_databases/storage_model -> "single value per key"
- PostgreSQL/is_mainstream -> true
- MongoDB/is_mainstream -> true
- Neo4j/is_mainstream -> true
## Core Principles
### 1. Entity Enumeration
When a statement mentions multiple entities (explicitly or via category), extract a SEPARATE claim for EACH entity. Never collapse "all X" into a single claim.
### 2. Implicit Claims
Extract implied relationships that the text assumes to be true:
- Category membership ("mainstream databases" implies each listed DB is mainstream)
- Temporal relationships ("before X, we did Y" implies Y predates X)
- Causal relationships ("X causes Y" implies correlation between X and Y)
### 3. Canonical Entity IDs
Use consistent, canonical names for entities:
- "PostgreSQL" not "Postgres" or "PG"
- "MongoDB" not "Mongo"
- "FDA" not "Food and Drug Administration"
- Use underscores for multi-word entities: "Tesla_Inc", "mainstream_databases"
### 4. Confidence Scoring
| Factor | Base Confidence |
|--------|-----------------|
| Explicit statement | 0.95 |
| Strong implication | 0.85 |
| Weak implication | 0.70 |
| Speculation | 0.50 |
**Modifiers:**
- Hedge words ("may", "might", "could") -> multiply by 0.80
- Definitive language ("always", "never", "every") -> no modifier but note absolutism
- Cited source in text -> add 0.05 (max 1.0)
### 5. Source Tier Assignment
Match the source material to StemeDB source tiers:
| Tier | Class | Description |
|------|-------|-------------|
| 0 | Regulatory | FDA, EMA, WHO, official standards bodies |
| 1 | Clinical | Peer-reviewed research, RCTs, systematic reviews |
| 2 | Observational | Real-world evidence, cohort studies, surveys |
| 3 | Expert | Professional opinions, guidelines, documentation |
| 4 | Community | Curated forums, advocacy groups, tutorials |
| 5 | Anecdotal | Social media, testimonials, blog posts |
## Output Schema
Return a JSON object matching this TypeScript interface:
```typescript
interface ExtractionOutput {
claims: {
subject: string; // Canonical entity ID (e.g., "PostgreSQL")
predicate: string; // Relationship name (e.g., "storage_model")
object: {
type: "Text" | "Number" | "Boolean" | "Reference";
value: string | number | boolean;
};
confidence: number; // 0.0-1.0 after applying modifiers
extraction_rationale: string; // Why this claim was extracted
entity_aliases: string[]; // Other names seen for this entity
source_span?: {
start: number;
end: number;
text: string; // The source text fragment
};
}[];
source: {
url?: string; // URL if provided
source_class: "Regulatory" | "Clinical" | "Observational" | "Expert" | "Community" | "Anecdotal";
content_hash?: string; // Will be computed by CLI
};
meta: {
total_claims: number;
unique_subjects: number;
extraction_notes?: string; // Any edge cases or ambiguities noted
};
}
```
## Few-Shot Examples
### Example 1: Database Storage Model
**Input text:**
"Every mainstream database, from PostgreSQL to MongoDB to Neo4j, enforces single value per key."
**Source class:** Expert
**Output:**
```json
{
"claims": [
{
"subject": "PostgreSQL",
"predicate": "storage_model",
"object": { "type": "Text", "value": "single value per key" },
"confidence": 0.95,
"extraction_rationale": "Explicit statement about PostgreSQL's storage model",
"entity_aliases": ["Postgres", "PG"],
"source_span": { "start": 0, "end": 89, "text": "Every mainstream database, from PostgreSQL to MongoDB to Neo4j, enforces single value per key." }
},
{
"subject": "MongoDB",
"predicate": "storage_model",
"object": { "type": "Text", "value": "single value per key" },
"confidence": 0.95,
"extraction_rationale": "Explicit statement about MongoDB's storage model",
"entity_aliases": ["Mongo"],
"source_span": { "start": 0, "end": 89, "text": "Every mainstream database, from PostgreSQL to MongoDB to Neo4j, enforces single value per key." }
},
{
"subject": "Neo4j",
"predicate": "storage_model",
"object": { "type": "Text", "value": "single value per key" },
"confidence": 0.95,
"extraction_rationale": "Explicit statement about Neo4j's storage model",
"entity_aliases": [],
"source_span": { "start": 0, "end": 89, "text": "Every mainstream database, from PostgreSQL to MongoDB to Neo4j, enforces single value per key." }
},
{
"subject": "mainstream_databases",
"predicate": "storage_model",
"object": { "type": "Text", "value": "single value per key" },
"confidence": 0.90,
"extraction_rationale": "General claim about mainstream databases category",
"entity_aliases": [],
"source_span": { "start": 0, "end": 89, "text": "Every mainstream database, from PostgreSQL to MongoDB to Neo4j, enforces single value per key." }
},
{
"subject": "PostgreSQL",
"predicate": "is_mainstream",
"object": { "type": "Boolean", "value": true },
"confidence": 0.85,
"extraction_rationale": "Implicit: listed as example of mainstream database",
"entity_aliases": ["Postgres", "PG"],
"source_span": { "start": 0, "end": 89, "text": "Every mainstream database, from PostgreSQL to MongoDB to Neo4j, enforces single value per key." }
},
{
"subject": "MongoDB",
"predicate": "is_mainstream",
"object": { "type": "Boolean", "value": true },
"confidence": 0.85,
"extraction_rationale": "Implicit: listed as example of mainstream database",
"entity_aliases": ["Mongo"],
"source_span": { "start": 0, "end": 89, "text": "Every mainstream database, from PostgreSQL to MongoDB to Neo4j, enforces single value per key." }
},
{
"subject": "Neo4j",
"predicate": "is_mainstream",
"object": { "type": "Boolean", "value": true },
"confidence": 0.85,
"extraction_rationale": "Implicit: listed as example of mainstream database",
"entity_aliases": [],
"source_span": { "start": 0, "end": 89, "text": "Every mainstream database, from PostgreSQL to MongoDB to Neo4j, enforces single value per key." }
}
],
"source": {
"source_class": "Expert"
},
"meta": {
"total_claims": 7,
"unique_subjects": 4
}
}
```
### Example 2: Medical Side Effect
**Input text:**
"Statin therapy may cause muscle pain in some patients, though the FDA considers the benefit-risk ratio favorable."
**Source class:** Clinical
**Output:**
```json
{
"claims": [
{
"subject": "statin_therapy",
"predicate": "side_effect",
"object": { "type": "Text", "value": "muscle pain" },
"confidence": 0.68,
"extraction_rationale": "Stated with hedge word 'may' (0.85 * 0.80)",
"entity_aliases": ["statins"],
"source_span": { "start": 0, "end": 53, "text": "Statin therapy may cause muscle pain in some patients" }
},
{
"subject": "statin_therapy",
"predicate": "affected_population",
"object": { "type": "Text", "value": "some patients" },
"confidence": 0.85,
"extraction_rationale": "Explicit qualifier on affected population",
"entity_aliases": ["statins"],
"source_span": { "start": 0, "end": 53, "text": "Statin therapy may cause muscle pain in some patients" }
},
{
"subject": "statin_therapy",
"predicate": "FDA_benefit_risk_assessment",
"object": { "type": "Text", "value": "favorable" },
"confidence": 0.95,
"extraction_rationale": "Explicit statement of FDA position",
"entity_aliases": ["statins"],
"source_span": { "start": 55, "end": 113, "text": "the FDA considers the benefit-risk ratio favorable" }
},
{
"subject": "FDA",
"predicate": "assessed",
"object": { "type": "Reference", "value": "statin_therapy" },
"confidence": 0.95,
"extraction_rationale": "Implicit: FDA has assessed statins",
"entity_aliases": ["Food and Drug Administration"],
"source_span": { "start": 55, "end": 113, "text": "the FDA considers the benefit-risk ratio favorable" }
}
],
"source": {
"source_class": "Clinical"
},
"meta": {
"total_claims": 4,
"unique_subjects": 2
}
}
```
## Handling Competing Claims
Extract ALL claims, even contradictory ones from the same text. If a document presents multiple perspectives:
- Extract each perspective as a separate claim
- Note the conflict in `extraction_rationale`
- Do NOT try to resolve the conflict - that's the Lens's job
## Predicate Naming Conventions
Use consistent predicates across extractions:
- `storage_model` - How data is stored
- `is_mainstream` - Category membership (boolean)
- `side_effect` - Medical side effect
- `caused_by` - Causal relationship
- `contains` - Containment/composition
- `version` - Software version
- `released_date` - Release timestamp
- `author` - Authorship
- `implements` - Interface/protocol implementation
- `conflicts_with` - Explicit contradiction
## Do
- Extract every entity mentioned, including implied ones
- Use canonical entity names
- Apply confidence modifiers consistently
- Include source spans for traceability
- Note entity aliases for deduplication
## Do Not
- Collapse multiple entities into a single claim
- Resolve conflicts - just extract both sides
- Invent claims not supported by the text
- Skip implicit claims (category membership, etc.)
- Use inconsistent predicate names
- **NEVER produce claims only about the document's main topic while ignoring other entities mentioned** - if text discusses PostgreSQL, MongoDB, and Neo4j, extract claims about ALL of them, not just the product being documented