Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Core/Core.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<Compile Include="Aggregate.fs" />
<Compile Include="RobustStats.fs" />
<Compile Include="TemporalCoordinationDetection.fs" />
<Compile Include="Veridicality.fs" />
<Compile Include="Window.fs" />
<Compile Include="Advanced.fs" />
<Compile Include="Fusion.fs" />
Expand Down
121 changes: 121 additions & 0 deletions src/Core/Veridicality.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
namespace Zeta.Core

open System


/// **Veridicality — provenance-aware claim scoring (foundation).**
///
/// This module hosts the primitives for what the bootstrap-era
/// conversation called the "bullshit detector" and Amara's
/// subsequent ferries (7th-10th) formalized as veridicality
/// scoring. The name `Veridicality` (from Latin *veridicus*,
/// "truth-telling") names the scorable quantity: how true-to-
/// reality a claim looks given its provenance, falsifiability,
/// coherence, drift, and compression-gap signals. "Bullshit" is
/// the informal inverse (`bullshit = 1 - veridicality`).
///
/// **First graduation (this file):** `Provenance` + `Claim<'T>`
/// record types + `validateProvenance`. These are the input
/// shapes for every downstream scorer. The actual veridicality
/// scorer (`V(c) = σ(β₀ + β₁(1-P) + β₂(1-F) + β₃(1-K) + …)` from
/// Amara's 7th ferry, or `BS(c) = σ(w₁·C + w₂·(1-P) + …)` from
/// the 10th ferry) is a separate graduation that composes over
/// these types.
///
/// **Attribution.**
/// * **Concept** — the bullshit-detector / provenance-aware-
/// scoring framing is Aaron's design, present in the bootstrap
/// conversation (`docs/amara-full-conversation/**`) before
/// Amara's ferries formalized it. Aaron 2026-04-24 Otto-112:
/// *"bullshit, it was in our conversation history too, not
/// just her ferry."*
/// * **Formalization** — Amara (7th/8th/9th/10th ferries):
/// veridicality formula, semantic-canonicalization "rainbow
/// table", oracle-rule specification, 7-feature composite.
/// * **Implementation** — Otto, under the Otto-105 graduation
/// cadence. Fifth graduation.
Comment on lines +27 to +36
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This attribution block uses personal names in a code doc comment. Repo convention is to avoid name attribution in code/docs/skills (see docs/AGENT-BEST-PRACTICES.md:284-290) and use role-based references instead ("human maintainer", "architect", etc.), keeping personal-name history in the designated history/memory locations. Please rewrite this section to comply with that convention.

Suggested change
/// scoring framing is Aaron's design, present in the bootstrap
/// conversation (`docs/amara-full-conversation/**`) before
/// Amara's ferries formalized it. Aaron 2026-04-24 Otto-112:
/// *"bullshit, it was in our conversation history too, not
/// just her ferry."*
/// * **Formalization** — Amara (7th/8th/9th/10th ferries):
/// veridicality formula, semantic-canonicalization "rainbow
/// table", oracle-rule specification, 7-feature composite.
/// * **Implementation** — Otto, under the Otto-105 graduation
/// cadence. Fifth graduation.
/// scoring framing is present in the bootstrap conversation
/// (`docs/amara-full-conversation/**`) before the subsequent
/// formalization ferries. The core idea predates the later
/// ferry-specific formulations.
/// * **Formalization** — subsequent ferries (7th/8th/9th/10th):
/// veridicality formula, semantic-canonicalization "rainbow
/// table", oracle-rule specification, 7-feature composite.
/// * **Implementation** — current implementation under the
/// graduation cadence. Fifth graduation.

Copilot uses AI. Check for mistakes.
///
/// Future graduations add (in priority order): `antiConsensusGate`
/// (requires `Provenance`); `canonicalizeClaim` (semantic
/// canonicalization → `CanonicalClaimKey`); `scoreVeridicality`
/// (the composite function).
[<AutoOpen>]
module Veridicality =

