requirements

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package requirements owns the v3 requirements-domain records of a living Change Saga. It intentionally has no dependency on the central saga loader, query registry, or CLI dispatcher so those integration points can evolve independently.

Index

Constants

View Source
const (
	Version = 3

	StorySchemaURL          = "https://changesaga.dev/schema/v3/story.schema.json"
	RevisionSchemaURL       = "https://changesaga.dev/schema/v3/story-revision.schema.json"
	LifecycleEventSchemaURL = "https://changesaga.dev/schema/v3/story-event.schema.json"
	CitationSchemaURL       = "https://changesaga.dev/schema/v3/citation.schema.json"
	RelationSchemaURL       = "https://changesaga.dev/schema/v3/relation.schema.json"

	MaxStories           = 10_000
	MaxRevisionsPerStory = 10_000
	MaxEventsPerStory    = 10_000
	MaxCitations         = 20_000
	MaxRelations         = 50_000
	MaxRecordBytes       = 1 << 20
)

Variables

This section is empty.

Functions

func StoryEventURN

func StoryEventURN(sagaID, storyID, eventID string) (string, error)

StoryEventURN returns the canonical name of an immutable lifecycle event. Event URNs are requirements-owned and deliberately do not require expanding the shared livingid parser during this merge-safe implementation slice.

Types

type AddCitationInput

type AddCitationInput struct {
	ID        string
	Kind      CitationKind
	Title     string
	Reference string
	CreatedAt time.Time
	RequestID string
}

type AddRelationInput

type AddRelationInput struct {
	ID                string
	Type              RelationType
	From              string
	To                string
	Rationale         string
	FromRevision      string
	ToRevision        string
	FromContentDigest string
	ToContentDigest   string
	CreatedAt         time.Time
	RequestID         string
}

type AddStoryInput

type AddStoryInput struct {
	ID                 string
	RevisionID         string
	EventID            string
	Title              string
	Statement          string
	Priority           string
	Citations          []string
	AcceptanceCriteria []Criterion
	CreatedAt          time.Time
	RequestID          string
}

type Citation

type Citation struct {
	Schema    string       `json:"$schema"`
	Version   int          `json:"version"`
	ID        string       `json:"id"`
	Kind      CitationKind `json:"kind"`
	Title     string       `json:"title"`
	Reference string       `json:"reference"`
	CreatedAt time.Time    `json:"created_at"`
	RequestID string       `json:"request_id,omitempty"`
}

Citation is immutable. Reference is the authoritative locator: an absolute URL, repository-and-commit notation, issue key/URL, document identity, or recorded-decision identity according to Kind.

type CitationKind

type CitationKind string
const (
	CitationURL              CitationKind = "url"
	CitationRepositoryCommit CitationKind = "repository_commit"
	CitationIssue            CitationKind = "issue"
	CitationDocument         CitationKind = "document"
	CitationDecision         CitationKind = "decision"
)

type Criterion

type Criterion struct {
	ID        string `json:"id"`
	Statement string `json:"statement"`
}

type Document

type Document struct {
	Root      string
	SagaID    string
	Stories   []Story
	Citations []Citation
	Relations []Relation
}

func Load

func Load(root, sagaID string) (Document, error)

func LoadWithOptions

func LoadWithOptions(root, sagaID string, options LoadOptions) (Document, error)

LoadWithOptions strictly loads only the bounded requirements-domain roots. It never follows symlinks and never opens narrative, design, work-plan, review, or diff content.

type LifecycleEvent

type LifecycleEvent struct {
	Schema    string         `json:"$schema"`
	Version   int            `json:"version"`
	ID        string         `json:"id"`
	Story     string         `json:"story"`
	Parents   []string       `json:"parents"`
	State     LifecycleState `json:"state"`
	Reason    string         `json:"reason,omitempty"`
	CreatedAt time.Time      `json:"created_at"`
	RequestID string         `json:"request_id,omitempty"`
}

type LifecycleState

type LifecycleState string
const (
	StateProposed LifecycleState = "proposed"
	StateAccepted LifecycleState = "accepted"
	StateDeferred LifecycleState = "deferred"
	StateRejected LifecycleState = "rejected"
	StateRetired  LifecycleState = "retired"
)

type LoadOptions

type LoadOptions struct {
	StaleInputs StaleInputs
}

type MutationResult

type MutationResult struct {
	URN      string
	Path     string
	Replayed bool
}

func AddCitation

func AddCitation(root, sagaID string, input AddCitationInput) (MutationResult, error)

