analysis

package
v0.0.8 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package analysis holds the pure-domain result model: findings, their severity and kind, and the immutable AnalysisReport every emitter renders from. It depends only on the standard library and the leaf identity package (for DocumentID); it imports nothing from application or infrastructure (ADR 0004).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AnalysisReport

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

AnalysisReport is the frozen result of the analysis stage: a deterministically sorted list of findings plus summary counts. It is immutable after construction — its fields are unexported and exposed through accessors.

The name intentionally matches the ubiquitous language fixed by ADR 0004 and architecture.md ("a frozen AnalysisReport"); the revive stutter warning is suppressed to keep that vocabulary stable across the codebase and docs.

func NewAnalysisReport

func NewAnalysisReport(findings []Finding) *AnalysisReport

NewAnalysisReport builds an immutable report from findings. The findings are copied and sorted deterministically by (Document, Line, Kind, Severity, ID), a total order, so every emitter renders byte-stable output regardless of discovery order. A nil or empty input yields an empty report.

func (*AnalysisReport) CountByKind

func (r *AnalysisReport) CountByKind(k FindingKind) int

CountByKind returns the number of findings of the given kind.

func (*AnalysisReport) CountBySeverity

func (r *AnalysisReport) CountBySeverity(s Severity) int

CountBySeverity returns the number of findings with the given severity.

func (*AnalysisReport) Findings

func (r *AnalysisReport) Findings() []Finding

Findings returns a copy of the sorted findings, preserving the report's immutability.

func (*AnalysisReport) Len

func (r *AnalysisReport) Len() int

Len returns the number of findings.

type Finding

type Finding struct {
	// ID is a stable identifier for the finding (e.g. a rule code).
	ID string
	// Kind classifies the finding.
	Kind FindingKind
	// Severity is the weight of the finding.
	Severity Severity
	// Location pins the finding to a document and line.
	Location Location
	// Message is the human-readable description.
	Message string
	// SuggestedFix is an optional remediation hint.
	SuggestedFix string
	// Details carries optional structured, machine-actionable context for a
	// finding — the data an agent needs to act WITHOUT re-deriving it from the
	// prose Message (e.g. the candidate documents for an ambiguous link, the
	// expected slug for a broken anchor, the raw target for a broken link). Keys
	// are stable, documented per kind (see the application finding builders and
	// the findings.json schema). nil when the finding has no structured detail.
	//
	// It is a pure-data map of stable string→string pairs; the domain attaches no
	// behavior to it. Emitters render it verbatim. Multi-valued detail (e.g. the
	// ambiguous candidate list) is encoded as a "\n"-joined string under a single
	// key so the type stays a flat, deterministic map.
	Details map[string]string
}

Finding is a single diagnostic produced by analysis.

type FindingKind

type FindingKind int

FindingKind classifies what a finding is about.

