block

package
v0.1.6 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package block holds the data model shared by every docsync stage: a defined Block, a Reference to one, and the closed-set constants (kind, carrier, stability, change class) that the ledger, findings, and JSON contract use.

Why a separate package with no behaviour: the scanner produces these, the matcher compares them, the ledger serialises them, the renderer reads them. If each stage defined its own struct there would be four lossy conversions. Keeping the model here and dependency-free means every stage, and every plugin, speaks the same shape.

Index

Constants

View Source
const (
	KeyID        = "id"
	KeyOwner     = "owner"
	KeyTags      = "tags"
	KeyStability = "stability"
	KeySpan      = "span"
	KeyPick      = "pick"
	KeyType      = "type"
	KeyFile      = "file"
	KeyLocal     = "local"
	KeyEnv       = "env"
	KeySecret    = "secret"
	KeySource    = "source"
	KeyFrom      = "from"
	KeyTruth     = "truth"
	KeySync      = "sync"
	KeyRunnable  = "runnable"
	KeyDeprecate = "deprecated"
	KeySunset    = "sunset"
	KeyDesc      = "desc"
	KeyDoc       = "doc"
	// KeyRepo is set by a workspace merge, never written by an author: the
	// repository a merged block was published from.
	KeyRepo = "repo"
	// KeyBranch is set by a workspace merge for blocks published from a
	// non-default branch (§9.2 `branch=`, Part VII "Ids and branches").
	KeyBranch = "branch"
)

Directive keys read by the core. Verbs may define more; these are the ones that change how a block is matched, hashed, or reported.

View Source
const DefaultStability = StabilityStable

DefaultStability applies when a def has no `stability=`.

View Source
const TrueValue = "true"

TrueValue is the only spelling of a boolean key (`secret=true`). Anything else is false; the spec does not infer booleans from shape (§9.1).

Variables

CarrierValues is the canonical order.

ClassValues is the canonical order.

KeyValues lists the core-recognised def keys so a linter can warn on unknown ones without hardcoding the list twice.

KindValues is the canonical order for enumeration.

StabilityValues is the canonical order.

ValueTypeValues is the canonical order, for messages and docs.

Functions

func Crosses added in v0.1.3

func Crosses(a, b Position) bool

Crosses reports two extents in one file that overlap without either one containing the other. Nesting is legitimate -- a method in a class, a subsection in a section -- but crossing blocks each hold part of the other, so an edit that concerns one flags both. A position with no extent (Start 0: remote, local, unbound) crosses nothing.

func Flags

func Flags(st Stability, classes []Class) bool

Flags reports whether a change with the given classes should flag prose under a stability policy. This is the single place the §20 table lives.

Invariant: ClassWhitespace never flags under any policy, and ClassMoved alone never flags (a move is absorbed by the ledger), so a change whose only classes are those two is silent everywhere except `frozen`, where a move is still silent but any other touch is an error. dsself:def id=flags-zfrzu4vz owner=@docsync stability=stable

func SecretAddress

func SecretAddress(s string) bool

SecretAddress reports text that holds a secret's address rather than its value, and so is safe to show.

Why it exists: the spec promises the tool "never stores, renders, or logs a value" and calls an address "safe to hash and render". Nothing enforced the difference, so `secret=true` on a line holding a real credential -- or any line in a `[secret] paths` file, which holds values by definition -- was printed by render, facts, context, read and export alike. A bare uppercase name is deliberately NOT treated as an address: an AWS access key id is uppercase too, and the spec already asks for `source=` on a bare env name.

Types

type Block

type Block struct {
	// ID is the full `prefix-suffix` id from the def.
	ID string `json:"id"`
	// Kind is decided by the extractor that bound the def.
	Kind Kind `json:"kind"`
	// Symbol is the human name of what was bound: `Store.SaveSession`,
	// `auth.port`, a heading title, or "" when the host has no symbols.
	Symbol string `json:"symbol,omitempty"`
	// Pos is where the block's content lives, not where the directive sits;
	// the directive line is DirectivePos.
	Pos Position `json:"pos"`
	// DirectivePos is the line(s) the `ds:def` occupied, including any
	// continuation lines. Renderers strip these; hashes exclude them.
	DirectivePos Position `json:"directive_pos"`
	// Carrier is how the def was written.
	Carrier Carrier `json:"carrier"`
	// Content is the bound text with the directive lines removed. For a fact
	// it is the single picked line. It is kept so `read`, `context`, and the
	// classifier have the body without re-reading the file.
	Content string `json:"-"`
	// Hash is textnorm.Hash(Content). Stored in full; displayed short.
	Hash string `json:"hash"`
	// Args holds every key from the def directive, verbatim, so verbs and
	// policies can read `owner`, `stability`, `env`, `from`, and so on. The
	// well-known ones are exposed by methods; unknown keys are preserved for
	// forward compatibility (§7).
	Args map[string]string `json:"args,omitempty"`
}

