slop

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package slop analyzes prose for repetitive, canned, or statistically overused AI-associated writing tendencies. It returns structured evidence (rates, calibrated components, grouped findings with locations) for an editorial agent to judge; it is not an AI-authorship detector and does not generate replacement prose.

The composite score and the word, trigram, and contrast rates implement the pinned upstream EQ-Bench slop-score method in stage-1/fallback mode (POS-tagged stage 2 disabled), as described in docs/methodology.md.

Index

Constants

View Source
const (
	SchemaVersion = 1
	Version       = "1.1.0"
	AnalyzerName  = "sst"

	// CompatibilityStage1Fallback names the compatibility basis precisely:
	// the composite score, list hit rates, and contrast detection match the
	// pinned upstream implementation with its POS-tagged second stage
	// disabled (the upstream website's documented fallback when the
	// wink-pos-tagger CDN is unavailable).
	CompatibilityStage1Fallback = "eqbench-stage1-fallback"
)

Schema and analyzer identity for versioned machine-readable output.

Variables

This section is empty.

Functions

This section is empty.

Types

type Analyzer

type Analyzer struct {
	// contains filtered or unexported fields
}

Analyzer holds loaded data and detectors. Construct once and reuse.

func NewAnalyzer

func NewAnalyzer() (*Analyzer, error)

NewAnalyzer loads the embedded data and compiles the contrast patterns.

func (*Analyzer) Analyze

func (a *Analyzer) Analyze(name, text string, opts Options) (Document, error)

Analyze examines one document and returns its structured result.

func (*Analyzer) AnalyzeAll

func (a *Analyzer) AnalyzeAll(inputs []Input, opts Options) (Report, error)

AnalyzeAll analyzes each input separately and adds a corpus aggregate when more than one document is present. Inputs are never concatenated.

func (*Analyzer) Compare

func (a *Analyzer) Compare(before, after Document, maxFindings int) Comparison

Compare builds a Comparison from two analyzed documents sharing the same analyzer method metadata.

type AnalyzerInfo

type AnalyzerInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

AnalyzerInfo identifies the program producing the report.

type Comparison

type Comparison struct {
	SchemaVersion int              `json:"schema_version"`
	Analyzer      AnalyzerInfo     `json:"analyzer"`
	Method        MethodInfo       `json:"method"`
	Before        Document         `json:"before"`
	After         Document         `json:"after"`
	Deltas        ComparisonDeltas `json:"deltas"`
}

Comparison pairs two document analyses with per-signal and per-finding deltas. It never declares a winner: a lower score is not a better revision.

type ComparisonDeltas

type ComparisonDeltas struct {
	Score      *ScoreDelta      `json:"score,omitempty"`
	Components []ComponentDelta `json:"components,omitempty"`
	Findings   []FindingDelta   `json:"findings"`
	Truncation *DeltaTruncation `json:"truncation,omitempty"`
}

ComparisonDeltas summarizes what changed between two drafts.

type Component

type Component struct {
	Name       string    `json:"name"`
	Count      int       `json:"count"`
	Rate       float64   `json:"rate"`
	Unit       string    `json:"unit"`
	Range      NormRange `json:"calibration_range"`
	Normalized float64   `json:"normalized"`
	Weight     float64   `json:"weight"`
	Points     float64   `json:"points"`
}

Component is one scored signal with its calibration basis and contribution.

type ComponentDelta

type ComponentDelta struct {
	Name   string  `json:"name"`
	Unit   string  `json:"unit"`
	Before float64 `json:"before"`
	After  float64 `json:"after"`
	Delta  float64 `json:"delta"`
}

ComponentDelta is the raw-rate change of one scored component.

type CorpusInfo

type CorpusInfo struct {
	Documents      int             `json:"documents"`
	Score          *ScoreSummary   `json:"score,omitempty"`
	SharedFindings []SharedFinding `json:"shared_findings,omitempty"`
}

CorpusInfo aggregates per-document results without concatenating inputs.

type Data

type Data struct {
	Words    map[string]struct{}
	Bigrams  map[string]struct{}
	Trigrams map[string]struct{}

	WordRange     NormRange
	TrigramRange  NormRange
	ContrastRange NormRange

	Manifest Manifest
}

Data is the loaded, ready-to-match analysis data.

func LoadData

func LoadData() (*Data, error)

LoadData parses the embedded lists and calibration ranges.

type DataInfo

type DataInfo struct {
	ListsSHA256        map[string]string `json:"lists_sha256"`
	LeaderboardResults int               `json:"leaderboard_results"`
}

DataInfo summarizes the embedded data provenance.

type DeltaTruncation

type DeltaTruncation struct {
	Shown int `json:"shown"`
	Total int `json:"total"`
}

DeltaTruncation records omission from the findings delta list.

type Document

type Document struct {
	Name       string      `json:"name"`
	Stats      Stats       `json:"stats"`
	Warnings   []string    `json:"warnings,omitempty"`
	Score      *Score      `json:"score"`
	Signals    []Signal    `json:"signals,omitempty"`
	Findings   []Finding   `json:"findings"`
	Truncation *Truncation `json:"truncation,omitempty"`
}

Document is the analysis of one input text.

type Finding

