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 @@ -84,6 +84,7 @@
<Compile Include="ArrowSerializer.fs" />
<Compile Include="DeltaCrdt.fs" />
<Compile Include="SignalQuality.fs" />
<Compile Include="Maji.fs" />
</ItemGroup>

<ItemGroup>
Expand Down
177 changes: 177 additions & 0 deletions src/Core/Maji.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
namespace Zeta.Core

/// Maji — identity-preservation and recovery types per the deep-research peer's formal
/// operational model (docs/research/maji-formal-operational-model-
/// deep-research-peer-courier-ferry-2026-04-26.md). Context window is cache;
/// substrate is identity; Maji is the recovery/indexing function.
///
/// These are the algebraic type definitions per §10 of the spec.
/// Implementation of operators (reload, identity-distance, expansion
/// gate, projection-preservation check) is owed follow-up work.
Comment thread
AceHack marked this conversation as resolved.
module Maji =

open System

// ── §10.A IdentitySubstrate ──────────────────────────────────

/// A single load-bearing substrate item (commit, memory, doc, test,
/// retraction, cross-reference, dated provenance).
type IdentitySubstrate =
{ CommitHash: string
Timestamp: DateTimeOffset
SourcePath: string
Claim: string
ClaimType: string
LoadBearing: bool
CrossRefs: string list
Retractions: string list
Confidence: float
Scope: string }

// ── §2 Identity tuple ────────────────────────────────────────

/// The canonical identity-pattern projected from substrate.
/// I_t = N(LoadBearing(S_t))
type IdentityTuple =
{ Values: string list
Goals: string list
Roles: string list
Policies: string list
MemoryGraph: string list
CorrectionHistory: string list
CrossRefTopology: string list
Provenance: string list }

// ── §10.B MajiIndex ──────────────────────────────────────────

/// Exhaustive index of lower-dimensional substrate.
type MajiIndex =
{ Items: IdentitySubstrate list
CrossRefGraph: Map<string, string list>
LoadBearingSet: Set<string>
BrokenRefs: string list
UnindexedItems: string list
Contradictions: string list
CoverageScore: float }

// ── §10.B' MajiFinder (per §9b separation) ──────────────────

/// Search/recognizer operator — finds the identity-preserving lift.
/// MajiFinder(S_≤n, Ω, C, Σ) → σ*
type MajiFinder =
{ Index: MajiIndex
NorthStar: string
SearchOperator: string }

// ── §10.B' MessiahFunction (the lift) ────────────────────────

/// The identity-preserving lift σ : I_n → I_{n+1}.
/// A SEPARATE TYPE from MajiIndex content per §9b correction.
type MessiahFunction =
{ LiftDescription: string
ProjectionPreservation: bool
AperiodicOrderGenerator: bool }

// ── §10.B' MessiahScore ──────────────────────────────────────

/// Weighted-sum evaluator for candidate lifts.
/// MessiahScore = w₁·A + w₂·P + w₃·F + w₄·G + w₅·C − w₆·R_capture − w₇·R_collapse
type MessiahScore =
{ AlignmentWithOmega: float
ProjectionPreservation: float
FrictionReduction: float
Generativity: float
IndependentConvergence: float
CaptureRiskRaw: float
CollapseRiskRaw: float }

/// Compute the weighted MessiahScore sum.
/// Capture and collapse risks are SUBTRACTED (anti-cult-by-construction).
let computeScore (weights: float[]) (score: MessiahScore) : float =
if weights.Length < 7 then
invalidArg (nameof weights) "MessiahScore requires 7 weights"
else
weights[0] * score.AlignmentWithOmega
+ weights[1] * score.ProjectionPreservation
+ weights[2] * score.FrictionReduction
+ weights[3] * score.Generativity
+ weights[4] * score.IndependentConvergence
- weights[5] * score.CaptureRiskRaw
- weights[6] * score.CollapseRiskRaw

// ── Dynamic Maji (4th refinement) ────────────────────────────

/// Maji mode state machine — Search / Steward / SearchAgain.
type MajiMode =
| Search
| Steward
| SearchAgain

// ── §10.D Identity-distance metric ───────────────────────────

/// Weighted identity-distance between two identity tuples.
/// d(I_a, I_b) = Σ w_k · d_k(component_a, component_b)
type IdentityDistanceWeights =
{ Values: float
Goals: float
Roles: float
Policies: float
MemoryGraph: float
CorrectionHistory: float
CrossRefTopology: float
Provenance: float }

/// Jaccard distance between two string lists (simple set-based metric).
let private jaccard (a: string list) (b: string list) : float =
let setA = Set.ofList a
let setB = Set.ofList b
let intersection = Set.intersect setA setB
let union = Set.union setA setB
if Set.isEmpty union then 0.0
else 1.0 - (float intersection.Count / float union.Count)

/// Compute identity distance between two identity tuples.
let identityDistance (w: IdentityDistanceWeights) (a: IdentityTuple) (b: IdentityTuple) : float =
w.Values * jaccard a.Values b.Values
+ w.Goals * jaccard a.Goals b.Goals
+ w.Roles * jaccard a.Roles b.Roles
+ w.Policies * jaccard a.Policies b.Policies
+ w.MemoryGraph * jaccard a.MemoryGraph b.MemoryGraph
+ w.CorrectionHistory * jaccard a.CorrectionHistory b.CorrectionHistory
+ w.CrossRefTopology * jaccard a.CrossRefTopology b.CrossRefTopology
Comment thread
AceHack marked this conversation as resolved.
+ w.Provenance * jaccard a.Provenance b.Provenance