Block is one defined unit: the target of a `ds:def`. Everything the ledger stores about a definition is here; verbs read their own keys from Args.

func (Block) Env

func (b Block) Env() string

Env returns `env=` or "".

func (Block) From

func (b Block) From() string

From returns `from=` or "".

func (Block) IsLocal

func (b Block) IsLocal() bool

IsLocal reports `local=true`.

func (Block) IsRunnable

func (b Block) IsRunnable() bool

IsRunnable reports `runnable=true`.

func (Block) IsSecret

func (b Block) IsSecret() bool

IsSecret reports `secret=true`.

func (Block) IsTruth

func (b Block) IsTruth() bool

IsTruth reports `truth=true`.

func (Block) Owner

func (b Block) Owner() string

Owner returns `owner=` or "".

func (*Block) SetContent

func (b *Block) SetContent(content string)

SetContent stores the body and recomputes the hash. It is the only way the hash should be set so Content and Hash can never disagree.

func (*Block) SetContentHashed

func (b *Block) SetContentHashed(content, hashed string)

SetContentHashed stores content but hashes hashed instead: grammar tiers hash the token stream so a formatter's whitespace never counts as a change (Part VII "What changed"), while Content stays the source as written for rendering. hashed goes through the same normalisation, so a tier that passes content itself gets exactly SetContent.

func (Block) Stability

func (b Block) Stability() Stability

Stability returns the def's policy, defaulting per spec. An invalid value is reported by the scanner as a finding; here it falls back to the default so downstream code never sees an unknown policy.

func (Block) Tags

func (b Block) Tags() []string

Tags returns the comma list from `tags=`.

type Carrier

type Carrier string

Carrier says where a directive sat: which comment syntax or link form. Verbs restrict which carriers they accept (§9.9), and findings report it so a remedy can say "the link on line 13" versus "the comment on line 13".

const (
	CarrierComment  Carrier = "comment"  // a host-language comment: // # -- /* */ <!-- -->
	CarrierBareLine Carrier = "bareline" // a bare `ds:...` line in a file with no comment syntax
	CarrierLink     Carrier = "link"     // a markdown link target `ds:verb?k=v`
	CarrierBlock    Carrier = "block"    // an html comment on its own line in markdown, i.e. block position
)

type Class

type Class string

Class is one classified difference between two versions of a block (§20). A change carries one or more classes.

const (
	ClassRenamed    Class = "renamed"    // symbol name changed
	ClassMoved      Class = "moved"      // file or line range changed, body identical
	ClassSignature  Class = "signature"  // parameters or return types changed
	ClassType       Class = "type"       // a type's shape changed: fields, variants
	ClassBody       Class = "body"       // statements changed, signature unchanged
	ClassComment    Class = "comment"    // comment lines only
	ClassWhitespace Class = "whitespace" // formatting only; never reported
	ClassValue      Class = "value"      // for facts: the picked value changed
	// ClassUnknown says the two versions differ but the older body was not
	// available to classify (§20). It is not a guess at what changed: it is
	// the honest statement that the difference is real and undescribed. It
	// arises when a citation drifted from a hash whose body is not in the
	// body store — pruned, never stored, or withheld because the block is
	// secret. It must never be substituted for ClassBody, because `api`
	// blocks do not flag on ClassBody and a silently-dropped signature
	// change is a wrong `ok`.
	ClassUnknown Class = "unknown"
)

type Kind

type Kind string

Kind says what a defined block is. It is decided by the extractor tier that bound the directive (docs/SPEC.md §7.1, §10) and stored in the ledger.

