config

package
v1.21.20 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const MaxPerUserConcurrency = 16

MaxPerUserConcurrency is the hardcoded ceiling on the per-user concurrent extraction count. Operators may configure a per-user default at or below this value; runtime overrides are also clamped to this ceiling. Exported so the api package can enforce the same cap without duplicating the constant.

Variables

This section is empty.

Functions

func ExpectedMigratableKeysSkipped

func ExpectedMigratableKeysSkipped() map[string]string

ExpectedMigratableKeysSkipped returns the set of leaf fields that exist on Config but are intentionally NOT emitted as migratable settings. This allowlist is what keeps the completeness gate from flagging fields that have a legitimate reason to be invisible to the DB-backed settings service.

Adding an entry here is a deliberate act — every entry must have a justification comment. An entry that says "TODO: migrate later" is a promise to do that work, tracked by the follow-up issue noted in the comment. SEM@d34da3918d4a3784077a74aedd722e45c29196cf: return the allowlist of config fields intentionally excluded from migratable settings, with justification (pure)

func GenerateExampleConfig

func GenerateExampleConfig() ([]byte, error)

GenerateExampleConfig produces the contents of config-example.yml from the classification registry. Only CategoryBootstrap keys are included — the example file documents the bootstrap-only config, since operational config lives in the database. Secret values are emitted as reference placeholders. SEM@a60b4f430769f6d36f0e3753a429ea699ba8b1a0: build annotated example YAML for bootstrap-only config keys with vault placeholders for secrets (pure)

func GenerateReferenceMarkdown

func GenerateReferenceMarkdown() ([]byte, error)

GenerateReferenceMarkdown produces the per-key configuration reference from the classification registry. It emits a precedence explainer plus two tables — bootstrap and operational — so the wiki Configuration-Reference page is generated, not hand-maintained. Secret defaults are shown as vault:// placeholders, never real values.