func AddRelation

func AddRelation(root, sagaID string, input AddRelationInput) (MutationResult, error)

func AddStory

func AddStory(root, sagaID string, input AddStoryInput) (MutationResult, error)

func ReviseStory

func ReviseStory(root, sagaID string, input ReviseStoryInput) (MutationResult, error)

func SetStoryState

func SetStoryState(root, sagaID string, input SetStoryStateInput) (MutationResult, error)

func SupersedeRelation

func SupersedeRelation(root, sagaID, relation string, at time.Time, requestID string) (MutationResult, error)

SupersedeRelation explicitly deactivates one relation without retargeting it. The replacement is atomic, serialized, and preserves all endpoint pins.

type Relation

type Relation struct {
	Schema             string        `json:"$schema"`
	Version            int           `json:"version"`
	ID                 string        `json:"id"`
	Type               RelationType  `json:"type"`
	From               string        `json:"from"`
	To                 string        `json:"to"`
	Rationale          string        `json:"rationale"`
	FromRevision       string        `json:"from_revision,omitempty"`
	ToRevision         string        `json:"to_revision,omitempty"`
	FromContentDigest  string        `json:"from_content_digest,omitempty"`
	ToContentDigest    string        `json:"to_content_digest,omitempty"`
	State              RelationState `json:"state"`
	CreatedAt          time.Time     `json:"created_at"`
	RequestID          string        `json:"request_id,omitempty"`
	SupersededAt       *time.Time    `json:"superseded_at,omitempty"`
	SupersedeRequestID string        `json:"supersede_request_id,omitempty"`

	Stale        bool     `json:"-"`
	StaleReasons []string `json:"-"`
}

Relation pins mutable endpoints separately from their stable identities. Computed stale fields are projections and are never persisted.

type RelationState

type RelationState string
const (
	RelationActive     RelationState = "active"
	RelationSuperseded RelationState = "superseded"
)

type RelationType

type RelationType string
const (
	RelationRefines       RelationType = "refines"
	RelationAddresses     RelationType = "addresses"
	RelationImplements    RelationType = "implements"
	RelationVerifies      RelationType = "verifies"
	RelationSupersedes    RelationType = "supersedes"
	RelationConflictsWith RelationType = "conflicts_with"
)

type ReviseStoryInput

type ReviseStoryInput struct {
	Story              string
	ID                 string
	Parents            []string
	Title              string
	Statement          string
	Priority           string
	Citations          []string
	AcceptanceCriteria []Criterion
	CreatedAt          time.Time
	RequestID          string
}

type Revision

type Revision struct {
	Schema             string      `json:"$schema"`
	Version            int         `json:"version"`
	ID                 string      `json:"id"`
	Story              string      `json:"story"`
	Parents            []string    `json:"parents"`
	Title              string      `json:"title"`
	Statement          string      `json:"statement"`
	Priority           string      `json:"priority"`
	Citations          []string    `json:"citations"`
	AcceptanceCriteria []Criterion `json:"acceptance_criteria"`
	CreatedAt          time.Time   `json:"created_at"`
	RequestID          string      `json:"request_id,omitempty"`
}

Revision is a complete story snapshot. A reader never inherits omitted values from a parent, which keeps branch merges deterministic.

type SetStoryStateInput

type SetStoryStateInput struct {
	Story     string
	ID        string
	Parents   []string
	State     LifecycleState
	Reason    string
	CreatedAt time.Time
	RequestID string
}

type StaleInputs

type StaleInputs struct {
	CurrentRevisions      map[string]string
	CurrentContentDigests map[string]string
	Missing               map[string]bool
}

StaleInputs supplies current values owned outside this package. Keys are stable endpoint URNs. Missing marks identities known to have disappeared; an absent map entry alone means "unknown", not stale.

type Story

type Story struct {
	Identity  StoryIdentity
	Revisions []Revision
	Events    []LifecycleEvent

	RevisionHeads    []string
	LifecycleHeads   []string
	CurrentRevision  *Revision
	CurrentLifecycle *LifecycleEvent
}

func (Story) LifecycleConflict

func (story Story) LifecycleConflict() bool

func (Story) RevisionConflict

func (story Story) RevisionConflict() bool

type StoryIdentity

type StoryIdentity struct {
	Schema    string    `json:"$schema"`
	Version   int       `json:"version"`
	ID        string    `json:"id"`
	CreatedAt time.Time `json:"created_at"`
	RequestID string    `json:"request_id,omitempty"`
}

Jump to

Keyboard shortcuts

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