config

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: 10 Imported by: 0

Documentation

Overview

Package config reads `.ds/config.toml` (docs/SPEC.md §23) and the workspace file, with defaults for everything the spec gives a default.

It parses the TOML subset the config actually uses, tables and dotted tables, `key = value` with strings, integers, floats, booleans, and arrays of scalars, and refuses anything else with a line number. A full TOML parser is a dependency the root module does not take (§37.1); the shape here is small, fixed, and covered by the conformance fixtures, and a value the reader does not understand is an error rather than a silent default.

Index

Constants

View Source
const (
	DefaultPrefix         = "ds"
	DefaultIncludeMode    = IncludeBuild
	DefaultMaxLines       = 40
	DefaultFuzzyThreshold = 0.8
	DefaultUnacked        = UnackedError
	DefaultSentence       = SentenceWording
	DefaultMaxFileKB      = 512
	DefaultMaxLineChars   = 2000
	DefaultRunTimeout     = "30s"
	// DefaultRunShell runs ds:run commands and the [review] command. It is
	// looked up on PATH; on Windows, Git for Windows provides it.
	DefaultRunShell       = "sh"
	DefaultURLTTL         = "7d"
	DefaultURLRate        = 30
	DefaultEnv            = ""
	DefaultRecords        = RecordsFrontmatter
	DefaultSuffixLength   = 8
	DefaultSuffixAlphabet = "23456789abcdefghjkmnpqrstuvwxyz"
	DefaultMaxDefsPerRun  = 20
	// DefaultSessionHook is what `ds init --agents` installs as the
	// session-start hook (§26.10); an empty agents.session_hook installs none.
	DefaultSessionHook   = "ds map --budget 2000"
	DefaultEscalateAfter = "7d"
	DefaultUpdateMode    = UpdateAuto
)

Defaults from the spec.

View Source
const (
	IncludeBuild = "build"
	IncludeRepo  = "repo"

	UnackedError = "error"
	UnackedWarn  = "warn"

	RecordsFrontmatter = "frontmatter"
	RecordsSQLite      = "sqlite"
	RecordsHTTP        = "http"

	// SentenceWording holds an ack to the words it approved: a cited
	// sentence rewritten since its ack is unacked (SPEC §18).
	// SentencePosition holds it to the citation's place only, the older
	// behaviour, for a repository that opts out knowingly.
	SentenceWording  = "wording"
	SentencePosition = "position"

	// The update modes of a release build of ds, least to most restrictive:
	// UpdateAuto installs a newer release before running a command,
	// UpdateNotify only says one exists, UpdateOff does neither. A
	// repository can make the binary more restrictive, never less, so a team
	// can pin every member to one version.
	UpdateAuto   = "auto"
	UpdateNotify = "notify"
	UpdateOff    = "off"
)

Closed-set values.

View Source
const (
	KeyNotifyGitHubIssues = "notify.github_issues"
	KeySources            = "sources"
	KeyWorkspaceID        = "workspace.id"
	KeyWorkspaceEnv       = "workspace.env"
)

Keys the specification names that this build refuses rather than ignores (docs/SPEC.md §38 lists them as open work). Each is the dotted path a file would set; a table key refuses the whole table.

View Source
const (
	TierNever     = "never"
	TierDigest    = "digest"
	TierImmediate = "immediate"
)

The tiers a snapshot drift can reach, in order of urgency. They are the vocabulary for Immediate, Digest and OnDeleted alike, so there is one set of words rather than a bespoke one per key.

View Source
const (
	DefaultDigestAfter = "14d"
	DefaultOnDeleted   = TierImmediate
)

Defaults for [notify.snapshot].

View Source
const Spec = "1.0"

Spec is the specification version this config schema follows.

View Source
const WorkspaceFile = "ds-workspace.toml"

WorkspaceFile is the name of the workspace declaration (§21), kept in the docs repo or a small index repo.

Variables