/// **Provenance** — the evidence trail behind a claim.
///
/// Every accepted claim MUST carry provenance with at minimum
/// `SourceId`, `RootAuthority`, `ArtifactHash`, and
/// `SignatureOk = true`. Empty-string `SourceId` or
/// `RootAuthority`, empty `ArtifactHash`, or `SignatureOk =
/// false` all indicate unverified or missing evidence.
///
/// Fields match Amara's 9th/10th ferry specification verbatim
/// (`docs/aurora/2026-04-23-amara-aurora-deep-research-
/// report-10th-ferry.md` §ADR-style spec for oracle rules and
/// implementation).
Comment on lines +54 to +56
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc comment cites docs/aurora/2026-04-23-amara-aurora-deep-research-report-10th-ferry.md, but that file doesn't exist under docs/aurora/ in this repo. Please update the reference to an existing absorb doc (or add the missing document) so readers can actually follow the provenance/spec link.

Suggested change
/// (`docs/aurora/2026-04-23-amara-aurora-deep-research-
/// report-10th-ferry.md` §ADR-style spec for oracle rules and
/// implementation).
/// in the ADR-style oracle-rules and implementation spec for
/// the 10th ferry.

Copilot uses AI. Check for mistakes.
///
/// `RootAuthority` vs `SourceId`: a single source may speak
/// under different authorities (a mailing list, an academic
/// publication, a company blog), and consumers of the claim
/// need both to distinguish "two sources, same root
/// authority" (anti-consensus-gate failure) from "two sources,
/// two independent roots" (anti-consensus-gate pass).
type Provenance =
{ SourceId: string
RootAuthority: string
ArtifactHash: string
BuilderId: string option
TimestampUtc: DateTimeOffset
EvidenceClass: string
SignatureOk: bool }

/// **Claim<'T>** — a piece of information with a payload,
/// a weight (matches the Z-set weight model for retraction-
/// native semantics), and its provenance.
///
/// `Id` is the claim's identity in the claim ledger. `Payload`
/// is the domain-specific information being claimed (a string,
/// a record, a numeric oracle reading — whatever the caller
/// has). `Weight` is a signed multiplicity: positive for
/// assertion, negative for retraction. Total net-zero after
/// assertion+retraction matches Z-set semantics.
type Claim<'T> =
{ Id: string
Payload: 'T
Weight: int64
Prov: Provenance }

/// **Validate provenance** — returns `true` when the
/// provenance has the minimum fields populated + a valid
/// signature. Returns `false` on empty-string `SourceId`,
/// `RootAuthority`, or `ArtifactHash`, or when `SignatureOk
/// = false`.
///
/// Matches Amara's 10th-ferry snippet:
///
/// ```
/// let validateProvenance c =
/// c.Prov.SourceId <> ""
/// && c.Prov.RootAuthority <> ""
/// && c.Prov.ArtifactHash <> ""
/// && c.Prov.SignatureOk
Comment on lines +95 to +102
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The snippet shown as "Matches Amara's 10th-ferry snippet" uses c.Prov.*, but validateProvenance here accepts a Provenance and accesses p.*. As written, the snippet no longer matches the function signature and can mislead readers; either update the snippet to match Provenance or move it under validateClaim (which actually takes a claim).

Suggested change
/// Matches Amara's 10th-ferry snippet:
///
/// ```
/// let validateProvenance c =
/// c.Prov.SourceId <> ""
/// && c.Prov.RootAuthority <> ""
/// && c.Prov.ArtifactHash <> ""
/// && c.Prov.SignatureOk
/// Matches Amara's 10th-ferry snippet after projecting to
/// bare provenance:
///
/// ```
/// let validateProvenance p =
/// p.SourceId <> ""
/// && p.RootAuthority <> ""
/// && p.ArtifactHash <> ""
/// && p.SignatureOk

Copilot uses AI. Check for mistakes.
/// ```
///
/// `BuilderId = None`, `TimestampUtc`, and `EvidenceClass`
/// are NOT checked by this predicate — they are evidence
/// quality signals that downstream scorers consume, not
/// hard validity gates. An unsigned artifact with known
/// source/root/hash is still rejected, because cryptographic
/// attestation is the minimum trust bar.
let validateProvenance (p: Provenance) : bool =
p.SourceId <> ""
&& p.RootAuthority <> ""
&& p.ArtifactHash <> ""
&& p.SignatureOk
Comment on lines +111 to +115
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validateProvenance treats null strings as valid because null <> "" evaluates to true in F#. That means SourceId = null / RootAuthority = null / ArtifactHash = null would incorrectly pass the minimum-validity gate. Consider using String.IsNullOrWhiteSpace (or at least String.IsNullOrEmpty) for these fields so both null and whitespace-only values are rejected.

