Conclusions

methodology

Conclusions

Definition

A conclusion is an evidence-based determination derived through a structured reasoning process, representing the synthesis of multiple signals, observations, and analyses into a definitive finding with a measured confidence level. In rigorous systems, conclusions are not opinions or guesses -- they are the products of disciplined epistemic processes that track provenance, weigh evidence, account for contradictions, and quantify uncertainty.

Within the Prismatic Platform, conclusions are first-class entities in the epistemic pipeline. Every conclusion carries metadata about its evidence chain, confidence score, validation status, and the reasoning framework that produced it. The platform distinguishes sharply between conclusions (validated through the Trinity Gate) and mere assertions (unvalidated claims).

Overview

The concept of conclusions in software systems extends far beyond simple if-then logic. Modern platforms deal with ambiguous data, contradictory signals, incomplete information, and evolving contexts. Drawing sound conclusions in such environments requires formal methodology.

The Prismatic Platform approaches conclusions through the lens of its NABLA Infinity epistemic framework. Seven axioms govern how conclusions are formed:

  1. Signal Plurality -- A conclusion requires at least two independent signals
  2. Contradiction Preservation -- Contradictory evidence is preserved alongside the conclusion, not discarded
  3. Absence Informative -- Missing data is itself treated as a signal
  4. Time Decay -- Evidence ages; conclusions from stale data are marked as degraded
  5. Unknown Valid -- "Inconclusive" is a legitimate conclusion
  6. Source Independence -- Independent sources receive higher weight
  7. Provenance Mandatory -- Every conclusion is traceable to its source evidence

These axioms ensure that conclusions drawn by the platform are epistemically sound rather than superficially confident. A system that reaches conclusions too quickly or too confidently is more dangerous than one that honestly reports uncertainty.

The lifecycle of a conclusion in the platform follows a well-defined path: evidence gathering, signal aggregation, hypothesis formation, confidence scoring, Trinity Gate validation, and finally conclusion registration. Each stage has explicit entry and exit criteria, and the entire chain is logged for audit purposes.

Historical and Philosophical Context

The formal treatment of conclusions in the Prismatic Platform draws from multiple intellectual traditions. The philosophical study of inference -- from Aristotelian syllogisms through Bayesian reasoning to modern epistemic logic -- provides the theoretical foundation. The practical study of decision-making under uncertainty -- from military intelligence analysis to financial risk assessment -- provides the operational context.

Traditional software systems treat conclusions as boolean outcomes: a test passes or fails, a threshold is exceeded or not, a condition is true or false. This binary model is adequate for deterministic domains but inadequate for the ambiguous, signal-rich environments where the Prismatic Platform operates. OSINT intelligence, security assessments, and due diligence investigations produce conclusions that exist on a continuum of certainty, not at binary endpoints.

The platform's approach synthesizes three traditions: deductive reasoning (conclusions that follow necessarily from premises), inductive reasoning (conclusions that are probable given accumulated evidence), and abductive reasoning (conclusions that represent the best explanation for observed evidence). The QEVE verification engine operationalizes all three through its five-stage pipeline.

Technical Details

Conclusion Data Model

Conclusions in the Prismatic Platform are structured entities with rich metadata:

defmodule Prismatic.Epistemic.Conclusion do
  @moduledoc """
  Represents an evidence-based conclusion derived through the
  platform's epistemic reasoning pipeline.

  Every conclusion carries its full provenance chain, confidence
  metrics, and validation status.
  """

  @type confidence :: float()

  @type t :: %__MODULE__{
    id: String.t(),
    statement: String.t(),
    confidence: confidence(),
    evidence_chain: [Evidence.t()],
    contradictions: [Contradiction.t()],
    reasoning_framework: atom(),
    trinity_gate_status: :passed | :failed | :pending,
    created_at: DateTime.t(),
    decay_rate: float(),
    provenance: Provenance.t(),
    metadata: map()
  }

  defstruct [
    :id,
    :statement,
    :confidence,
    evidence_chain: [],
    contradictions: [],
    reasoning_framework: :nabla_infinity,
    trinity_gate_status: :pending,
    created_at: nil,
    decay_rate: 0.01,
    provenance: nil,
    metadata: %{}
  ]

  @spec valid?(t()) :: boolean()
  def valid?(%__MODULE__{} = conclusion) do
    conclusion.confidence >= confidence_threshold(conclusion) and
      conclusion.trinity_gate_status == :passed and
      length(conclusion.evidence_chain) >= 2 and
      conclusion.provenance != nil
  end

  @spec confidence_threshold(t()) :: float()
  defp confidence_threshold(%__MODULE__{metadata: %{context: :critical}}), do: 0.95
  defp confidence_threshold(%__MODULE__{metadata: %{context: :standard}}), do: 0.80
  defp confidence_threshold(%__MODULE__{metadata: %{context: :exploratory}}), do: 0.60
  defp confidence_threshold(_), do: 0.80