const (
	// BrokenLink is a reference whose target document does not exist.
	BrokenLink FindingKind = iota
	// BrokenAnchor is a reference whose target document exists but anchor does not.
	BrokenAnchor
	// Orphan is a document nothing links to.
	Orphan
	// Unreachable is a document not reachable from the root set.
	Unreachable
	// Ambiguous is a reference that matches multiple candidate documents.
	Ambiguous
	// KnowledgeGap is a detected documentation gap.
	KnowledgeGap
	// UnderLinked is a document with fewer inbound links than the discoverability
	// threshold (but at least one outbound link). Below-default it is Info; a
	// config knob can promote it to Warning (ADR 0012).
	UnderLinked
	// DeadEnd is a document with inbound links but no outbound navigational links
	// (a terminal node). Below-default it is Info; a config knob can promote it to
	// Warning (ADR 0012).
	DeadEnd
	// SuggestedLink is a topology-based suggestion that two UNLINKED but
	// structurally-close documents may warrant a navigational link (ADR 0013). It
	// is always Info and NEVER gates the exit code (it is an experimental,
	// additive discoverability hint, not a defect).
	SuggestedLink
	// DeadLink is an external (http/https) link that failed an opt-in liveness
	// check (--check-external): unreachable, an error status, or refused by the
	// SSRF guard. It is produced only when external checking is enabled, so it is
	// kept OUT of the default deterministic output (ADR 0003).
	DeadLink
	// ArticulationPoint is a document that is a cut VERTEX of the undirected link
	// closure (ADR 0015): removing or unlinking it fragments the corpus into more
	// pieces. It is always Info and NEVER gates the exit code (even --strict) — it
	// is a structural-resilience hint, not a defect — mirroring SuggestedLink and
	// KnowledgeGap.
	ArticulationPoint
	// Bridge is a navigational link that is a cut EDGE of the undirected closure
	// (ADR 0015): it is the only connection between two parts of the corpus, so
	// losing it disconnects them. Like ArticulationPoint it is always Info and
	// never gates the exit code.
	Bridge
	// LowScentAnchor is a navigational link whose anchor text shares too few
	// meaningful tokens with its destination — the target's title or its section
	// headings (the fragment's own heading for an anchored link) — to preview
	// where it leads (ADR 0016): a generic "click here" / a label unrelated to
	// the destination gives a reader or agent weak "information scent" (Pirolli &
	// Card 1999). It is always Info and NEVER gates the exit code (even --strict)
	// — a discoverability hint, not a defect — mirroring SuggestedLink,
	// ArticulationPoint and Bridge.
	LowScentAnchor
	// FarFromRoot is a document reachable from the root set but at or beyond the
	// configured hop-distance threshold from the NEAREST root (ADR 0021): it is
	// "reachable but effectively undiscoverable" by link traversal, since an agent
	// or reader following links from an entry point is unlikely to reach it that
	// deep. It is always Info and NEVER gates the exit code (even --strict) — a
	// discoverability hint, not a defect — mirroring UnderLinked's intent but
	// keyed on distance-from-entry-point rather than raw in-degree.
	FarFromRoot
	// OKFMissingFrontmatter is an OKF v0.1 conformance violation (rule R1, ADR
	// 0023): a non-reserved concept document (any `.md` other than index.md /
	// log.md) has no parseable YAML frontmatter block — either absent entirely or
	// present-but-unparseable (the state is carried in Details). It is produced
	// ONLY in OKF conformance mode (--okf) and is Error severity: when the mode is
	// on it gates the exit code (exit 1) regardless of --strict.
	OKFMissingFrontmatter
	// OKFMissingType is an OKF v0.1 conformance violation (rule R2, ADR 0023): a
	// concept document's frontmatter has no non-empty string `type` field. matlatl
	// NEVER validates the type VALUE against any list (OKF §4.1 forbids a central
	// registry). Produced ONLY in OKF mode; Error severity; gates exit 1
	// independent of --strict.
	OKFMissingType
	// OKFReservedFileStructure is an OKF v0.1 conformance violation (rule R3, ADR
	// 0023): a reserved file does not follow its required structure — a log.md `##`
	// heading is not an ISO 8601 `YYYY-MM-DD` date, a non-root index.md carries
	// frontmatter, or a root index.md carries a frontmatter key other than
	// okf_version. Produced ONLY in OKF mode; Error severity; gates exit 1
	// independent of --strict.
	OKFReservedFileStructure
)

func ParseFindingKind added in v0.0.4

func ParseFindingKind(s string) (FindingKind, bool)

ParseFindingKind maps a canonical kind name (the String form, e.g. "broken-link") back to its FindingKind — the pure inverse of String. The second result is false for any string that is not a defined kind name (including "" and "unknown").

func (FindingKind) String

func (k FindingKind) String() string

String returns the canonical name of the finding kind.

func (FindingKind) Valid

func (k FindingKind) Valid() bool

Valid reports whether k is a defined FindingKind.

type Location

type Location struct {
	Document identity.DocumentID
	// Line is the 1-based source line, or 0 if not line-specific.
	Line int
}

Location pins a finding to a source position.

type Severity

type Severity int

Severity classifies the weight of a finding. The ordering (Info < Warning < Error) is meaningful and used for threshold comparisons.

const (
	// Info is an informational finding.
	Info Severity = iota
	// Warning is a finding that does not fail the build by default.
	Warning
	// Error is a finding that fails the build (exit 1, ADR 0005).
	Error
)

func (Severity) String

func (s Severity) String() string

String returns the canonical name of the severity.

func (Severity) Valid

func (s Severity) Valid() bool

Valid reports whether s is a defined Severity.

Jump to

Keyboard shortcuts

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