featureflags

package
v1.1.6 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package featureflags provides a built-in, file-backed feature flag registry for the nSelf CLI binary.

This package is distinct from internal/flags/, which is a thin HTTP client over the runtime feature-flags plugin (port 3305). This package serves build-time / install-time capability gates that ship inside the CLI binary itself — no plugin required, no network calls.

Layout:

  • registry.yaml is the canonical catalog (embedded via go:embed).
  • State (per-flag enabled/disabled overrides) lives in `.nself/features.json` inside the project working directory.

Spec source: .claude/docs/ARCHITECTURE.md § Feature Flags.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SaveState

func SaveState(projectDir string, s *State) error

SaveState writes the state file atomically (write+rename) with 0600 perms.

0600 follows the project-wide rule for .env-equivalent state files: state includes which features the operator has enabled, which is sensitive enough to keep readable only by the owning user.

func StatePath

func StatePath(projectDir string) string

StatePath returns the absolute path the state file would occupy for the given project directory.

Types

type Flag

type Flag struct {
	Key         string   `yaml:"key" json:"key"`
	Type        FlagType `yaml:"type" json:"type"`
	Surface     string   `yaml:"surface" json:"surface"`
	Description string   `yaml:"description" json:"description"`
	Default     bool     `yaml:"default" json:"default"`
	Introduced  string   `yaml:"introduced" json:"introduced"`
	AutoKill    string   `yaml:"auto_kill,omitempty" json:"auto_kill,omitempty"`
	Owner       string   `yaml:"owner,omitempty" json:"owner,omitempty"`
	DocsURL     string   `yaml:"docs_url,omitempty" json:"docs_url,omitempty"`
}

Flag is a single registry entry as declared in registry.yaml.

Fields use struct tags for both yaml (registry source) and json (state file + machine output).

type FlagType

type FlagType string

FlagType narrows the allowed flag categories.

const (
	// FlagTypeRelease toggles new behavior that will eventually be permanent.
	FlagTypeRelease FlagType = "release"
	// FlagTypeOps toggles operational behavior (rate limits, strict modes).
	FlagTypeOps FlagType = "ops"
	// FlagTypeKillSwitch is an emergency disable path; never auto-enables.
	FlagTypeKillSwitch FlagType = "kill_switch"
)

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry is the loaded set of flags from registry.yaml.

The zero value is not usable; obtain one via Load.

func Load

func Load() (*Registry, error)

Load parses the embedded registry.yaml.

Returns an error if the YAML is malformed or any entry fails validation. Validation rejects: empty key, unknown type, empty surface, empty description, duplicate key, and malformed auto_kill date (when present).

func (*Registry) All

func (r *Registry) All() []Flag

All returns the registry flags in declaration order.

func (*Registry) ClearOverride

func (r *Registry) ClearOverride(s *State, key string) error

ClearOverride removes an override for key. No-op if no override exists. Returns an error if the key is not in the registry.

func (*Registry) Get

func (r *Registry) Get(key string) (Flag, bool)

Get returns the flag for key, or ok=false if not in the registry.

func (*Registry) Keys

func (r *Registry) Keys() []string

Keys returns the sorted set of registry keys.

func (*Registry) Resolve

func (r *Registry) Resolve(s *State) []Status

Resolve returns the effective Status for every registry flag, given the supplied state.

func (*Registry) ResolveOne

func (r *Registry) ResolveOne(s *State, key string) (Status, bool)

ResolveOne returns the Status for a single flag.

Returns ok=false when the key is not in the registry. An override for a key that doesn't exist is ignored — registry membership is authoritative.

func (*Registry) SetOverride

func (r *Registry) SetOverride(s *State, key string, enabled bool) error

SetOverride mutates s by recording an override for key. The key must exist in the registry; otherwise an error is returned.

type State

type State struct {
	Overrides map[string]bool `json:"overrides"`
	UpdatedAt time.Time       `json:"updated_at"`
}

State is the persisted per-flag override map.

Keys are flag keys; values are the user's requested enabled state. The absence of a key means "use registry default".

func LoadState

func LoadState(projectDir string) (*State, error)

LoadState reads the state file at <projectDir>/.nself/features.json.

A missing file is NOT an error: the returned State has an empty overrides map. Use it as the working baseline.

type Status

type Status struct {
	Flag       Flag      `json:"flag"`
	Enabled    bool      `json:"enabled"`
	Overridden bool      `json:"overridden"`
	Source     string    `json:"source"` // "default" | "override"
	UpdatedAt  time.Time `json:"updated_at,omitempty"`
}

Status is the resolved view of a flag: its registry entry plus the effective enabled state (override or default) and a flag indicating whether an override is in play.

Jump to

Keyboard shortcuts

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