end

Conclusion Derivation Pipeline

The process of deriving a conclusion involves multiple stages:

defmodule Prismatic.Epistemic.ConclusionPipeline do
  @moduledoc """
  Pipeline for deriving conclusions from raw evidence through
  structured epistemic reasoning stages.
  """

  alias Prismatic.Epistemic.{Conclusion, Evidence, TrinityGate}

  @spec derive([Evidence.t()], keyword()) ::
    {:ok, Conclusion.t()} | {:error, atom()} | {:inconclusive, map()}
  def derive(evidence_list, opts \\ []) do
    context = Keyword.get(opts, :context, :standard)
    framework = Keyword.get(opts, :framework, :nabla_infinity)

    with {:ok, validated_evidence} <- validate_evidence(evidence_list),
         {:ok, signals} <- extract_signals(validated_evidence),
         :ok <- verify_signal_plurality(signals),
         {:ok, contradictions} <- detect_contradictions(signals),
         {:ok, hypothesis} <- form_hypothesis(signals, contradictions),
         {:ok, scored} <- score_confidence(hypothesis, signals),
         {:ok, conclusion} <- build_conclusion(scored, contradictions, framework),
         {:ok, verified} <- TrinityGate.validate(conclusion) do
      {:ok, verified}
    else
      {:insufficient_signals, count} ->
        {:inconclusive, %{reason: :insufficient_signals, count: count, minimum: 2}}

      {:low_confidence, score} ->
        {:inconclusive, %{reason: :low_confidence, score: score,
                          threshold: confidence_threshold(context)}}

      {:trinity_gate_failed, failures} ->
        {:error, {:trinity_gate_failed, failures}}

      error ->
        {:error, error}
    end
  end

  defp verify_signal_plurality(signals) when length(signals) >= 2, do: :ok
  defp verify_signal_plurality(signals),
    do: {:insufficient_signals, length(signals)}

  defp detect_contradictions(signals) do
    contradictions =
      for s1 <- signals,
          s2 <- signals,
          s1.id < s2.id,
          contradicts?(s1, s2) do
        %{signal_a: s1.id, signal_b: s2.id, nature: describe_contradiction(s1, s2)}
      end

    {:ok, contradictions}
  end

  defp score_confidence(hypothesis, signals) do
    base_confidence = hypothesis.initial_confidence
    signal_boost = length(signals) * 0.05
    independence_factor = calculate_independence(signals)
    time_decay = calculate_time_decay(signals)

    final_confidence =
      (base_confidence + signal_boost) * independence_factor * time_decay
      |> min(1.0)
      |> max(0.0)

    {:ok, %{hypothesis | confidence: final_confidence}}
  end
end

Trinity Gate Validation for Conclusions

Every conclusion must pass the three-layer Trinity Gate before being accepted:

