Problem

Standard RAG retrieves text by semantic similarity and hands it to the LLM as one fused object. But language carries two payloads at once: facticity (what happened) and interpretation (the persuasion, emotion, and rhetorical stance wrapped around it). “Everyone agrees this migration is catastrophic!” contains a factual claim wrapped in a persuasive frame — social proof, hyperbolic modality, declarative pressure. Standard RAG can’t see the seam. The LLM absorbs the stance along with the facts.

Prompt-level defenses (“don’t be manipulated”) fail structurally: the instruction competes with adversarial content on the same channel.

Approach

SFL Engine applies an MVC-like separation at the data layer, borrowed from Systemic Functional Linguistics’ metafunctions:

  • Ideational payload — processes, participants, circumstances: what happened.
  • Interpersonal payload — mood, modality, tenor, attitude: how it was said.

A two-pass pipeline extracts and separates them before storage:

Input → Pass 1 (spaCy) → Pass 2 (LLM) → Store (Postgres + pgvector)
                         ↓
                   Ideational Payload    → facts, process types, participants
                   Interpersonal Payload → mood, modality, tenor, attitude
                         ↓
                   Retrieve (RRF + Scalar Stance Filters)
                         ↓
                   LLM receives: facts without persuasion

Pass 1 (spaCy, subprocess sidecar) is rule-based syntactic parsing — clause boundaries, process types, participants. Pass 2 (LLM, via ruby_llm) is semantic annotation — mood, modality weight, tenor, attitude. Retrieval merges vector similarity and keyword search via Reciprocal Rank Fusion, then applies scalar stance filters that exclude clauses matching structural fingerprints of cognitive distortion — before the context window is assembled. This is the Rhetorical Firewall: not a claim that manipulation is removed, but a deterministic boundary that keeps rhetorical metadata from being treated as inseparable factual context.

The synthesis is composite, not single-discipline — SFL for the metadata, CBT’s distortion taxonomy for the filters, Unix philosophy for the two-pass composability, cybersecurity’s air-gapping model for the firewall framing.

Outcome

Phases 0–5 of the rebuild are implemented: two-pass pipeline, Postgres/pgvector storage, hybrid retrieval, unified analysis engine, boot composition root, CLI, and HTTP API. The system design was assessed with the SIFT protocol at 78/100 — suitable for continued development and controlled internal use, not yet unconditionally production-ready. All P0 (blocking/security/data-integrity) findings from that assessment are fixed and closed: transactionally atomic clause review, sanitized API error responses, a pinned toolchain, opt-in Docker auto-start, and a containerized API service.

This remains a research-oriented engineering artifact, not a validated outcome study — no external corpus has yet established that stance filtering improves LLM reasoning outcomes or adversarial robustness in practice.