The Problem with Intelligence Reports
Intelligence reports present conclusions. But conclusions without visible reasoning are assertions. The Discourse Grammar solves this by giving every claim, every score, and every recommendation a traceable provenance chain that readers can inspect, challenge, and extend.
8 Node Types
Every element of an intelligence argument is typed. No ambiguity about what a statement is.
Question
The driving inquiry. Every analysis begins with a question — often implicit. The grammar makes it explicit.
Claim
An assertion about the world. Claims must be grounded in evidence or explicitly marked as opinion.
Evidence
Data, observations, or findings that support or oppose a claim. Carries a confidence score [0.0 - 1.0].
Source
Where evidence came from. The SBPI Autoresearch Pipeline, SerpAPI, conference proceedings, or a human analyst.
Signal
A market or behavioral event detected by the scoring pipeline. Signals become evidence when attached to claims.
Prediction
A testable forecast. Predictions have deadlines and can be scored against outcomes in future cycles.
Directive
An action recommendation. What should stakeholders do based on the analysis? Traces back to supporting claims.
Annotation
Reader feedback. The highest-value signal in the system. A domain expert challenging a claim is worth more than a thousand data points.
8 Relation Types
Nodes connect through typed edges. Every connection has a defined semantic meaning.
| Relation | From | To | Meaning |
|---|---|---|---|
supports | Evidence | Claim | Evidence strengthens the claim |
opposes | Evidence | Claim | Evidence weakens or contradicts the claim |
informs | Source | Evidence | Source is the origin of this evidence |
triggers | Signal | Question | A market signal raises a new question |
predicts | Claim | Prediction | A claim implies a testable forecast |
annotates | Annotation | Any Node | Reader attaches feedback to a discourse element |
grounds | Question | Claim | A question motivates the claim's investigation |
supersedes | Node | Node | New information replaces or updates an older node |
Interactive Node-Relation Map
Heritage
The Discourse Grammar draws from three lineages:
- Roam Research Discourse Graph — Joel Chan's plugin for linking claims to evidence in a knowledge synthesis workspace. We adopt the node/relation vocabulary and extend it for machine reasoning.
- Joel Chan's Knowledge Synthesis — The idea that knowledge claims are not atomic facts but argumentation chains. A claim unsupported by evidence is an assertion; supported, it becomes knowledge.
- Datalog / Predicate Logic — Each triple in the knowledge graph is a predicate:
supports(EVD_001, CLM_001). SPARQL queries traverse these predicates to reconstruct reasoning chains on demand.
ShurIQ Application
Every score in a SHUR IQ stack ranking report has a visible provenance chain. Readers do not have to trust a number — they can click through to the evidence, see the source, check the confidence, and form their own judgment. This transforms the report from a static document into a live argumentative surface.
OWL Ontology Extensions
The discourse grammar is implemented as OWL class extensions to sbpi.ttl. Every node type and relation has formal domain/range constraints that SHACL validation enforces.
DiscourseNode Superclass & 7 Subclasses
All discourse elements inherit from sbpi:DiscourseNode. Signal and Prediction have dual inheritance — they exist in both the scoring and discourse layers.
# ── Discourse Grammar: Node Type Hierarchy ── sbpi:DiscourseNode a owl:Class ; rdfs:label "Discourse Node" ; rdfs:comment "Abstract superclass for all discourse grammar nodes" . sbpi:Claim a owl:Class ; rdfs:subClassOf sbpi:DiscourseNode ; rdfs:label "Claim" ; rdfs:comment "An assertion about the world, requiring evidence" . sbpi:Evidence a owl:Class ; rdfs:subClassOf sbpi:DiscourseNode ; rdfs:label "Evidence" ; rdfs:comment "Data or observation that supports or opposes a claim" . sbpi:Source a owl:Class ; rdfs:subClassOf sbpi:DiscourseNode ; rdfs:label "Source" ; rdfs:comment "Provenance origin for evidence" . sbpi:Question a owl:Class ; rdfs:subClassOf sbpi:DiscourseNode ; rdfs:label "Question" ; rdfs:comment "Driving inquiry motivating analysis" . sbpi:DirectiveNode a owl:Class ; rdfs:subClassOf sbpi:DiscourseNode ; rdfs:label "Directive" ; rdfs:comment "Actionable recommendation derived from claims" . sbpi:Annotation a owl:Class ; rdfs:subClassOf sbpi:DiscourseNode ; rdfs:label "Annotation" ; rdfs:comment "Reader feedback on any discourse node" . # ── Dual-Inheritance: Scoring + Discourse ── sbpi:Signal a owl:Class ; rdfs:subClassOf sbpi:DiscourseNode , sbpi:ScoringElement ; rdfs:label "Signal" . sbpi:Prediction a owl:Class ; rdfs:subClassOf sbpi:DiscourseNode , sbpi:ScoringElement ; rdfs:label "Prediction" .
9 Object Properties (Relations)
# ── Discourse Relations with Domain/Range ── sbpi:supports a owl:ObjectProperty ; rdfs:domain sbpi:Evidence ; rdfs:range sbpi:Claim . sbpi:opposes a owl:ObjectProperty ; rdfs:domain sbpi:Evidence ; rdfs:range sbpi:Claim . sbpi:informs a owl:ObjectProperty ; rdfs:domain sbpi:Source ; rdfs:range sbpi:Evidence . sbpi:triggers a owl:ObjectProperty ; rdfs:domain sbpi:Signal ; rdfs:range sbpi:Question . sbpi:predicts a owl:ObjectProperty ; rdfs:domain sbpi:Claim ; rdfs:range sbpi:Prediction . sbpi:annotates a owl:ObjectProperty ; rdfs:domain sbpi:Annotation ; rdfs:range sbpi:DiscourseNode . sbpi:grounds a owl:ObjectProperty ; rdfs:domain sbpi:Question ; rdfs:range sbpi:Claim . sbpi:supersedes a owl:ObjectProperty ; rdfs:domain sbpi:DiscourseNode ; rdfs:range sbpi:DiscourseNode . sbpi:derivedFrom a owl:ObjectProperty ; rdfs:domain sbpi:DiscourseNode ; rdfs:range sbpi:DiscourseNode ; rdfs:comment "Provenance chain: this node was derived from another" .
3 Datatype Properties
sbpi:hasConfidence a owl:DatatypeProperty ; rdfs:domain sbpi:Evidence ; rdfs:range xsd:decimal ; rdfs:comment "Confidence score [0.0 - 1.0]" . sbpi:nodeFormat a owl:DatatypeProperty ; rdfs:domain sbpi:DiscourseNode ; rdfs:range xsd:string ; rdfs:comment "Output format hint: text, chart, table" . sbpi:discourseText a owl:DatatypeProperty ; rdfs:domain sbpi:DiscourseNode ; rdfs:range xsd:string ; rdfs:comment "Human-readable text content of the node" .
K-Pop Vertical Extension
The K-Pop extension demonstrates how the discourse grammar adapts to vertical-specific domains. Four new classes and ten high-value edge types capture the unique dynamics of the K-Pop industry.
# ── K-Pop Vertical Extension ── kpop:Agency a owl:Class ; rdfs:subClassOf sbpi:TrackedCompany ; rdfs:label "K-Pop Agency" ; rdfs:comment "Entertainment company managing K-Pop artists (e.g., HYBE, SM, JYP)" . kpop:ArtistGroup a owl:Class ; rdfs:label "K-Pop Group" ; rdfs:comment "Multi-member performance group (e.g., BTS, BLACKPINK, aespa)" . kpop:Soloist a owl:Class ; rdfs:label "K-Pop Soloist" ; rdfs:comment "Individual K-Pop artist" . kpop:Fandom a owl:Class ; rdfs:label "Fandom" ; rdfs:comment "Organized fan community with coordinated buying/streaming behavior" . # ── K-Pop Edge Types (10 high-value relations) ── kpop:manages a owl:ObjectProperty ; rdfs:domain kpop:Agency ; rdfs:range kpop:ArtistGroup . kpop:hasFandom a owl:ObjectProperty ; rdfs:domain kpop:ArtistGroup ; rdfs:range kpop:Fandom . kpop:memberOf a owl:ObjectProperty ; rdfs:domain kpop:Soloist ; rdfs:range kpop:ArtistGroup . kpop:comebackEvent a owl:ObjectProperty ; rdfs:domain kpop:ArtistGroup ; rdfs:range sbpi:Signal . kpop:rivalsWith a owl:ObjectProperty ; rdfs:domain kpop:Agency ; rdfs:range kpop:Agency . kpop:distributedBy a owl:ObjectProperty ; rdfs:domain kpop:ArtistGroup ; rdfs:range sbpi:TrackedCompany . kpop:streamingMetric a owl:DatatypeProperty ; rdfs:domain kpop:ArtistGroup ; rdfs:range xsd:integer . kpop:chartsOn a owl:ObjectProperty ; rdfs:domain kpop:ArtistGroup ; rdfs:range sbpi:TrackedCompany . kpop:collaboratesWith a owl:ObjectProperty ; rdfs:domain kpop:ArtistGroup ; rdfs:range kpop:ArtistGroup . kpop:fandomAction a owl:ObjectProperty ; rdfs:domain kpop:Fandom ; rdfs:range sbpi:Signal .
SHACL Validation Shapes
SHACL shapes enforce structural rules at data ingestion time. A Claim without evidence or an Evidence node without confidence will fail validation before entering the store.
# ── SHACL: Discourse Grammar Validation ── sbpi-sh:ClaimShape a sh:NodeShape ; sh:targetClass sbpi:Claim ; sh:property [ sh:path sbpi:discourseText ; sh:minCount 1 ; sh:datatype xsd:string ; sh:message "Every Claim must have discourse text" ] ; sh:property [ sh:path [ sh:inversePath sbpi:supports ] ; sh:minCount 1 ; sh:message "Every Claim must have at least one supporting Evidence" ] . sbpi-sh:EvidenceShape a sh:NodeShape ; sh:targetClass sbpi:Evidence ; sh:property [ sh:path sbpi:hasConfidence ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:decimal ; sh:minInclusive 0.0 ; sh:maxInclusive 1.0 ; sh:message "Evidence must have exactly one confidence score in [0.0, 1.0]" ] ; sh:property [ sh:path [ sh:inversePath sbpi:informs ] ; sh:minCount 1 ; sh:message "Evidence must trace to at least one Source" ] . # ── SHACL: K-Pop Vertical ── kpop-sh:ArtistGroupShape a sh:NodeShape ; sh:targetClass kpop:ArtistGroup ; sh:property [ sh:path [ sh:inversePath kpop:manages ] ; sh:minCount 1 ; sh:class kpop:Agency ; sh:message "Every ArtistGroup must be managed by at least one Agency" ] . kpop-sh:AgencyShape a sh:NodeShape ; sh:targetClass kpop:Agency ; sh:property [ sh:path rdfs:label ; sh:minCount 1 ; sh:message "Every Agency must have a label" ] .
Evidence Trail
These are real evidence chains retrieved from the Oxigraph store. Every claim below was traced to its sources via SPARQL. The confidence scores, the sources, and the support/opposition relationships are all stored as RDF triples — not prose.
SPARQL Query — ReelShort Evidence Chain
PREFIX sbpi: <http://shurai.com/ontology/sbpi#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?evidence ?confidence ?text ?relation ?sourceName WHERE { ?evidence ?relation sbpi:CLM_reelshort_decline . FILTER(?relation IN (sbpi:supports, sbpi:opposes)) ?evidence sbpi:hasConfidence ?confidence ; sbpi:discourseText ?text . ?source sbpi:informs ?evidence ; rdfs:label ?sourceName . } ORDER BY DESC(?confidence)
SPARQL Query — DramaBox Evidence Chain
PREFIX sbpi: <http://shurai.com/ontology/sbpi#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?evidence ?confidence ?text ?sourceName WHERE { ?evidence sbpi:supports sbpi:CLM_dramabox_overtake . ?evidence sbpi:hasConfidence ?confidence ; sbpi:discourseText ?text . ?source sbpi:informs ?evidence ; rdfs:label ?sourceName . } ORDER BY DESC(?confidence)
SPARQL Query — Disney Evidence Chain
PREFIX sbpi: <http://shurai.com/ontology/sbpi#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?evidence ?confidence ?text ?sourceName WHERE { ?evidence sbpi:supports sbpi:CLM_disney_surge . ?evidence sbpi:hasConfidence ?confidence ; sbpi:discourseText ?text . ?source sbpi:informs ?evidence ; rdfs:label ?sourceName . } ORDER BY DESC(?confidence)
SPARQL Query — COL/BeLive Evidence Chain
PREFIX sbpi: <http://shurai.com/ontology/sbpi#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?evidence ?confidence ?text ?sourceName WHERE { ?evidence sbpi:supports sbpi:CLM_col_belive_shopify . ?evidence sbpi:hasConfidence ?confidence ; sbpi:discourseText ?text . ?source sbpi:informs ?evidence ; rdfs:label ?sourceName . }
What makes this different
Traditional intelligence reports present conclusions as prose. The Discourse Grammar stores every element as a typed node in a knowledge graph. The Evidence Trail tab reconstructs the reasoning chain on demand via SPARQL. If new evidence arrives next week, the chain updates — the claim does not need to be rewritten. The data drives the narrative, not the other way around.
Live Data — Oxigraph Store Statistics
The knowledge graph currently holds 3,202 triples across two layers: the original SBPI scoring data and the new discourse grammar layer seeded in this session.
Instance Counts by Type
Layer Composition
Scoring Layer — 3,057 triples
The original SBPI data: company profiles, weekly composite scores, dimension breakdowns, tier classifications, and 54 market signals from W10-W12 2026. This layer is the quantitative foundation — the numbers behind every stack ranking position.
| Companies tracked | 12 |
| Weekly snapshots | 3 (W10-W12) |
| Scoring dimensions | 4 |
| Market signals | 54 |
| Tier classifications | 4 |
Discourse Layer — 145 triples
The argumentation layer seeded this session: 4 claims with full evidence chains, 3 source attributions, 2 driving questions, 2 directives, and 1 testable prediction. This layer transforms raw scores into auditable intelligence.
| Claims | 4 |
| Evidence nodes | 9 |
| Sources | 3 |
| Questions | 2 |
| Directives | 2 |
| Predictions | 1 |
Growth Trajectory
The discourse layer is intentionally thin in Phase 1 — 145 triples against 3,057 in the scoring layer. This is by design. The discourse layer will grow proportionally as each weekly report cycle adds new claims and evidence. The annotation layer (Phase 2) will add reader feedback triples, creating a third growth vector. Projected store size by Q2 2026: approximately 8,000-10,000 triples.
SPARQL Query — Instance Count by Type
PREFIX sbpi: <http://shurai.com/ontology/sbpi#> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> SELECT ?type (COUNT(?node) AS ?count) WHERE { ?node rdf:type ?type . FILTER(?type IN ( sbpi:Claim, sbpi:Evidence, sbpi:Source, sbpi:Question, sbpi:DirectiveNode, sbpi:Signal, sbpi:Prediction )) } GROUP BY ?type ORDER BY DESC(?count)
The Annotation Loop
Gordon Pask's Conversation Theory posits that understanding is demonstrated through teach-back — the ability to re-express an idea and have discrepancies surface. In the Discourse Grammar, reader annotations are the teach-back mechanism. When a reader opposes a high-confidence claim, that disagreement is a Teach-Back Delta — and it is more valuable than any automated signal.
Annotation Prefix Conventions
Readers annotate using 4 prefix symbols. Each prefix maps to a discourse relation type:
grounds
opposes relation to the target claim
supports relation to the target claim
triggers relation to a new QUE
pending.yaml Format
Annotations are staged in a YAML file before processing. Each entry specifies the target node, the prefix type, the annotator, and the text content.
# pending.yaml — Staged reader annotations annotations: - id: "ANN_001" target: "CLM_reelshort_decline" prefix: "~" annotator: "limore@shurai.com" timestamp: "2026-03-28T10:15:00Z" text: "ReelShort still dominates LATAM markets. Composite decline may not reflect regional strength." - id: "ANN_002" target: "CLM_disney_surge" prefix: "+" annotator: "analyst@microco.com" timestamp: "2026-03-28T11:30:00Z" text: "Disney reportedly allocating $50M for vertical drama originals in 2026 — confirms infrastructure commoditization thesis." - id: "ANN_003" target: "CLM_col_belive_shopify" prefix: "?" annotator: "analyst@microco.com" timestamp: "2026-03-28T12:00:00Z" text: "Has COL/BeLive disclosed pricing or signed any customers since FILMART announcement?"
Processing Pipeline
annotation_processor.py reads pending.yaml, classifies each annotation by prefix, generates a SPARQL UPDATE, and executes it against the Oxigraph store.
annotation_processor.py — Classification Logic
def classify_annotation(entry): """Map prefix to discourse relation and node type.""" prefix_map = { "?": {"node_type": "Question", "relation": "grounds"}, "~": {"node_type": "Evidence", "relation": "opposes"}, "+": {"node_type": "Evidence", "relation": "supports"}, "!": {"node_type": "Signal", "relation": "triggers"} } return prefix_map[entry["prefix"]]
SPARQL UPDATE Template
Each processed annotation generates a SPARQL UPDATE that inserts the new node and its relations into the graph:
PREFIX sbpi: <http://shurai.com/ontology/sbpi#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> INSERT DATA { # Create the annotation node sbpi:{ann_id} a sbpi:Annotation , sbpi:{node_type} ; sbpi:discourseText "{text}"^^xsd:string ; sbpi:hasConfidence "{confidence}"^^xsd:decimal ; sbpi:annotatedBy "{annotator}"^^xsd:string ; sbpi:annotatedAt "{timestamp}"^^xsd:dateTime . # Link annotation to target sbpi:{ann_id} sbpi:annotates sbpi:{target_id} . # Create the discourse relation sbpi:{ann_id} sbpi:{relation} sbpi:{target_id} . }
Sample Annotations — Processing Preview
Here is what happens when the 3 pending annotations are processed:
Teach-Back Delta: "ReelShort still dominates LATAM markets. Composite decline may not reflect regional strength."
Annotator: limore@shurai.com | Relation: opposes | Confidence: 0.70 (reader-assigned) | This creates opposing evidence against the ReelShort decline claim, raising the question of whether composite scores adequately capture regional dominance.
Evidence Extension: "Disney reportedly allocating $50M for vertical drama originals in 2026 — confirms infrastructure commoditization thesis."
Annotator: analyst@microco.com | Relation: supports | Confidence: 0.75 (reader-assigned) | This strengthens the Disney surge claim with budget allocation data not captured in the automated pipeline.
New Question: "Has COL/BeLive disclosed pricing or signed any customers since FILMART announcement?"
Annotator: analyst@microco.com | Relation: grounds | This question becomes a research directive for the next autoresearch cycle — the SerpAPI pipeline will prioritize COL/BeLive customer data.
Why Annotations Are the Highest-Value Signal
Automated pipelines process public data at scale. But domain experts possess private context that no pipeline can access: internal pricing conversations, competitive intelligence from trade shows, relationship dynamics between companies. When these experts annotate a claim, they inject private signal into a public-data graph. The Teach-Back Delta — the gap between what the graph says and what the expert knows — is where the most valuable intelligence lives.
System Architecture
Three layers, six components, one feedback loop. The architecture is designed for incremental growth — each report cycle adds triples, each annotation sharpens the graph, and each query returns richer provenance chains over time.
Three-Layer Stack
Annotation Layer
Reader feedback, Teach-Back Deltas, expert domain signal
Growing — added per reader interaction
Discourse Layer — 145 triples
Claims, Evidence, Sources, Questions, Directives, Predictions
Growing — added per report cycle
Scoring Layer — 3,057 triples
Company profiles, weekly composites, dimension scores, signals, tiers
Growing — added per autoresearch run
Component Registry
| Component | Type | Role |
|---|---|---|
sbpi.ttl |
OWL Ontology | Core vocabulary: scoring classes, discourse grammar nodes, object/datatype properties |
kpop.ttl |
OWL Extension | Vertical extension: K-Pop domain classes and high-value edge types |
| SHACL Shapes | Validation | Structural constraints: evidence must have confidence, claims must have evidence |
| Oxigraph Store | Triple Store | SPARQL 1.1 compliant graph database, local deployment, 3,202 triples |
/evidence-trail |
Claude Skill | Accepts a claim ID, traverses the graph, returns formatted provenance chain |
annotation_processor.py |
ETL Script | Reads pending.yaml, classifies by prefix, generates SPARQL UPDATE, executes against store |
Data Flow
Published
Annotates
pending.yaml
UPDATE
Graph
Cycle
The feedback loop closes when reader annotations from cycle N improve the provenance chains in cycle N+1.
Full Architecture Diagram
Phase 1 to Phase 2
Phase 1 (Current)
- Discourse Grammar ontology designed and committed to
sbpi.ttl - K-Pop vertical extension with SHACL validation
- 4 claims with full evidence chains loaded into Oxigraph
/evidence-trailskill traverses and formats provenance- Annotation processor pipeline specified
- This explainer site documents the system
Phase 2 (Next)
- Annotatable reports: inline annotation UI in editorial sites
- Live
pending.yamlintake from report readers annotation_processor.pyintegrated into report cycle- Teach-Back Delta scoring: weight reader corrections by domain expertise
- Prediction tracking: automated scoring of
PRDnodes against outcomes - Second vertical extension (audience agency or content analysis)
Design Principle: Data Drives Narrative
The architecture inverts the traditional intelligence workflow. Instead of an analyst writing a report and then defending it, the Discourse Grammar stores the argument structure first. Reports are rendered from the graph, not written into it. This means the same evidence chain can render as a board-level summary, a detailed analyst brief, or an annotatable research surface — all from the same underlying triples. The narrative is a view over the data, not the data itself.