defmodule Prismatic.Epistemic.TrinityGate do
  @moduledoc """
  Three-layer verification gate for conclusions.
  ALL three layers must pass for a conclusion to be accepted.
  """

  @spec validate(Conclusion.t()) :: {:ok, Conclusion.t()} | {:error, map()}
  def validate(%Conclusion{} = conclusion) do
    results = %{
      structural: check_structural_consistency(conclusion),
      logical: check_logical_consistency(conclusion),
      formal: check_formal_necessity(conclusion)
    }

    case Enum.all?(Map.values(results), &(&1 == :pass)) do
      true ->
        {:ok, %{conclusion | trinity_gate_status: :passed}}

      false ->
        failures = results |> Enum.filter(fn {_k, v} -> v != :pass end) |> Map.new()
        {:error, %{gate: :trinity, failures: failures}}
    end
  end

  defp check_structural_consistency(conclusion) do
    graph = build_evidence_graph(conclusion.evidence_chain)

    cond do
      not acyclic?(graph) -> {:fail, :circular_evidence}
      not connected?(graph) -> {:fail, :disconnected_evidence}
      true -> :pass
    end
  end

  defp check_logical_consistency(conclusion) do
    propositions = extract_propositions(conclusion)

    cond do
      contains_self_contradiction?(propositions) -> {:fail, :self_contradictory}
      violates_modus_ponens?(propositions) -> {:fail, :logical_violation}
      true -> :pass
    end
  end

  defp check_formal_necessity(conclusion) do
    case conclusion.metadata[:formal_proof] do
      nil -> :pass
      proof -> verify_formal_proof(proof)
    end
  end
end

Confidence Decay Over Time

Conclusions are not static -- their confidence degrades over time as the underlying evidence ages:

defmodule Prismatic.Epistemic.ConfidenceDecay do
  @moduledoc """
  Models the time-based decay of conclusion confidence.
  Implements the NABLA Infinity Time Decay axiom.
  """

  @spec current_confidence(Conclusion.t()) :: float()
  def current_confidence(%Conclusion{} = conclusion) do
    age_hours = DateTime.diff(DateTime.utc_now(), conclusion.created_at, :hour)
    decay_factor = :math.exp(-conclusion.decay_rate * age_hours)

    (conclusion.confidence * decay_factor)
    |> max(0.0)
    |> Float.round(4)
  end

  @spec needs_refresh?(Conclusion.t(), float()) :: boolean()
  def needs_refresh?(%Conclusion{} = conclusion, threshold \\ 0.50) do
    current_confidence(conclusion) < threshold
  end
end

Conclusion Registry and Lifecycle Management

defmodule Prismatic.Epistemic.ConclusionRegistry do
  @moduledoc """
  Registry for managing conclusion lifecycle, including creation,
  supersession, decay monitoring, and audit trail maintenance.
  """

  use GenServer

  @type registry_state :: %{
    conclusions: %{String.t() => Conclusion.t()},
    supersession_chain: %{String.t() => String.t()},
    audit_log: [audit_entry()]
  }

  @type audit_entry :: %{
    conclusion_id: String.t(),
    action: :created | :superseded | :expired | :refreshed,
    timestamp: DateTime.t(),
    actor: String.t()
  }

  @spec start_link(keyword()) :: GenServer.on_start()
  def start_link(opts) do
    GenServer.start_link(__MODULE__, opts, name: __MODULE__)
  end

  @spec register(Conclusion.t()) :: {:ok, String.t()} | {:error, term()}
  def register(conclusion) do
    GenServer.call(__MODULE__, {:register, conclusion})
  end

  @spec supersede(String.t(), Conclusion.t()) :: {:ok, String.t()} | {:error, term()}
  def supersede(old_id, new_conclusion) do
    GenServer.call(__MODULE__, {:supersede, old_id, new_conclusion})
  end

  @spec get(String.t()) :: {:ok, Conclusion.t()} | {:error, :not_found}
  def get(id) do
    GenServer.call(__MODULE__, {:get, id})
  end

  @impl true
  def init(_opts) do
    schedule_decay_check()
    {:ok, %{conclusions: %{}, supersession_chain: %{}, audit_log: []}}
  end

  @impl true
  def handle_call({:register, conclusion}, _from, state) do
    entry = %{conclusion_id: conclusion.id, action: :created,
              timestamp: DateTime.utc_now(), actor: "pipeline"}
    new_state = %{state |
      conclusions: Map.put(state.conclusions, conclusion.id, conclusion),
      audit_log: [entry | state.audit_log]
    }
    {:reply, {:ok, conclusion.id}, new_state}
  end

  @impl true
  def handle_call({:supersede, old_id, new_conclusion}, _from, state) do
    supersede_entry = %{conclusion_id: old_id, action: :superseded,
                        timestamp: DateTime.utc_now(), actor: "pipeline"}
    create_entry = %{conclusion_id: new_conclusion.id, action: :created,
                     timestamp: DateTime.utc_now(), actor: "pipeline"}

    new_state = %{state |
      conclusions: state.conclusions
        |> Map.put(new_conclusion.id, new_conclusion)
        |> Map.delete(old_id),
      supersession_chain: Map.put(state.supersession_chain, old_id, new_conclusion.id),
      audit_log: [create_entry, supersede_entry | state.audit_log]
    }
    {:reply, {:ok, new_conclusion.id}, new_state}
  end

  @impl true
  def handle_call({:get, id}, _from, state) do
    case Map.get(state.conclusions, id) do
      nil -> {:reply, {:error, :not_found}, state}
      conclusion -> {:reply, {:ok, conclusion}, state}
    end
  end

  @impl true
  def handle_info(:decay_check, state) do
    expired =
      state.conclusions
      |> Enum.filter(fn {_id, c} ->
        Prismatic.Epistemic.ConfidenceDecay.needs_refresh?(c, 0.30)
      end)
      |> Enum.map(fn {id, _c} -> id end)

    entries = Enum.map(expired, fn id ->
      %{conclusion_id: id, action: :expired, timestamp: DateTime.utc_now(), actor: "decay_monitor"}
    end)

    new_state = %{state |
      conclusions: Map.drop(state.conclusions, expired),
      audit_log: entries ++ state.audit_log
    }

    schedule_decay_check()
    {:noreply, new_state}
  end

  defp schedule_decay_check do
    Process.send_after(self(), :decay_check, :timer.hours(1))
  end
