prototypes

package
v0.1.1 Latest Latest
Warning

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

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

Documentation

Overview

Package prototypes owns the optional v3 prototype capability of a living Change Saga. It is deliberately independent of the Saga loader, CLI, query registry, server, and requirements package; cross-domain checks happen only through Compose.

Index

Constants

View Source
const (
	Version = 3

	IdentitySchemaURL   = "https://changesaga.dev/schema/v3/prototype.schema.json"
	RevisionSchemaURL   = "https://changesaga.dev/schema/v3/prototype-revision.schema.json"
	AnnotationSchemaURL = "https://changesaga.dev/schema/v3/prototype-annotation.schema.json"

	MaxPrototypes            = 10_000
	MaxRevisionsPerPrototype = 10_000
	MaxAnnotations           = 50_000
	MaxRecordBytes           = 1 << 20
	MaxHTMLFiles             = 2_000
	MaxHTMLFileBytes         = 8 << 20
	MaxHTMLPackageBytes      = 64 << 20
)

Variables

This section is empty.

Functions

func AnnotationURN

func AnnotationURN(sagaID, prototypeID, annotationID string) (string, error)

func PrototypeURN

func PrototypeURN(sagaID, prototypeID string) (string, error)

func ReadPinnedStyle

func ReadPinnedStyle(repositoryRoot string, style StyleSource) ([]byte, error)

ReadPinnedStyle returns repository CSS only when the requested declaration is safe and still matches its SHA-256 pin. Viewers can use this as the sole style-serving boundary instead of opening arbitrary repository paths.

func RevisionURN

func RevisionURN(sagaID, prototypeID, revisionID string) (string, error)

Types

type AddAnnotationInput

type AddAnnotationInput struct {
	ID, Prototype, Target, Rationale string
	PrototypeRevision                string
	PrototypeContentDigest           string
	StoryRevision                    string
	Selector                         Selector
	CreatedAt                        time.Time
	RequestID                        string
}

type AddExternalInput

type AddExternalInput struct {
	ID, RevisionID, Title string
	State                 State
	URL                   string
	EmbedURL              string
	FallbackURL           string
	Allowlist             *ProviderAllowlist
	CreatedAt             time.Time
	RequestID             string
}

type AddHTMLInput

type AddHTMLInput struct {
	ID, RevisionID, Title string
	State                 State
	SourcePath            string
	CreatedAt             time.Time
	RequestID             string
}

type AddStyleInput

type AddStyleInput struct {
	Prototype        string
	ID               string
	Parents          []string
	RepositoryRoot   string
	Path             string
	CustomProperties []string
	Roles            []StyleRole
	CreatedAt        time.Time
	RequestID        string
}

type Annotation

type Annotation struct {
	Schema                 string    `json:"$schema"`
	Version                int       `json:"version"`
	ID                     string    `json:"id"`
	Prototype              string    `json:"prototype"`
	Target                 string    `json:"target"`
	Rationale              string    `json:"rationale"`
	PrototypeRevision      string    `json:"prototype_revision,omitempty"`
	PrototypeContentDigest string    `json:"prototype_content_digest,omitempty"`
	StoryRevision          string    `json:"story_revision"`
	Selector               Selector  `json:"selector"`
	CreatedAt              time.Time `json:"created_at"`
	RequestID              string    `json:"request_id,omitempty"`
}

Annotation is the single persisted edge between a prototype and a story or criterion. Endpoint existence is intentionally not a record-level rule.

type AnnotationProjection

type AnnotationProjection struct {
	Annotation        Annotation `json:"annotation"`
	PrototypeResolved bool       `json:"prototype_resolved"`
	TargetResolved    bool       `json:"target_resolved"`
	Current           bool       `json:"current"`
	StaleReasons      []string   `json:"stale_reasons"`
}

type CompositionInputs

type CompositionInputs struct {
	Stories []StoryInput
}

CompositionInputs are owned by the caller so this package does not import the requirements domain. They describe only the current requirement heads.

type CoverageProjection

type CoverageProjection struct {
	Capability  string                 `json:"capability"`
	Annotations []AnnotationProjection `json:"annotations"`
	Prototypes  []ResourceCoverage     `json:"prototypes"`
	Stories     []ResourceCoverage     `json:"stories"`
	Gaps        []QualityGap           `json:"gaps"`
}

func Compose

func Compose(document Document, inputs CompositionInputs) CoverageProjection

Compose resolves the prototype domain against a caller-supplied requirements snapshot. Missing endpoints and stale pins become quality gaps, never structural load errors. The returned edge list is the one source for both prototype-to-story and story-to-prototype projections.

func ProjectCoverage

func ProjectCoverage(document Document, inputs CompositionInputs) CoverageProjection

ProjectCoverage is a naming alias suited to query adapters.

type Document

type Document struct {
	Root        string
	SagaID      string
	Adopted     bool
	Prototypes  []Prototype
	Annotations []Annotation
}

func Load

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

func LoadWithOptions

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

LoadWithOptions reads only saga.json and ___requirements/prototypes. It never follows symlinks or opens stories, narrative, design, work-plan, review, or diff data.

type Identity

type Identity 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"`
}

type LoadOptions

type LoadOptions struct {
	// RepositoryRoot is optional. When supplied, declared repository CSS is
	// re-read safely and its projection is marked stale if its pin changed.
	RepositoryRoot string
}

type MutationResult

type MutationResult struct {
	URN      string
	Path     string
	Replayed bool
}

func AddAnnotation

func AddAnnotation(root, sagaID string, input AddAnnotationInput) (MutationResult, error)

func AddExternal

func AddExternal(root, sagaID string, input AddExternalInput) (MutationResult, error)

func AddExternalPrototype

func AddExternalPrototype(root, sagaID string, input AddExternalInput) (MutationResult, error)

func AddHTML

func AddHTML(root, sagaID string, input AddHTMLInput) (MutationResult, error)

func AddHTMLPrototype

func AddHTMLPrototype(root, sagaID string, input AddHTMLInput) (MutationResult, error)

AddHTMLPrototype is an explicit-name alias for adapters that prefer the resource noun in mutation calls.

func AddRepositoryStyle

func AddRepositoryStyle(root, sagaID string, input AddStyleInput) (MutationResult, error)

func AddStyle

func AddStyle(root, sagaID string, input AddStyleInput) (MutationResult, error)

AddStyle appends a revision that pins one validated repository stylesheet. The prior immutable HTML tree is copied into the new revision package.

func Annotate

func Annotate(root, sagaID string, input AddAnnotationInput) (MutationResult, error)

func RefreshRepositoryStyle

func RefreshRepositoryStyle(root, sagaID string, input AddStyleInput) (MutationResult, error)

func Revise

func Revise(root, sagaID string, input ReviseInput) (MutationResult, error)

Revise appends a complete revision. HTML revisions must provide a fresh HTMLSourcePath; this prevents a mutable directory outside the Saga from becoming an implicit part of the revision.

func RevisePrototype

func RevisePrototype(root, sagaID string, input ReviseInput) (MutationResult, error)

type Prototype

type Prototype struct {
	Identity        Identity
	Revisions       []Revision
	RevisionHeads   []string
	CurrentRevision *Revision
}

func (Prototype) RevisionConflict

func (p Prototype) RevisionConflict() bool

type ProviderAllowlist

type ProviderAllowlist struct {
	Provider    string   `json:"provider"`
	EmbedOrigin string   `json:"embed_origin"`
	Sandbox     []string `json:"sandbox"`
	Permissions []string `json:"permissions"`
}

type QualityGap

type QualityGap struct {
	Kind     string `json:"kind"`
	Resource string `json:"resource"`
	Message  string `json:"message"`
}

type Region

type Region struct {
	X      float64 `json:"x"`
	Y      float64 `json:"y"`
	Width  float64 `json:"width"`
	Height float64 `json:"height"`
}

type ResourceCoverage

type ResourceCoverage struct {
	Resource    string   `json:"resource"`
	Status      string   `json:"status"`
	Annotations []string `json:"annotations"`
}

type ReviseInput

type ReviseInput struct {
	Prototype      string
	ID             string
	Parents        []string
	Title          string
	State          State
	Source         Source
	HTMLSourcePath string
	Styles         []StyleSource
	CreatedAt      time.Time
	RequestID      string
}

type Revision

type Revision struct {
	Schema    string        `json:"$schema"`
	Version   int           `json:"version"`
	ID        string        `json:"id"`
	Prototype string        `json:"prototype"`
	Parents   []string      `json:"parents"`
	Title     string        `json:"title"`
	State     State         `json:"state"`
	Source    Source        `json:"source"`
	Styles    []StyleSource `json:"styles"`
	CreatedAt time.Time     `json:"created_at"`
	RequestID string        `json:"request_id,omitempty"`
}

Revision is a complete snapshot. Source files for an HTML revision are immutable children of the same <id>.revision package as revision.json.

type Selector

type Selector struct {
	Kind       SelectorKind `json:"kind"`
	ElementID  string       `json:"element_id,omitempty"`
	ExactText  string       `json:"exact_text,omitempty"`
	Region     *Region      `json:"region,omitempty"`
	ProviderID string       `json:"provider_id,omitempty"`
	DeepLink   string       `json:"deep_link,omitempty"`
}

type SelectorKind

type SelectorKind string
const (
	SelectorElement  SelectorKind = "element"
	SelectorText     SelectorKind = "text"
	SelectorRegion   SelectorKind = "region"
	SelectorProvider SelectorKind = "provider"
)

type Source

type Source struct {
	Kind          SourceKind         `json:"kind"`
	Entrypoint    string             `json:"entrypoint,omitempty"`
	ContentDigest string             `json:"content_digest,omitempty"`
	URL           string             `json:"url,omitempty"`
	EmbedURL      string             `json:"embed_url,omitempty"`
	FallbackURL   string             `json:"fallback_url,omitempty"`
	Allowlist     *ProviderAllowlist `json:"allowlist,omitempty"`
}

Source is a closed discriminated union. HTML paths are relative to their immutable revision package. Embed allowlisting is persisted explicitly so a viewer never infers permission merely from a recognizable hostname.

type SourceKind

type SourceKind string
const (
	SourceHTML     SourceKind = "html"
	SourceExternal SourceKind = "external"
	SourceEmbed    SourceKind = "embed"
)

type State

type State string
const (
	StateDraft   State = "draft"
	StateReady   State = "ready"
	StateRetired State = "retired"
)

type StoryInput

type StoryInput struct {
	URN               string
	CurrentRevision   string
	Criteria          []string
	PrototypeRequired bool
}

type StyleRole

type StyleRole struct {
	Role  string `json:"role"`
	Class string `json:"class"`
}

type StyleSource

type StyleSource struct {
	Path             string      `json:"path"`
	Digest           string      `json:"digest"`
	CustomProperties []string    `json:"custom_properties"`
	Roles            []StyleRole `json:"roles"`

	Stale       bool   `json:"-"`
	StaleReason string `json:"-"`
}

Jump to

Keyboard shortcuts

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