model

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultGraphDir is the conventional graph directory relative to repo root
	// when initialized with sdd init.
	DefaultGraphDir = ".sdd/graph"

	// SDDDirName is the metadata directory name at the repository root.
	SDDDirName = ".sdd"
)

Variables

View Source
var LayerAbbrev = map[Layer]string{
	LayerStrategic:   "stg",
	LayerConceptual:  "cpt",
	LayerTactical:    "tac",
	LayerOperational: "ops",
	LayerProcess:     "prc",
}

LayerAbbrev maps full layer names to abbreviations used in IDs.

View Source
var LayerFromAbbrev = map[string]Layer{
	"stg": LayerStrategic,
	"cpt": LayerConceptual,
	"tac": LayerTactical,
	"ops": LayerOperational,
	"prc": LayerProcess,
}

LayerFromAbbrev maps abbreviations to full layer names.

View Source
var TypeAbbrev = map[EntryType]string{
	TypeSignal:   "s",
	TypeDecision: "d",
	TypeAction:   "a",
}

TypeAbbrev maps full type names to abbreviations used in IDs.

View Source
var TypeFromAbbrev = map[string]EntryType{
	"s": TypeSignal,
	"d": TypeDecision,
	"a": TypeAction,
}

TypeFromAbbrev maps abbreviations to full type names.

Functions

func AttachDirRelPath

func AttachDirRelPath(id string) (string, error)

AttachDirRelPath returns the relative path to the attachment directory for an entry ID. This is the entry's file path without the .md extension.

func DeriveBranchName

func DeriveBranchName(entryID, description string) string

DeriveBranchName creates a branch name from an entry ID and description. Format: sdd/<entry-suffix>-<description-slug>

func FormatConfig

func FormatConfig(cfg Config) string

FormatConfig returns a commented YAML config template with the given graph dir.

func FormatFrontmatter

func FormatFrontmatter(e *Entry) string

FormatFrontmatter creates the YAML frontmatter string for an entry.

func FormatWIPMarker

func FormatWIPMarker(m *WIPMarker) string

FormatWIPMarker creates the file content for a WIP marker.

func GenerateID

func GenerateID(typ EntryType, layer Layer, suffix string) string

GenerateID creates a new document ID with the current timestamp and a random suffix.

func GenerateIDAt

func GenerateIDAt(typ EntryType, layer Layer, suffix string, t time.Time) string

GenerateIDAt creates a new document ID with the given timestamp and a random suffix. Accepts the time explicitly so callers can inject a clock for testability.

func GenerateWIPMarkerID

func GenerateWIPMarkerID(participant string) string

GenerateWIPMarkerID creates a marker ID from the current timestamp and participant name.

func IDToRelPath

func IDToRelPath(id string) (string, error)

IDToRelPath converts an entry ID to its relative file path in the hierarchical layout. ID format: YYYYMMDD-HHmmss-type-layer-suffix Path format: YYYY/MM/DD-HHmmss-type-layer-suffix.md

func IsWIPDir

func IsWIPDir(d fs.DirEntry) bool

IsWIPDir returns true if the given directory entry represents the wip/ directory.

func RandomSuffix

func RandomSuffix(n int) (string, error)

RandomSuffix returns an n-character lowercase alphanumeric string suitable for use as the trailing random portion of a document ID.

func RelPathToID

func RelPathToID(rel string) (string, error)

RelPathToID converts a relative path (YYYY/MM/DD-HHmmss-type-layer-suffix.md) to a full entry ID.

func ResolveAttachmentLinks(content, id string) string

ResolveAttachmentLinks replaces {{attachments}} placeholders in content with the actual relative directory path for markdown links.

func ValidateEntry

func ValidateEntry(e *Entry, g *Graph)

ValidateEntry checks a single entry for integrity issues and populates its Warnings field. Used both at lint time (all entries) and at write time (new entry before commit).

func WIPDir

func WIPDir(graphDir string) string

WIPDir returns the path to the wip/ directory within a graph directory.

func WIPMarkerPath

func WIPMarkerPath(markerID string) string

WIPMarkerPath returns the path to a marker file relative to the graph directory.

Types

type Config

type Config struct {
	GraphDir string `yaml:"graph_dir"`
}

Config represents the contents of .sdd/config.yaml.

func ParseConfig

func ParseConfig(data []byte) (*Config, error)

ParseConfig unmarshals YAML bytes into a Config struct.

type Entry

type Entry struct {
	ID           string
	Type         EntryType
	Layer        Layer
	Kind         Kind // only meaningful for decisions; empty = directive (default)
	Refs         []string
	Supersedes   []string
	Closes       []string
	Participants []string
	Confidence   string
	Content      string
	Time         time.Time
	Preflight    string    // "skipped" or "error" annotation from pre-flight validation
	Attachments  []string  // filenames discovered from the co-located attachment directory
	Summary      string    // LLM-generated summary: this entry + direct relationships
	SummaryHash  string    // hex-encoded hash of the rendered summary prompt inputs
	Warnings     []Warning // validation issues found during graph construction
}