View Source
var (
	IncludeModeValues = []string{IncludeBuild, IncludeRepo}
	UnackedValues     = []string{UnackedError, UnackedWarn}
	RecordsValues     = []string{RecordsFrontmatter, RecordsSQLite, RecordsHTTP}
	SentenceValues    = []string{SentenceWording, SentencePosition}
	// UpdateModeValues is ordered least restrictive first; callers combine
	// several sources by taking the latest in this list.
	UpdateModeValues = []string{UpdateAuto, UpdateNotify, UpdateOff}
)

IncludeModeValues, UnackedValues, RecordsValues are the canonical lists.

View Source
var (
	ErrSyntax   = errors.New("config: syntax error")
	ErrType     = errors.New("config: wrong value type")
	ErrValue    = errors.New("config: invalid value")
	ErrUnknown  = errors.New("config: unknown key")
	ErrSpec     = errors.New("config: spec version not supported by this tool")
	ErrNoScan   = errors.New("config: scan.code and scan.docs are both empty; nothing would be scanned")
	ErrRequired = errors.New("config: required key missing")
	// ErrNotImplemented refuses a key the specification describes but this
	// build does not act on. Accepting it silently would let a team believe
	// a channel or a source was configured when nothing reads it.
	ErrNotImplemented = errors.New("config: key not implemented yet")
)

Sentinel errors.

View Source
var (
	DefaultImmediateClasses = []string{"signature", "type", "renamed", "value"}
	DefaultDigestClasses    = []string{"body", "comment"}
)

DefaultImmediateClasses are the classes that change what a citation asserts; DefaultDigestClasses are the ones that do not but are still worth knowing eventually.

View Source
var (
	ErrWorkspaceName  = fmt.Errorf("%w: workspace.name is required", ErrRequired)
	ErrWorkspaceRepos = fmt.Errorf("%w: workspace.repos must list at least one repository", ErrRequired)
)

Workspace errors.

View Source
var NotImplementedValues = map[string]string{
	KeyNotifyGitHubIssues: "Slack ([notify] slack) is the only notify channel",
	KeySources:            "ds:cfg query= has no source to run against; cite a def by id instead",
	KeyWorkspaceID:        "each repository's [id] in .ds/config.toml is what minting uses",
	KeyWorkspaceEnv:       "each repository's [env] in .ds/config.toml is what checking uses",
}

NotImplementedValues maps each refused key to what to do instead, which the load error repeats. Removing an entry is how a key becomes supported: the parser then needs a setter and something outside this package must read it, which a test in this package enforces.

TierValues is the canonical order, lowest first.

Functions

func CanonicalURL

func CanonicalURL(url string) string

CanonicalURL reduces the ways one repository's URL is written to one form, host/path: `git@github.com:org/api.git`, `https://github.com/org/api`, `ssh://git@github.com/org/api` and `github.com/org/api` are the same repository. Case is folded, since hosts and most forges ignore it.

func RepoName

func RepoName(url string) string

RepoName returns the last path segment of a repo URL, which is how the index names its per-repo directory and how `repo=` appears in rows.

Types

type AgentsConfig

type AgentsConfig struct {
	MaxDefsPerRun int
	MCP           bool
	SessionHook   string
}

AgentsConfig is [agents].

type CheckConfig

type CheckConfig struct {
	FuzzyThreshold float64
	Unacked        string
	Permalink      string
	// SnapshotMaxAge, e.g. "30d", makes `check --frozen` warn when
	// .ds/foreign.tsv is older than that. Empty (the default) means never:
	// a pinned check that also failed with age would stop being
	// reproducible, which is the one thing --frozen exists to guarantee. It
	// is a nudge for a CI that never syncs, and a warning is the strongest
	// it may be.
	SnapshotMaxAge string
	// Sentence is what an ack holds a citation to: its wording
	// (SentenceWording, the default) or only its position.
	Sentence string
}

CheckConfig is [check].

type Config