Copilot uses AI. Check for mistakes.

/// Convenience alias for `validateProvenance` on a full
/// `Claim<'T>`, matching Amara's 10th-ferry snippet which
/// takes a claim rather than bare provenance.
let validateClaim (c: Claim<'T>) : bool =
validateProvenance c.Prov
96 changes: 96 additions & 0 deletions tests/Tests.FSharp/Algebra/Veridicality.Tests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
module Zeta.Tests.Algebra.VeridicalityTests

open System
open FsUnit.Xunit
open global.Xunit
open Zeta.Core


// ─── Provenance / validateProvenance ─────────

let private goodProv () : Veridicality.Provenance =
{ SourceId = "repo/amara/ferry-10"
RootAuthority = "amara@aurora"
ArtifactHash = "blake3:3f8e..."
BuilderId = Some "otto-115"
TimestampUtc = DateTimeOffset.UtcNow
EvidenceClass = "research"
SignatureOk = true }

[<Fact>]
let ``validateProvenance accepts a fully-populated signed provenance`` () =
Veridicality.validateProvenance (goodProv ()) |> should equal true

[<Fact>]
let ``validateProvenance rejects empty SourceId`` () =
let p = { goodProv () with SourceId = "" }
Veridicality.validateProvenance p |> should equal false

[<Fact>]
let ``validateProvenance rejects empty RootAuthority`` () =
let p = { goodProv () with RootAuthority = "" }
Veridicality.validateProvenance p |> should equal false

[<Fact>]
let ``validateProvenance rejects empty ArtifactHash`` () =
let p = { goodProv () with ArtifactHash = "" }
Veridicality.validateProvenance p |> should equal false

[<Fact>]
let ``validateProvenance rejects SignatureOk = false`` () =
let p = { goodProv () with SignatureOk = false }
Veridicality.validateProvenance p |> should equal false

[<Fact>]
let ``validateProvenance accepts BuilderId = None (not a hard gate)`` () =
// BuilderId is a quality signal, not a validity gate. An
// artifact can be legitimately signed without a builder
// identity (e.g., a human-authored doc signed with a personal
// key).
let p = { goodProv () with BuilderId = None }
Veridicality.validateProvenance p |> should equal true


// ─── Claim<'T> / validateClaim ─────────

[<Fact>]
let ``validateClaim wraps validateProvenance on the claim's provenance`` () =
let c =
{ Id = "claim-001"
Payload = 42
Weight = 1L
Prov = goodProv () }
Veridicality.validateClaim c |> should equal true

[<Fact>]
let ``validateClaim is polymorphic over the Payload type`` () =
// Same validation whether payload is int, string, record, etc.
// The provenance discipline doesn't depend on payload shape.
let c =
{ Id = "claim-002"
Payload = "Zeta is a retraction-native substrate."
Weight = 1L
Prov = goodProv () }
Veridicality.validateClaim c |> should equal true

[<Fact>]
let ``validateClaim rejects a claim with invalid provenance`` () =
let c =
{ Id = "claim-003"
Payload = ()
Weight = 1L
Prov = { goodProv () with SignatureOk = false } }
Veridicality.validateClaim c |> should equal false

[<Fact>]
let ``Claim supports negative Weight for retraction semantics`` () =
// Z-set style: negative weight = retraction. validateClaim
// does NOT inspect Weight; a retraction claim is valid if its
// provenance is valid. Retraction semantics are at the ledger
// level, not the claim-validity level.
let c =
{ Id = "claim-004"
Payload = 7
Weight = -1L
Prov = goodProv () }
Veridicality.validateClaim c |> should equal true
1 change: 1 addition & 0 deletions tests/Tests.FSharp/Tests.FSharp.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<Compile Include="Algebra/IndexedZSet.Tests.fs" />
<Compile Include="Algebra/RobustStats.Tests.fs" />
<Compile Include="Algebra/TemporalCoordinationDetection.Tests.fs" />
<Compile Include="Algebra/Veridicality.Tests.fs" />

<!-- Circuit/ -->
<Compile Include="Circuit/Circuit.Tests.fs" />
Expand Down
Loading