func ParseEntry

func ParseEntry(filename, content string) (*Entry, error)

ParseEntry parses a graph entry from its filename and file content.

func (*Entry) IsContract

func (e *Entry) IsContract() bool

IsContract returns true if this decision is a standing constraint.

func (*Entry) IsPlan

func (e *Entry) IsPlan() bool

IsPlan returns true if this decision is an implementation plan.

func (*Entry) LayerLabel

func (e *Entry) LayerLabel() string

LayerLabel returns a display label for the layer.

func (*Entry) ShortContent

func (e *Entry) ShortContent(maxLen int) string

ShortContent returns content truncated to maxLen, preferring sentence boundaries. Accumulates complete sentences up to the limit. If no sentence fits, accumulates words.

func (*Entry) TypeLabel

func (e *Entry) TypeLabel() string

TypeLabel returns a display label for the entry type.

type EntryType

type EntryType string
const (
	TypeSignal   EntryType = "signal"
	TypeDecision EntryType = "decision"
	TypeAction   EntryType = "action"
)

type Graph

type Graph struct {
	Entries      []*Entry
	ByID         map[string]*Entry
	RefsTo       map[string][]string // reverse index: entry ID -> IDs that reference it
	ClosedBy     map[string][]string // reverse index: entry ID -> IDs that close it
	SupersededBy map[string][]string // reverse index: entry ID -> IDs that supersede it
	// contains filtered or unexported fields
}

Graph holds all entries and their reference indexes.

func NewGraph

func NewGraph(entries []*Entry) *Graph

NewGraph builds a graph from the given entries without touching the filesystem.

func (*Graph) ActiveDecisions

func (g *Graph) ActiveDecisions() []*Entry

ActiveDecisions returns active directive decisions (not closed, not superseded, not contracts).

func (*Graph) BuildShowTree

func (g *Graph) BuildShowTree(id string, maxDepth int, includeDownstream bool, rendered, primaries map[string]bool) *ShowTree

BuildShowTree constructs the upstream and optionally downstream traversal trees for a primary entry, respecting max depth, cross-group dedup (rendered), and future-primary dedup (primaries). Both directions use per-direction visited sets. The rendered map is updated with newly-shown entries.

func (*Graph) Contracts

func (g *Graph) Contracts() []*Entry

Contracts returns active contract decisions (not superseded). Contracts are never closed — they stay active until superseded.

func (*Graph) DerivedStatus

func (g *Graph) DerivedStatus(e *Entry) Status

DerivedStatus returns the computed lifecycle status for an entry, derived from graph relationships. Superseded is checked before closed so a superseded-then-closed entry (rare) surfaces as superseded. When multiple entries close or supersede the target, the first one (by graph insertion order) is reported.

func (*Graph) Downstream

func (g *Graph) Downstream(id string) []*Entry

Downstream returns entries that reference, close, or supersede the given ID. Results are sorted by time (oldest first).

func (*Graph) Filter

func (g *Graph) Filter(f GraphFilter) []*Entry

Filter returns entries matching the given filter criteria. Zero-value fields match all. When Kind is specified, only decisions are returned (kind is meaningless for other types).

func (*Graph) GraphDir

func (g *Graph) GraphDir() string

GraphDir returns the directory the graph was loaded from.

func (*Graph) Lint

func (g *Graph) Lint() []*Entry

Lint returns all entries that have validation warnings.

func (*Graph) OpenSignals

func (g *Graph) OpenSignals() []*Entry

OpenSignals returns signals that are not closed and not superseded.

func (*Graph) Plans

func (g *Graph) Plans() []*Entry

Plans returns active plan decisions (not closed, not superseded).

func (*Graph) RecentActions

func (g *Graph) RecentActions(n int) []*Entry

RecentActions returns the last n actions by timestamp.

func (*Graph) RefChain

func (g *Graph) RefChain(id string) []*Entry

RefChain returns the entry and all entries it transitively references, in dependency order.

func (*Graph) ResolveID

func (g *Graph) ResolveID(input string) (string, error)

ResolveID resolves a user-supplied ID string (full or short form) to a full entry ID. Full IDs pass through unchanged. Short form {type}-{layer}-{suffix} is matched against entries; a unique match returns the full ID, ambiguous matches return an error listing all candidates (sorted). Inputs that do not recognize as either shape, that use unknown type or layer abbreviations, or that match zero entries pass through unchanged so the caller's existing "entry not found" surface fires against the user's original text.

func (*Graph) ResolveIDs

func (g *Graph) ResolveIDs(inputs []string) ([]string, error)

ResolveIDs resolves a slice of user-supplied IDs. Ambiguous inputs stop resolution and return the error; other inputs pass through the same semantics as ResolveID.

func (*Graph) SetGraphDir

