config

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package config loads and validates project.config.yaml — the single project-specific input that keeps this engine generic. Nothing in this package (or anywhere else in the engine) may hardcode a project name, facet, or module; every project-specific value comes from the Config this package produces.

Index

Constants

View Source
const CurrentSchemaVersion = 1

CurrentSchemaVersion is the only schema_version this engine build understands. LoadConfig refuses to run against any other value.

View Source
const FileName = "project.config.yaml"

FileName is the project config's fixed filename. The upward search in cmd/dossierx and the index lookup in internal/check both name it, so it is a constant rather than a literal repeated at each site.

View Source
const ReservedOverviewFacet = "overview"

ReservedOverviewFacet is the one facet name every module gets automatically, without a project listing it in Facets: claims under module.overview.* are module-level orientation notes (see model.Claim.EffectiveKind), injected into every one of that module's other facet tabs by internal/render rather than getting their own tab. It deliberately does not need to appear in Facets — validate() below never checks it, and internal/lint.IDShapeLint treats it as always valid regardless of what a project declares.

Variables

View Source
var ErrNotFound = errors.New("config file not found")

ErrNotFound is wrapped into LoadConfig's returned error whenever the config file itself does not exist at the given path (as opposed to existing but being malformed or invalid). Callers (notably the CLI) use errors.Is(err, ErrNotFound) to distinguish "nothing there" from other load failures and react accordingly (e.g. a distinct exit code).

View Source
var ThemeTokenAllowlist = []string{
	"accent",
	"accent-bg",
	"ink",
	"muted",
	"faint",
	"paper",
	"card-bg",
	"border",
	"link",
	"warn",
	"warn-bg",
	"font-sans",
	"font-mono",
	"radius",
}

ThemeTokenAllowlist is the fixed, engine-owned set of viewer.theme keys. Any key in viewer.theme not present here is a load-time error. This list is intentionally the only place that defines the engine's theme vocabulary; internal/render's CSS-emitting helper iterates it (in this order) to keep output deterministic.

Functions

This section is empty.

Types

type Config

type Config struct {
	SchemaVersion int `yaml:"schema_version"`
	// Title is the project's display name, used as the viewer's <title>,
	// header, and sidebar heading. Optional; internal/render falls back to
	// a generic default ("dossierx viewer") when unset, so existing configs
	// that predate this field keep working unchanged.
	Title string `yaml:"title,omitempty"`
	// Eyebrow is an optional one-line subtitle rendered directly under the
	// title in the sidebar header (e.g. "user-intelligence service"),
	// mirroring the reference docs explainer page's .eyebrow line. Unset means no
	// eyebrow line is rendered at all — it is not required the way Title's
	// generic fallback is.
	Eyebrow       string   `yaml:"eyebrow,omitempty"`
	Facets        []string `yaml:"facets"`
	Modules       []string `yaml:"modules"`
	ClaimsDir     string   `yaml:"claims_dir"`
	DoctrineFacet string   `yaml:"doctrine_facet,omitempty"`
	Viewer        Viewer   `yaml:"viewer,omitempty"`

	// Tracks is the project's declared registry of cross-cutting concerns —
	// the second axis claims may join, orthogonal to Modules. See
	// model.TrackRef for the axis itself.
	//
	// It is declared here, and not inferred from whatever ids claims happen
	// to mention, for the same reason Modules is: a vocabulary that creates
	// itself on first use cannot catch a typo, and "checkout" vs "check-out"
	// would silently become two features nobody notices are one. A claim
	// naming a track absent from this list is a lint error (track-unknown).
	//
	// Optional. A project that declares none behaves exactly as it did
	// before tracks existed — every track-* lint is a no-op, and the viewer
	// renders no Tracks group.
	Tracks []Track `yaml:"tracks,omitempty"`

	// SourceDirs is the optional list of directories (relative to this
	// config file's own directory, like ClaimsDir) the engine scans for
	// "dossierx-claim: <id>" comments — the code side of internal/implink's
	// claim-to-code linking. Unset/empty means "do not scan" — "dossierx
	// check" behaves exactly as it did before this field existed, the same
	// zero-cost-when-unused contract every other optional feature in this
	// engine follows (mockup_modules, viewer.template_overrides, ...). A
	// project only opts in by naming its actual source roots, same as it
	// only opts into claim data via ClaimsDir — the engine never assumes
	// or guesses where "the code" is.
	SourceDirs []string `yaml:"source_dirs,omitempty"`

	// MockupModules is the checked-in allowlist of modules permitted to
	// author a claim carrying RawHTML AT ALL — on any layout, not only
	// model.LayoutMockup. The NAME PREDATES v0.4.1, which made raw_html an
	// attachment legal beside card, banner, list and tree content; the gate
	// widened with it and the field's name did not, so a reader who takes
	// this for a mockup-only allowlist will expect a `card` claim bearing
	// markup to be ungated, and it is not. It is the "module allowlist" leg
	// of the raw-html-scope lint's five-part gate (see
	// internal/lint/raw_html_scope.go). It is optional: a project that has
	// never authored a raw_html claim need not set it, and the lint treats
	// an unset/empty list as "no module may author one", not a vacuous
	// pass. Every entry must also appear in Modules — an
	// allowlisted module that isn't even a project module can never gate
	// anything, which almost certainly indicates a typo (same reasoning as
	// DoctrineFacet's membership check below).
	MockupModules []string `yaml:"mockup_modules,omitempty"`
	// contains filtered or unexported fields
}