type Finding struct {
	ID        string     `json:"id"`
	Kind      string     `json:"kind"` // "word", "trigram", "bigram", "contrast", "repeated_opening", "repeated_trigram"
	Text      string     `json:"text"`
	Count     int        `json:"count"`
	Reason    string     `json:"reason"`
	Scored    bool       `json:"scored"` // contributes to the composite score
	Locations []Location `json:"locations,omitempty"`
}

Finding is one grouped, ranked, locatable piece of evidence.

type FindingDelta

type FindingDelta struct {
	Kind   string `json:"kind"`
	Text   string `json:"text"`
	Before int    `json:"before"`
	After  int    `json:"after"`
	Status string `json:"status"` // "added", "removed", "increased", "decreased", "unchanged"
}

FindingDelta is the count change of one finding present in either draft.

type GroupTruncation

type GroupTruncation struct {
	Shown int `json:"shown"`
	Total int `json:"total"`
}

GroupTruncation counts shown vs. total findings in one kind group.

type Input

type Input struct {
	Name string
	Text string
}

Input is one named text to analyze.

type Location

type Location struct {
	Start   int    `json:"start"`
	End     int    `json:"end"`
	Excerpt string `json:"excerpt"`
}

Location is a byte-offset span into the original UTF-8 input: [Start, End).

type Manifest

type Manifest struct {
	Version int `json:"version"`
	Source  struct {
		Repo    string `json:"repo"`
		Commit  string `json:"commit"`
		License string `json:"license"`
	} `json:"source"`
	Files map[string]struct {
		SHA256  string `json:"sha256"`
		Bytes   int    `json:"bytes"`
		Entries int    `json:"entries,omitempty"`
	} `json:"files"`
	Leaderboard struct {
		SHA256                string `json:"sha256"`
		Bytes                 int    `json:"bytes"`
		Results               int    `json:"results"`
		IncludesHumanBaseline bool   `json:"includes_human_baseline"`
	} `json:"leaderboard"`
}

Manifest records data provenance from the pinned upstream source.

type MethodInfo

type MethodInfo struct {
	Compatibility     string       `json:"compatibility"`
	CompatibilityNote string       `json:"compatibility_note"`
	Upstream          UpstreamInfo `json:"upstream"`
	Data              DataInfo     `json:"data"`
	DomainNote        string       `json:"domain_note"`
}

MethodInfo describes the analysis basis, data provenance, and calibration caveats without burdening normal output.

type NormRange

type NormRange struct {
	Min float64 `json:"min"`
	Max float64 `json:"max"`
}

NormRange is a padded min/max calibration range from the leaderboard.

type Options

type Options struct {
	MaxFindings  int      // per finding group; default 10
	Full         bool     // disable finding limits
	ExcludeTerms []string // exact (case-insensitive) finding texts to omit
}

Options tunes report shape. Zero values give the bounded default report.

type Report

type Report struct {
	SchemaVersion int          `json:"schema_version"`
	Analyzer      AnalyzerInfo `json:"analyzer"`
	Method        MethodInfo   `json:"method"`
	Documents     []Document   `json:"documents"`
	Corpus        *CorpusInfo  `json:"corpus,omitempty"`
}

Report is the top-level analyzer result.

type Score

type Score struct {
	Value      float64     `json:"value"`
	Basis      string      `json:"basis"`
	Components []Component `json:"components"`
}

Score is the decomposed EQ-derived composite. It orients; it is not an authorship or quality verdict.

type ScoreDelta

type ScoreDelta struct {
	Basis  string  `json:"basis"`
	Before float64 `json:"before"`
	After  float64 `json:"after"`
	Delta  float64 `json:"delta"`
}

ScoreDelta is the composite change, labeled by basis.

type ScoreSummary

type ScoreSummary struct {
	Min    float64 `json:"min"`
	Median float64 `json:"median"`
	Mean   float64 `json:"mean"`
	Max    float64 `json:"max"`
}

ScoreSummary describes the distribution of document scores.

type SharedFinding

type SharedFinding struct {
	Kind      string `json:"kind"`
	Text      string `json:"text"`
	Documents int    `json:"documents"`
	Count     int    `json:"count"`
}

SharedFinding is a finding present in more than one document, which suggests an author- or model-level habit rather than topic vocabulary.

type Signal

type Signal struct {
	Name  string  `json:"name"`
	Kind  string  `json:"kind"` // "descriptive" or "diagnostic"
	Value float64 `json:"value"`
	Unit  string  `json:"unit,omitempty"`
	Note  string  `json:"note,omitempty"`
}

Signal is a retained non-scored measurement (descriptive or diagnostic).

type Stats

type Stats struct {
	Chars       int `json:"chars"`
	Words       int `json:"words"`
	Sentences   int `json:"sentences"`
	Paragraphs  int `json:"paragraphs"`
	UniqueWords int `json:"unique_words"`
}

Stats are input statistics relevant to result confidence.

type Truncation

type Truncation struct {
	MaxFindings int                        `json:"max_findings"`
	Groups      map[string]GroupTruncation `json:"groups,omitempty"`
}

Truncation records deterministic finding limits and what was omitted.

type UpstreamInfo

type UpstreamInfo struct {
	Repo   string `json:"repo"`
	Commit string `json:"commit"`
}

UpstreamInfo pins the source implementation used for compatibility.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL