maturity

package
v0.44.0 Latest Latest
Warning

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

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

Documentation

Overview

Package maturity scores where each fak capability sits on its LIFECYCLE maturity ladder — and, crucially, what the next step to advance it is.

The sibling scorecards ask "is the fleet's dev discipline healthy" (internal/conceptusage), "can an agent adopt fak" (agent-readiness), or "is a concept a durable product" (tools/product_scorecard.py). None of them asks the question an operator running a long-horizon program asks of every feature:

A v1 prototype can be legitimately COMPLETE — but is it tested? does fak
itself run it? is it benchmarked? is it the default, or still an opt-in?
Where is each capability in its lifecycle, and what is the NEXT thing that
would mature it?

That is this scorecard. It places every declared capability (one per internal/<leaf> lane in dos.toml [lanes.trees]) on a closed lifecycle ladder, best last:

proposed -> prototyped -> tested -> dogfooded -> benchmarked -> default

The load-bearing property — the same invariant the rest of the kernel carries — is that NO RUNG CAN BE REACHED BY EDITING THE CLAIM. Each rung is gated by evidence the capability's author did not write: code on disk, a *_test.go, an import from cmd/ (fak itself runs it), a Benchmark func / an authority row, a documented verb. To move a capability up the ladder you change the real tree, not a data file.

Two structural ideas make this an "agentic culture" subsystem, not just a report:

  • Immaturity is NOT a defect. A capability honestly sitting at `prototyped` is a complete v1 that simply has not been matured yet — that is the normal, expected state, and the operator should SEE it without it counting against anyone. What IS a defect is a LADDER-SKIP: a capability that has high-rung evidence (fak runs it; it is benchmarked) while a LOWER rung is unmet (it has no tests). Appearing more mature than the evidence supports is the overclaim this refuses — the maturity sibling of the product scorecard's verdict-overclaim and the readiness ladder's READINESS_OVERCLAIM (#582/G1).

  • Every gap is the next work item. For each capability the FIRST unmet rung is rendered as a concrete, checkable next step ("wire it into a fak verb so fak itself runs it"). `fak maturity next` is that backlog — the queue an agent (or the issue-dispatch loop) pulls from to advance the fleet one rung at a time. The desire to create the next work item is mechanized: the tree itself says what is owed.

Every number is re-derived from disk (dos.toml + the tree + a few top-level docs). The score cannot be moved by editing a JSON file — only by actually maturing a capability.

Index

Constants

View Source
const IssueSchema = "fak-maturity-issues/1"

IssueSchema is the machine-readable envelope for the maturity backlog -> GitHub issue bridge. It turns the ranked `fak maturity next` backlog into the work surface the issue-dispatch loop already consumes.

View Source
const MaxRung = RungDefault

MaxRung is the top of the monotonic ladder.

View Source
const (
	Schema = "fak-maturity-scorecard/1"
)

Variables

View Source
var RungName = []string{"proposed", "prototyped", "tested", "dogfooded", "default"}

RungName is the closed display vocabulary, indexed by Rung. `benchmarked` is NOT a ladder rung — measurement is an orthogonal badge (a capability can be measured at any rung), so forcing it into the total order would manufacture false inversions. It is tracked per capability and is the natural step AFTER `default`.

Functions

func Compare

func Compare(current ScorecardPayload, baseline map[string]any) string

Compare proves movement against a pinned --json baseline: capabilities promoted, ladder-skips retired, and the index lift.

func EncodeAnatomyJSON added in v0.44.0

func EncodeAnatomyJSON(w io.Writer, a Anatomy) error

func EncodeAnatomyPortfolioJSON added in v0.44.0

func EncodeAnatomyPortfolioJSON(w io.Writer, p AnatomyPortfolio) error

func IssueBody

func IssueBody(item IssueItem) string

IssueBody renders a stable marker-stamped issue body. The title carries the maturity(<lane>) scope so the existing issue router sends the issue back to the capability lane.

func Markdown

func Markdown(p ScorecardPayload) string

Markdown renders the durable scorecard doc.

func MarkerKey

func MarkerKey(body string) string

MarkerKey extracts the maturity work key from a GitHub issue body.

func PublicIssueRouteableLane

func PublicIssueRouteableLane(lane string) bool

PublicIssueRouteableLane reports whether a maturity lane can be turned into a public GitHub issue by default. The scorecard can still measure private-boundary lanes; only the public issue feeder filters them.

func Render

func Render(p ScorecardPayload) string

Render is the terminal view: the headline, the rung distribution as a bar chart, and the top of the next-work backlog.

func RenderAnatomyPortfolioText added in v0.44.0

func RenderAnatomyPortfolioText(w io.Writer, p AnatomyPortfolio)

func RenderAnatomyText added in v0.44.0

func RenderAnatomyText(w io.Writer, a Anatomy)

func RenderIssueResult

func RenderIssueResult(r IssueResult) string

RenderIssueResult is the human dry-run/live card for `fak maturity route`.

func RenderNext

func RenderNext(p ScorecardPayload) string

RenderNext is the focused backlog view — the agentic-culture queue an agent or the dispatch loop pulls from. One ticket-shaped line per capability.

func VerifyRuntimeProofs added in v0.44.0

func VerifyRuntimeProofs(root string) error

VerifyRuntimeProofs runs every declared witness in stable lane order.

Types

type Anatomy added in v0.44.0

type Anatomy struct {
	Schema        string          `json:"schema"`
	Package       string          `json:"package"`
	Directory     string          `json:"directory"`
	Shape         AnatomyShape    `json:"shape"`
	Flow          AnatomyFlow     `json:"flow"`
	Outcomes      AnatomyOutcomes `json:"outcomes"`
	Contracts     AnatomyContract `json:"contracts"`
	Documentation AnatomyDocs     `json:"documentation"`
	Position      AnatomyPosition `json:"position"`
	Caveats       []string        `json:"caveats"`
}

Anatomy is a static structural readout for one Go package. Counts describe syntax, not runtime frequency or independently executable paths.

func AnalyzeAnatomy added in v0.44.0

func AnalyzeAnatomy(root, target string) (Anatomy, error)

type AnatomyContract added in v0.44.0

type AnatomyContract struct {
	GuardClauses        int `json:"guard_clauses"`
	Panics              int `json:"panics"`
	AssumptionComments  int `json:"assumption_comments"`
	ExpectationComments int `json:"expectation_comments"`
	InvariantComments   int `json:"invariant_comments"`
	RequirementComments int `json:"requirement_comments"`
	TODOs               int `json:"todos"`
}

type AnatomyDocs added in v0.44.0

type AnatomyDocs struct {
	ExportedSymbols   int  `json:"exported_symbols"`
	DocumentedExports int  `json:"documented_exports"`
	PackageDoc        bool `json:"package_doc"`
}

type AnatomyFlow added in v0.44.0

type AnatomyFlow struct {
	DecisionPoints       int `json:"decision_points"`
	CyclomaticComplexity int `json:"cyclomatic_complexity"`
	MaximumFunction      int `json:"maximum_function_complexity"`
	MaximumNesting       int `json:"maximum_nesting"`
}

type AnatomyOutcomes added in v0.44.0

type AnatomyOutcomes struct {
	ReturnSites           int `json:"return_sites"`
	ErrorHandlingBranches int `json:"error_handling_branches"`
	ErrorExits            int `json:"error_exits"`
	SuccessExits          int `json:"success_exits"`
	AmbiguousExits        int `json:"ambiguous_exits"`
}

type AnatomyPortfolio added in v0.44.0

type AnatomyPortfolio struct {
	Schema          string                  `json:"schema"`
	Summary         AnatomyPortfolioSummary `json:"summary"`
	Packages        []Anatomy               `json:"packages"`
	MissingPackages []string                `json:"missing_packages,omitempty"`
	Rankings        AnatomyRankings         `json:"rankings"`
	Caveats         []string                `json:"caveats"`
}

AnatomyPortfolio compares first-class internal leaves without collapsing the underlying measurements into an opaque quality score.

func AnalyzeAnatomyPortfolio added in v0.44.0

func AnalyzeAnatomyPortfolio(root string, limit int) (AnatomyPortfolio, error)

AnalyzeAnatomyPortfolio analyzes the capability roster declared in dos.toml. Limit affects ranking lists only; the package corpus and summary remain full.

type AnatomyPortfolioSummary added in v0.44.0

type AnatomyPortfolioSummary struct {
	DeclaredPackages     int `json:"declared_packages"`
	Packages             int `json:"packages"`
	ProductionFiles      int `json:"production_files"`
	Functions            int `json:"functions"`
	Statements           int `json:"statements"`
	DecisionPoints       int `json:"decision_points"`
	CyclomaticComplexity int `json:"cyclomatic_complexity"`
	ErrorExits           int `json:"error_exits"`
	SuccessExits         int `json:"success_exits"`
	AmbiguousExits       int `json:"ambiguous_exits"`
	AssumptionComments   int `json:"assumption_comments"`
	ExpectationComments  int `json:"expectation_comments"`
	InvariantComments    int `json:"invariant_comments"`
	RequirementComments  int `json:"requirement_comments"`
	DependencyCycles     int `json:"dependency_cycle_packages"`
	ExportedSymbols      int `json:"exported_symbols"`
	DocumentedExports    int `json:"documented_exports"`
	CLIReachablePackages int `json:"cli_reachable_packages"`
}

type AnatomyPosition added in v0.44.0

type AnatomyPosition struct {
	InternalDependencies   []string `json:"internal_dependencies"`
	InternalDependents     []string `json:"internal_dependents"`
	TransitiveDependencies int      `json:"transitive_dependencies"`
	TransitiveDependents   int      `json:"transitive_dependents"`
	CommandDistance        int      `json:"command_distance"`
	InDependencyCycle      bool     `json:"in_dependency_cycle"`
	CLIReachable           bool     `json:"cli_reachable"`
}

type AnatomyRank added in v0.44.0

type AnatomyRank struct {
	Package string  `json:"package"`
	Value   float64 `json:"value"`
}

type AnatomyRankings added in v0.44.0

type AnatomyRankings struct {
	Complexity             []AnatomyRank `json:"aggregate_complexity"`
	ComplexityDensity      []AnatomyRank `json:"complexity_per_function"`
	MaximumFunction        []AnatomyRank `json:"maximum_function_complexity"`
	DocumentationGap       []AnatomyRank `json:"undocumented_exports"`
	Dependencies           []AnatomyRank `json:"internal_dependencies"`
	Dependents             []AnatomyRank `json:"internal_dependents"`
	Assumptions            []AnatomyRank `json:"assumption_comments"`
	Expectations           []AnatomyRank `json:"expectation_comments"`
	TransitiveDependencies []AnatomyRank `json:"transitive_dependencies"`
	TransitiveDependents   []AnatomyRank `json:"transitive_dependents"`
	ErrorExits             []AnatomyRank `json:"error_exits"`
}

type AnatomyShape added in v0.44.0

type AnatomyShape struct {
	Files      int `json:"files"`
	TestFiles  int `json:"test_files"`
	Functions  int `json:"functions"`
	Statements int `json:"statements"`
}

type Capability

type Capability struct {
	Lane string `json:"lane"` // the dos.toml lane key (== leaf package name)
	Dir  string `json:"dir"`  // the leaf tree root, e.g. internal/adjudicator

	HasCode        bool   `json:"has_code"`   // a non-test .go file exists
	HasTests       bool   `json:"has_tests"`  // a *_test.go exists
	Integrated     bool   `json:"integrated"` // reachable from a production command import graph
	Dogfooded      bool   `json:"dogfooded"`  // a declared runtime witness passes
	RuntimeProof   string `json:"runtime_proof,omitempty"`
	Benchmarked    bool   `json:"benchmarked"`     // a Benchmark func or a BENCHMARK-AUTHORITY row
	DefaultSurface bool   `json:"default_surface"` // a documented verb / named in llms.txt

	// Rung is the monotonic current lifecycle rung: the highest R such that EVERY
	// promotion predicate up to and including R holds. A gap caps it.
	Rung Rung `json:"rung"`
	// TopEvidence is the highest rung whose predicate holds, ignoring gaps below
	// it. TopEvidence > Rung means the capability skipped a lower rung.
	TopEvidence Rung `json:"top_evidence"`
	// Skip is true when high-rung evidence sits over an unmet lower rung — a
	// maturity inversion / overclaim (e.g. fak runs it but it has no tests).
	Skip bool `json:"skip"`

	// Next is the first unmet rung rendered as a concrete next work item, or nil
	// when the capability is already at the top of the ladder.
	Next *NextWork `json:"next,omitempty"`
}

Capability is one declared leaf and the lifecycle facts re-derived for it. All the boolean facts are read from ground truth the author of the leaf did not write.

type ExistingIssue

type ExistingIssue struct {
	Number int    `json:"number"`
	Title  string `json:"title"`
	Body   string `json:"body"`
	State  string `json:"state"`
	URL    string `json:"url"`
}

ExistingIssue is the subset of a gh issue row this bridge needs.

func FetchExistingIssues

func FetchExistingIssues(repo string, limit int) ([]ExistingIssue, error)

FetchExistingIssues queries gh for all issues that may carry maturity markers.

type IssueItem

type IssueItem struct {
	Key      string   `json:"key"`
	Lane     string   `json:"lane"`
	FromRung string   `json:"from_rung"`
	Gap      string   `json:"gap"`
	Title    string   `json:"title"`
	Witness  string   `json:"witness"`
	Skip     bool     `json:"skip"`
	Labels   []string `json:"labels,omitempty"`
	Body     string   `json:"-"`
}

IssueItem is one maturity next-work item rendered as a dedupable GitHub issue.

func IssueItems

func IssueItems(p ScorecardPayload, limit int, labels []string) []IssueItem

IssueItems projects the ranked maturity backlog into at most limit issue-shaped work items. limit <= 0 means all current backlog items.

type IssuePlanRow

type IssuePlanRow struct {
	Action  string `json:"action"`
	Key     string `json:"key"`
	Number  *int   `json:"number,omitempty"`
	State   string `json:"state,omitempty"`
	Lane    string `json:"lane"`
	Title   string `json:"title"`
	Body    string `json:"-"`
	Gap     string `json:"gap"`
	Witness string `json:"witness"`
	Skip    bool   `json:"skip"`
}

IssuePlanRow is one create/update decision for a maturity issue.

func BuildIssuePlan

func BuildIssuePlan(items []IssueItem, existing []ExistingIssue) []IssuePlanRow

BuildIssuePlan decides whether each maturity item creates a new issue or updates the issue that already carries the stable marker key.

type IssueProjection

type IssueProjection struct {
	Items   []IssueItem       `json:"items"`
	Skipped []IssueSkippedRow `json:"skipped,omitempty"`
}

IssueProjection is the public-issue projection of the maturity backlog.

func ProjectIssueItems

func ProjectIssueItems(p ScorecardPayload, limit int, labels []string) IssueProjection

ProjectIssueItems projects the ranked maturity backlog into public GitHub issue work while preserving private-boundary skips for operator visibility. The limit counts routed public items, not skipped private-boundary rows.

type IssueResult

type IssueResult struct {
	Schema    string            `json:"schema"`
	Mode      string            `json:"mode"`
	Workspace string            `json:"workspace"`
	Maturity  map[string]any    `json:"maturity"`
	Planned   []IssuePlanRow    `json:"planned"`
	Synced    []IssueSyncRow    `json:"synced"`
	Skipped   []IssueSkippedRow `json:"skipped,omitempty"`
}

IssueResult is the CLI result for `fak maturity route`.

type IssueRunner

type IssueRunner func(args []string) (stdout, stderr string, ok bool)

IssueRunner is injectable so tests never shell out to gh.

type IssueSkippedRow

type IssueSkippedRow struct {
	Key    string `json:"key"`
	Lane   string `json:"lane"`
	Reason string `json:"reason"`
	Title  string `json:"title"`
}

IssueSkippedRow records a maturity item that remains visible in `fak maturity next`, but is not safe to auto-route into public GitHub issues.

type IssueSyncRow

type IssueSyncRow struct {
	Key    string `json:"key"`
	Action string `json:"action"`
	OK     bool   `json:"ok"`
	Stdout string `json:"stdout"`
	Stderr string `json:"stderr"`
}

IssueSyncRow is one gh create/edit outcome from a --live run.

func SyncIssuePlan

func SyncIssuePlan(plan []IssuePlanRow, repo string, labels []string, runner IssueRunner) []IssueSyncRow

SyncIssuePlan applies a planned create/update set via gh. Labels are applied only to newly-created issues, matching gh's issue edit/create split.

type NextWork

type NextWork struct {
	Lane     string `json:"lane"`
	FromRung Rung   `json:"from_rung"` // where the capability is now
	Gap      Rung   `json:"gap"`       // the first rung it is missing
	Title    string `json:"title"`     // imperative, ticket-shaped
	Witness  string `json:"witness"`   // the evidence that would close it
	Skip     bool   `json:"skip"`      // is filling this gap also resolving a ladder-skip?
}

NextWork is one mechanically-derived "next thing that would mature this capability" — the unit the agentic-culture backlog is made of. It mirrors the CLAUDE.md "not yet" idiom: the gap, the missing witness, and the checkable step.

type Options

type Options struct {
	Root string

	// Witnesses overrides runtime witness loading for deterministic callers and tests.
	Witnesses func(root string) (map[string]RuntimeProof, error)
	// contains filtered or unexported fields
}

Options pins the root and the tree facts so the score is deterministic for tests. The facts seam lets a test inject a synthetic tree without touching disk.

type Rung

type Rung int

Rung is a closed lifecycle level, total-ordered worst -> best. A value outside this set is a bug, not a lower score — the same discipline the closed refusal vocabulary applies to a reason token.

const (
	RungProposed   Rung = iota // 0 — a named capability with no code on disk yet
	RungPrototyped             // 1 — v1 code exists in the leaf (legitimately "complete")
	RungTested                 // 2 — the leaf carries unit tests (the QA rung)
	RungDogfooded              // 3 — fak ITSELF runs it: it is on the running binary's import path
	RungDefault                // 4 — a passing runtime proof declares the capability active without opt-in
)

func (Rung) String

func (r Rung) String() string

type RuntimeProof added in v0.44.0

type RuntimeProof struct {
	Lane           string `json:"lane"`
	Command        string `json:"command"`
	OutputContains string `json:"output_contains"`
	DefaultOn      bool   `json:"default_on,omitempty"`
	DefaultReason  string `json:"default_reason,omitempty"`
}

RuntimeProof is a reproducible runtime invocation that proves fak executes a capability.

type ScorecardPayload

type ScorecardPayload struct {
	Schema            string         `json:"schema"`
	OK                bool           `json:"ok"`
	Verdict           string         `json:"verdict"`
	Finding           string         `json:"finding"`
	Reason            string         `json:"reason"`
	NextAction        string         `json:"next_action"`
	Workspace         string         `json:"workspace"`
	Corpus            map[string]any `json:"corpus"`
	Caps              []Capability   `json:"capabilities"`
	Backlog           []NextWork     `json:"backlog"`
	RuntimeProofOK    bool           `json:"runtime_proof_ok"`
	RuntimeProofCount int            `json:"runtime_proof_count"`
	RuntimeProofError string         `json:"runtime_proof_error,omitempty"`
}

ScorecardPayload is the uniform control-pane envelope every fak scorecard emits.

func Build

func Build(opts Options) ScorecardPayload

Build is the fold: re-derive every capability's facts, adjudicate each, and roll up the distribution + the ladder-skip debt + the next-work backlog.

Jump to

Keyboard shortcuts

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