const (
	KindFunc      Kind = "func"      // a function or method from a grammar tier
	KindType      Kind = "type"      // a type, class, struct, interface, enum
	KindConst     Kind = "const"     // a const or var declaration
	KindStatement Kind = "stmt"      // a statement, e.g. a SQL statement
	KindKey       Kind = "key"       // a key in a structured file (yaml, toml, json, ini, env)
	KindLine      Kind = "line"      // a single line in a grammarless file
	KindSpan      Kind = "span"      // a line range in a grammarless file
	KindSection   Kind = "section"   // a markdown heading and its section
	KindParagraph Kind = "paragraph" // a markdown paragraph
	KindLinkText  Kind = "linktext"  // the text of an inline markdown def link, i.e. a fact
	KindElement   Kind = "element"   // an html/xml element
	KindFile      Kind = "file"      // a whole file, from pick=file on an asset
)

type Position

type Position struct {
	File  string `json:"file"`
	Start int    `json:"start"`
	End   int    `json:"end"`
}

Position locates a directive or a block in a file. Lines are 1-based and inclusive; a single line has Start == End. File is repo-relative with `/` separators.

type Reference

type Reference struct {
	// Verb is the directive verb, e.g. "block".
	Verb string `json:"verb"`
	// ID is the referenced id, or "" for verbs that do not point at a def
	// (`table`, `claim`, `url`, and `run cmd=`).
	ID string `json:"id,omitempty"`
	// Pos is the line the reference sits on. For a link it is the line of the
	// enclosing sentence, which is what findings attach to.
	Pos Position `json:"pos"`
	// Carrier is link, comment, or block position.
	Carrier Carrier `json:"carrier"`
	// Sentence is the enclosing sentence, list item, or table cell (§18), or
	// "" for block-position references, which have no prose around them.
	Sentence string `json:"sentence,omitempty"`
	// SentenceHash is textnorm.Hash(Sentence), what an ack is recorded against.
	SentenceHash string `json:"sentence_hash,omitempty"`
	// Args holds every key from the directive verbatim.
	Args map[string]string `json:"args,omitempty"`
	// Region is the repo-mode fence that follows a block-position
	// reference (§9.2 include.mode = repo), or nil in build mode.
	Region *Region `json:"region,omitempty"`
}

Reference is one use of a defined id: a `ds:block`, `ds:cfg`, `ds:run`, or any other referring verb, wherever it sat.

func (Reference) Directive

func (r Reference) Directive() directive.Directive

Directive reconstructs the parsed directive for a reference, for verbs that want the typed accessors.

func (*Reference) SetSentence

func (r *Reference) SetSentence(s string)

SetSentence stores the enclosing prose and its hash together.

type Region

type Region struct {
	Start int    `json:"start"`
	End   int    `json:"end"`
	Hash  string `json:"hash"`
	Text  string `json:"-"`
}

Region is a rendered copy kept in the document between a block-position directive and its closer `<!-- /ds:block hash=… -->`. Hash is the short block hash the copy was rendered from; Text is the copy itself.

type Stability

type Stability string

Stability is the `stability=` key on a def: which change classes flag prose (§20). The zero value is not valid; DefaultStability is the spec default.

const (
	StabilityFrozen   Stability = "frozen"   // any class but whitespace flags, and is an error on its own
	StabilityStable   Stability = "stable"   // default: any class but whitespace and comment flags
	StabilityAPI      Stability = "api"      // only signature, type, renamed, value flag
	StabilityVolatile Stability = "volatile" // nothing flags
)

func ParseStability

func ParseStability(s string) (Stability, bool)

ParseStability validates a `stability=` value.

type ValueType added in v0.1.3

type ValueType string

ValueType is a def's declared `type=` (§9.1, §11): what shape its value must have. A scan checks the picked value against it, so a fact that stops being the thing its sentences say it is -- a port that became a word, a version that lost its patch number -- is a finding, not a silent pass. Before, type= was accepted and checked nothing (bug 54).

const (
	TypeURL      ValueType = "url"
	TypeEmail    ValueType = "email"
	TypeInt      ValueType = "int"
	TypeFloat    ValueType = "float"
	TypePercent  ValueType = "percent"
	TypeSemver   ValueType = "semver"
	TypeDate     ValueType = "date"
	TypeDuration ValueType = "duration"
	TypeHost     ValueType = "host"
	TypeOpRef    ValueType = "opref"
)

The value types, as §9.1 lists them. `url` also decides rendering: an inline def of that type becomes a link.

func (ValueType) Accepts added in v0.1.3

func (t ValueType) Accepts(value string) bool

Accepts reports whether value has the shape t declares. An unknown type accepts nothing; the scan reports it as unknown rather than as a mismatch.

func (ValueType) Known added in v0.1.3

func (t ValueType) Known() bool

Known reports whether t is one of ValueTypeValues.

Jump to

Keyboard shortcuts

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