Skip to content

Go Library

PRISM provides a Go library for programmatic access to all functionality.

Installation

go get github.com/grokify/prism

Quick Start

package main

import (
    "encoding/json"
    "fmt"
    "os"

    "github.com/grokify/prism"
)

func main() {
    // Load document
    data, _ := os.ReadFile("prism.json")
    var doc prism.PRISMDocument
    json.Unmarshal(data, &doc)

    // Validate
    if errs := doc.Validate(); errs.HasErrors() {
        fmt.Println("Validation errors:", errs)
        return
    }

    // Calculate score
    score := doc.CalculatePRISMScore(nil, nil)
    fmt.Printf("PRISM Score: %.1f%% (%s)\n",
        score.Overall*100, score.Interpretation)

    // Check individual metrics
    for _, m := range doc.Metrics {
        status := m.CalculateStatus()
        meetsSLO := m.MeetsSLO()
        fmt.Printf("  %s: %s (SLO met: %v)\n",
            m.Name, status, meetsSLO)
    }
}

Loading Documents

From File

data, err := os.ReadFile("prism.json")
if err != nil {
    log.Fatal(err)
}

var doc prism.PRISMDocument
if err := json.Unmarshal(data, &doc); err != nil {
    log.Fatal(err)
}

From HTTP

resp, err := http.Get("https://example.com/prism.json")
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

var doc prism.PRISMDocument
if err := json.NewDecoder(resp.Body).Decode(&doc); err != nil {
    log.Fatal(err)
}

Validation

Basic Validation

errs := doc.Validate()
if errs.HasErrors() {
    for _, e := range errs.Errors {
        fmt.Printf("Error at %s: %s\n", e.Field, e.Message)
    }
}

Validation Error Types

type ValidationError struct {
    Field   string // e.g., "metrics[0].domain"
    Message string // e.g., "invalid domain 'sec'"
}

type ValidationErrors struct {
    Errors []ValidationError
}

func (ve *ValidationErrors) HasErrors() bool
func (ve *ValidationErrors) Error() string

Score Calculation

Basic Score

score := doc.CalculatePRISMScore(nil, nil)

fmt.Printf("Overall: %.1f%%\n", score.Overall*100)
fmt.Printf("Base Score: %.1f%%\n", score.BaseScore*100)
fmt.Printf("Security: %.1f%%\n", score.SecurityScore*100)
fmt.Printf("Operations: %.1f%%\n", score.OperationsScore*100)

Custom Weights

config := &prism.ScoreConfig{
    MaturityWeight:    0.3,
    PerformanceWeight: 0.7,
    StageWeights: map[string]float64{
        prism.StageDesign:   0.10,
        prism.StageBuild:    0.20,
        prism.StageTest:     0.15,
        prism.StageRuntime:  0.35,
        prism.StageResponse: 0.20,
    },
    DomainWeights: map[string]float64{
        prism.DomainSecurity:   0.6,
        prism.DomainOperations: 0.4,
    },
}

score := doc.CalculatePRISMScore(config, nil)

With Awareness Data

awareness := &prism.CustomerAwarenessData{
    Period: "2024-01",
    Distribution: []prism.AwarenessDistribution{
        {State: prism.AwarenessUnaware, Percent: 0.10},
        {State: prism.AwarenessAwareNotActing, Percent: 0.20},
        {State: prism.AwarenessAwareRemediating, Percent: 0.30},
        {State: prism.AwarenessAwareRemediated, Percent: 0.40},
    },
}

score := doc.CalculatePRISMScore(nil, awareness)
fmt.Printf("Awareness Score: %.2f\n", score.AwarenessScore)

Metric Operations

Calculate Status

for _, m := range doc.Metrics {
    status := m.CalculateStatus()
    fmt.Printf("%s: %s\n", m.Name, status)
}

Check SLO