type Config struct {
	Spec      string
	Prefix    string
	Workspace string
	Scan      ScanConfig
	Include   IncludeConfig
	Check     CheckConfig
	Policy    PolicyConfig
	Owners    map[string][]string
	Secret    SecretConfig
	Env       EnvConfig
	Resolve   ResolveConfig
	Run       RunConfig
	URL       URLConfig
	Records   RecordsConfig
	Notify    NotifyConfig
	Agents    AgentsConfig
	ID        IDConfig
	Plugins   PluginsConfig
	Review    ReviewConfig
	Ledger    LedgerConfig
	Update    UpdateConfig
}

Config mirrors the file. Field docs are the spec's meaning; see §23.

func Default

func Default() Config

Default returns a config with every spec default filled in and no scan paths; Validate rejects it until scan.code or scan.docs is set.

func Parse

func Parse(r io.Reader) (Config, error)

Parse reads TOML text into a Config over the defaults. Unknown keys are errors: a misspelled key that silently did nothing is the classic config failure and the spec's "unknown warns" rule applies to directives, not to the file that configures the tool.

func ParseOnto

func ParseOnto(base Config, r io.Reader) (Config, error)

ParseOnto reads a config file on top of base instead of the built-in defaults: a key the file sets wins, and every key it does not set keeps base's value. It is how an organisation-wide binary's defaults (cli.WithConfigDefaults) reach a repository whose config.toml does not mention them — reading onto the built-in defaults instead dropped them all.

base is not modified. Its maps are copied first, because applying a file writes into them, and an organisation hook that shares one map between calls would otherwise carry one repository's owners into the next.

func (Config) IDConfig added in v0.1.3

func (c Config) IDConfig() id.Config

IDConfig is the id shape this config mints and checks with: id, with an empty value standing for its default. Validate has already refused a value the minting rules would refuse, so a loaded config's IDConfig is always valid.

func (Config) KnownEnv added in v0.1.3

func (c Config) KnownEnv(name string) bool

KnownEnv reports whether name may be used as an environment: always when env.known is empty (the list is opt-in), else only when it is listed. It is the one test every place that takes an environment name applies -- a --env flag, a directive's env= -- so they cannot disagree.

func (Config) Validate

func (c Config) Validate() error

Validate checks closed-set values and ranges.

type EnvConfig

type EnvConfig struct {
	Default string
	Known   []string
}

EnvConfig is [env].

type IDConfig

type IDConfig struct {
	SuffixAlphabet string
	SuffixLength   int
}

IDConfig is id.

type IncludeConfig

type IncludeConfig struct {
	Mode     string
	MaxLines int
}

IncludeConfig is [include].

type LedgerConfig

type LedgerConfig struct {
	Shard bool
}

LedgerConfig is [ledger]: shard = true writes .ds/ledger/<dir>.tsv per top-level directory instead of one file (§ Scale).

type NotifyConfig

type NotifyConfig struct {
	Snapshot      SnapshotNotifyConfig
	Slack         string
	EscalateAfter string
}

NotifyConfig is [notify].

type PluginsConfig

type PluginsConfig struct {
	Verbs []string
	Picks []string
}

PluginsConfig is [plugins] (§9.9, §37.4): names of process plugins the CLI should look for on PATH as `ds-<verb>` and `ds-pick-<scheme>`.

type PolicyConfig

type PolicyConfig struct {
	RequireDoc []string
}

PolicyConfig is [policy].

type RecordsConfig

type RecordsConfig struct {
	Source string
	Path   string
	// Table is the default table for the sqlite source when a `ds:table`
	// names no kind=.
	Table string
}

RecordsConfig is [records].

type ResolveConfig

type ResolveConfig struct {
	Enabled   bool
	StoreHash bool
	Providers []string
}

ResolveConfig is [resolve].

type ReviewConfig

type ReviewConfig struct {
	Command string
}

ReviewConfig is [review]: the command `review --ai` pipes findings and context into, which must print a unified diff (§22). The model is the user's choice; the tool never calls one itself.

