clustering

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultNeighborsLimit = 10
	MaxNeighborsLimit     = 1000
)

Neighbor defaults and hard limits.

Variables

This section is empty.

Functions

func NormalizeText

func NormalizeText(s string) string

NormalizeText lowercases and removes characters that are not letters, digits, or whitespace, then collapses whitespace.

func SourceRevision

func SourceRevision(candidates []Candidate) string

SourceRevision computes a stable hash from the candidate source state.

func SourceWindow

func SourceWindow(candidates []Candidate) (time.Time, time.Time)

SourceWindow returns the minimum and maximum UpdatedAt of the candidates.

func StableID

func StableID(ref MemberRef) string

StableID returns the deterministic stable cluster id derived from a member identity. The same canonical member always produces the same stable id.

func Tokens

func Tokens(text string, stop bool) []string

Tokens returns sorted unique tokens from normalized text, filtering stop words and single-character tokens.

func TokensLimited

func TokensLimited(text string, stop bool, maxWords int) []string

TokensLimited returns sorted unique tokens with an optional hard limit on the number of input words processed. A limit of 0 means unlimited.

Types

type Candidate

type Candidate struct {
	ThreadID  int64
	Repo      domain.RepoRef
	Kind      string
	Number    int
	State     string
	Title     string
	Body      string
	Author    string
	Labels    []string
	CreatedAt time.Time
	UpdatedAt time.Time
}

Candidate is a thread considered for duplicate-candidate clustering.

func (Candidate) Ref

func (c Candidate) Ref() MemberRef

Ref returns the member identity for the candidate.

type Cluster