func (g *Graph) SetGraphDir(dir string)

SetGraphDir records the directory the graph was loaded from. Used by IO callers (e.g. sdd.LoadGraph) to attach provenance after constructing the in-memory graph.

func (*Graph) TopologicalOrder

func (g *Graph) TopologicalOrder() []*Entry

TopologicalOrder returns entries sorted so that every entry appears after all entries it references (refs, closes, supersedes). Entries with no references come first. This is a stable sort — entries at the same depth are ordered by time.

type GraphFilter

type GraphFilter struct {
	Type     EntryType
	Layer    Layer
	Kind     Kind
	OpenOnly bool // when true, exclude closed/superseded signals and decisions
}

GraphFilter specifies criteria for filtering graph entries.

type IDParts

type IDParts struct {
	Timestamp string
	Time      time.Time
	TypeCode  string // abbreviation: "s", "d", "a"
	LayerCode string // abbreviation: "stg", "cpt", "tac", "ops", "prc"
	Suffix    string
}

IDParts holds the parsed components of a document ID.

func ParseID

func ParseID(id string) (IDParts, error)

ParseID parses a document ID into its components. ID format: {YYYYMMDD}-{HHmmss}-{type}-{layer}-{suffix}

type Kind

type Kind string

Kind distinguishes directive decisions (need action), contract decisions (standing constraints), and plan decisions (implementation plans that need action to close).

const (
	KindDirective Kind = "directive"
	KindContract  Kind = "contract"
	KindPlan      Kind = "plan"
)

type Layer

type Layer string
const (
	LayerStrategic   Layer = "strategic"
	LayerConceptual  Layer = "conceptual"
	LayerTactical    Layer = "tactical"
	LayerOperational Layer = "operational"
	LayerProcess     Layer = "process"
)

type ShowTree

type ShowTree struct {
	Primary    *Entry
	Upstream   []ShowTreeItem
	Downstream []ShowTreeItem
}

ShowTree holds the upstream and downstream chains for a single primary entry.

type ShowTreeItem

type ShowTreeItem struct {
	Entry       *Entry
	Depth       int
	Relations   []string       // e.g. ["refs"], ["refs", "closes"], ["refd-by"]
	ShownAbove  bool           // already rendered earlier — "(see above)" marker
	ShownBelow  bool           // future primary — "(see below)" marker
	SummaryOnly bool           // true for depth > 0
	Truncated   []TruncatedRef // children hidden at max-depth boundary
}

ShowTreeItem represents an entry at a specific depth in a show tree. Depth 0 is the primary entry. Depth 1+ entries are summary-only.

type Status

type Status struct {
	Kind StatusKind
	By   string
}

Status is the computed lifecycle status for an entry. By is populated only for compound states (ClosedBy, SupersededBy) and holds the full entry ID of the first closer/superseder.

type StatusKind

type StatusKind string

StatusKind is the lifecycle state of an entry derived from graph relationships.

const (
	StatusNone         StatusKind = ""              // actions — facts have no lifecycle state
	StatusActive       StatusKind = "active"        // decision (directive, plan, contract) not closed or superseded
	StatusOpen         StatusKind = "open"          // signal not closed or superseded
	StatusClosedBy     StatusKind = "closed-by"     // closed by another entry (By carries the full ID)
	StatusSupersededBy StatusKind = "superseded-by" // superseded by another entry
)

type TruncatedRef

type TruncatedRef struct {
	ID        string
	Relations []string
	Kind      Kind
}

TruncatedRef describes a child entry hidden at the max-depth boundary.

type WIPMarker

type WIPMarker struct {
	ID          string // filename without .md: {YYYYMMDD}-{HHmmss}-{participant}
	Entry       string // graph entry ID being worked on
	Participant string
	Exclusive   bool
	Branch      string // git branch name (empty if not a branched work stream)
	Content     string // free-text description
	Time        time.Time
}

WIPMarker represents an in-flight work marker.

func HasExclusiveMarker

func HasExclusiveMarker(markers []*WIPMarker, entryID string) (*WIPMarker, bool)

HasExclusiveMarker returns true if any marker for the given entry is exclusive.

func MarkersForEntry

func MarkersForEntry(markers []*WIPMarker, entryID string) []*WIPMarker

MarkersForEntry returns all markers that reference the given graph entry ID.

func ParseWIPMarker

func ParseWIPMarker(filename, content string) (*WIPMarker, error)

ParseWIPMarker parses a WIP marker from its filename and file content.

func (*WIPMarker) ShortContent

func (m *WIPMarker) ShortContent(maxLen int) string

ShortContent returns the first line of the marker content, truncated to maxLen.

type Warning

type Warning struct {
	Field   string // "refs", "closes", "supersedes"
	Value   string // the offending ID or value
	Message string // human-readable description
}

Warning represents a validation issue found on a graph entry.

Jump to

Keyboard shortcuts

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