for _, m := range doc.Metrics {
    if m.MeetsSLO() {
        fmt.Printf("✓ %s meets SLO\n", m.Name)
    } else {
        fmt.Printf("✗ %s does not meet SLO\n", m.Name)
    }
}

Progress to Target

for _, m := range doc.Metrics {
    progress := m.ProgressToTarget()
    fmt.Printf("%s: %.1f%% of target\n", m.Name, progress*100)
}

Maturity Model

Create Model

// Full model (all domains)
model := prism.NewMaturityModel()

// Domain-filtered model
securityOnly := prism.NewMaturityModelForDomains(
    []string{prism.DomainSecurity},
)

Access Cells

cell := model.GetCell(prism.DomainSecurity, prism.StageBuild)
if cell != nil {
    fmt.Printf("Level: %d\n", cell.CurrentLevel)
    fmt.Printf("Score: %.1f%%\n", cell.CalculateMaturityScore()*100)
}

Constants

Available Constants

// Domains
prism.DomainSecurity   // "security"
prism.DomainOperations // "operations"
prism.AllDomains()     // []string

// Stages
prism.StageDesign   // "design"
prism.StageBuild    // "build"
prism.StageTest     // "test"
prism.StageRuntime  // "runtime"
prism.StageResponse // "response"
prism.AllStages()   // []string

// Categories
prism.CategoryPrevention  // "prevention"
prism.CategoryDetection   // "detection"
prism.CategoryResponse    // "response"
prism.CategoryReliability // "reliability"
prism.CategoryEfficiency  // "efficiency"
prism.CategoryQuality     // "quality"
prism.AllCategories()     // []string

// Metric Types
prism.MetricTypeCoverage     // "coverage"
prism.MetricTypeRate         // "rate"
prism.MetricTypeLatency      // "latency"
prism.MetricTypeRatio        // "ratio"
prism.MetricTypeCount        // "count"
prism.MetricTypeDistribution // "distribution"
prism.MetricTypeScore        // "score"

// SLO Operators
prism.SLOOperatorGTE // "gte"
prism.SLOOperatorLTE // "lte"
prism.SLOOperatorGT  // "gt"
prism.SLOOperatorLT  // "lt"
prism.SLOOperatorEQ  // "eq"

Validation Functions

if prism.IsValidDomain("security") {
    // valid
}

if prism.IsValidStage("build") {
    // valid
}

if prism.IsValidCategory("prevention") {
    // valid
}

Analysis Package

The analysis package provides document analysis and gap identification.

Analyze Document

import "github.com/grokify/prism/analysis"

result := analysis.Analyze(doc)

// Summary statistics
fmt.Printf("Goals: %d\n", result.Summary.TotalGoals)
fmt.Printf("SLO Compliance: %.1f%%\n", result.Summary.SLOCompliance)
fmt.Printf("Avg Maturity Gap: %.1f\n", result.Summary.AvgMaturityGap)

// Goal analysis
for _, ga := range result.Goals {
    fmt.Printf("%s: M%d → M%d (gap: %d)\n",
        ga.GoalName, ga.CurrentLevel, ga.TargetLevel, ga.Gap)
}

// Identified gaps
for _, gap := range result.Gaps {
    fmt.Printf("[%s] %s: %s\n", gap.Severity, gap.Type, gap.Description)
}

Calculate Roadmap Progress

progress := analysis.CalculateRoadmapProgress(doc)

fmt.Printf("Overall: %.1f%%\n", progress.OverallCompletion)

for _, pp := range progress.PhaseProgress {
    fmt.Printf("%s: %.1f%% complete\n", pp.PhaseName, pp.Completion)
}

for _, gp := range progress.GoalProgress {
    fmt.Printf("%s: M%d → M%d\n", gp.GoalName, gp.CurrentLevel, gp.TargetLevel)
}

Filter Gaps

// Filter by type
maturityGaps := analysis.FilterGapsByType(result.Gaps, analysis.GapTypeMaturity)
sloGaps := analysis.FilterGapsByType(result.Gaps, analysis.GapTypeSLO)