type RunConfig

type RunConfig struct {
	Enabled bool
	Allow   []string
	Timeout string
	// Shell is the program ds:run commands and the [review] command run
	// under, invoked as `<shell> -c <command>` and, for file=, `<shell>
	// <file>`. Empty means DefaultRunShell. It exists for machines without
	// sh and for teams whose commands are written for another shell
	// (`pwsh`); docsync never picks a different shell by itself, because the
	// same text means different things to different shells.
	Shell string
	Env   map[string]map[string]string
}

RunConfig is [run] and [run.env.<name>].

type ScanConfig

type ScanConfig struct {
	Code         []string
	Docs         []string
	Exclude      []string
	Generated    []string
	MaxFileKB    int
	MaxLineChars int
}

ScanConfig is [scan] and [scan.limits].

type SecretConfig

type SecretConfig struct {
	Paths []string
}

SecretConfig is [secret].

type SnapshotNotifyConfig

type SnapshotNotifyConfig struct {
	// Enabled defaults to true where a workspace is configured and is
	// always false without one: a repo that cites nothing foreign has no
	// snapshot to go stale.
	Enabled bool
	// Immediate and Digest rank the classes that flag. A class named in
	// both is a configuration error; a class that flags but is named in
	// neither is treated as Immediate, because guessing the other way fails
	// toward silence.
	Immediate []string
	Digest    []string
	// DigestAfter is how long a digest-tier drift waits before it is worth
	// mentioning at all.
	DigestAfter string
	// OnDeleted ranks the case that is not a class: the upstream block is
	// gone. It has no second version to compare, and its consequence is
	// known in advance — the next sync turns its citations broken — so it
	// is its own key rather than a member of a class list.
	OnDeleted string
	// Owner receives snapshot messages. Empty falls back to the owners of
	// the citing files, because the people who must run `ds sync` and
	// resolve what it surfaces are in this repo, not the one that changed.
	Owner string
}

SnapshotNotifyConfig is [notify.snapshot] (§21): when a citing repo is told that the upstream it pinned has moved.

Drift is what triggers a message, never age on its own — a snapshot ninety days old against an upstream that has not moved costs nobody anything. Urgency comes from the change class, which `check` already computes, so the same rule decides whether prose flags and whether a person is interrupted.

type URLConfig

type URLConfig struct {
	TTL           string
	RatePerMinute int
}

URLConfig is [url].

type UpdateConfig added in v0.1.5

type UpdateConfig struct {
	Mode string
}

UpdateConfig is [update]: how a release build of ds keeps itself current while working in this repository. The library never updates anything; the CLI reads this key.

type Workspace

type Workspace struct {
	Name  string
	Repos []string
	// Index is where published ledgers meet: a git repository URL or a
	// local path. An https endpoint is an adapter for later.
	Index string
	// DefaultBranch is the only branch `publish` runs from; empty means the
	// repository's own default as reported by the VCS.
	DefaultBranch string
	// StaleAfterCommits is how far a published ledger may fall behind its
	// repo's default branch before consumers warn (§21); 0 disables.
	StaleAfterCommits int
}

Workspace is `ds-workspace.toml`.

func ParseWorkspace

func ParseWorkspace(r io.Reader) (Workspace, error)

ParseWorkspace reads a workspace file. The [workspace.id] and [workspace.env] tables the specification describes are refused as not implemented (NotImplementedValues): each repository mints and selects with its own id and [env], and a workspace-wide value that nothing applied would let a team believe its repositories agreed when they need not.

func (Workspace) Member

func (w Workspace) Member(url string) bool

Member reports whether url is one of the workspace's repositories, by canonical URL. It is what lets only the canonical repository publish: a fork or a mirror shares the last path segment, and so the index directory, but not the URL.

func (Workspace) Validate

func (w Workspace) Validate() error

Validate checks the required fields.

Jump to

Keyboard shortcuts

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