type Cluster struct {
	ID          int64
	StableID    string
	State       ClusterState
	Repo        domain.RepoRef
	Canonical   MemberRef
	Revision    string
	WindowStart time.Time
	WindowEnd   time.Time
	Members     []Member
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

Cluster is a group of duplicate-candidate threads.

func (Cluster) MemberRefs

func (c Cluster) MemberRefs() []MemberRef

MemberRefs returns the included member refs in deterministic order.

type ClusterReport

type ClusterReport struct {
	Repo     domain.RepoRef
	Clusters []Cluster
}

ClusterReport is a repository-level view of clusters.

type ClusterRun

type ClusterRun struct {
	ID             int64
	Repo           domain.RepoRef
	SourceRevision string
	WindowStart    time.Time
	WindowEnd      time.Time
	ParamsHash     string
	Status         string
	StartedAt      time.Time
	CompletedAt    *time.Time
	Stats          string
}

ClusterRun records one clustering computation for a repository and source window.

type ClusterState

type ClusterState string

ClusterState is the local lifecycle of a cluster.

const (
	ClusterOpen   ClusterState = "open"
	ClusterClosed ClusterState = "closed"
	// ClusterRetired preserves governance history for a cluster that is no
	// longer present in the latest computation.
	ClusterRetired ClusterState = "retired"
)

type Clusterer

type Clusterer struct {
	Config Config
}

Clusterer groups candidates into duplicate-candidate clusters.

func NewClusterer

func NewClusterer(cfg Config) *Clusterer

NewClusterer creates a clusterer with the supplied config, falling back to defaults for zero or out-of-range values.

func (*Clusterer) Cluster

func (cl *Clusterer) Cluster(candidates []Candidate, overrides []MembershipOverride) ([]Cluster, error)

Cluster groups candidates into duplicate-candidate clusters and applies membership overrides deterministically.

type Config

type Config struct {
	Threshold     float64
	MaxCandidates int
	MaxPairs      int
	MaxBodyTokens int
}

Config tunes clustering limits and thresholds.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns hard, deterministic defaults.

func (Config) ParamsHash

func (c Config) ParamsHash() string

ParamsHash returns a stable hash of the configuration used for attribution.

type Member

type Member struct {
	ThreadID int64
	Ref      MemberRef
	Title    string
	State    string
	Score    float64
	Reason   string
	Included bool
}

Member is one thread inside a cluster.

type MemberRef

type MemberRef struct {
	Owner  string
	Repo   string
	Kind   string
	Number int
}

MemberRef identifies a thread across repositories and kinds.

func ExtractRefs

func ExtractRefs(text string, defaultRepo domain.RepoRef) []MemberRef

ExtractRefs returns explicit GitHub issue/PR references found in text. Bare #123 references inherit the default repository and an empty kind.

func (MemberRef) Less

func (m MemberRef) Less(other MemberRef) bool

Less defines a deterministic total order for canonical selection.

func (MemberRef) String

func (m MemberRef) String() string

type MembershipOverride

type MembershipOverride struct {
	ID        int64
	ClusterID int64
	Ref       MemberRef
	Action    OverrideAction
	Reason    string
	CreatedAt time.Time
}

MembershipOverride records an explicit local include/exclude/canonical decision.

type Neighbor

type Neighbor struct {
	ThreadID int64
	Ref      MemberRef
	Title    string
	State    string
	Score    float64
	Reason   string
}

Neighbor is a scored thread near a query candidate.

func Neighbors

func Neighbors(query Candidate, candidates []Candidate, cfg Config, limit int) ([]Neighbor, error)

Neighbors scores every candidate against the query using deterministic local signals and returns the top limit results with stable tie ordering.

The query itself is excluded from the returned set. Scores and reasons are produced by the same Signals used for duplicate-candidate clustering.

type OverrideAction

type OverrideAction string

OverrideAction is a local governance instruction for a cluster member.

const (
	OverrideInclude      OverrideAction = "include"
	OverrideExclude      OverrideAction = "exclude"
	OverrideSetCanonical OverrideAction = "set_canonical"
)

type Signals

type Signals struct {
	ExplicitRef  bool
	TitleJaccard float64
	BodyJaccard  float64
	LabelJaccard float64
	SameAuthor   bool
}

Signals are the explainable components used to score duplicate candidacy. All fields are deterministic and derived from local thread content or metadata.

func (Signals) Reason

func (s Signals) Reason() string

Reason produces a human-readable explanation of the strongest signals.

func (Signals) Score

func (s Signals) Score() float64

Score returns a [0,1] combined score using fixed transparent weights.

type Store

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

Store persists and queries duplicate-candidate clusters in a SQLite corpus.

func NewStore

func NewStore(db *sql.DB) *Store

NewStore returns a cluster store backed by the supplied database. The database must already contain the clustering schema; Corpus.Open applies it.

func (*Store) AddOverride

func (s *Store) AddOverride(ctx context.Context, clusterID int64, ref MemberRef, action OverrideAction, reason string) error

AddOverride records a membership override and applies it to the cluster.

func (*Store) CloseCluster

func (s *Store) CloseCluster(ctx context.Context, clusterID int64) error

CloseCluster marks a cluster closed without touching GitHub.

func (*Store) Compute

func (s *Store) Compute(ctx context.Context, repo domain.RepoRef, candidates []Candidate, cfg Config) (*ClusterRun, []Cluster, error)

Compute clusters a caller-provided candidate set and persists it, matching existing clusters by stable id so that ids and overrides survive.

func (*Store) ComputeForRepo

func (s *Store) ComputeForRepo(ctx context.Context, repo domain.RepoRef, cfg Config) (*ClusterRun, []Cluster, error)

ComputeForRepo loads thread candidates for a repository, clusters them, applies stored overrides, and persists the result.

func (*Store) GetCluster

func (s *Store) GetCluster(ctx context.Context, stableID string) (*Cluster, error)

GetCluster returns a cluster by stable id with its members.

func (*Store) GetClusterForMember

func (s *Store) GetClusterForMember(ctx context.Context, ref MemberRef) (*Cluster, error)

GetClusterForMember returns the cluster that currently includes the given member reference, or nil if the member is not an included member of any cluster. The match is case-insensitive on owner and repo.

func (*Store) ListClusters

func (s *Store) ListClusters(ctx context.Context, repo domain.RepoRef, state ClusterState, limit int) ([]Cluster, error)

ListClusters returns clusters for a repository, optionally filtered by state.

func (*Store) ListOverrides

func (s *Store) ListOverrides(ctx context.Context, clusterID int64, limit int) ([]MembershipOverride, error)

ListOverrides returns membership overrides for a cluster.

func (*Store) MergeClusters

func (s *Store) MergeClusters(ctx context.Context, fromID, toID int64, reason string) error

MergeClusters moves all members from the source cluster into the target cluster and closes the source cluster. A merge override is recorded.

func (*Store) ReopenCluster

func (s *Store) ReopenCluster(ctx context.Context, clusterID int64) error

ReopenCluster reopens a closed cluster.

func (*Store) Report

func (s *Store) Report(ctx context.Context, repo domain.RepoRef, limit int) (*ClusterReport, error)

Report returns a concise cluster report for a repository.

func (*Store) SplitCluster

func (s *Store) SplitCluster(ctx context.Context, clusterID int64, ref MemberRef, reason string) error

SplitCluster removes a member from a cluster and creates a new singleton cluster for that member.

Jump to

Keyboard shortcuts

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