Rows come from referenceSettings, i.e. the registry itself, not from GetMigratableSettings: that projection omits empty-valued and conditionally-emitted settings for database-seeding reasons, and the reference doubles as the TMI_* env-var allowlist, so it must name every setting the server can read (#810). SEM@4077bab0af75093efb1660aa34801b2c752c9c0f: build the wiki configuration reference as Markdown from the full registry, with a precedence explainer, bootstrap/operational tables and a process-environment section (pure)

func IsSecretReference

func IsSecretReference(value string) bool

IsSecretReference reports whether value is a secret-reference locator (vault://, env://, or file://) rather than an inline secret literal. SEM@b583a71af02ca00e2c408d9d52e1e41f514df3ff: report whether a config value is a secret-reference locator rather than an inline literal (pure)

func KeysInFile

func KeysInFile(path string) (map[string]bool, error)

KeysInFile returns every dotted leaf key present in a YAML config file, as a set. Used to distinguish a value an operator actually wrote from the struct default that every setting otherwise carries — the distinction the settings service needs to know whether a database value may apply (#415). SEM@10b74985ed52c143cb0fb6e853b2d5f106de198f: list every dotted leaf key present in a YAML config file as a set (reads file)

func OperationalKeysInFile

func OperationalKeysInFile(path string) ([]string, error)

OperationalKeysInFile returns the operational-category setting keys present in a YAML config file. Operational config belongs in the database; finding it in a file indicates drift during the bootstrap-only migration. SEM@e81aaa612078c97ad77ca1478c9812ee7e86b331: list operational-category config keys present in a YAML file to detect bootstrap drift (reads file)

func ParseFlags deprecated

func ParseFlags() (configFile string, generateConfig bool, err error)

ParseFlags parses command line flags and returns the config file path.

Deprecated: prefer ParseFlagsExt, which also reports --version. SEM@611336ef1d0532d45b3fcb7690961fe67029d425: parse CLI flags and return config file path and generate-config flag; deprecated in favor of ParseFlagsExt (pure)

func PrintConfigHelp

func PrintConfigHelp() error

PrintConfigHelp prints guidance about configuration files. It is invoked when the server binary is run with --generate-config. SEM@a60b4f430769f6d36f0e3753a429ea699ba8b1a0: print guidance on setting up local configuration files from the example template (pure)

func ResolveSecretValue

func ResolveSecretValue(ctx context.Context, value string, vault SecretResolver) (string, error)

ResolveSecretValue dereferences a secret config value.

  • An inline value (no recognized scheme:// prefix) is returned unchanged. A value such as "postgres://..." is inline — postgres is not a reference scheme.
  • env://NAME resolves to the value of environment variable NAME; an unset or empty variable is an error.
  • file://PATH reads PATH and returns its whitespace-trimmed contents.
  • vault://PATH dereferences PATH through the supplied SecretResolver. A nil resolver is an error (a vault reference requires a configured secrets provider).

Resolution failures are returned as typed errors; this function never panics. SEM@b583a71af02ca00e2c408d9d52e1e41f514df3ff: dereference a vault://, env://, or file:// secret locator to its plaintext value (reads env/file/vault)

func ValidateClassifications

func ValidateClassifications(settings []MigratableSetting) error

ValidateClassifications checks that every setting carries a complete and internally consistent ConfigClass. It returns a single error listing every violation found. This is the mechanism that makes the classification model self-enforcing: a misclassified setting fails the build. SEM@b4834203783bf0a76ea4b6d187622b91f43a018b: validate that every config setting has a complete and consistent classification (pure)

func ValidateSettingDefs

func ValidateSettingDefs(defs []SettingDef) error

ValidateSettingDefs checks the registry's internal consistency and returns an error naming every problem found, one per line, or nil. It is the enforcement point for the rule that every setting must be classified: a definition whose Category is the zero value is rejected.

This supersedes ValidateClassifications for the SettingDef registry: every rule that function enforces on a MigratableSetting is carried across here, plus the additional legality rules that apply to SettingDef's config-path (YAMLPath/EnvVar/Get) and Seeded fields. SEM@90fd6060aa317cecb2310cc1bcb5092066f872ae: validate the setting registry's internal consistency and return all problems (pure)

func ValidateTimmyConfig added in v1.21.13

func ValidateTimmyConfig(t TimmyConfig, buildMode string) error

ValidateTimmyConfig enforces the Timmy invariants on any Timmy config (env/YAML or DB-resolved) for the given build mode. SEM@57a0ccb18013f0ed5d8a8631da478fae012e3c67: validate Timmy dev-only flag, LLM provider and max tokens for a build mode (pure)

func ValidateTimmyDumpFlag added in v1.21.13

func ValidateTimmyDumpFlag(enabled bool, buildMode string) error

ValidateTimmyDumpFlag rejects enabling timmy.dump_extracted_text_to_note in production builds. SEM@57a0ccb18013f0ed5d8a8631da478fae012e3c67: reject enabling the dev-only extracted-text dump flag in production builds (pure)

Types

type AdministratorConfig

type AdministratorConfig struct {
	Provider    string `yaml:"provider" json:"provider"`                           // OAuth/SAML provider ID (required)
	ProviderId  string `yaml:"provider_id,omitempty" json:"provider_id,omitempty"` // Provider's user ID (for users, preferred)
	Email       string `yaml:"email,omitempty" json:"email,omitempty"`             // Provider's email (for users, fallback)
	GroupName   string `yaml:"group_name,omitempty" json:"group_name,omitempty"`   // Group name (for groups)
	SubjectType string `yaml:"subject_type" json:"subject_type"`                   // "user" or "group" (required)
}

AdministratorConfig represents a single administrator entry configuration SEM@ef979cc7527137e0448782341a4ffe8e944571f5: configuration entry identifying a user or group to bootstrap as an administrator (pure)

type AlertingConfig

type AlertingConfig struct {
	Enabled       bool   `yaml:"enabled" env:"TMI_ALERTING_ENABLED"`
	WebhookURL    string `yaml:"webhook_url" env:"TMI_ALERTING_WEBHOOK_URL"`
	WebhookSecret string `yaml:"webhook_secret" env:"TMI_ALERTING_WEBHOOK_SECRET"`
}

AlertingConfig holds configuration for the operator-pinned audit alert sink (#395). When Enabled is true, EnsurePinnedAlertSubscription upserts a single operator-owned webhook subscription that delivers system_audit.admin_write events to WebhookURL. WebhookSecret is the HMAC signing secret for that subscription; it may be an env:// or vault:// reference resolved at startup by ResolveSecretReferences. SEM@13c4215bf8e204da342579717f97f7393bb5fe2f: configuration struct for the operator-pinned audit alert webhook URL and signing secret (pure)

type AuthConfig

type AuthConfig struct {
	JWT                  JWTConfig    `yaml:"jwt"`
	OAuth                OAuthConfig  `yaml:"oauth"`
	SAML                 SAMLConfig   `yaml:"saml"`
	Cookie               CookieConfig `yaml:"cookie"`
	AutoPromoteFirstUser bool         `yaml:"auto_promote_first_user" env:"TMI_AUTH_AUTO_PROMOTE_FIRST_USER"`
	EveryoneIsAReviewer  bool         `yaml:"everyone_is_a_reviewer" env:"TMI_AUTH_EVERYONE_IS_A_REVIEWER"`
	BuildMode            string       `yaml:"build_mode" env:"TMI_BUILD_MODE"` // dev, test, or production
	// StepUpWindowSeconds controls how recent the auth_time JWT claim must be
	// for /admin/* writes (#355). Default 300 (5 minutes); minimum 60.
	StepUpWindowSeconds int `yaml:"step_up_window_seconds" env:"TMI_AUTH_STEP_UP_WINDOW_SECONDS"`
}

AuthConfig holds authentication configuration SEM@e81aaa612078c97ad77ca1478c9812ee7e86b331: configuration struct aggregating JWT, OAuth, SAML, cookie, and role settings (pure)

type CORSConfig

type CORSConfig struct {
	AllowedOrigins []string `yaml:"allowed_origins" env:"TMI_CORS_ALLOWED_ORIGINS"` // Comma-separated allowed origins
}

CORSConfig holds CORS configuration SEM@314b7ae8fe586a75ecee2e8fa7103d3193f15f7c: configuration for allowed CORS origins (pure)

type Category

type Category int

Category answers: where does the value come from at rest? SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: enum classifying where a config value originates at rest (pure)

const (
	// CategoryUnclassified is the zero value. A setting with this category
	// fails the validation suite — it forces every setting to be classified.
	CategoryUnclassified Category = iota
	// CategoryBootstrap settings are loaded from file/env only, never the DB,
	// and consumed at startup before the settings service exists.
	CategoryBootstrap
	// CategoryOperational settings are DB-backed and runtime-editable.
	CategoryOperational
)

func ClassificationCategoryFor

func ClassificationCategoryFor(key string) Category

ClassificationCategoryFor returns the Category of a setting key. It is the exported entry point for callers outside the config package that need to know whether a key is bootstrap or operational. SEM@290855b441dc47580986878bc40a3cb20d4ea51a: return the lifecycle category (bootstrap vs operational) for a setting key (pure)

func (Category) String

func (c Category) String() string

SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: convert a Category to its canonical string name (pure)

type Config

type Config struct {
	Server                    ServerConfig            `yaml:"server"`
	Database                  DatabaseConfig          `yaml:"database"`
	Auth                      AuthConfig              `yaml:"auth"`
	WebSocket                 WebSocketConfig         `yaml:"websocket"`
	Webhooks                  WebhookConfig           `yaml:"webhooks"`
	Logging                   LoggingConfig           `yaml:"logging"`
	Operator                  OperatorConfig          `yaml:"operator"`
	Secrets                   SecretsConfig           `yaml:"secrets"`
	Administrators            []AdministratorConfig   `yaml:"administrators"`
	Timmy                     TimmyConfig             `yaml:"timmy"`
	SSRF                      SSRFConfig              `yaml:"ssrf"`
	Observability             ObservabilityConfig     `yaml:"observability"`
	ContentSources            ContentSourcesConfig    `yaml:"content_sources"`
	ContentExtractors         ContentExtractorsConfig `yaml:"content_extractors"`
	ContentOAuth              ContentOAuthConfig      `yaml:"content_oauth"`
	ContentTokenEncryptionKey string                  `yaml:"content_token_encryption_key" env:"TMI_CONTENT_TOKEN_ENCRYPTION_KEY"`
	Alerting                  AlertingConfig          `yaml:"alerting"`
	// contains filtered or unexported fields
}

Config holds all application configuration SEM@10b74985ed52c143cb0fb6e853b2d5f106de198f: top-level application configuration aggregating all subsystem config structs (pure)

func Load

func Load(configFile string) (*Config, error)

Load loads configuration from YAML file with environment variable overrides SEM@1a4ca5f99be4a25df66b2836e9b9f4c87628184a: load and validate server configuration from a YAML file with env-var overrides (reads files, reads env)

func LoadSettingsSource

func LoadSettingsSource(configFile string) (*Config, error)

LoadSettingsSource loads a YAML file that carries only operational settings — a `tmi-dbtool --export-config` snapshot, say — rather than a server configuration.

It skips the bootstrap validation Load() performs, because a settings source legitimately has no database.url, jwt.secret or build_mode: those are CategoryBootstrap keys that live in the server's own config file, and --export-config never writes them. Validating such a file as though it were a server config is what broke the export/import round-trip that --export-config's own output header advertises, and that `deploy-aws.sh --config-export` depends on — it failed with "database url is required (TMI_DATABASE_URL)" (#791).

Callers get a Config whose operational fields reflect the file and whose bootstrap fields are defaults; only GetMigratableSettings() output is meaningful. Do NOT use this to configure a running server. SEM@1a4ca5f99be4a25df66b2836e9b9f4c87628184a: load operational-settings config from YAML without bootstrap validation (reads files, reads env)

func (*Config) GetBaseURL

func (c *Config) GetBaseURL() string

GetBaseURL returns the server's public base URL for callbacks. If BaseURL is explicitly configured, it is returned as-is. Otherwise, the URL is auto-inferred from Interface, Port, and TLSEnabled. SEM@df41a3866f5824f0f8fb588edb04475095615bcf: compute the server's public base URL from config, inferring scheme and host if not explicit (pure)

func (*Config) GetCookieDomain

func (c *Config) GetCookieDomain() string

GetCookieDomain returns the cookie domain for HttpOnly auth cookies.

It returns ONLY an explicitly configured domain; otherwise it returns "" so the cookie is set without a Domain attribute (a host-only cookie scoped to the exact request host). The domain is deliberately never inferred from the bind/listen address or base URL: the server binds to 0.0.0.0 in dev, and deriving the cookie Domain from that produced Domain=0.0.0.0, which browsers reject (an IP literal that does not match the request host), so the auth cookies were silently discarded (#497). A host-only cookie is also the strictly more secure default in production -- it cannot leak to sibling subdomains -- so omitting Domain is correct everywhere unless an operator explicitly needs cross-host scoping. SEM@99bccde8ec15f1645b5b007b4a0aecd710743633: return only the explicitly configured cookie domain, else empty for a host-only cookie (pure)

func (*Config) GetEnabledOAuthProviders

func (c *Config) GetEnabledOAuthProviders() []OAuthProviderConfig

GetEnabledOAuthProviders returns a slice of enabled OAuth providers SEM@951145f6425b88fab9b769b19da233acbe42824c: list all enabled OAuth provider configs (pure)

func (*Config) GetJWTDuration

func (c *Config) GetJWTDuration() time.Duration

GetJWTDuration returns the JWT expiration duration SEM@951145f6425b88fab9b769b19da233acbe42824c: convert the JWT expiration seconds setting to a time.Duration (pure)

func (*Config) GetLogLevel

func (c *Config) GetLogLevel() slogging.LogLevel

GetLogLevel returns the parsed log level SEM@1d6e8926b4e58c0d98fff4d43bd3f6df1852d61a: parse and return the configured log level as a typed LogLevel (pure)

func (*Config) GetMigratableSettings

func (c *Config) GetMigratableSettings() []MigratableSetting

GetMigratableSettings returns every setting that has a config-file or environment delivery path, with its current value read from this Config.

This projects the registry (setting_defs_*.go) rather than maintaining a parallel list. A def with OmitWhenEmpty is left out entirely when its value is empty, reproducing the pre-registry builders' conditional emission (see OmitWhenEmpty's doc comment on SettingDef for why this matters beyond cosmetics). server.tls_cert_file and server.tls_key_file are special-cased instead of using OmitWhenEmpty: their old emission guard was server.tls_enabled, a different field than the one being emitted, and OmitWhenEmpty can only test a def's own Get() output.

auth.oauth.providers.*, auth.saml.providers.* and content_oauth.providers.* are generated per configured provider rather than declared statically — dynamic cardinality means no fixed dotted key — and are appended after the registry projection.

A def whose Key appears in ExpectedMigratableKeysSkipped() is never emitted, regardless of OmitWhenEmpty: that list's predicate is exactly "intentionally not a migratable setting" (see its doc comment), and two of its entries — content_token_encryption_key, database.oracle_wallet_location — now have a SettingDef with a real Get accessor. Matching on Key rather than YAMLPath matters: the list's other three entries are rename cases keyed by the pre-refactor STRUCT path (e.g. "auth.oauth.callback_url"), while the corresponding defs' Key is the renamed migratable-setting key (e.g. "auth.oauth_callback_url") — matching Key against that map leaves those three correctly emitted under their renamed key and skips only the two bootstrap-by-construction keys.

Class is assigned via classificationFor(key) in the final pass below, for every emitted setting — defs-projected and generated provider keys alike — exactly as the pre-registry implementation did. It is NOT taken from SettingDef.Class directly, even though the two agree on Category/Visibility/Secret for every currently-emitted key (Task 5 built SettingDef.Class as classificationFor(key) with Mutability overridden via withMutability(...) on many operational defs). Consuming SettingDef.Class here would flow those Mutability overrides into GetMigratableSettings' observable output for the first time — a real behavior change (dozens of keys' hot/static column in config-reference.md) that Ruling 15 explicitly deferred to Phase E ("making classificationFor() consult the registry... belongs in Phase E"). SEM@e6cee63c3a07d38f471e0ebfb81722849f36085e: list all config settings eligible for database migration with classification applied (pure)

func (*Config) GetOAuthProvider

func (c *Config) GetOAuthProvider(providerID string) (OAuthProviderConfig, bool)

GetOAuthProvider returns a specific OAuth provider configuration SEM@951145f6425b88fab9b769b19da233acbe42824c: fetch a single enabled OAuth provider config by provider ID (pure)

func (*Config) GetWebSocketInactivityTimeout

func (c *Config) GetWebSocketInactivityTimeout() time.Duration

GetWebSocketInactivityTimeout returns the websocket inactivity timeout duration SEM@5fab45cd0e653a12ca75749776c15b98390816b8: convert the WebSocket inactivity timeout seconds setting to a time.Duration (pure)

func (*Config) IsSecureCookies

func (c *Config) IsSecureCookies() bool

IsSecureCookies returns whether cookies should have the Secure flag set. Returns true if explicitly configured or if TLS is enabled. SEM@314b7ae8fe586a75ecee2e8fa7103d3193f15f7c: report whether the Secure flag should be set on session cookies (pure)

func (*Config) IsTestMode

func (c *Config) IsTestMode() bool

IsTestMode returns true if running in test mode SEM@00b0ee530c36c62288babea895dd77d7bfeeac94: report whether the server is running in test mode (pure)

func (*Config) ResolveSecretReferences

func (c *Config) ResolveSecretReferences(ctx context.Context, vault SecretResolver) error

ResolveSecretReferences walks the secret fields of the loaded Config and, for any field whose value is a vault://, env://, or file:// reference, dereferences it in place. Inline values (the dev/test default shape) are left unchanged.

The fields walked include every CategoryBootstrap secret plus the four Timmy API keys. The Timmy keys are CategoryOperational + Secret (see classification_registry.go), but their runtime consumers still read from the in-memory cfg.Timmy struct, so they need load-time resolution until #419 routes those consumers through SettingsService. Once #419 lands, the Timmy entries here can be removed and resolution moves to per-read.

It must run AFTER secrets.NewProvider (so the vault leg works) but BEFORE any consumer reads Auth.JWT.Secret or Database.URL (JWT init, DB connect). Secrets.VaultToken is resolved separately by ResolveSecretsConfigReferences, which runs before the provider is built; it is not re-resolved here.

vault references the secrets provider's vault leg; it may be nil, in which case any vault:// reference is reported as an error. SEM@13c4215bf8e204da342579717f97f7393bb5fe2f: dereference vault://, env://, and file:// secret references across all bootstrap secret fields in place (reads env/file/vault)

func (*Config) ResolveSecretsConfigReferences

func (c *Config) ResolveSecretsConfigReferences(ctx context.Context) error

ResolveSecretsConfigReferences dereferences secret-reference values inside the Secrets block itself (currently only Secrets.VaultToken). It is called BEFORE the secrets provider is constructed, so it is passed no SecretResolver: only env:// and file:// references resolve here. A vault:// reference for Secrets.VaultToken is rejected — the provider cannot dereference a token it needs in order to exist.

An inline value (the dev/test default shape) is left unchanged. SEM@b583a71af02ca00e2c408d9d52e1e41f514df3ff: resolve env:// and file:// secret references in the Secrets config block before provider construction (reads env/file)

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration at config.Load() time.

IMPORTANT: This runs at startup BEFORE the database settings service exists. As of #415, the config files (config-development.yml, config-test.yml, config-production.yml) are bootstrap-only — all CategoryOperational config (OAuth/SAML providers, websocket tunables, content extractors/OAuth, Timmy, administrators) was removed from the files and is now DB-seeded from the classification registry via SettingsService.SeedDefaults -> DefaultOperationalSettings(). Validating operational config here is wrong by construction: the file no longer carries it, so the values would always be the zero/default fallbacks rather than the effective runtime config.

Therefore Validate() checks ONLY CategoryBootstrap config (server, database, CORS, JWT secret). Operational config correctness is enforced by the classification registry + ValidateClassifications suite; its values come from SeedDefaults. See validateOperationalRemoved below for the rationale on each operational check that used to live here. SEM@0ad78fa809c1bae435ba37740922d1e1b33e13d9: validate bootstrap-only config fields (server, database, JWT secret, CORS) at load time (pure)

func (*Config) ValidateRequired

func (c *Config) ValidateRequired() error

ValidateRequired checks that every Required-classified bootstrap setting has a non-empty effective value. It is called from Load() after Validate() succeeds, so the Config has already had defaults, file values, and env overrides applied.

All five Required settings (server.port, server.interface, database.url, auth.build_mode, auth.jwt.secret) are CategoryBootstrap — their values are known at Load() time, making this the correct enforcement point.

All missing required keys are collected into a single error rather than failing on the first, mirroring the ValidateClassifications multi-error style. SEM@b4834203783bf0a76ea4b6d187622b91f43a018b: validate that all Required-classified bootstrap settings have non-empty values (pure)

type ConfigClass

type ConfigClass struct {
	Category   Category
	Secret     bool
	ValueKind  ValueKind
	Delivery   *Delivery // nil for CategoryBootstrap
	Visibility Visibility
	Mutability Mutability
	Consumers  []Consumer
	Required   bool
}

ConfigClass is the complete classification of one configuration item. SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: complete classification metadata for one configuration setting (pure)

func ClassificationFor

func ClassificationFor(key string) ConfigClass

ClassificationFor returns the full ConfigClass for a setting key. It is the exported entry point for callers outside the config package. SEM@dcb09b6afcb6a3a78ce7ba3c345e459ba9cf55a2: return the full ConfigClass for a setting key (pure)

type ConfluenceConfig

type ConfluenceConfig struct {
	Enabled bool `yaml:"enabled" env:"TMI_CONTENT_SOURCE_CONFLUENCE_ENABLED"`
}

ConfluenceConfig holds settings for the delegated Confluence content source. OAuth-provider settings (client id/secret, endpoints, scopes, extra_authorize_params for audience=api.atlassian.com) live under content_oauth.providers.confluence.

This struct intentionally has no picker fields — Confluence has no picker UX; users paste page URLs. SEM@6199f1bebeb0a5e637b7c38588d721ac36b525f4: configuration for the Confluence content source integration (pure)

func (ConfluenceConfig) IsConfigured

func (c ConfluenceConfig) IsConfigured() bool

IsConfigured returns true when the source is enabled. The OAuth provider configuration is validated separately via the content_oauth registry. SEM@6199f1bebeb0a5e637b7c38588d721ac36b525f4: validate that the Confluence integration is enabled (pure)

type ConnectionPoolConfig

type ConnectionPoolConfig struct {
	MaxOpenConns    int `yaml:"max_open_conns" env:"TMI_DB_MAX_OPEN_CONNS"`         // Maximum open connections (default: 10)
	MaxIdleConns    int `yaml:"max_idle_conns" env:"TMI_DB_MAX_IDLE_CONNS"`         // Maximum idle connections (default: 2)
	ConnMaxLifetime int `yaml:"conn_max_lifetime" env:"TMI_DB_CONN_MAX_LIFETIME"`   // Max connection lifetime in seconds (default: 240)
	ConnMaxIdleTime int `yaml:"conn_max_idle_time" env:"TMI_DB_CONN_MAX_IDLE_TIME"` // Max idle time in seconds (default: 30)
}

ConnectionPoolConfig holds database connection pool settings SEM@fe6575f1c15d84b67ee9853a0e59055c1ebe44b6: configuration struct for DB connection pool size and lifetime limits (pure)

type Consumer

type Consumer int

Consumer is a closed enum of the processes that read configuration. Add a value here when a new component type is introduced. SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: enum of process types that read configuration (pure)

const (
	// ConsumerMonolith is the primary TMI server process.
	ConsumerMonolith Consumer = iota
	// ConsumerTMIUX is the tmi-ux frontend client.
	ConsumerTMIUX
	// ConsumerWorkerExtractor is the extractor worker process.
	ConsumerWorkerExtractor
	// ConsumerWorkerChunkEmbed is the chunk-embed worker process.
	ConsumerWorkerChunkEmbed
)

func (Consumer) String

func (c Consumer) String() string

SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: convert a Consumer to its canonical process-name string (pure)

type ContentExtractorsConfig

type ContentExtractorsConfig struct {
	CompressedSizeBytes       int64         `yaml:"compressed_size_bytes" env:"TMI_CONTENT_EXTRACTORS_COMPRESSED_SIZE_BYTES"`
	DecompressedSizeBytes     int64         `yaml:"decompressed_size_bytes" env:"TMI_CONTENT_EXTRACTORS_DECOMPRESSED_SIZE_BYTES"`
	PartSizeBytes             int64         `yaml:"part_size_bytes" env:"TMI_CONTENT_EXTRACTORS_PART_SIZE_BYTES"`
	PPTXSlides                int           `yaml:"pptx_slides" env:"TMI_CONTENT_EXTRACTORS_PPTX_SLIDES"`
	XLSXCells                 int           `yaml:"xlsx_cells" env:"TMI_CONTENT_EXTRACTORS_XLSX_CELLS"`
	MarkdownSizeBytes         int64         `yaml:"markdown_size_bytes" env:"TMI_CONTENT_EXTRACTORS_MARKDOWN_SIZE_BYTES"`
	WallClockBudget           time.Duration `yaml:"wall_clock_budget" env:"TMI_CONTENT_EXTRACTORS_WALL_CLOCK_BUDGET"`
	PerUserConcurrencyDefault int           `yaml:"per_user_concurrency_default" env:"TMI_CONTENT_EXTRACTORS_PER_USER_CONCURRENCY_DEFAULT"`
	// AsyncEnabled routes extraction through the async worker pipeline instead
	// of inline processing. Requires NATS. Default false (inline mode).
	AsyncEnabled bool `yaml:"async_enabled" env:"TMI_EXTRACTION_ASYNC_ENABLED"`
}

ContentExtractorsConfig holds operator-tunable defaults for the OOXML extractor pipeline. Each value must be > 0 and <= the corresponding hardcoded ceiling. SEM@d34da3918d4a3784077a74aedd722e45c29196cf: operator-tunable limits for the OOXML content extractor pipeline (pure)

func DefaultContentExtractorsConfig

func DefaultContentExtractorsConfig() ContentExtractorsConfig

DefaultContentExtractorsConfig returns the project-wide defaults documented in the OOXML design spec. SEM@5c3161aebd21c6f134ca3df11e282514ff6f0518: build the project-default content extractor pipeline limits (pure)

func (ContentExtractorsConfig) Validate

func (c ContentExtractorsConfig) Validate() error

Validate enforces > 0 and <= ceiling for every field. SEM@d18c6f98b08a7050e43b60a513bea5be33b09bf4: validate that all extractor config values are positive and within hardcoded ceilings (pure)

type ContentOAuthConfig

type ContentOAuthConfig struct {
	CallbackURL            string                                `yaml:"callback_url" env:"TMI_CONTENT_OAUTH_CALLBACK_URL"`
	AllowedClientCallbacks []string                              `yaml:"allowed_client_callbacks"`
	Providers              map[string]ContentOAuthProviderConfig `yaml:"providers"`
}

ContentOAuthConfig holds configuration for delegated content OAuth providers. SEM@13e72c114e339424dba2382d2756380036c57166: top-level config struct for content OAuth providers and allowed callbacks (pure)

func (*ContentOAuthConfig) Validate

func (c *ContentOAuthConfig) Validate(encryptionKey string) error

Validate returns an error if any enabled provider is missing required fields, or if at least one provider is enabled but the encryption key is empty/invalid. SEM@13e72c114e339424dba2382d2756380036c57166: validate that all enabled content OAuth providers have required fields and an encryption key (pure)

type ContentOAuthProviderConfig

type ContentOAuthProviderConfig struct {
	Enabled              bool              `yaml:"enabled"`
	Name                 string            `yaml:"name"`
	Icon                 string            `yaml:"icon"`
	ClientID             string            `yaml:"client_id"`
	ClientSecret         string            `yaml:"client_secret"`
	AuthURL              string            `yaml:"auth_url"`
	TokenURL             string            `yaml:"token_url"`
	UserinfoURL          string            `yaml:"userinfo_url"`
	RevocationURL        string            `yaml:"revocation_url"`
	RequiredScopes       []string          `yaml:"required_scopes"`
	ExtraAuthorizeParams map[string]string `yaml:"extra_authorize_params"`
}

ContentOAuthProviderConfig is one entry under content_oauth.providers.*

ExtraAuthorizeParams are appended to the authorize URL query string. They are useful for providers that require non-standard parameters beyond the standard OAuth 2.0 + PKCE set (e.g. Atlassian's audience=api.atlassian.com). yaml-only for now; if env-var support is needed later it can be added without breaking existing configs. SEM@aed9318ad317c1a2668a12e84c4d9d773b83d4cc: config struct for a single content OAuth provider including endpoints and scopes (pure)

type ContentSourcesConfig

type ContentSourcesConfig struct {
	GoogleDrive     GoogleDriveConfig     `yaml:"google_drive"`
	GoogleWorkspace GoogleWorkspaceConfig `yaml:"google_workspace"`
	Confluence      ConfluenceConfig      `yaml:"confluence"`
	Microsoft       MicrosoftConfig       `yaml:"microsoft"`
}

ContentSourcesConfig holds configuration for all content source providers. SEM@586d554a03f2ad309bdab24eb6ead126adc17e6e: aggregated configuration for all content source providers including Google Drive and Microsoft (pure)

type CookieConfig

type CookieConfig struct {
	Enabled bool   `yaml:"enabled" env:"TMI_COOKIE_ENABLED"` // Enable HttpOnly cookie-based auth (default: true)
	Domain  string `yaml:"domain" env:"TMI_COOKIE_DOMAIN"`   // Cookie domain; leave empty for a host-only cookie (recommended). Never inferred from the bind address (#497).
	Secure  bool   `yaml:"secure" env:"TMI_COOKIE_SECURE"`   // Require HTTPS (auto-derived from TLSEnabled if not set)
}

CookieConfig holds HttpOnly session cookie configuration SEM@314b7ae8fe586a75ecee2e8fa7103d3193f15f7c: configuration struct for HttpOnly session cookie domain and security flags (pure)

type DatabaseConfig

type DatabaseConfig struct {
	URL                  string               `yaml:"url" env:"TMI_DATABASE_URL"`                              // Connection string URL (12-factor app pattern) - REQUIRED
	OracleWalletLocation string               `yaml:"oracle_wallet_location" env:"TMI_ORACLE_WALLET_LOCATION"` // Path to Oracle wallet directory (Oracle ADB only)
	ConnectionPool       ConnectionPoolConfig `yaml:"connection_pool"`
	Redis                RedisConfig          `yaml:"redis"`
}

DatabaseConfig holds database configuration. The primary configuration method is DATABASE_URL which contains all connection parameters. Database type is automatically detected from the URL scheme (postgres://, mysql://, etc.) SEM@fe6575f1c15d84b67ee9853a0e59055c1ebe44b6: configuration for the primary database connection URL, Oracle wallet, connection pool, and Redis (pure)

type Delivery

type Delivery struct {
	// StampedIntoEnvelope: the monolith copies this into job envelopes.
	StampedIntoEnvelope bool
	// SharedInvariant: the monolith ALSO consumes this; ingest and the
	// monolith must agree. The validation suite enforces that SharedInvariant
	// implies StampedIntoEnvelope.
	SharedInvariant bool
}

Delivery describes how an operational setting reaches a process that cannot ask the monolith over HTTP. It is nil on bootstrap settings. SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: struct describing how an operational setting is delivered to non-monolith processes (pure)

type DiscoveredField

type DiscoveredField struct {
	// DottedKey is the lower-snake-case dotted path produced from yaml
	// tags (e.g. "auth.cookie.enabled").
	DottedKey string

	// EnvVar is the value of the `env` struct tag on the leaf field, or
	// "" if absent. Used by the test to flag fields that should plumb a
	// TMI_* env var but don't.
	EnvVar string
}

DiscoveredField is a leaf-level field found by reflection over Config. It is the input the build-time completeness gate compares against the keys actually emitted by GetMigratableSettings — see TestMigratableSettings_CoverEveryConfigField in migratable_discovery_test.go. SEM@ac5e96c911b24411e0a2143b92aa3725fb7df190: dotted-key and env-var metadata for a single scalar config leaf field (pure)

func DiscoverConfigFields

func DiscoverConfigFields() []DiscoveredField

DiscoverConfigFields walks Config with reflection and returns every leaf field that should be a candidate for the migratable-settings emit set.

Fields skipped (by design):

  • Unexported fields (reflection cannot read them).
  • Map types (auth.oauth.providers, auth.saml.providers, content_oauth.providers): the per-instance key is dynamic, so enumeration cannot produce a fixed dotted path. These are walked by the per-provider helpers in migratable_settings.go.
  • Slice-of-struct types (administrators): same reasoning — variable cardinality, dynamic keys.
  • Fields with yaml tag "-" (explicitly excluded).
  • Anonymous (embedded) struct fields — none in Config today.

The walker recurses into named struct fields. A leaf is anything that is NOT itself a struct (after dereferencing pointers). SEM@ac5e96c911b24411e0a2143b92aa3725fb7df190: list all scalar leaf fields in Config using yaml struct tags via reflection (pure)

type EmbeddingProfile

type EmbeddingProfile struct {
	Model     string `json:"model"`
	Endpoint  string `json:"endpoint"`
	Dimension int    `json:"dimension"`
}

EmbeddingProfile is the shared, correctness-invariant embedding configuration. The same profile MUST be used to embed documents at ingest (by the tmi-chunk-embed worker) and to embed the user's query at search time (by the monolith). Disagreement makes vector search silently wrong.

The API key is deliberately NOT part of this struct: it is a secret, resolved independently on each side from its own secret source, never carried in a job envelope. SEM@f0ba616243817f3864baaeb58b887479f81abb8e: shared embedding model, endpoint, and dimension config stamped into job envelopes (pure)

func (EmbeddingProfile) Validate

func (p EmbeddingProfile) Validate() error

Validate returns an error if the profile is missing a required field. SEM@f0ba616243817f3864baaeb58b887479f81abb8e: validate that an embedding profile has all required non-empty fields (pure)

type Flags

type Flags struct {
	ConfigFile     string
	GenerateConfig bool
	ShowVersion    bool
}

Flags is the parsed result of ParseFlags. SEM@611336ef1d0532d45b3fcb7690961fe67029d425: parsed CLI flag values for config file path, config generation, and version display (pure)

func ParseFlagsExt

func ParseFlagsExt() (Flags, error)

ParseFlagsExt parses command line flags and returns the full Flags struct. --version / -v is a re-entrant, side-effect-free path: it can be invoked while a server is already running because it does not touch the database, listening sockets, or any shared on-disk state. SEM@611336ef1d0532d45b3fcb7690961fe67029d425: parse all CLI flags and return the full Flags struct including version flag (pure)

type GoogleDriveConfig

type GoogleDriveConfig struct {
	Enabled              bool   `yaml:"enabled" env:"TMI_CONTENT_SOURCE_GOOGLE_DRIVE_ENABLED"`
	ServiceAccountEmail  string `yaml:"service_account_email" env:"TMI_CONTENT_SOURCE_GOOGLE_DRIVE_SERVICE_ACCOUNT_EMAIL"`
	CredentialsFile      string `yaml:"credentials_file" env:"TMI_CONTENT_SOURCE_GOOGLE_DRIVE_CREDENTIALS_FILE"`
	BrowserOAuthClientID string `yaml:"browser_oauth_client_id" env:"TMI_CONTENT_SOURCE_GOOGLE_DRIVE_BROWSER_OAUTH_CLIENT_ID"`
	PickerDeveloperKey   string `yaml:"picker_developer_key" env:"TMI_CONTENT_SOURCE_GOOGLE_DRIVE_PICKER_DEVELOPER_KEY"`
	PickerAppID          string `yaml:"picker_app_id" env:"TMI_CONTENT_SOURCE_GOOGLE_DRIVE_PICKER_APP_ID"`
}

GoogleDriveConfig holds Google Drive service account configuration.

The Browser*/Picker* fields are public, browser-safe values used to bootstrap the in-browser Google Picker for service-mode Drive sources. They are optional; when all three are set, the /config response advertises them via ContentProvider.picker_config so the client can render a real picker instead of URL-paste UX. None of these values authorize anything on their own — the user OAuth handshake happens client-side via Google Identity Services with PKCE; no client_secret is ever surfaced. SEM@f2e01937e40c91e87ac47a34d11870fde716d093: Google Drive service account and browser picker configuration settings (pure)

func (GoogleDriveConfig) HasPickerConfig

func (c GoogleDriveConfig) HasPickerConfig() bool

HasPickerConfig returns true when all three browser-safe picker bootstrap values are set. The /config handler emits ContentProvider.picker_config only when all three are present — partial configuration is treated as unconfigured. SEM@f2e01937e40c91e87ac47a34d11870fde716d093: return true when all three browser-safe Google Picker bootstrap values are set (pure)

func (GoogleDriveConfig) IsConfigured

func (c GoogleDriveConfig) IsConfigured() bool

IsConfigured returns true if Google Drive has the minimum required configuration. SEM@d45ce3e9fce97c6e783aa7b8abbc40743c54ff54: return true when Google Drive is enabled with minimum required credentials (pure)

func (GoogleDriveConfig) PickerConfig

func (c GoogleDriveConfig) PickerConfig() map[string]string

PickerConfig returns the browser-safe picker bootstrap map suitable for the /config response. Returns nil when HasPickerConfig is false. SEM@f2e01937e40c91e87ac47a34d11870fde716d093: build the browser-safe Google Picker bootstrap map, or nil if incomplete (pure)

type GoogleWorkspaceConfig

type GoogleWorkspaceConfig struct {
	Enabled            bool   `yaml:"enabled" env:"TMI_CONTENT_SOURCE_GOOGLE_WORKSPACE_ENABLED"`
	PickerDeveloperKey string `yaml:"picker_developer_key" env:"TMI_CONTENT_SOURCE_GOOGLE_WORKSPACE_PICKER_DEVELOPER_KEY"`
	PickerAppID        string `yaml:"picker_app_id" env:"TMI_CONTENT_SOURCE_GOOGLE_WORKSPACE_PICKER_APP_ID"`
}

GoogleWorkspaceConfig holds settings for the delegated Google Workspace content source. OAuth-provider settings (client id/secret, endpoints, scopes) live under content_oauth.providers.google_workspace.

PickerDeveloperKey and PickerAppID are Google Cloud project values that the browser-side Google Picker JS needs; they are not secrets. SEM@d1d001debf78074ff7ac194deeb67ced6da6be19: config struct for the Google Workspace content source, including Picker credentials (pure)

func (GoogleWorkspaceConfig) IsConfigured

func (c GoogleWorkspaceConfig) IsConfigured() bool

IsConfigured returns true when the source is enabled and both picker inputs are non-empty. SEM@d1d001debf78074ff7ac194deeb67ced6da6be19: validate that Google Workspace integration is enabled and fully configured (pure)

type JWTConfig

type JWTConfig struct {
	Secret              string `yaml:"secret" env:"TMI_JWT_SECRET"`
	ExpirationSeconds   int    `yaml:"expiration_seconds" env:"TMI_JWT_EXPIRATION_SECONDS"`
	SigningMethod       string `yaml:"signing_method" env:"TMI_JWT_SIGNING_METHOD"`
	RefreshTokenDays    int    `yaml:"refresh_token_days" env:"TMI_REFRESH_TOKEN_DAYS"`       // Refresh token TTL in days (default: 7)
	SessionLifetimeDays int    `yaml:"session_lifetime_days" env:"TMI_SESSION_LIFETIME_DAYS"` // Absolute session lifetime in days (default: 7)
}

JWTConfig holds JWT configuration SEM@36538e427d89135597d0d3615fcf217f9f4088e4: configuration struct for JWT secret, signing method, and token lifetimes (pure)

type LoggingConfig

type LoggingConfig struct {
	// Level is the minimum log level to emit. One of: debug, info, warn, error.
	Level string `yaml:"level" env:"TMI_LOG_LEVEL"`
	// IsDev enables developer-friendly text formatting plus source file/line
	// tagging on every record. Production deployments should set this false.
	IsDev bool `yaml:"is_dev" env:"TMI_LOG_IS_DEV"`
	// IsTest forces test-mode behavior (e.g., stable timestamps).
	IsTest bool `yaml:"is_test" env:"TMI_LOG_IS_TEST"`
	// LogDir is the directory holding the active log file (tmi.log) and
	// rotated backups. Created on startup if missing. Default: "logs".
	LogDir string `yaml:"log_dir" env:"TMI_LOG_DIR"`
	// MaxAgeDays is the maximum number of days to retain rotated backup
	// files before lumberjack deletes them. 0 = retain indefinitely
	// (subject to MaxBackups). Default: 7.
	MaxAgeDays int `yaml:"max_age_days" env:"TMI_LOG_MAX_AGE_DAYS"`
	// MaxSizeMB is the maximum size of the active log file (logs/tmi.log)
	// in megabytes before lumberjack rotates it. The active file is renamed
	// with a timestamp suffix and a fresh tmi.log is opened. Default: 100.
	MaxSizeMB int `yaml:"max_size_mb" env:"TMI_LOG_MAX_SIZE_MB"`
	// MaxBackups is the maximum number of rotated backup files to retain.
	// 0 = retain all (subject to MaxAgeDays). Default: 10.
	MaxBackups int `yaml:"max_backups" env:"TMI_LOG_MAX_BACKUPS"`
	// AlsoLogToConsole, when true, mirrors every log line to stdout in
	// addition to the file. Useful in development. Default: true.
	AlsoLogToConsole bool `yaml:"also_log_to_console" env:"TMI_LOG_ALSO_LOG_TO_CONSOLE"`
	// CloudErrorThreshold is the number of consecutive cloud-sink write
	// failures observed at 60-second poll intervals before a single Warn
	// entry is emitted. Counter resets on a quiet interval. Set to 0 to
	// disable the alarm. Default: 5.
	CloudErrorThreshold int `yaml:"cloud_error_threshold" env:"TMI_LOG_CLOUD_ERROR_THRESHOLD"`

	// Enhanced debug logging options
	LogAPIRequests              bool `yaml:"log_api_requests" env:"TMI_LOG_API_REQUESTS"`
	LogAPIResponses             bool `yaml:"log_api_responses" env:"TMI_LOG_API_RESPONSES"`
	LogWebSocketMsg             bool `yaml:"log_websocket_messages" env:"TMI_LOG_WEBSOCKET_MESSAGES"`
	RedactAuthTokens            bool `yaml:"redact_auth_tokens" env:"TMI_LOG_REDACT_AUTH_TOKENS"`
	SuppressUnauthenticatedLogs bool `yaml:"suppress_unauthenticated_logs" env:"TMI_LOG_SUPPRESS_UNAUTH_LOGS"`
}

LoggingConfig holds configuration for the slog-based logger and its lumberjack-backed file rotator. Most knobs map directly onto gopkg.in/natefinch/lumberjack.v2; see the wiki page "Operator Guide: Logging & Log Rotation" for full operator-facing documentation. SEM@e81aaa612078c97ad77ca1478c9812ee7e86b331: configuration struct for log level, rotation, console mirroring, and debug verbosity flags (pure)

type MicrosoftConfig

type MicrosoftConfig struct {
	Enabled             bool   `yaml:"enabled" env:"TMI_CONTENT_SOURCE_MICROSOFT_ENABLED"`
	TenantID            string `yaml:"tenant_id" env:"TMI_CONTENT_SOURCE_MICROSOFT_TENANT_ID"`
	ClientID            string `yaml:"client_id" env:"TMI_CONTENT_SOURCE_MICROSOFT_CLIENT_ID"`
	ApplicationObjectID string `yaml:"application_object_id" env:"TMI_CONTENT_SOURCE_MICROSOFT_APPLICATION_OBJECT_ID"`
	PickerOrigin        string `yaml:"picker_origin" env:"TMI_CONTENT_SOURCE_MICROSOFT_PICKER_ORIGIN"`
}

MicrosoftConfig holds Microsoft Graph (OneDrive-for-Business + SharePoint) content source configuration. The OAuth client_id/client_secret live under content_oauth.providers.microsoft; this struct holds the source-side values needed for picker initialization (client_id and tenant_id are surfaced to the browser via the picker-token endpoint) and the picker-grant call (application_object_id is the TMI Entra app's object id, used as the Graph permission grantee). SEM@586d554a03f2ad309bdab24eb6ead126adc17e6e: Microsoft Graph content source settings for picker initialization and Graph permission grants (pure)

func (MicrosoftConfig) IsConfigured

func (c MicrosoftConfig) IsConfigured() bool

IsConfigured returns true when all required fields are present and Enabled. PickerOrigin is optional — Experience 1 (paste-URL) works without it; only Experience 2 (picker) requires it. Operators must set it for picker UX. SEM@d45ce3e9fce97c6e783aa7b8abbc40743c54ff54: return true when Microsoft content source is enabled with all required tenant and app fields (pure)

type MigratableSetting

type MigratableSetting struct {
	Key         string
	Value       string
	Type        string
	Description string
	Secret      bool   // true = mask value in API responses (kept for back-compat; mirrors Class.Secret)
	Source      string // "config" or "environment"
	EnvVar      string // TMI_* environment variable that overrides this setting ("" if none)
	Class       ConfigClass
	// Explicit reports whether an operator actually supplied this value —
	// the env var is set, or the key was present in the YAML file — as
	// opposed to it being the struct default that every key carries.
	//
	// The settings service needs this to decide precedence. Source alone
	// cannot: it reports "config" both for "written in the file" and for
	// "nobody ever set this", and treating the latter as configured is what
	// made every operational database value unreachable (#415).
	Explicit bool
}

MigratableSetting represents a setting that can be migrated from config to database SEM@10b74985ed52c143cb0fb6e853b2d5f106de198f: DTO representing a single config setting eligible for database migration (pure)

func DefaultOperationalSettings

func DefaultOperationalSettings() []MigratableSetting

DefaultOperationalSettings returns the operational-category settings from a default Config. It is the seed source for the DB-backed settings service. Bootstrap-category settings are intentionally excluded — they are file/env only and must never be written to the database. SEM@ab3b70da0bebdbb7db5fefc97e15036dc3f5c4c5: return operational-category migratable settings from a default config, excluding bootstrap-only settings (pure)

func (MigratableSetting) IsSecret

func (m MigratableSetting) IsSecret() bool

IsSecret reports whether this setting's value must never be shown in an API response or written to a log.

Consult this rather than either flag directly. The two are NOT equivalent and the difference is a live trap: Class.Secret is false for the whole `auth.oauth.providers.`, `auth.saml.providers.` and `content_oauth.providers.` subtrees (see prefixClassifications — a blanket true there would mis-mask non-secret sub-keys like .client_id), so for those subtrees secrecy is carried ONLY by the per-setting Secret flag that the provider helpers set on .client_secret, .sp_private_key and .idp_metadata_b64xml. The Class.Secret->Secret sync in GetMigratableSettings runs in one direction only, so checking Class.Secret alone silently treats a real OAuth client secret as public. SEM@2daf3be663df9da54323f16d115f12d78d435c3f: report whether a setting's value must be masked in responses and logs (pure)

type Mutability

type Mutability int

Mutability answers: can it change after startup? SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: enum indicating whether a config setting requires restart to change (pure)

const (
	// MutabilityStatic: read once at boot; a change needs a restart.
	MutabilityStatic Mutability = iota
	// MutabilityHot: re-read at use time; a runtime edit takes effect at once.
	MutabilityHot
)

func (Mutability) String

func (m Mutability) String() string

SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: convert a Mutability to its canonical string name (pure)

type OAuthConfig

type OAuthConfig struct {
	CallbackURL string                         `yaml:"callback_url" env:"TMI_OAUTH_CALLBACK_URL"`
	Providers   map[string]OAuthProviderConfig `yaml:"providers"`
	// ClientCallbackAllowList controls which client_callback URLs the
	// /oauth2/authorize endpoint is willing to redirect to after a successful
	// login. Each entry is either an exact URL or a wildcard pattern ending
	// in "*". An empty list rejects any client_callback (fail-closed). Set
	// via env TMI_OAUTH_CLIENT_CALLBACK_ALLOWLIST as a comma-separated list.
	ClientCallbackAllowList []string `yaml:"client_callback_allowlist" env:"TMI_OAUTH_CLIENT_CALLBACK_ALLOWLIST"`
}

OAuthConfig holds OAuth configuration SEM@e81aaa612078c97ad77ca1478c9812ee7e86b331: configuration struct for OAuth callback URL, providers map, and client-callback allowlist (pure)

type OAuthProviderConfig

type OAuthProviderConfig struct {
	ID               string             `yaml:"id"`
	Name             string             `yaml:"name"`
	Enabled          bool               `yaml:"enabled"`
	Icon             string             `yaml:"icon"`
	ClientID         string             `yaml:"client_id"`
	ClientSecret     string             `yaml:"client_secret"`
	AuthorizationURL string             `yaml:"authorization_url"`
	TokenURL         string             `yaml:"token_url"`
	UserInfo         []UserInfoEndpoint `yaml:"userinfo"`
	Issuer           string             `yaml:"issuer"`
	JWKSURL          string             `yaml:"jwks_url"`
	Scopes           []string           `yaml:"scopes"`
	AdditionalParams map[string]string  `yaml:"additional_params"`
	AuthHeaderFormat string             `yaml:"auth_header_format,omitempty"`
	AcceptHeader     string             `yaml:"accept_header,omitempty"`
}

OAuthProviderConfig holds configuration for an OAuth provider SEM@65af9b7db2850b6e18076df15ed522c8df4bb64c: configuration struct for a single OAuth provider's credentials, endpoints, and scopes (pure)

type ObservabilityConfig

type ObservabilityConfig struct {
	Enabled        bool    `yaml:"enabled" env:"TMI_OTEL_ENABLED"`
	SamplingRate   float64 `yaml:"sampling_rate" env:"TMI_OTEL_SAMPLING_RATE"`
	PrometheusPort int     `yaml:"prometheus_port" env:"TMI_OTEL_PROMETHEUS_PORT"`
}

ObservabilityConfig holds OpenTelemetry configuration SEM@e81aaa612078c97ad77ca1478c9812ee7e86b331: configuration for OpenTelemetry tracing and Prometheus metrics export (pure)

type OperatorConfig

type OperatorConfig struct {
	Name         string `yaml:"name" env:"TMI_OPERATOR_NAME"`
	Contact      string `yaml:"contact" env:"TMI_OPERATOR_CONTACT"`
	Jurisdiction string `yaml:"jurisdiction" env:"TMI_OPERATOR_JURISDICTION"`
}

OperatorConfig holds operator/maintainer information SEM@3a14034a3f1269afac3c226b27ecd2df7e050a75: configuration struct for operator identity and jurisdiction metadata (pure)

type ProcessEnvVar

type ProcessEnvVar struct {
	// Name is the exact variable name or, for a Pattern, the documented
	// shape with the operator-supplied part in angle brackets, e.g.
	// "TMI_SECRET_<KEY>"; the text before the first '<' is the prefix the
	// code scans for.
	Name string
	// Binary names the reader: "server", "rotator" or "workers" (chunkembed,
	// extractor, worker-probe, component-controller).
	Binary string
	// Purpose is the one-line operator-facing description. No angle
	// brackets, backticks or pipes — it is rendered into a Markdown table.
	Purpose string
	// Secret marks a value that must never be logged or echoed.
	Secret bool
	// Pattern marks Name as a prefix pattern rather than a fixed name.
	Pattern bool
}

ProcessEnvVar documents one environment variable that a TMI binary reads straight from its process environment — outside the Config struct, the SettingDef registry and the config file. The registry cannot see these, so they are declared here by hand and rendered into config-reference.md (which doubles as the TMI_* allowlist) by GenerateReferenceMarkdown. The gate test in process_env_test.go fails when a TMI_* token appears in Go source without being declared here or in the registry (#810). SEM@3b682947: describe an env var a binary reads outside the config registry (pure)

func ProcessEnvVars

func ProcessEnvVars() []ProcessEnvVar

ProcessEnvVars returns a copy of the process-environment inventory, so callers cannot mutate it. SEM@3b682947: list a defensive copy of the process-environment env var inventory (pure)

type RedisConfig

type RedisConfig struct {
	URL        string `yaml:"url" env:"TMI_REDIS_URL"` // Connection string URL (redis://[:password@]host:port[/db]), takes precedence over individual fields; rediss:// also enables TLS
	Host       string `yaml:"host" env:"TMI_REDIS_HOST"`
	Port       string `yaml:"port" env:"TMI_REDIS_PORT"`
	Password   string `yaml:"password" env:"TMI_REDIS_PASSWORD"`
	DB         int    `yaml:"db" env:"TMI_REDIS_DB"`
	TLSEnabled bool   `yaml:"tls_enabled" env:"TMI_REDIS_TLS_ENABLED"` // Connect with TLS; the server cert is verified against tls_ca_file only
	TLSCAFile  string `yaml:"tls_ca_file" env:"TMI_REDIS_TLS_CA_FILE"` // PEM CA that signed the Redis server certificate (required when TLS is on)
}

RedisConfig holds Redis configuration SEM@3b682947: configuration struct for Redis connection coordinates, credentials, and CA-pinned TLS (pure)

type SAMLConfig

type SAMLConfig struct {
	Enabled   bool                          `yaml:"enabled" env:"TMI_SAML_ENABLED"`
	Providers map[string]SAMLProviderConfig `yaml:"providers"`
}

SAMLConfig holds SAML configuration SEM@fe6575f1c15d84b67ee9853a0e59055c1ebe44b6: configuration struct for SAML enabled flag and provider map (pure)

type SAMLProviderConfig

type SAMLProviderConfig struct {
	ID                  string `yaml:"id"`
	Name                string `yaml:"name"`
	Enabled             bool   `yaml:"enabled"`
	Icon                string `yaml:"icon"`
	EntityID            string `yaml:"entity_id"`
	MetadataURL         string `yaml:"metadata_url"`
	MetadataXML         string `yaml:"metadata_xml"`
	ACSURL              string `yaml:"acs_url"`
	SLOURL              string `yaml:"slo_url"`
	SPPrivateKey        string `yaml:"sp_private_key"`
	SPPrivateKeyPath    string `yaml:"sp_private_key_path"`
	SPCertificate       string `yaml:"sp_certificate"`
	SPCertificatePath   string `yaml:"sp_certificate_path"`
	IDPMetadataURL      string `yaml:"idp_metadata_url"`
	IDPMetadataB64XML   string `yaml:"idp_metadata_b64xml"` // Base64-encoded IdP metadata XML
	AllowIDPInitiated   bool   `yaml:"allow_idp_initiated"`
	ForceAuthn          bool   `yaml:"force_authn"`
	SignRequests        bool   `yaml:"sign_requests"`
	NameIDAttribute     string `yaml:"name_id_attribute"`
	EmailAttribute      string `yaml:"email_attribute"`
	NameAttribute       string `yaml:"name_attribute"`
	GivenNameAttribute  string `yaml:"given_name_attribute"`
	FamilyNameAttribute string `yaml:"family_name_attribute"`
	GroupsAttribute     string `yaml:"groups_attribute"`
}

SAMLProviderConfig holds configuration for a SAML provider. It is only ever a value of SAMLConfig.Providers, which overrideStructWithEnv hands to overrideSAMLProviders; that reads SAML_PROVIDERS_<ID>_<FIELD> (no TMI_ prefix), so env tags on these fields would never be consulted and there are none. SEM@3b682947: configuration struct for a single SAML provider's SP/IdP metadata, keys, and attribute mappings (pure)

type SSRFConfig

type SSRFConfig struct {
	IssueURI      SSRFURIConfig `yaml:"issue_uri"`
	DocumentURI   SSRFURIConfig `yaml:"document_uri"`
	RepositoryURI SSRFURIConfig `yaml:"repository_uri"`
	Timmy         SSRFURIConfig `yaml:"timmy"`
	Webhook       SSRFURIConfig `yaml:"webhook"`
}

SSRFConfig holds SSRF protection settings for URI validation SEM@e81aaa612078c97ad77ca1478c9812ee7e86b331: configuration grouping per-URI-type SSRF protection allowlists and scheme restrictions (pure)

type SSRFURIConfig

type SSRFURIConfig struct {
	Allowlist string `yaml:"allowlist"`
	Schemes   string `yaml:"schemes"`
}

SSRFURIConfig holds allowlist and scheme configuration for a single URI type SEM@e81aaa612078c97ad77ca1478c9812ee7e86b331: allowlist and permitted schemes for a single URI category used in SSRF validation (pure)

type SecretResolver

type SecretResolver interface {
	// ResolveVault returns the secret value stored at the given vault path.
	ResolveVault(ctx context.Context, path string) (string, error)
}

SecretResolver dereferences a vault:// secret locator. It is implemented in a package that can import internal/secrets; internal/config cannot import internal/secrets directly (that would create an import cycle, because internal/secrets imports internal/config for config.SecretsConfig). SEM@b583a71af02ca00e2c408d9d52e1e41f514df3ff: interface for dereferencing a vault:// secret path to its plaintext value (pure)

type SecretsConfig

type SecretsConfig struct {
	Provider string `yaml:"provider" env:"TMI_SECRETS_PROVIDER"` // "env" (default), "file", "vault", "aws"

	// Directory holding one file per secret key (provider "file").
	FileDir string `yaml:"file_dir" env:"TMI_SECRETS_FILE_DIR"`

	// HashiCorp Vault (design only - implementation deferred)
	VaultAddress string `yaml:"vault_address" env:"TMI_VAULT_ADDRESS"`
	VaultToken   string `yaml:"vault_token" env:"TMI_VAULT_TOKEN"`
	VaultPath    string `yaml:"vault_path" env:"TMI_VAULT_PATH"`

	// AWS Secrets Manager
	AWSRegion     string `yaml:"aws_region" env:"TMI_AWS_REGION"`
	AWSSecretName string `yaml:"aws_secret_name" env:"TMI_AWS_SECRET_NAME"`
}

SecretsConfig holds configuration for external secret providers SEM@3b682947: configuration struct for external secret-provider selection and per-provider connection settings (pure)

type ServerConfig

type ServerConfig struct {
	Port                string        `yaml:"port" env:"TMI_SERVER_PORT"`
	Interface           string        `yaml:"interface" env:"TMI_SERVER_INTERFACE"`
	BaseURL             string        `yaml:"base_url" env:"TMI_SERVER_BASE_URL"` // Public base URL for callbacks (auto-inferred if empty)
	ReadTimeout         time.Duration `yaml:"read_timeout" env:"TMI_SERVER_READ_TIMEOUT"`
	WriteTimeout        time.Duration `yaml:"write_timeout" env:"TMI_SERVER_WRITE_TIMEOUT"`
	IdleTimeout         time.Duration `yaml:"idle_timeout" env:"TMI_SERVER_IDLE_TIMEOUT"`
	TLSEnabled          bool          `yaml:"tls_enabled" env:"TMI_SERVER_TLS_ENABLED"`
	TLSCertFile         string        `yaml:"tls_cert_file" env:"TMI_SERVER_TLS_CERT_FILE"`
	TLSKeyFile          string        `yaml:"tls_key_file" env:"TMI_SERVER_TLS_KEY_FILE"`
	TLSSubjectName      string        `yaml:"tls_subject_name" env:"TMI_SERVER_TLS_SUBJECT_NAME"`
	HTTPToHTTPSRedirect bool          `yaml:"http_to_https_redirect" env:"TMI_SERVER_HTTP_TO_HTTPS_REDIRECT"`
	TrustedProxies      []string      `yaml:"trusted_proxies" env:"TMI_TRUSTED_PROXIES"`             // Comma-separated CIDRs/IPs for X-Forwarded-For validation
	RateLimitPublicRPM  int           `yaml:"ratelimit_public_rpm" env:"TMI_RATELIMIT_PUBLIC_RPM"`   // Requests/min per IP for public endpoints (default: 10)
	DisableRateLimiting bool          `yaml:"disable_rate_limiting" env:"TMI_DISABLE_RATE_LIMITING"` // Disable all rate limiting (dev/test only)
	// RequireIfMatch controls optimistic-locking enforcement on PUT/PATCH
	// (T14 / #385). When false (default this release), missing If-Match returns
	// a Deprecation/Warning header but the write proceeds. When true, missing
	// If-Match returns 428 Precondition Required. Flip to true in the next release.
	RequireIfMatch bool       `yaml:"require_if_match" env:"TMI_REQUIRE_IF_MATCH"`
	CORS           CORSConfig `yaml:"cors"`
}

ServerConfig holds HTTP server configuration SEM@e81aaa612078c97ad77ca1478c9812ee7e86b331: configuration for the HTTP server port, TLS, timeouts, rate limits, and CORS (pure)

type SettingDef

type SettingDef struct {
	// Key is the canonical dotted setting key, e.g. "server.port".
	Key string
	// Class is the full classification: category, visibility, secrecy,
	// mutability, consumers, delivery.
	Class ConfigClass
	// Type is the value's canonical type: "string", "bool", "int",
	// "float", or "json".
	Type string
	// Description is human-readable and required; it feeds generated docs
	// and the admin API.
	Description string
	// Default is the canonical string form of the compiled-in default.
	// Required for operational settings, which have no config file to
	// fall back to.
	Default string

	// YAMLPath, EnvVar and Get are populated only for settings currently
	// delivered by config file or environment: all bootstrap settings, plus
	// operational settings still in transition (see Transitional).
	YAMLPath string
	EnvVar   string
	// Get extracts this setting's current value from a loaded Config as a
	// canonical string. Nil for settings with no config-file path.
	Get func(*Config) string

	// Transitional marks an operational setting that still has a config/env
	// delivery path during the Phase A-E cutover described in the spec.
	// Every Transitional entry is scheduled for removal in Phase E; the
	// ratchet test in Task 9 prevents new ones from being added.
	Transitional bool

	// Seeded marks an operational setting that is written into the
	// system_settings table on database initialisation. It is deliberately
	// explicit rather than inferred: the set of seeded keys does not
	// coincide with any other property of a setting, and inferring it wrong
	// would either seed rows nobody set or stop seeding rows the server
	// expects. Only operational settings may be Seeded.
	Seeded bool

	// OmitWhenEmpty reproduces the conditional emission of the pre-registry
	// builders: this setting is left out of GetMigratableSettings() entirely
	// when its value is empty, rather than emitted with an empty value.
	//
	// It is load-bearing, not cosmetic. DefaultOperationalSettings() feeds
	// both SeedDefaults (which would otherwise write a row per omitted key on
	// every fresh database) and #794's origin backfill (which uses the same
	// set to decide seeded-vs-explicit, and therefore env-vs-database
	// precedence on existing databases).
	//
	// Phase E removes this along with the rest of the transitional machinery.
	OmitWhenEmpty bool
}

SettingDef is the single authoritative declaration of one configuration setting. Every setting the server can read — bootstrap or operational, config-delivered or database-seeded — has exactly one SettingDef.

Which fields are legal depends on Class.Category; ValidateSettingDefs enforces that (see setting_def_validation.go). SEM@71b4a22251f6acd8a9fb37257d5938c174392b09: declare a single configuration setting's type, class, default, and delivery path

func AllSettingDefs

func AllSettingDefs() []SettingDef

AllSettingDefs returns a copy of the registry, so callers cannot mutate it. SEM@51cab5c0b8755f522c896d5e22ac0a1eb206031f: list a defensive copy of the setting definition registry (pure)

func DefFor

func DefFor(key string) (SettingDef, bool)

DefFor returns the declaration for a setting key, and whether one exists. SEM@51cab5c0b8755f522c896d5e22ac0a1eb206031f: fetch a setting's registry declaration by key (pure)

func SeedableOperationalDefs

func SeedableOperationalDefs() []SettingDef

SeedableOperationalDefs returns the operational settings that should be seeded into system_settings on database initialisation, sorted by key.

This is the single source for the seed list. DefaultSystemSettings() in api/models projects it, rather than maintaining a parallel list — the parallel list is what left rate_limit.requests_per_minute and rate_limit.requests_per_hour seeded but unclassified (#809).

Filtering on Seeded, not just CategoryOperational, is deliberate: the registry holds far more operational defs (config/env-delivered knobs like websocket.inactivity_timeout_seconds) than are ever written into system_settings. Seeded marks exactly the subset that is. SEM@62e82fc4e96a1c18f4e1ac1d698de4fefb974b42: list operational settings that should be seeded into the database (pure)

func (SettingDef) IsSecret

func (d SettingDef) IsSecret() bool

IsSecret reports whether this setting's value must never appear in an API response or a log line.

This answers the question only for STATICALLY DECLARED settings. The per-provider keys under auth.oauth.providers., auth.saml.providers. and content_oauth.providers. are generated per configured provider and have no SettingDef; for those, Class.Secret is deliberately false (a blanket true would mis-mask non-secret sub-keys like .client_id) and secrecy is carried only by the per-setting Secret flag that the provider helpers set on .client_secret, .sp_private_key and .idp_metadata_b64xml. Never reach for this method to decide secrecy for a provider key — use MigratableSetting.IsSecret(), which ORs both flags. SEM@51cab5c0b8755f522c896d5e22ac0a1eb206031f: report whether a statically declared setting's value must be masked (pure)

type StampedConfig

type StampedConfig struct {
	Embedding EmbeddingProfile `json:"embedding"`
}

StampedConfig is the subset of operational configuration the monolith stamps into every job envelope. It carries only non-secret values; secrets are resolved from mounted secret sources by each consumer. SEM@f0ba616243817f3864baaeb58b887479f81abb8e: non-secret operational config the monolith stamps into every job envelope (pure)

func (StampedConfig) Validate

func (s StampedConfig) Validate() error

Validate returns an error if the stamped configuration is incomplete. SEM@f0ba616243817f3864baaeb58b887479f81abb8e: validate that a stamped config contains a complete embedding profile (pure)

type StampedConfigProvider

type StampedConfigProvider interface {
	Get(ctx context.Context) (StampedConfig, error)
}

StampedConfigProvider is the single read point for stamped configuration. Both the monolith's job-envelope builder and the monolith's own Timmy query path read through this interface, which is what makes the shared-invariant guarantee structural rather than a matter of discipline. SEM@f0ba616243817f3864baaeb58b887479f81abb8e: interface for fetching the current stamped config used by job envelope builders and query paths

type TimmyConfig

type TimmyConfig struct {
	Enabled     bool   `yaml:"enabled" env:"TMI_TIMMY_ENABLED"`
	LLMProvider string `yaml:"llm_provider" env:"TMI_TIMMY_LLM_PROVIDER"`
	LLMModel    string `yaml:"llm_model" env:"TMI_TIMMY_LLM_MODEL"`
	LLMAPIKey   string `yaml:"llm_api_key" env:"TMI_TIMMY_LLM_API_KEY"`
	LLMBaseURL  string `yaml:"llm_base_url" env:"TMI_TIMMY_LLM_BASE_URL"`
	// LLMMaxTokens is the maximum tokens a chat completion may generate.
	// Anthropic's Messages API requires it on every request (#754 phase 2);
	// OpenAI's does not. Zero means "use the provider backend's default"
	// (internal/llm.anthropicDefaultMaxTokens for Anthropic; unset/provider
	// default for OpenAI) — see DefaultTimmyConfig for the seeded value.
	LLMMaxTokens                    int    `yaml:"llm_max_tokens" env:"TMI_TIMMY_LLM_MAX_TOKENS"`
	TextEmbeddingProvider           string `yaml:"text_embedding_provider" env:"TMI_TIMMY_TEXT_EMBEDDING_PROVIDER"`
	TextEmbeddingModel              string `yaml:"text_embedding_model" env:"TMI_TIMMY_TEXT_EMBEDDING_MODEL"`
	TextEmbeddingAPIKey             string `yaml:"text_embedding_api_key" env:"TMI_TIMMY_TEXT_EMBEDDING_API_KEY"`
	TextEmbeddingBaseURL            string `yaml:"text_embedding_base_url" env:"TMI_TIMMY_TEXT_EMBEDDING_BASE_URL"`
	EmbeddingDimension              int    `yaml:"embedding_dimension" env:"TMI_TIMMY_EMBEDDING_DIMENSION"`
	TextRetrievalTopK               int    `yaml:"text_retrieval_top_k" env:"TMI_TIMMY_TEXT_RETRIEVAL_TOP_K"`
	CodeEmbeddingProvider           string `yaml:"code_embedding_provider" env:"TMI_TIMMY_CODE_EMBEDDING_PROVIDER"`
	CodeEmbeddingModel              string `yaml:"code_embedding_model" env:"TMI_TIMMY_CODE_EMBEDDING_MODEL"`
	CodeEmbeddingAPIKey             string `yaml:"code_embedding_api_key" env:"TMI_TIMMY_CODE_EMBEDDING_API_KEY"`
	CodeEmbeddingBaseURL            string `yaml:"code_embedding_base_url" env:"TMI_TIMMY_CODE_EMBEDDING_BASE_URL"`
	CodeRetrievalTopK               int    `yaml:"code_retrieval_top_k" env:"TMI_TIMMY_CODE_RETRIEVAL_TOP_K"`
	QueryDecompositionEnabled       bool   `yaml:"query_decomposition_enabled" env:"TMI_TIMMY_QUERY_DECOMPOSITION_ENABLED"`
	RerankProvider                  string `yaml:"rerank_provider" env:"TMI_TIMMY_RERANK_PROVIDER"`
	RerankModel                     string `yaml:"rerank_model" env:"TMI_TIMMY_RERANK_MODEL"`
	RerankAPIKey                    string `yaml:"rerank_api_key" env:"TMI_TIMMY_RERANK_API_KEY"`
	RerankBaseURL                   string `yaml:"rerank_base_url" env:"TMI_TIMMY_RERANK_BASE_URL"`
	RerankTopK                      int    `yaml:"rerank_top_k" env:"TMI_TIMMY_RERANK_TOP_K"`
	MaxConversationHistory          int    `yaml:"max_conversation_history" env:"TMI_TIMMY_MAX_CONVERSATION_HISTORY"`
	OperatorSystemPrompt            string `yaml:"operator_system_prompt" env:"TMI_TIMMY_OPERATOR_SYSTEM_PROMPT"`
	MaxMemoryMB                     int    `yaml:"max_memory_mb" env:"TMI_TIMMY_MAX_MEMORY_MB"`
	InactivityTimeoutSeconds        int    `yaml:"inactivity_timeout_seconds" env:"TMI_TIMMY_INACTIVITY_TIMEOUT_SECONDS"`
	MaxMessagesPerUserPerHour       int    `yaml:"max_messages_per_user_per_hour" env:"TMI_TIMMY_MAX_MESSAGES_PER_USER_PER_HOUR"`
	MaxSessionsPerThreatModel       int    `yaml:"max_sessions_per_threat_model" env:"TMI_TIMMY_MAX_SESSIONS_PER_THREAT_MODEL"`
	MaxConcurrentLLMRequests        int    `yaml:"max_concurrent_llm_requests" env:"TMI_TIMMY_MAX_CONCURRENT_LLM_REQUESTS"`
	ChunkSize                       int    `yaml:"chunk_size" env:"TMI_TIMMY_CHUNK_SIZE"`
	ChunkOverlap                    int    `yaml:"chunk_overlap" env:"TMI_TIMMY_CHUNK_OVERLAP"`
	LLMTimeoutSeconds               int    `yaml:"llm_timeout_seconds" env:"TMI_TIMMY_LLM_TIMEOUT_SECONDS"`
	EmbeddingCleanupIntervalMinutes int    `yaml:"embedding_cleanup_interval_minutes" env:"TMI_TIMMY_EMBEDDING_CLEANUP_INTERVAL_MINUTES"`
	EmbeddingIdleDaysActive         int    `yaml:"embedding_idle_days_active" env:"TMI_TIMMY_EMBEDDING_IDLE_DAYS_ACTIVE"`
	EmbeddingIdleDaysClosed         int    `yaml:"embedding_idle_days_closed" env:"TMI_TIMMY_EMBEDDING_IDLE_DAYS_CLOSED"`

	// DumpExtractedTextToNote, when true, persists the markdown produced by
	// each successful content extraction as a Note on the parent threat
	// model. Dev/test inspection aid only — the server refuses to start
	// with this flag enabled if Auth.BuildMode == "production".
	DumpExtractedTextToNote bool `yaml:"dump_extracted_text_to_note" env:"TMI_TIMMY_DUMP_EXTRACTED_TEXT_TO_NOTE"`
}

TimmyConfig holds configuration for the Timmy AI assistant feature SEM@f7cc4344884e20bc7f6fb9a5815e2e1d530c0ff6: hold configuration for the Timmy AI assistant feature (pure)

func DefaultTimmyConfig

func DefaultTimmyConfig() TimmyConfig

DefaultTimmyConfig returns configuration with sensible defaults SEM@f7cc4344884e20bc7f6fb9a5815e2e1d530c0ff6: build a TimmyConfig populated with sensible operational defaults (pure)

func (TimmyConfig) IsCodeIndexConfigured

func (tc TimmyConfig) IsCodeIndexConfigured() bool

IsCodeIndexConfigured returns true if the code embedding provider and model are configured SEM@37a05c9c7bcde023781ade490d31e55313f5a793: validate that code embedding provider and model are configured (pure)

func (TimmyConfig) IsConfigured

func (tc TimmyConfig) IsConfigured() bool

IsConfigured returns true if the required LLM and text embedding providers are configured SEM@37a05c9c7bcde023781ade490d31e55313f5a793: validate that LLM and text embedding providers are configured (pure)

func (TimmyConfig) IsRerankConfigured

func (tc TimmyConfig) IsRerankConfigured() bool

IsRerankConfigured returns true if the reranker provider and model are configured SEM@cd3e5390e6efba1b5a645e4a00ef2a5b842d39ff: validate that reranker provider and model are configured (pure)

func (TimmyConfig) ValidateLLMMaxTokens

func (tc TimmyConfig) ValidateLLMMaxTokens() error

ValidateLLMMaxTokens reports whether LLMMaxTokens is a valid value. Zero is not an error — it means "use the backend's default" (see DefaultTimmyConfig and internal/llm.anthropicDefaultMaxTokens) — only a negative value is rejected. SEM@f7cc4344884e20bc7f6fb9a5815e2e1d530c0ff6: validate that LLMMaxTokens is non-negative (pure)

func (TimmyConfig) ValidateLLMProvider

func (tc TimmyConfig) ValidateLLMProvider() error

ValidateLLMProvider reports whether LLMProvider is a recognized value. An empty LLMProvider is not an error here — that "not configured" state is IsConfigured's concern; this method only rejects an unrecognized non-empty value, which deserves its own message rather than being folded into "not configured." SEM@f7cc4344884e20bc7f6fb9a5815e2e1d530c0ff6: validate that a non-empty LLMProvider is a recognized provider name (pure)

type UserInfoEndpoint

type UserInfoEndpoint struct {
	URL    string            `yaml:"url" json:"url"`
	Claims map[string]string `yaml:"claims" json:"claims,omitempty"`
}

UserInfoEndpoint represents a single userinfo endpoint and its claim mappings SEM@ef979cc7527137e0448782341a4ffe8e944571f5: configuration struct for a userinfo endpoint URL and its claim mappings (pure)

type ValueKind

type ValueKind int

ValueKind answers: is the stored value the secret itself, or a pointer to it?

The registry records the DEFAULT (inline) kind of a setting. A secret VALUE may still be a vault://, env://, or file:// reference at runtime: the same key is typically inline in dev and a reference in prod. Such references are dereferenced at startup, per value, by ResolveSecretValue (see secret_reference.go) — IsSecretReference inspects the value's scheme prefix, so no registry change is needed to support a reference value.

ValueKindReference in the REGISTRY is therefore reserved for a key that is ALWAYS a reference regardless of deployment; today no key is classified that way, so the "ValueKindReference => Secret" validation rule holds vacuously. SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: enum indicating whether a config field holds an inline value or a secret reference (pure)

const (
	// ValueKindInline means the field holds the actual value. This is the
	// zero value and a safe default for non-secret settings. A secret field
	// classified inline may still carry a vault://, env://, or file://
	// reference value, resolved at load time by ResolveSecretValue.
	ValueKindInline ValueKind = iota
	// ValueKindReference means the field ALWAYS holds a locator (vault://...,
	// a file path, an env-var name) dereferenced at use time, in every
	// deployment. Only valid when Secret. Per-value references on an
	// otherwise-inline key do NOT require this — see the type doc above.
	ValueKindReference
)

func (ValueKind) String

func (v ValueKind) String() string

SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: convert a ValueKind to its canonical string name (pure)

type Visibility

type Visibility int

Visibility answers: who may read this setting through the API? SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: enum classifying which API audience may read a config setting (pure)

const (
	// VisibilityInternal: server-side only, never in any API response.
	VisibilityInternal Visibility = iota
	// VisibilityAdminOnly: visible to admins via /admin config endpoints.
	VisibilityAdminOnly
	// VisibilityPublic: exposed on the unauthenticated /config endpoint.
	VisibilityPublic
)

func (Visibility) String

func (v Visibility) String() string

SEM@84a87a09a2929e0ab55a7f5b5a619f296148d6a1: convert a Visibility to its canonical string name (pure)

type WebSocketConfig

type WebSocketConfig struct {
	InactivityTimeoutSeconds int `yaml:"inactivity_timeout_seconds" env:"TMI_WEBSOCKET_INACTIVITY_TIMEOUT_SECONDS"`
}

WebSocketConfig holds WebSocket timeout configuration SEM@fe6575f1c15d84b67ee9853a0e59055c1ebe44b6: configuration struct for WebSocket session inactivity timeout (pure)

type WebhookConfig

type WebhookConfig struct {
	AllowHTTPTargets bool `yaml:"allow_http_targets" env:"TMI_WEBHOOK_ALLOW_HTTP_TARGETS"` // Allow non-HTTPS webhook URLs (e.g., for intra-cluster communication)
}

WebhookConfig holds webhook configuration SEM@baf9ecb79a22da23c9922e1df63b14cb07d01523: configuration struct controlling whether non-HTTPS webhook targets are permitted (pure)

Directories

Path Synopsis
Package bootstrap provides the minimal, environment-only configuration a TMI worker component needs to start and reach the point where it can accept a job.
Package bootstrap provides the minimal, environment-only configuration a TMI worker component needs to start and reach the point where it can accept a job.

Jump to

Keyboard shortcuts

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