Documentation
¶
Index ¶
- Constants
- func AggregateReviewState(reviews []Review) string
- func ChapterTarget(sagaID, chapterID string) string
- func CurrentDesignContentDigest(document *Saga, target string) (string, bool, error)
- func CurrentDesignContentDigests(document *Saga) (map[string]string, error)
- func DeckTarget(sagaID, deckID string) string
- func EntrypointError(value string) string
- func FlatAttachmentFilename(messageID string, order int, fragmentID string) (string, error)
- func FlatClaimFilename(id string) string
- func FlatDeckFilename(target string, rank int) (string, error)
- func FlatDiffReviewFilename(id string) string
- func FlatEvidenceFilename(target, identity string) string
- func FlatItemFilename(slideTarget, itemTarget string, rank int) (string, error)
- func FlatKey(value string) string
- func FlatMessageFilename(threadID, id string) string
- func FlatReviewFilename(target, id string) string
- func FlatSlideAssetFilename(slideManifest, extension string) (string, error)
- func FlatSlideFilename(deckTarget, slideTarget string, rank int) (string, error)
- func FlatTargetKey(target string) string
- func FlatThreadEventFilename(threadID, id string) string
- func FlatThreadFilename(target, id string) string
- func FlatVerificationFilename(claimID, id string) string
- func FragmentTarget(sagaID, fragmentID string) string
- func FullLoadCount() uint64
- func IsFlatReviewRecord(name string) bool
- func ItemTarget(sagaID, slideID, itemID string) string
- func LandmarkTarget(sagaID, fragmentID, landmarkID string) string
- func Load(root string) (*Saga, Validation, error)
- func LoadMutationIndex(root string) (MutationIndex, Validation, error)
- func LoadNarrative(root string) (*Saga, Validation, error)
- func LoadOutline(root string) (*Saga, Validation, error)
- func LoadReviewState(index MutationIndex) (ReviewState, Validation, error)
- func LoadTargetDiffs(index MutationIndex, target string) ([]DiffFile, Validation, error)
- func PortabilityWarning(name string) string
- func PortablePathWarning(value string) string
- func ReviewIdentityKey(review Review) string
- func SagaSchemaURL(version int) string
- func SagaTarget(sagaID string) string
- func SectionTarget(sagaID, sectionID string) string
- func SlideTarget(sagaID, slideID string) string
- func SupportedSagaVersion(version int) bool
- func ValidAnnotationColor(value string) bool
- func ValidClaimKind(value string) bool
- func ValidID(value string) bool
- func ValidMarkdownAnchor(value string) bool
- func ValidMediaType(value string) bool
- func ValidVerificationMethod(value string) bool
- func ValidVerificationStatus(value string) bool
- func ValidateAnchor(anchor Anchor) error
- func ValidateFlatRoot(root string) error
- func ValidateReviewerIdentity(reviewer *ReviewerIdentity) error
- type AddedAnchor
- type Anchor
- type ChapterManifest
- type Claim
- type Deck
- type DeckManifest
- type DiffFile
- type DiffReference
- type DiffReview
- type DiffSelector
- type Fragment
- type FragmentManifest
- type Issue
- type Item
- type ItemManifest
- type Landmark
- type LandmarkRegion
- type LandmarkSelector
- type Manifest
- type MarkdownFootnote
- type MarkdownHeading
- type Message
- type MessageManifest
- type MutationIndex
- type NoteSelector
- type PR
- type Point
- type Presentation
- type Review
- type ReviewState
- type ReviewerIdentity
- type Saga
- type Section
- type SectionManifest
- type Shape
- type Slide
- type SlideManifest
- type Source
- type Suggestion
- type TextSelector
- type Thread
- type ThreadEvent
- type ThreadManifest
- type Validation
- type Verification
Constants ¶
const ( MaxDesignDigestTargets = 10_000 MaxDesignDigestFilesPerTarget = 1_024 MaxDesignDigestBytesPerTarget = 16 << 20 )
const ( FlatManifestName = "00-saga.json" FlatMaxBasename = 64 FlatMaxPath = 240 )
const ( // ComponentVersion is the version of the existing narrative, evidence, and // review records. A v3 Saga container deliberately continues to use these // byte-compatible v2 component records. ComponentVersion = 2 LegacySagaVersion = 2 CurrentSagaVersion = 3 SlideSagaVersion = 4 V2SchemaURL = "https://changesaga.dev/schema/v2/saga.schema.json" V3SchemaURL = "https://changesaga.dev/schema/v3/saga.schema.json" V4SchemaURL = "https://changesaga.dev/schema/v4/saga.schema.json" // CurrentVersion and SchemaURL remain the v2 component/init aliases. Keeping // them stable prevents adding v3-only roots without an explicit upgrade. CurrentVersion = ComponentVersion SchemaURL = V2SchemaURL )
const MaxNoteRunes = 2000
MaxNoteRunes bounds sticky note text so a single annotation stays a compact canvas note rather than an unbounded document; schema/v2 enforces the same limit as maxLength.
Variables ¶
This section is empty.
Functions ¶
func AggregateReviewState ¶ added in v0.1.0
AggregateReviewState is deliberately conservative: one current rejection wins, otherwise one or more approvals produce approved, and no decisions is unreviewed. The individual decisions remain available to show who approved.
func ChapterTarget ¶
func CurrentDesignContentDigest ¶ added in v0.1.0
CurrentDesignContentDigest looks up one addressable design target using the same canonical digest contract as CurrentDesignContentDigests.
func CurrentDesignContentDigests ¶ added in v0.1.0
CurrentDesignContentDigests returns the current digest for every addressable target beneath ___design. Digests cover authored design content only: evidence, approvals, and review records do not invalidate requirement or work-plan relations. The fixed budgets keep a query from turning one design target into an unbounded filesystem read.
func DeckTarget ¶ added in v0.1.0
func EntrypointError ¶
EntrypointError reports why a fragment entrypoint is unusable, or "" when it is a well-formed package-relative path.
The check is deliberately expressed in slash-path terms rather than through path/filepath. filepath.Clean rewrites "assets/app.js" to "assets\app.js" on Windows, so an OS-dependent normalization comparison would reject a portable nested entrypoint on exactly one platform. Backslashes are rejected outright because they are an ordinary filename byte on Unix and a separator on Windows, which would make one saga address two different files.
func FlatAttachmentFilename ¶ added in v0.1.0
func FlatClaimFilename ¶ added in v0.1.0
func FlatDeckFilename ¶ added in v0.1.0
func FlatDiffReviewFilename ¶ added in v0.1.0
func FlatEvidenceFilename ¶ added in v0.1.0
func FlatItemFilename ¶ added in v0.1.0
func FlatMessageFilename ¶ added in v0.1.0
func FlatReviewFilename ¶ added in v0.1.0
func FlatSlideAssetFilename ¶ added in v0.1.0
func FlatSlideFilename ¶ added in v0.1.0
func FlatTargetKey ¶ added in v0.1.0
func FlatThreadEventFilename ¶ added in v0.1.0
func FlatThreadFilename ¶ added in v0.1.0
func FlatVerificationFilename ¶ added in v0.1.0
func FragmentTarget ¶
func FullLoadCount ¶ added in v0.0.8
func FullLoadCount() uint64
FullLoadCount reports process-local full Saga loads. It is diagnostic instrumentation used by scale budgets to keep review mutations off this path; review-only and mutation-index loads do not increment it.
func IsFlatReviewRecord ¶ added in v0.1.0
IsFlatReviewRecord reports whether name belongs to the mutable review overlay in a v4 Saga. Keeping this classification beside the filename grammar lets caches observe review changes without mistaking authored deck, slide, Item, or evidence records for mutable review state.
func ItemTarget ¶ added in v0.1.0
func LandmarkTarget ¶
func LoadMutationIndex ¶ added in v0.0.8
func LoadMutationIndex(root string) (MutationIndex, Validation, error)
LoadMutationIndex validates the manifest/package skeleton and returns exact target directories. It is intentionally bounded by authored hierarchy nodes, not by the number of diff mappings or changed atoms.
func LoadNarrative ¶ added in v0.0.8
func LoadNarrative(root string) (*Saga, Validation, error)
LoadNarrative reads the complete reviewable narrative and annotations while leaving coverage records and diff-review state unopened. Incremental prose endpoints use it so reaching a chapter or fragment cannot trigger coverage graph construction.
func LoadOutline ¶ added in v0.0.8
func LoadOutline(root string) (*Saga, Validation, error)
LoadOutline reads the narrative and review metadata needed to render the reviewer shell without opening coverage records, landmark records, claims, verifications, diff reviews, fragment content, or message attachments. It is deliberately not a replacement for Load: callers that make readiness or mutation decisions must still use the complete validated model.
func LoadReviewState ¶ added in v0.0.8
func LoadReviewState(index MutationIndex) (ReviewState, Validation, error)
LoadReviewState reads only review-owned paths named by a validated mutation index. It never opens coverage mappings or ordinary authored fragments.
func LoadTargetDiffs ¶ added in v0.0.8
func LoadTargetDiffs(index MutationIndex, target string) ([]DiffFile, Validation, error)
LoadTargetDiffs reads only one validated narrative target's authored evidence. It is the bounded mapping seam used by linked-code requests: no sibling target's ___diffs directory is opened.
func PortabilityWarning ¶
PortabilityWarning reports why a path component cannot exist on every platform Change Saga supports, or "" when the name is portable. It never produces errors: a saga that already contains such a name stays loadable on the platform that created it, but authors are told before publishing it.
func PortablePathWarning ¶
PortablePathWarning applies PortabilityWarning to every component of a slash path.
func ReviewIdentityKey ¶ added in v0.1.0
ReviewIdentityKey identifies a reviewer persona without trusting the legacy payload author. Read surfaces populate AttributionIdentity from Git; loaders that have not resolved Git yet fall back to the display author or local attribution bucket while still separating human, AI, and legacy personas.
func SagaSchemaURL ¶ added in v0.1.0
func SagaTarget ¶
func SectionTarget ¶
func SlideTarget ¶ added in v0.1.0
func SupportedSagaVersion ¶ added in v0.1.0
func ValidAnnotationColor ¶
func ValidClaimKind ¶ added in v0.0.2
func ValidMarkdownAnchor ¶
func ValidMediaType ¶
ValidMediaType reports whether a fragment media type is one the format defines. Engines render text/markdown, text/html, text/plain, image/svg+xml, and raster image/* fragments.
func ValidVerificationMethod ¶ added in v0.0.2
func ValidVerificationStatus ¶ added in v0.0.2
func ValidateAnchor ¶
func ValidateFlatRoot ¶ added in v0.1.0
func ValidateReviewerIdentity ¶ added in v0.1.0
func ValidateReviewerIdentity(reviewer *ReviewerIdentity) error
ValidateReviewerIdentity validates explicit provenance on a newly recorded review. A nil identity is accepted for compatibility with legacy records.
Types ¶
type AddedAnchor ¶ added in v0.0.2
type AddedAnchor struct {
Line int `json:"line"`
Heading string `json:"heading"`
Anchor string `json:"anchor"`
}
AddedAnchor records one heading that gained a stable anchor.
func FixMarkdownHeadingAnchors ¶ added in v0.0.2
func FixMarkdownHeadingAnchors(content []byte, reserved map[string]bool) ([]byte, []AddedAnchor)
FixMarkdownHeadingAnchors appends " {#anchor}" to every heading that does not already declare one and returns the rewritten content. It is deliberately the narrowest possible edit: headings that already carry an anchor keep it, fenced code is skipped, and every other byte — including indentation, blank lines, and CRLF endings — is preserved. Nothing is renamed, so an anchor that a landmark or link already points at cannot move.
reserved names identifiers the generated anchors must avoid, which is how a non-heading landmark keeps its id from being claimed by a heading that would then conflict with it.
type Anchor ¶
type Anchor struct {
Type string `json:"type"`
Shapes []Shape `json:"shapes,omitempty"`
Text *TextSelector `json:"text,omitempty"`
Note *NoteSelector `json:"note,omitempty"`
Diff *DiffSelector `json:"diff,omitempty"`
Coordinate string `json:"coordinate_space,omitempty"`
}
type ChapterManifest ¶
type Claim ¶ added in v0.0.2
type Claim struct {
Path string `json:"-"`
Version int `json:"version"`
ID string `json:"id"`
Target string `json:"target"`
Kind string `json:"kind"`
Statement string `json:"statement"`
Evidence []string `json:"evidence"`
CreatedAt time.Time `json:"created_at"`
}
Claim is one falsifiable assertion made by the change author. Claims are deliberately independent records: adding a second claim never rewrites the first record and two authors do not contend on one aggregate manifest. Evidence here does not contribute to coverage; it points at exact code that an independent reviewer can inspect when testing the assertion.
type DeckManifest ¶ added in v0.1.0
type DiffFile ¶
type DiffFile struct {
Path string `json:"-"`
Version int `json:"version"`
Diffs []DiffReference `json:"diffs"`
}
type DiffReference ¶
type DiffReview ¶
type DiffSelector ¶
type DiffSelector struct {
URI string `json:"uri"`
}
type Fragment ¶
type Fragment struct {
Path string `json:"path"`
Directory string `json:"-"`
ID string `json:"id"`
Title string `json:"title,omitempty"`
MediaType string `json:"media_type"`
Entrypoint string `json:"entrypoint"`
Order int `json:"order,omitempty"`
Target string `json:"target"`
Diffs []DiffFile `json:"diffs,omitempty"`
HasDiffs bool `json:"-"`
Landmarks []Landmark `json:"landmarks,omitempty"`
Reviews []Review `json:"reviews,omitempty"`
SlideMeta *SlideManifest `json:"-"`
}
type FragmentManifest ¶
type ItemManifest ¶ added in v0.1.0
type ItemManifest struct {
Version int `json:"version"`
ID string `json:"id"`
SlideID string `json:"slide"`
Rank int `json:"rank"`
Kind string `json:"kind"`
Label string `json:"label"`
Description string `json:"description,omitempty"`
Selector LandmarkSelector `json:"selector"`
Hotspot *LandmarkRegion `json:"hotspot,omitempty"`
About string `json:"about,omitempty"`
Body string `json:"body,omitempty"`
Placement string `json:"placement,omitempty"`
Leader string `json:"leader,omitempty"`
}
type Landmark ¶
type Landmark struct {
Path string `json:"-"`
Directory string `json:"-"`
Version int `json:"version"`
ID string `json:"id"`
Label string `json:"label"`
Description string `json:"description,omitempty"`
Selector LandmarkSelector `json:"selector"`
Hotspot *LandmarkRegion `json:"hotspot,omitempty"`
Target string `json:"target"`
Diffs []DiffFile `json:"diffs,omitempty"`
HasDiffs bool `json:"-"`
ItemMeta *ItemManifest `json:"-"`
Reviews []Review `json:"reviews,omitempty"`
}
type LandmarkRegion ¶
type LandmarkSelector ¶
type LandmarkSelector struct {
Type string `json:"type"`
ElementID string `json:"element_id,omitempty"`
HeadingID string `json:"heading_id,omitempty"`
Exact string `json:"exact,omitempty"`
Prefix string `json:"prefix,omitempty"`
Suffix string `json:"suffix,omitempty"`
X float64 `json:"x,omitempty"`
Y float64 `json:"y,omitempty"`
Width float64 `json:"width,omitempty"`
Height float64 `json:"height,omitempty"`
}
type Manifest ¶
type Manifest struct {
Schema string `json:"$schema,omitempty"`
Version int `json:"version"`
ID string `json:"id"`
Title string `json:"title"`
PR *PR `json:"pr,omitempty"`
Source Source `json:"source"`
Presentation *Presentation `json:"presentation,omitempty"`
}
func ReadManifest ¶ added in v0.1.0
ReadManifest reads only the root manifest. Format-aware front ends use it to refuse ambiguous report/slide operations before opening a heavier application view.
type MarkdownFootnote ¶ added in v0.1.0
MarkdownFootnote describes the single-line, plain-text definition used by prose diff citations. Keeping this subset deliberately small makes the definition suitable for an exact-text landmark.
func MarkdownFootnotes ¶ added in v0.1.0
func MarkdownFootnotes(source string) []MarkdownFootnote
MarkdownFootnotes returns prose citation definitions outside fenced code. Change Saga's authoring contract keeps these definitions on one line and in plain text so the same bytes can be selected by an exact-text landmark.
type MarkdownHeading ¶
MarkdownHeading describes the small heading subset supported by the reference renderer. Explicit anchors use: ## Heading {#stable-anchor}.
func MarkdownHeadings ¶
func MarkdownHeadings(source string) []MarkdownHeading
func ParseMarkdownHeading ¶
func ParseMarkdownHeading(line string) (MarkdownHeading, bool)
type MessageManifest ¶
type MutationIndex ¶ added in v0.0.8
type MutationIndex struct {
Root string
Manifest Manifest
Targets map[string]string
ReviewTargets map[string]string
}
MutationIndex is the small structural contract needed to append review records safely. It reads manifests and package names, never coverage mappings or authored bodies, so a comment does not parse the full saga diff index.
func MutationIndexFromDocument ¶ added in v0.0.8
func MutationIndexFromDocument(document *Saga) MutationIndex
MutationIndexFromDocument derives the compact mutation view from an already validated structural generation without touching disk again.
type NoteSelector ¶
type PR ¶
PR uses a pointer for Number so an absent pull request number stays absent. schema/v2/saga.schema.json requires a positive number when the field is present; a plain int could not tell "unset" from an invalid literal 0.
type Presentation ¶ added in v0.1.0
type Review ¶
type Review struct {
Path string `json:"-"`
AttributionDetail string `json:"-"`
AttributionIdentity string `json:"-"`
Version int `json:"version"`
ID string `json:"id"`
Author string `json:"author,omitempty"`
Reviewer *ReviewerIdentity `json:"reviewer,omitempty"`
State string `json:"state"`
Body string `json:"body,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
func CurrentReviews ¶ added in v0.1.0
CurrentReviews returns the latest event for every distinct reviewer persona. Git attribution identifies the author; reviewer metadata distinguishes that author's direct decision from decisions made through individual AI agents. An open or closed event retracts only the matching persona's decision.
type ReviewState ¶ added in v0.0.8
type ReviewState struct {
Threads []*Thread
DiffReviews []DiffReview
ByTarget map[string][]Review
}
ReviewState is the mutable overlay stored independently from source and coverage indexes.
type ReviewerIdentity ¶ added in v0.1.0
type ReviewerIdentity struct {
Kind string `json:"kind"`
Name string `json:"name,omitempty"`
Agent string `json:"agent,omitempty"`
Model string `json:"model,omitempty"`
}
ReviewerIdentity describes the persona that made a review decision. Git remains the authority for who introduced the event; this metadata says whether that person acted directly or through a particular AI reviewer. It is optional only so review records created before this field existed stay readable without being incorrectly relabeled as human decisions.
type Saga ¶
type Saga struct {
Root string `json:"root"`
Manifest Manifest `json:"manifest"`
Section *Section `json:"section"`
Decks []*Deck `json:"decks,omitempty"`
Threads []*Thread `json:"threads,omitempty"`
DiffReviews []DiffReview `json:"diff_reviews,omitempty"`
Claims []Claim `json:"claims,omitempty"`
Verifications []Verification `json:"verifications,omitempty"`
}
type Section ¶
type Section struct {
Path string `json:"path"`
Kind string `json:"kind"`
ID string `json:"id"`
Title string `json:"title"`
Order int `json:"order,omitempty"`
Target string `json:"target"`
Children []*Section `json:"children,omitempty"`
Fragments []*Fragment `json:"fragments,omitempty"`
Diffs []DiffFile `json:"diffs,omitempty"`
// HasDiffs records the presence of this target's ___diffs directory without
// materializing any evidence records. Narrative-only loads use it to render
// a lazy linked-code affordance while keeping coverage metadata unopened.
HasDiffs bool `json:"-"`
Reviews []Review `json:"reviews,omitempty"`
}
type SectionManifest ¶
type Shape ¶
type Shape struct {
Type string `json:"type"`
X float64 `json:"x,omitempty"`
Y float64 `json:"y,omitempty"`
Width float64 `json:"width,omitempty"`
Height float64 `json:"height,omitempty"`
Points []Point `json:"points,omitempty"`
Color string `json:"color,omitempty"`
StrokeWidth float64 `json:"stroke_width,omitempty"`
}
type SlideManifest ¶ added in v0.1.0
type SlideManifest struct {
Version int `json:"version"`
ID string `json:"id"`
DeckID string `json:"deck"`
Title string `json:"title"`
Rank int `json:"rank"`
Intent string `json:"intent"`
Layout string `json:"layout"`
MediaType string `json:"media_type"`
Entrypoint string `json:"entrypoint"`
Takeaway string `json:"takeaway"`
ReadingOrder []string `json:"reading_order"`
ExceptionRationale string `json:"exception_rationale,omitempty"`
}
type Suggestion ¶
type Suggestion struct {
Replacement string `json:"replacement"`
}
type TextSelector ¶
type Thread ¶
type Thread struct {
Path string `json:"-"`
Version int `json:"version"`
ID string `json:"id"`
Target string `json:"target"`
Anchor Anchor `json:"anchor"`
Kind string `json:"kind,omitempty"`
Suggestion *Suggestion `json:"suggestion,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
CreatedAt time.Time `json:"created_at"`
Directory string `json:"-"`
AttributionDetail string `json:"-"`
Messages []*Message `json:"messages,omitempty"`
Events []ThreadEvent `json:"events,omitempty"`
State string `json:"state"`
}
type ThreadEvent ¶
type ThreadManifest ¶
type ThreadManifest struct {
Version int `json:"version"`
ID string `json:"id"`
Target string `json:"target"`
Anchor Anchor `json:"anchor"`
Kind string `json:"kind,omitempty"`
Suggestion *Suggestion `json:"suggestion,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
type Validation ¶
type Verification ¶ added in v0.0.2
type Verification struct {
Path string `json:"-"`
Version int `json:"version"`
ID string `json:"id"`
Claim string `json:"claim"`
Status string `json:"status"`
Method string `json:"method,omitempty"`
Summary string `json:"summary"`
Command string `json:"command,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
Verification is an append-only result for one claim. The latest result is useful for navigation, but the complete history remains committed as separate files so a later result never erases the earlier one.