end

Implementation in the Prismatic Platform

Security Assessment Conclusions

In the Prismatic Perimeter EASM system, security assessments produce conclusions about an organization's attack surface. Each security rating (A-F) is a conclusion derived from multiple evidence sources: certificate transparency logs, DNS enumeration results, vulnerability scans, and compliance checks. The conclusion pipeline ensures that a security rating is never based on a single scan but always synthesizes multiple independent signals.

OSINT Intelligence Conclusions

The 120 OSINT tools produce raw intelligence that is fed into the conclusion pipeline. When investigating an entity, the platform cross-references data from Czech business registries (ARES, Justice, Commercial Register), global sources (Shodan, VirusTotal, Censys), and sanctions databases (EU, OFAC, UN). The conclusion pipeline synthesizes these signals, preserves contradictions (e.g., when one source lists an entity as active but another shows dissolution), and produces a confidence-scored conclusion.

Quality Gate Verdicts

Every quality gate produces a conclusion: the code either meets the quality standard or it does not. These conclusions are derived from multiple signals (compilation warnings, Credo violations, Dialyzer errors, test coverage, performance benchmarks). The quality gate conclusion must pass the Trinity Gate, ensuring that the verdict is structurally consistent (no contradictory metrics), logically consistent (the reasoning from metrics to verdict follows valid inference), and formally necessary (the thresholds are properly calibrated).

Agent Decision Making

The 530 autonomous agents make thousands of decisions during platform operation. Each decision is a conclusion derived through the agent's reasoning framework. Strategic agents (L3) produce conclusions about resource allocation, escalation priorities, and operational direction. Tactical agents (L2) produce conclusions about specific technical actions. All agent conclusions are logged with full provenance for audit purposes.

Comparison with Alternatives

ApproachEvidence RequirementContradiction HandlingConfidence TrackingProvenancePrismatic Assessment
Boolean decisionsSingle conditionIgnoredNoneNoneInsufficient for complex domains
Probabilistic inferenceStatistical dataAveraged awayProbability scoresPartialGood foundation, needs enrichment
Bayesian reasoningPrior + evidenceUpdated priorsPosterior probabilityPartialStrong influence on platform design
NABLA Infinity conclusions2+ independent signalsPreserved explicitlyConfidence with decayFull chainPlatform standard
Expert opinionHuman judgmentSubjective resolutionInformalNoneSupplementary only