Config is the fully-decoded, fully-validated project.config.yaml.

func DecodeConfig added in v0.3.0

func DecodeConfig(raw []byte, dir, name string) (*Config, error)

DecodeConfig is LoadConfig with the bytes already in hand and the anchor directory supplied separately.

It exists for "dossierx check --staged", which has to evaluate the project against the config THE INDEX HOLDS while still resolving claims_dir and the stores against the real working-tree directory — the index's copy of the file has no directory of its own to be relative to. Splitting the read from the decode is what keeps that caller on this exact strict-decode-and-validate path instead of growing a second, drifting copy of it.

name is used only in error messages, so a caller reading from somewhere other than the filesystem can still say which file it means.

func LoadConfig

func LoadConfig(path string) (*Config, error)

LoadConfig reads, strictly decodes, and validates the project config at path. "Strict" means an unknown YAML field is a hard error, not silently ignored. All path-shaped fields (claims_dir, viewer.template_overrides) are resolved relative to path's own directory, never the process cwd.

func (*Config) Dir

func (c *Config) Dir() string

Dir returns the absolute directory the config file lives in.

func (*Config) HasTrack added in v0.7.0

func (c *Config) HasTrack(id string) bool

HasTrack reports whether id names a track this project declares.

func (*Config) HubGatingEnabled

func (c *Config) HubGatingEnabled() bool

HubGatingEnabled reports whether doctrine hub-gating logic should run at all. When false, callers must skip the check entirely rather than treat it as a vacuous pass.

func (*Config) Path added in v0.3.0

func (c *Config) Path() string

Path returns the absolute path of the config file this was loaded from, or "" when it was decoded from bytes. Callers that need to find the SAME file somewhere else (the git index, above all) must use this rather than assuming Dir()+FileName: --config takes an arbitrary path, and a project whose config is named something else would otherwise be looked up as a file that is not there — which, for a gate, means silently falling back to weaker evidence.

func (*Config) TrackByID added in v0.7.0

func (c *Config) TrackByID(id string) (Track, bool)

TrackByID returns the declared track with the given id and whether it was found. The zero Track is returned when it was not.

func (*Config) TrackIDs added in v0.7.0

func (c *Config) TrackIDs() []string

TrackIDs returns every declared track id, in declaration order. Callers that need to test membership of a claim-supplied id (the track-unknown lint, the CLI's track leaves) use HasTrack instead.

type Track added in v0.7.0

type Track struct {
	// ID is the stable identifier claims cite in their `tracks:` list and
	// the CLI takes as an argument ("dossierx track show <id>"). Required,
	// unique within the project.
	ID string `yaml:"id"`

	// Title is the human-readable name rendered in the viewer's sidebar and
	// at the head of the track's page. Required: a track exists to be read
	// about by someone asking "what does the user get", and an id is not an
	// answer to that question.
	Title string `yaml:"title"`

	// Summary is an optional one-line description of what the track covers,
	// rendered under the Title. Optional because a well-named track with an
	// owned claim already says what it is — the owned claim's body IS the
	// long form.
	Summary string `yaml:"summary,omitempty"`
}

Track is one declared cross-cutting concern: a named grouping claims may join from any module. See Config.Tracks for why the registry is explicit, and model.TrackRef for the claim-side membership this declares the vocabulary for.

type Viewer

type Viewer struct {
	// TemplateOverrides is a directory of partial template overrides,
	// resolved relative to the config file's directory. Missing
	// individual partial files inside it fall back to engine defaults
	// per-component (soft fallback). If set but the directory itself does
	// not exist, LoadConfig returns a hard error.
	TemplateOverrides string `yaml:"template_overrides,omitempty"`

	// Theme maps CSS custom-property token names (without the leading
	// "--") to their values. Keys must be drawn from ThemeTokenAllowlist —
	// this is the only project-specific CSS vocabulary the engine
	// recognizes, kept as a fixed list for typo protection. Values are
	// injected verbatim into a generated :root{...} stylesheet block, so
	// they are validated defensively (see validateTheme) rather than
	// trusted as safe CSS.
	Theme map[string]string `yaml:"theme,omitempty"`
}

Viewer holds viewer/render related configuration.

Jump to

Keyboard shortcuts

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