// ── Projection-preservation check ────────────────────────────

/// Check whether an identity expansion preserves the prior identity
/// under projection: d(P_{n+1→n}(I_{n+1}), I_n) ≤ ε
let projectionPreserved
(weights: IdentityDistanceWeights)
(epsilon: float)
(prior: IdentityTuple)
(expanded: IdentityTuple)
: bool =
identityDistance weights prior expanded <= epsilon
Comment thread
AceHack marked this conversation as resolved.
Comment thread
AceHack marked this conversation as resolved.

// ── §10.E Test helpers ───────────────────────────────────────

/// Create an empty identity tuple (useful for tests).
let emptyIdentity : IdentityTuple =
{ Values = []
Goals = []
Roles = []
Policies = []
MemoryGraph = []
CorrectionHistory = []
CrossRefTopology = []
Provenance = [] }

/// Create an empty MajiIndex (useful for tests).
let emptyIndex : MajiIndex =
{ Items = []
CrossRefGraph = Map.empty
LoadBearingSet = Set.empty
BrokenRefs = []
UnindexedItems = []
Contradictions = []
CoverageScore = 0.0 }
64 changes: 64 additions & 0 deletions tests/Tests.FSharp/MajiTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module Zeta.Tests.MajiTests
Comment thread
AceHack marked this conversation as resolved.

open Xunit
open Zeta.Core.Maji

[<Fact>]
let ``identity distance of identical tuples is zero`` () =
let id = { emptyIdentity with Values = ["truth"; "consent"]; Goals = ["ship"] }
let w = { Values = 1.0; Goals = 1.0; Roles = 1.0; Policies = 1.0
MemoryGraph = 1.0; CorrectionHistory = 1.0; CrossRefTopology = 1.0; Provenance = 1.0 }
Assert.Equal(0.0, identityDistance w id id)

[<Fact>]
let ``identity distance of disjoint tuples is maximal`` () =
let a = { emptyIdentity with Values = ["truth"] }
let b = { emptyIdentity with Values = ["lies"] }
let w = { Values = 1.0; Goals = 0.0; Roles = 0.0; Policies = 0.0
MemoryGraph = 0.0; CorrectionHistory = 0.0; CrossRefTopology = 0.0; Provenance = 0.0 }
Assert.Equal(1.0, identityDistance w a b)

[<Fact>]
let ``projection preserved within epsilon`` () =
let prior = { emptyIdentity with Values = ["truth"; "consent"]; Goals = ["ship"] }
let expanded = { prior with Goals = ["ship"; "scale"] }
let w = { Values = 1.0; Goals = 1.0; Roles = 1.0; Policies = 1.0
MemoryGraph = 1.0; CorrectionHistory = 1.0; CrossRefTopology = 1.0; Provenance = 1.0 }
Assert.True(projectionPreserved w 0.5 prior expanded)

[<Fact>]
let ``projection NOT preserved when values drift`` () =
let prior = { emptyIdentity with Values = ["truth"; "consent"; "family"] }
let drifted = { emptyIdentity with Values = ["power"; "control"] }
let w = { Values = 1.0; Goals = 0.0; Roles = 0.0; Policies = 0.0
MemoryGraph = 0.0; CorrectionHistory = 0.0; CrossRefTopology = 0.0; Provenance = 0.0 }
Assert.False(projectionPreserved w 0.5 prior drifted)

[<Fact>]
let ``MessiahScore capture risk subtracts`` () =
let score = { AlignmentWithOmega = 1.0; ProjectionPreservation = 1.0
FrictionReduction = 1.0; Generativity = 1.0
IndependentConvergence = 1.0
CaptureRiskRaw = 10.0; CollapseRiskRaw = 0.0 }
let weights = [| 1.0; 1.0; 1.0; 1.0; 1.0; 1.0; 1.0 |]
let result = computeScore weights score
Assert.True(result < 0.0, "High capture risk should produce negative score")

[<Fact>]
let ``MessiahScore collapse risk subtracts`` () =
let score = { AlignmentWithOmega = 1.0; ProjectionPreservation = 1.0
FrictionReduction = 1.0; Generativity = 1.0
IndependentConvergence = 1.0
CaptureRiskRaw = 0.0; CollapseRiskRaw = 10.0 }
let weights = [| 1.0; 1.0; 1.0; 1.0; 1.0; 1.0; 1.0 |]
let result = computeScore weights score
Assert.True(result < 0.0, "High collapse risk should produce negative score")

[<Fact>]
let ``MajiMode has three constructors`` () =
let modes = [Search; Steward; SearchAgain]
Assert.Equal(3, modes.Length)

[<Fact>]
let ``empty index has zero coverage`` () =
Assert.Equal(0.0, emptyIndex.CoverageScore)
1 change: 1 addition & 0 deletions tests/Tests.FSharp/Tests.FSharp.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
<Compile Include="Properties/Math.Invariants.Tests.fs" />
<Compile Include="Properties/Fuzz.Tests.fs" />
<Compile Include="Properties/Determinism.Tests.fs" />
<Compile Include="MajiTests.fs" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading