Documentation
¶
Overview ¶
Package adr parses ADR files under docs/decisions, renders the INDEX.md decision index, and scaffolds new ADR files from the rendered template (awf new adr). Generated by awf sync (regenerates docs/decisions/INDEX.md).
Index ¶
- Constants
- Variables
- func AdoptionBoundary(dir string) (cutoff int, gaps []int, err error)
- func ContentDigest(sections map[string]string) string
- func FrozenContentEqual(before, after ADR) bool
- func HistoryTransitionValid(before, after ADR) bool
- func NewFile(dir, title string, format Format) (string, error)
- func NextNumber(dir string) (string, error)
- func RenderIndexMD(corpus Corpus) string
- func TransitionLegal(from, to string, format ...Format) bool
- type ADR
- func (a ADR) ApplicationBatches() ([]ApplicationBatch, error)
- func (a ADR) Bucket() string
- func (a ADR) DecisionItems() []int
- func (a ADR) DeclaredSlugs() []string
- func (a ADR) HasSameStatus(other ADR) bool
- func (a ADR) HasStatus() bool
- func (a ADR) InvariantDecls() []InvariantDecl
- func (a ADR) IsAbandoned() bool
- func (a ADR) IsAccepted() bool
- func (a ADR) IsGoverned() bool
- func (a ADR) IsImplemented() bool
- func (a ADR) IsImplementing() bool
- func (a ADR) IsInflight() bool
- func (a ADR) IsLegacyShipped() bool
- func (a ADR) IsLive() bool
- func (a ADR) IsProposed() bool
- func (a ADR) IsSuperseded() bool
- func (a ADR) IsV1() bool
- func (a ADR) IsV2() bool
- func (a ADR) OperationProgress() (OperationProgress, error)
- func (a ADR) ReachedAccepted() bool
- type ApplicationBatch
- type AppliedOperation
- type ClaimOperationHistory
- type Corpus
- func (c Corpus) All() []ADR
- func (c Corpus) ByNumber(num string) (ADR, bool)
- func (c Corpus) ClaimOperationHistory(claimID string) (ClaimOperationHistory, bool)
- func (c Corpus) Has(num string) bool
- func (c Corpus) NextIdentity() (int, error)
- func (c Corpus) OperationProgress(number string) (OperationProgress, bool, error)
- func (c Corpus) Raw(num string) ([]byte, error)
- type Format
- type FormatBoundaries
- type HistoryEvent
- type HistoryEventKind
- type InvariantDecl
- type OpVerb
- type Operation
- type OperationProgress
- type OperationRecord
- type Status
- type StatusEntry
Constants ¶
const ( V1FormatMarker = "current-state-v1" V2FormatMarker = "current-state-v2" )
Format markers are the exact governed `format:` frontmatter values.
Variables ¶
var FilenameRe = regexp.MustCompile(`^(\d{4})-.+\.md$`)
FilenameRe matches an ADR filename (NNNN-slug.md); group 1 is the 4-digit number.
Functions ¶
func AdoptionBoundary ¶ added in v0.22.0
AdoptionBoundary validates and seals the existing brownfield ADR identities. Every existing decision is legacy at first adoption; governed records cannot appear below the newly established cutoff.
func ContentDigest ¶ added in v0.22.0
ContentDigest computes the current-state-v1 content-sha256 over the five canonical sections in fixed order, excluding frontmatter and Status history. Each section is serialized as its heading line followed by its body with trailing whitespace stripped, so cosmetic trailing-blank-line noise does not change the digest while any substantive edit does. Accepted freezes this value; a later terminal Status-history entry must repeat it. awf both computes and re-verifies it, so this canonical form is the single source of truth.
func FrozenContentEqual ¶ added in v0.22.0
FrozenContentEqual reports whether a pair preserves canonical ADR content. Proposed records remain editable; every later status freezes the five content-sha256 sections at their before-state digest.
func HistoryTransitionValid ¶ added in v0.22.0
HistoryTransitionValid reports whether a pair preserves append-only Status history: equal histories at the same status, or an exact before prefix plus one entry when the status follows a legal lifecycle edge.
func NewFile ¶ added in v0.6.0
NewFile scaffolds a new ADR under dir: the next sequential number, the rendered template.md with every marker comment stripped and its date and title heading filled in, named NNNN-slug.md. Refuses to overwrite an existing file at that path. touches-state: adr-system/adr-lifecycle:adr-new-strips-markers - NewFile strips every marker comment from the copied template; proof in adr_test.go touches-state: adr-system/adr-lifecycle:adr-new-heading-matches-file - NewFile fills the heading from the allocated file number; proof in adr_test.go touches-state: adr-system/adr-lifecycle:adr-new-no-overwrite - refuse-overwrite guard; unbacked (unreachable), see ADR-0042 Verify note
func NextNumber ¶ added in v0.6.0
NextNumber returns the next available 4-digit ADR number for dir: one more than the highest number ParseDir finds, or "0001" for an ADR-less dir. touches-state: adr-system/adr-lifecycle:adr-new-sequential-numbering - NextNumber returns highest-plus-one; proof in adr_test.go
func RenderIndexMD ¶ added in v0.22.0
RenderIndexMD renders the decisions/INDEX.md index for corpus (ADR-0135 item 8). It replaces the status-partitioned ACTIVE.md with two sections: "In flight" lists the Proposed and Accepted ADRs whose adoption is still under way, and "History" is a compact roll of the terminal Implemented and Abandoned decisions kept only as rationale. Both sections always render, with a placeholder line when empty, so the content is never blank and its document-map link resolves out of the box. The content carries no generated-by banner - that is the caller's job (internal/project's generateIndexMD, via injectBanner).
func TransitionLegal ¶ added in v0.22.0
TransitionLegal reports whether from -> to is legal for the selected format. Omitting format preserves the V1 behavior used by existing callers.
Types ¶
type ADR ¶
type ADR struct {
Number string // e.g. "0001"
Title string // e.g. "ADR-0001: Template Overlay Rendering Engine"
Status string // e.g. "Accepted"
Date string // frontmatter date, retained verbatim as YYYY-MM-DD text
Filename string // e.g. "0001-template-overlay-rendering-engine.md"
Path string // path as globbed
Domains []string // `domains:` frontmatter (ADR-0014)
Tags []string // `tags:` frontmatter (keyword labels)
Related []int // `related:` frontmatter (ADR numbers)
Sections map[string]string // `## ` heading -> non-fenced section body
DecisionStart int // raw file byte offset of the Decision heading; 0 when absent
DecisionEnd int // raw file byte offset immediately after the Decision section; 0 when absent
// Governed fields are populated only for an ADR at or above one of the
// lock's format cutoffs. A legacy-format record leaves them zero.
Format Format // Legacy, CurrentStateV1, or CurrentStateV2
NoneState bool // State changes section is exactly "None."
Operations []Operation // parsed `## State changes` operations
History []HistoryEvent // parsed `## Status history` events
}
ADR is a parsed ADR record.
func ParseBytes ¶ added in v0.18.0
ParseBytes parses one ADR from bytes: status and the other frontmatter fields, plus the title from the first `# ` heading. It is the seam the git-blob consumers take (ADR-0130 item 5): internal/audit reads history rather than the working tree, so it cannot take a Corpus, but it can share the parser and the frontmatter schema, which is where the duplication actually was.
found reports whether frontmatter was present at all, which is the tri-state the audit needs: absent frontmatter is a legitimate empty status, while present-but-unparseable is an error. name is the ADR's base filename, from which Filename and Number are derived; Path is left empty, since a blob-sourced record has no working-tree path.
func ParseRecord ¶ added in v0.22.0
func ParseRecord(name string, data []byte, boundaries FormatBoundaries) (ADR, error)
ParseRecord routes by the V1 and V2 format boundaries.
func ParseV1 ¶ added in v0.22.0
ParseV1 parses and validates one current-state-v1 ADR. name is the base filename (Number is derived from it); Title comes from the first `# ` heading. It enforces the exact frontmatter, status enum, section order, sequential Decision items, State-changes and Status-history grammar, and the per-ADR lifecycle and digest rules. Cross-ADR facts (sequence contiguity, ID reuse, claim provenance) are validated at the corpus level.
func (ADR) ApplicationBatches ¶ added in v0.22.0
func (a ADR) ApplicationBatches() ([]ApplicationBatch, error)
ApplicationBatches projects the application records owned by a governed ADR.
func (ADR) Bucket ¶ added in v0.18.0
Bucket returns the legacy status group for an ADR. Every superseded ADR folds into one group regardless of the successor its status names.
func (ADR) DecisionItems ¶ added in v0.18.0
DecisionItems returns the numbers of the column-0 numbered items of the Decision section, in order of appearance.
func (ADR) DeclaredSlugs ¶ added in v0.18.0
DeclaredSlugs returns the invariant slugs a's Invariants section declares, backed and unbacked alike, in declaration order.
func (ADR) HasSameStatus ¶ added in v0.18.0
HasSameStatus reports exact status equality without exporting literal comparisons to migration consumers.
func (ADR) HasStatus ¶ added in v0.18.0
HasStatus reports whether the record carries a frontmatter status at all. The audit distinguishes an ADR with no status from one with a real status, and that tri-state is what the bytes seam carries (ADR-0130 item 3).
func (ADR) InvariantDecls ¶ added in v0.18.0
func (a ADR) InvariantDecls() []InvariantDecl
InvariantDecls returns the declarations a's Invariants section carries, in declaration order. Status-independent: the ref-validity check and the retirement migration resolve slug anchors against any ADR's declarations, not just Implemented ones (ADR-0120 item 2).
func (ADR) IsAbandoned ¶ added in v0.22.0
IsAbandoned reports the current-state-v1 terminal Abandoned state.
func (ADR) IsAccepted ¶ added in v0.22.0
IsAccepted reports the current-state-v1 Accepted state: the decision is normative only for executing its pending State changes, which never override the topic claims describing current reality (ADR-0135).
func (ADR) IsGoverned ¶ added in v0.22.0
IsGoverned reports whether the record uses either current-state format.
func (ADR) IsImplemented ¶ added in v0.18.0
IsImplemented reports whether the ADR's decisions have shipped. Invariant backing and token retirement are both gated on this.
func (ADR) IsImplementing ¶ added in v0.22.0
IsImplementing reports whether a V2 decision has applied only part of its declared operations.
func (ADR) IsInflight ¶ added in v0.18.0
IsInflight reports a decision still under review or implementation.
func (ADR) IsLegacyShipped ¶ added in v0.18.0
IsLegacyShipped reports whether a legacy decision shipped, including the historical Superseded state. Migration inventory uses this broader predicate; normal legacy authority continues to use its existing predicates.
func (ADR) IsLive ¶ added in v0.18.0
IsLive reports whether the ADR's decisions are current guidance.
func (ADR) IsProposed ¶ added in v0.18.0
IsProposed reports whether the ADR's body is still mutable.
func (ADR) IsSuperseded ¶ added in v0.18.0
IsSuperseded reports whether the ADR has been retired. The prefix test tolerates the pre-generation-12 suffixed form as well as the bare status ADR-0128 item 4 moves to.
func (ADR) OperationProgress ¶ added in v0.22.0
func (a ADR) OperationProgress() (OperationProgress, error)
OperationProgress projects declared operations into applied, remaining, and canceled partitions without inferring removal from claim absence.
func (ADR) ReachedAccepted ¶ added in v0.22.0
ReachedAccepted reports whether the ADR's history entered Accepted, including a later transition to a terminal state.
type ApplicationBatch ¶ added in v0.22.0
ApplicationBatch is one implicit or explicit application of declared state operations. Operations are retained in declaration/event order.
type AppliedOperation ¶ added in v0.22.0
AppliedOperation is one applied declaration and its inherited batch sequence.
type ClaimOperationHistory ¶ added in v0.22.0
type ClaimOperationHistory struct {
Origin *OperationRecord
LegacyBaseline bool
RevisedBy []OperationRecord
RemovedBy *OperationRecord
}
ClaimOperationHistory is the implemented add/update/remove history for one qualified claim identity.
type Corpus ¶ added in v0.18.0
type Corpus struct {
// contains filtered or unexported fields
}
Corpus is the parsed decisions directory: one parse, threaded to every consumer that needs an ADR fact (ADR-0130 item 1). It answers questions rather than exposing fields for a caller to re-derive an answer from (item 2), which is what collapsed the three-way "is live" and the twice-built supersession relation into one place.
The zero value is not useful; construct with NewCorpus.
func LoadCorpus ¶ added in v0.18.0
LoadCorpus parses a decisions directory into the view. It is the single construction seam: adr.ParseDir has no production caller outside this package, so every consumer - the *Project that threads the view to the checks, and the schema migrations, which run before a Project can be opened and so cannot be handed one - enters through here.
func (Corpus) ByNumber ¶ added in v0.18.0
ByNumber returns the ADR with the given four-digit number. The ADR number is the sole identity key (ADR-0130 item 4).
func (Corpus) ClaimOperationHistory ¶ added in v0.22.0
func (c Corpus) ClaimOperationHistory(claimID string) (ClaimOperationHistory, bool)
ClaimOperationHistory returns applied operation history for claimID in batch sequence order. Remaining and canceled operations are excluded, and every returned slice is fresh.
func (Corpus) Has ¶ added in v0.18.0
Has reports whether the corpus contains an ADR with the given number.
func (Corpus) NextIdentity ¶ added in v0.22.0
NextIdentity returns one more than the highest ADR identity, or 1 for an empty corpus. Migration code uses this semantic query rather than adding a raw decisions-directory reader.
func (Corpus) OperationProgress ¶ added in v0.22.0
func (c Corpus) OperationProgress(number string) (OperationProgress, bool, error)
OperationProgress returns the operation partition for one ADR. Missing and invalid-present records are deliberately distinct.
func (Corpus) Raw ¶ added in v0.18.0
Raw returns the ADR file's bytes. Raw access is enumerated and closed (ADR-0130 item 6): the migration's offset surgery and the retired-key frontmatter scan are the only two legitimate consumers below the semantic layer. A third caller means the view is missing a question.
type Format ¶ added in v0.22.0
type Format int
Format distinguishes legacy, current-state-v1, and current-state-v2 ADRs.
const ( // Legacy is a pre-cutover ADR: identity, status, and date only. Legacy Format = iota // CurrentStateV1 is a `format: current-state-v1` ADR with State changes and // status-only history. CurrentStateV1 // CurrentStateV2 is a `format: current-state-v2` ADR with heterogeneous // status and application history. CurrentStateV2 )
type FormatBoundaries ¶ added in v0.22.0
FormatBoundaries are the immutable ADR format cutoffs from one snapshot. A zero V2From leaves every governed record in the V1 region.
type HistoryEvent ¶ added in v0.22.0
type HistoryEvent struct {
Kind HistoryEventKind
Date string
Status string
Digest string
Sequence int
HasSequence bool
Rationale string
Operations []Operation
}
HistoryEvent is one parsed `## Status history` line.
type HistoryEventKind ¶ added in v0.22.0
type HistoryEventKind uint8
HistoryEventKind distinguishes lifecycle events from operation-application events in current-state-v2 Status history.
const ( HistoryStatus HistoryEventKind = iota + 1 HistoryApplied )
type InvariantDecl ¶ added in v0.18.0
InvariantDecl is one invariant declaration in an ADR's Invariants section. The grammar lives here rather than in internal/invariants because ADR-0130 item 2 makes declared slugs a question the corpus view answers, and corpus-owns-field-reads forbids any other package reading ADR.Sections to re-derive it. Bullet carries the whole declaration - lead line plus wrapped continuation lines - so a consumer can scan it for the `Verify:` note without a second pass over the section.
type Operation ¶ added in v0.22.0
type Operation struct {
Verb OpVerb
ID string // qualified claim ID
Slug string // local slug component of ID
}
Operation is one parsed `## State changes` entry: a verb over a qualified claim ID `<domain>/<topic>:<local-slug>` (ADR-0135 item 3).
type OperationProgress ¶ added in v0.22.0
type OperationProgress struct {
Applied []AppliedOperation
Remaining []Operation
Canceled []Operation
}
OperationProgress partitions an ADR's declarations by application state.
type OperationRecord ¶ added in v0.22.0
OperationRecord is the ADR identity and implementation order for one claim operation. StateSequence orders implemented mutations independently of ADR number.
type Status ¶ added in v0.22.0
type Status = string
Status is an ADR lifecycle status as presented by semantic corpus queries.
type StatusEntry ¶ added in v0.22.0
type StatusEntry = HistoryEvent
StatusEntry preserves the source-compatible V1 name while ADR.History uses the common event representation.