// Filter by severity
highPriority := analysis.FilterGapsBySeverity(result.Gaps, analysis.SeverityHigh)

// Count by severity
counts := analysis.CountGapsBySeverity(result.Gaps)
fmt.Printf("High: %d, Medium: %d, Low: %d\n",
    counts[analysis.SeverityHigh],
    counts[analysis.SeverityMedium],
    counts[analysis.SeverityLow])

Export Package

The export package converts PRISM documents to OKR and V2MOM formats.

Export to OKR

import "github.com/grokify/prism/export"

okrDoc := export.ConvertToOKR(doc)

// Access objectives
for _, obj := range okrDoc.Objectives {
    fmt.Printf("Objective: %s\n", obj.Title)
    for _, kr := range obj.KeyResults {
        fmt.Printf("  KR: %s (%.1f%%)\n", kr.Title, kr.Score*100)
    }
}

// Serialize to JSON
data, _ := json.MarshalIndent(okrDoc, "", "  ")
fmt.Println(string(data))

Export to V2MOM

v2momDoc := export.ConvertToV2MOM(doc)

fmt.Printf("Vision: %s\n", v2momDoc.Vision)
fmt.Printf("Values: %v\n", v2momDoc.Values)

for _, method := range v2momDoc.Methods {
    fmt.Printf("Method: %s\n", method.Name)
    for _, measure := range method.Measures {
        fmt.Printf("  Measure: %s = %.2f (target: %s)\n",
            measure.Name, measure.Current, measure.Target)
    }
}

Convert Individual Elements

// Convert single goal to objective
objective := export.GoalToObjective(goal, doc)

// Convert SLO to key result
keyResult := export.SLOToKeyResult(metric, maturityLevel, doc)

// Convert goal to V2MOM method
method := export.GoalToMethod(goal, doc, 1) // priority 1

Output Package

The output package provides formatting utilities for CLI and reports.

Helper Functions

import "github.com/grokify/prism/output"

// Truncate strings for display
name := output.TruncateString("Very Long Service Name", 15) // "Very Long Se..."

// Format SLO operators
symbol := output.OperatorSymbol("gte") // ">="
symbol = output.OperatorSymbol("lte")  // "<="

// Safe percentage calculation
pct := output.SafePercent(3, 4) // 75.0

// Goal status based on maturity
status := output.GoalStatus(3, 5) // "Behind"
status = output.GoalStatus(5, 5)  // "Achieved"

// Maturity level names
name := output.MaturityLevelName(1) // "Reactive"
name = output.MaturityLevelName(5)  // "Optimizing"

// Status symbols
sym := output.StatusSymbol("completed") // "[x]"
sym = output.StatusSymbol("in_progress") // "[~]"
sym = output.StatusSymbol("blocked")     // "[!]"

Formatter

formatter := output.NewFormatter("text")

// Write table
formatter.WriteTable(&output.TableData{
    Title:   "Goals",
    Headers: []string{"NAME", "CURRENT", "TARGET"},
    Rows: [][]string{
        {"Reliability", "M3", "M5"},
        {"Velocity", "M3", "M4"},
    },
    Summary: "Total: 2 goals",
})

// Write JSON
formatter.WriteJSON(data)

JSON Schema

Access Embedded Schema

import "github.com/grokify/prism/schema"

schemaJSON := schema.PRISMSchemaJSON()
fmt.Println(string(schemaJSON))

Error Handling

data, err := os.ReadFile("prism.json")
if err != nil {
    log.Fatalf("Failed to read file: %v", err)
}

var doc prism.PRISMDocument
if err := json.Unmarshal(data, &doc); err != nil {
    log.Fatalf("Failed to parse JSON: %v", err)
}

if errs := doc.Validate(); errs.HasErrors() {
    log.Fatalf("Validation failed: %v", errs)
}

score := doc.CalculatePRISMScore(nil, nil)
// Use score...