Best Practices

  1. Never discard contradictory evidence -- Contradictions are information. A conclusion that ignores contradictions is less trustworthy than one that explicitly acknowledges them. The contradiction preservation axiom encodes this principle.

  2. Track confidence decay -- Conclusions based on old evidence should have reduced confidence. Implement explicit time-based decay models using exponential or linear decay functions.

  3. Require signal plurality -- A conclusion based on a single signal is a guess. Require at least two independent signals for any operational conclusion. The signal plurality axiom is the foundation of sound conclusions.

  4. Make conclusions immutable -- Once derived, a conclusion should not be modified. Instead, derive a new conclusion with updated evidence and let the new one supersede the old. This preserves the audit trail.

  5. Log the full provenance chain -- Every conclusion should be traceable back through its evidence, signals, and reasoning framework to the original data sources.

  6. Distinguish between confidence levels -- Use explicit thresholds: 0.95 for critical decisions, 0.80 for standard operations, 0.60 for exploratory analysis.

  7. Accept "inconclusive" as valid -- A system that always produces a conclusion is a system that sometimes produces wrong conclusions. "Inconclusive" should be a first-class result.

  8. Validate through the Trinity Gate -- Every conclusion that drives action should pass structural, logical, and formal verification.

Common Pitfalls

  1. Premature conclusions -- Reaching a conclusion before sufficient evidence has been gathered. This violates the signal plurality axiom and produces fragile conclusions.

  2. Confirmation bias -- Weighting evidence that supports the expected conclusion more heavily than contradictory evidence. The contradiction preservation axiom guards against this. See Cherry Pick Evidence for the specific anti-pattern.

  3. Stale conclusions -- Continuing to rely on conclusions whose evidence has aged beyond relevance. Time decay modeling prevents this.

  4. False precision -- Reporting a confidence of 0.9734 when the underlying evidence only supports a distinction between "high" and "medium" confidence.

  5. Conclusion laundering -- Using a weak conclusion as evidence for a stronger conclusion. The provenance tracking system detects and flags this circular reasoning.

  6. Ignoring absence -- Failing to treat missing evidence as informative. The NABLA axiom "absence informative" explicitly addresses this pattern.

  7. Single-source conclusions -- Basing a conclusion on a single data source, no matter how authoritative. Even the best source can be wrong.

  8. Over-aggregation -- Combining evidence from incompatible domains or time periods without adjusting for the mismatch. Domain-aware aggregation is essential.

Use Cases

Due Diligence Assessments

When conducting due diligence on a business entity, the platform gathers evidence from dozens of sources, detects contradictions, scores confidence, and produces a structured conclusion about the entity's risk profile. The conclusion includes explicit references to all supporting and contradicting evidence.

Security Rating Derivation

Security ratings (A-F) are conclusions derived from attack surface analysis. The rating conclusion synthesizes vulnerability data, configuration analysis, certificate status, compliance posture, and historical incident data. Each rating includes a confidence score and the full evidence chain.

Automated Quality Verdicts

The pre-commit quality gate produces a pass/fail conclusion for every code change. This conclusion is derived from compilation analysis, static analysis (Credo, Dialyzer), test results, coverage metrics, and performance benchmarks.

Incident Root Cause Analysis

When a system incident occurs, the automated diagnostics pipeline gathers telemetry, logs, and metrics, then derives a conclusion about the root cause. The conclusion explicitly preserves multiple hypotheses when evidence is ambiguous.

See Also

  • NABLA Infinity -- The epistemic framework governing conclusion derivation
  • Cherry Pick Evidence -- Anti-pattern of selective evidence that corrupts conclusions
  • QEVE -- Verification engine that validates conclusion robustness
  • Conflicting Signals -- How the platform handles contradictory evidence
  • Evidence Over Opinion -- The principle that conclusions must be evidence-based
  • Confidence Threshold -- Minimum confidence levels for different contexts
  • Audit Trail -- How conclusion provenance is tracked
  • Glossary Index -- Complete listing of all platform concepts

Connect & Contribute

Created by Tomas Korcak (korczis) | Open Source under GHL